Merge inbound to mozilla-central r=merge a=merge
authorBogdan Tara <btara@mozilla.com>
Mon, 04 Dec 2017 22:20:49 +0200
changeset 394895 7d191882de19faa537753b2deaea9444277a6533
parent 394862 4a003542df78bc7f08b37c4759e3a64c71e74552 (current diff)
parent 394894 d1b45fb8d2049dd04d169582e099a34140abfdfe (diff)
child 394896 5be384bcf00191f97d32b4ac3ecd1b85ec7b18e1
push id33020
push userbtara@mozilla.com
push dateMon, 04 Dec 2017 20:21:20 +0000
treeherdermozilla-central@7d191882de19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone59.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
Merge inbound to mozilla-central r=merge a=merge
dom/webidl/RTCPeerConnection.webidl
old-configure.in
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/css/compositing/mix-blend-mode/mix-blend-mode-transition.html
testing/web-platform/tests/css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html
xpcom/threads/LabeledEventQueue.cpp
xpcom/threads/LabeledEventQueue.h
--- a/browser/base/content/test/alerts/browser.ini
+++ b/browser/base/content/test/alerts/browser.ini
@@ -5,10 +5,11 @@ support-files =
 
 [browser_notification_close.js]
 skip-if = os == 'win' # Bug 1227785
 [browser_notification_do_not_disturb.js]
 skip-if = os == 'win' # Bug 1352791
 [browser_notification_open_settings.js]
 skip-if = os == 'win' # Bug 1411118
 [browser_notification_remove_permission.js]
+skip-if = os == 'win' # Bug 1411118
 [browser_notification_replace.js]
 [browser_notification_tab_switching.js]
--- a/browser/base/content/test/performance/browser_startup_flicker.js
+++ b/browser/base/content/test/performance/browser_startup_flicker.js
@@ -36,17 +36,18 @@ add_task(async function() {
     }
 
     rects = rects.filter(rect => {
       let inRange = (val, min, max) => min <= val && val <= max;
       let width = frame.width;
 
       let exceptions = [
         {name: "bug 1403648 - urlbar down arrow shouldn't flicker",
-         condition: r => r.h == 5 && inRange(r.w, 8, 9) && // 5x9px area
+         condition: r => // 5x9px area, sometimes less at the end of the opacity transition
+                         inRange(r.h, 3, 5) && inRange(r.w, 7, 9) &&
                          inRange(r.y1, 40, 80) && // in the toolbar
                          // at ~80% of the window width
                          inRange(r.x1, width * .75, width * .9)
         },
 
         {name: "bug 1394914 - sidebar toolbar icon should be visible at first paint",
          condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size
                          inRange(r.y1, 40, 80) && // in the toolbar
--- a/browser/base/content/test/performance/browser_windowopen_flicker.js
+++ b/browser/base/content/test/performance/browser_windowopen_flicker.js
@@ -66,49 +66,58 @@ add_task(async function() {
       Services.tm.idleDispatchToMainThread(() => {
         waitForIdle(count - 1);
       });
     })();
   });
   win.removeEventListener("MozAfterPaint", afterPaintListener);
 
   let unexpectedRects = 0;
-  let foundTinyPaint = false;
+  let ignoreTinyPaint = true;
   for (let i = 1; i < frames.length; ++i) {
     let frame = frames[i], previousFrame = frames[i - 1];
-    if (!foundTinyPaint &&
+    if (ignoreTinyPaint &&
         previousFrame.width == 1 && previousFrame.height == 1) {
-      foundTinyPaint = true;
-      todo(false, "shouldn't first paint a 1x1px window");
+      todo(false, "shouldn't initially paint a 1x1px window");
       continue;
     }
 
+    ignoreTinyPaint = false;
     let rects = compareFrames(frame, previousFrame).filter(rect => {
       let inRange = (val, min, max) => min <= val && val <= max;
       let width = frame.width;
 
       const spaceBeforeFirstTab = AppConstants.platform == "macosx" ? 100 : 0;
       let inFirstTab = r =>
         inRange(r.x1, spaceBeforeFirstTab, spaceBeforeFirstTab + 50) && r.y1 < 30;
 
       let exceptions = [
         {name: "bug 1403648 - urlbar down arrow shouldn't flicker",
-         condition: r => r.h == 5 && inRange(r.w, 8, 9) && // 5x9px area
+         condition: r => // 5x9px area, sometimes less at the end of the opacity transition
+                         inRange(r.h, 3, 5) && inRange(r.w, 7, 9) &&
                          inRange(r.y1, 40, 80) && // in the toolbar
                          // at ~80% of the window width
                          inRange(r.x1, width * .75, width * .9)
         },
 
         {name: "bug 1394914 - sidebar toolbar icon should be visible at first paint",
          condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size
                          inRange(r.y1, 40, 80) && // in the toolbar
                          // near the right end of screen
                          inRange(r.x1, width - 100, width - 50)
         },
 
+        {name: "bug 1403648 - urlbar should be focused at first paint",
+         condition: r => inRange(r.y2, 60, 80) && // in the toolbar
+                         // taking 50% to 75% of the window width
+                         inRange(r.w, width * .5, width * .75) &&
+                         // starting at 15 to 25% of the window width
+                         inRange(r.x1, width * .15, width * .25)
+        },
+
         {name: "bug 1421463 - reload toolbar icon shouldn't flicker",
          condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size
                          inRange(r.y1, 40, 80) && // in the toolbar
                          // near the left side of the screen
                          inRange(r.x1, 65, 100)
         },
 
         {name: "bug 1401955 - about:home favicon should be visible at first paint",
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -2705,17 +2705,18 @@ var SessionStoreInternal = {
 
     let activePageData = tabData.entries[tabData.index - 1] || null;
 
     // If the page has a title, set it.
     if (activePageData) {
       if (activePageData.title &&
           activePageData.title != activePageData.url) {
         win.gBrowser.setInitialTabTitle(tab, activePageData.title, { isContentTitle: true });
-      } else if (activePageData.url != "about:blank") {
+      } else if (activePageData.url != "about:blank" &&
+                 activePageData.url != "about:newtab") {
         win.gBrowser.setInitialTabTitle(tab, activePageData.url);
       }
     }
 
     // Restore the tab icon.
     if ("image" in tabData) {
       // Use the serialized contentPrincipal with the new icon load.
       let loadingPrincipal = Utils.deserializePrincipal(tabData.iconLoadingPrincipal);
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1251,16 +1251,29 @@ def pgo_flags(compiler):
         )
 
 
 set_config('PROFILE_GEN_CFLAGS', pgo_flags.gen_cflags)
 set_config('PROFILE_GEN_LDFLAGS', pgo_flags.gen_ldflags)
 set_config('PROFILE_USE_CFLAGS', pgo_flags.use_cflags)
 set_config('PROFILE_USE_LDFLAGS', pgo_flags.use_ldflags)
 
+
+@depends(c_compiler)
+def preprocess_option(compiler):
+    # The uses of PREPROCESS_OPTION depend on the spacing for -o/-Fi.
+    if compiler.type in ('gcc', 'clang'):
+        return '-E -o '
+    else:
+        return '-P -Fi'
+
+
+set_config('PREPROCESS_OPTION', preprocess_option)
+
+
 # We only want to include windows.configure when we are compiling on
 # Windows, for Windows.
 
 
 @depends(target, host)
 def is_windows(target, host):
     return host.kernel == 'WINNT' and target.kernel == 'WINNT'
 
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -677,16 +677,17 @@ nsContentSink::ProcessLinkHeader(const n
       href.Truncate();
       rel.Truncate();
       title.Truncate();
       type.Truncate();
       media.Truncate();
       anchor.Truncate();
       referrerPolicy.Truncate();
       crossOrigin.SetIsVoid(true);
+      as.Truncate();
 
       seenParameters = false;
     }
 
     start = ++end;
   }
 
   href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
--- a/dom/clients/manager/ClientManagerActors.cpp
+++ b/dom/clients/manager/ClientManagerActors.cpp
@@ -32,10 +32,17 @@ AllocClientManagerParent()
 
 bool
 DeallocClientManagerParent(PClientManagerParent* aActor)
 {
   delete aActor;
   return true;
 }
 
+void
+InitClientManagerParent(PClientManagerParent* aActor)
+{
+  auto actor = static_cast<ClientManagerParent*>(aActor);
+  actor->Init();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/clients/manager/ClientManagerActors.h
+++ b/dom/clients/manager/ClientManagerActors.h
@@ -19,13 +19,16 @@ bool
 DeallocClientManagerChild(PClientManagerChild* aActor);
 
 PClientManagerParent*
 AllocClientManagerParent();
 
 bool
 DeallocClientManagerParent(PClientManagerParent* aActor);
 
+void
+InitClientManagerParent(PClientManagerParent* aActor);
+
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // _mozilla_dom_ClientManagerActors_h
--- a/dom/clients/manager/ClientManagerParent.cpp
+++ b/dom/clients/manager/ClientManagerParent.cpp
@@ -112,12 +112,19 @@ ClientManagerParent::RecvPClientSourceCo
 
 ClientManagerParent::ClientManagerParent()
   : mService(ClientManagerService::GetOrCreateInstance())
 {
 }
 
 ClientManagerParent::~ClientManagerParent()
 {
+  mService->RemoveManager(this);
+}
+
+void
+ClientManagerParent::Init()
+{
+  mService->AddManager(this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/clients/manager/ClientManagerParent.h
+++ b/dom/clients/manager/ClientManagerParent.h
@@ -58,14 +58,17 @@ class ClientManagerParent final : public
 
   mozilla::ipc::IPCResult
   RecvPClientSourceConstructor(PClientSourceParent* aActor,
                                const ClientSourceConstructorArgs& aArgs) override;
 
 public:
   ClientManagerParent();
   ~ClientManagerParent();
+
+  void
+  Init();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // _mozilla_dom_ClientManagerParent_h
--- a/dom/clients/manager/ClientManagerService.cpp
+++ b/dom/clients/manager/ClientManagerService.cpp
@@ -1,19 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ClientManagerService.h"
 
+#include "ClientManagerParent.h"
 #include "ClientSourceParent.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/SystemGroup.h"
+#include "nsIAsyncShutdown.h"
 
 namespace mozilla {
 namespace dom {
 
 using mozilla::ipc::AssertIsOnBackgroundThread;
 using mozilla::ipc::ContentPrincipalInfo;
 using mozilla::ipc::PrincipalInfo;
 
@@ -51,46 +55,175 @@ MatchPrincipalInfo(const PrincipalInfo& 
       break;
     }
   }
 
   // Clients (windows/workers) should never have an expanded principal type.
   MOZ_CRASH("unexpected principal type!");
 }
 
+class ClientShutdownBlocker final : public nsIAsyncShutdownBlocker
+{
+  RefPtr<GenericPromise::Private> mPromise;
+
+  ~ClientShutdownBlocker() = default;
+
+public:
+  explicit ClientShutdownBlocker(GenericPromise::Private* aPromise)
+    : mPromise(aPromise)
+  {
+    MOZ_DIAGNOSTIC_ASSERT(mPromise);
+  }
+
+  NS_IMETHOD
+  GetName(nsAString& aNameOut) override
+  {
+    aNameOut =
+      NS_LITERAL_STRING("ClientManagerService: start destroying IPC actors early");
+    return NS_OK;
+  }
+
+  NS_IMETHOD
+  BlockShutdown(nsIAsyncShutdownClient* aClient) override
+  {
+    mPromise->Resolve(true, __func__);
+    aClient->RemoveBlocker(this);
+    return NS_OK;
+  }
+
+  NS_IMETHOD
+  GetState(nsIPropertyBag**) override
+  {
+    return NS_OK;
+  }
+
+  NS_DECL_ISUPPORTS
+};
+
+NS_IMPL_ISUPPORTS(ClientShutdownBlocker, nsIAsyncShutdownBlocker)
+
+// Helper function the resolves a MozPromise when we detect that the browser
+// has begun to shutdown.
+RefPtr<GenericPromise>
+OnShutdown()
+{
+  RefPtr<GenericPromise::Private> ref = new GenericPromise::Private(__func__);
+
+  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("ClientManagerServer::OnShutdown",
+  [ref] () {
+    nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
+    if (!svc) {
+      ref->Resolve(true, __func__);
+      return;
+    }
+
+    nsCOMPtr<nsIAsyncShutdownClient> phase;
+    MOZ_ALWAYS_SUCCEEDS(svc->GetXpcomWillShutdown(getter_AddRefs(phase)));
+    if (!phase) {
+      ref->Resolve(true, __func__);
+      return;
+    }
+
+    nsCOMPtr<nsIAsyncShutdownBlocker> blocker = new ClientShutdownBlocker(ref);
+    nsresult rv =
+      phase->AddBlocker(blocker, NS_LITERAL_STRING(__FILE__), __LINE__,
+                        NS_LITERAL_STRING("ClientManagerService shutdown"));
+
+    if (NS_FAILED(rv)) {
+      ref->Resolve(true, __func__);
+      return;
+    }
+  });
+
+  MOZ_ALWAYS_SUCCEEDS(
+    SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
+
+  return ref.forget();
+}
+
 } // anonymous namespace
 
 ClientManagerService::ClientManagerService()
+  : mShutdown(false)
 {
   AssertIsOnBackgroundThread();
+
+  // While the ClientManagerService will be gracefully terminated as windows
+  // and workers are naturally killed, this can cause us to do extra work
+  // relatively late in the shutdown process.  To avoid this we eagerly begin
+  // shutdown at the first sign it has begun.  Since we handle normal shutdown
+  // gracefully we don't really need to block anything here.  We just begin
+  // destroying our IPC actors immediately.
+  OnShutdown()->Then(GetCurrentThreadSerialEventTarget(), __func__,
+    [] () {
+      RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance();
+      if (svc) {
+        svc->Shutdown();
+      }
+    });
 }
 
 ClientManagerService::~ClientManagerService()
 {
   AssertIsOnBackgroundThread();
   MOZ_DIAGNOSTIC_ASSERT(mSourceTable.Count() == 0);
+  MOZ_DIAGNOSTIC_ASSERT(mManagerList.IsEmpty());
 
   MOZ_DIAGNOSTIC_ASSERT(sClientManagerServiceInstance == this);
   sClientManagerServiceInstance = nullptr;
 }
 
+void
+ClientManagerService::Shutdown()
+{
+  AssertIsOnBackgroundThread();
+
+  // If many ClientManagerService are created and destroyed quickly we can
+  // in theory get more than one shutdown listener calling us.
+  if (mShutdown) {
+    return;
+  }
+  mShutdown = true;
+
+  // Begin destroying our various manager actors which will in turn destroy
+  // all source, handle, and operation actors.
+  AutoTArray<ClientManagerParent*, 16> list(mManagerList);
+  for (auto actor : list) {
+    Unused << PClientManagerParent::Send__delete__(actor);
+  }
+}
+
 // static
 already_AddRefed<ClientManagerService>
 ClientManagerService::GetOrCreateInstance()
 {
   AssertIsOnBackgroundThread();
 
   if (!sClientManagerServiceInstance) {
     sClientManagerServiceInstance = new ClientManagerService();
   }
 
   RefPtr<ClientManagerService> ref(sClientManagerServiceInstance);
   return ref.forget();
 }
 
+// static
+already_AddRefed<ClientManagerService>
+ClientManagerService::GetInstance()
+{
+  AssertIsOnBackgroundThread();
+
+  if (!sClientManagerServiceInstance) {
+    return nullptr;
+  }
+
+  RefPtr<ClientManagerService> ref(sClientManagerServiceInstance);
+  return ref.forget();
+}
+
 bool
 ClientManagerService::AddSource(ClientSourceParent* aSource)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aSource);
   auto entry = mSourceTable.LookupForAdd(aSource->Info().Id());
   // Do not permit overwriting an existing ClientSource with the same
   // UUID.  This would allow a spoofed ClientParentSource actor to
@@ -129,10 +262,33 @@ ClientManagerService::FindSource(const n
   if (source->IsFrozen() ||
       !MatchPrincipalInfo(source->Info().PrincipalInfo(), aPrincipalInfo)) {
     return nullptr;
   }
 
   return source;
 }
 
+void
+ClientManagerService::AddManager(ClientManagerParent* aManager)
+{
+  AssertIsOnBackgroundThread();
+  MOZ_DIAGNOSTIC_ASSERT(aManager);
+  MOZ_ASSERT(!mManagerList.Contains(aManager));
+  mManagerList.AppendElement(aManager);
+
+  // If shutdown has already begun then immediately destroy the actor.
+  if (mShutdown) {
+    Unused << PClientManagerParent::Send__delete__(aManager);
+  }
+}
+
+void
+ClientManagerService::RemoveManager(ClientManagerParent* aManager)
+{
+  AssertIsOnBackgroundThread();
+  MOZ_DIAGNOSTIC_ASSERT(aManager);
+  DebugOnly<bool> removed = mManagerList.RemoveElement(aManager);
+  MOZ_ASSERT(removed);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/clients/manager/ClientManagerService.h
+++ b/dom/clients/manager/ClientManagerService.h
@@ -2,49 +2,68 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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_dom_ClientManagerService_h
 #define _mozilla_dom_ClientManagerService_h
 
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "mozilla/MozPromise.h"
 #include "nsDataHashtable.h"
 
 namespace mozilla {
 
 namespace dom {
 
+class ClientManagerParent;
 class ClientSourceParent;
 
 // Define a singleton service to manage client activity throughout the
 // browser.  This service runs on the PBackground thread.  To interact
 // it with it please use the ClientManager and ClientHandle classes.
 class ClientManagerService final
 {
   // Store the ClientSourceParent objects in a hash table.  We want to
   // optimize for insertion, removal, and lookup by UUID.
   nsDataHashtable<nsIDHashKey, ClientSourceParent*> mSourceTable;
 
+  nsTArray<ClientManagerParent*> mManagerList;
+
+  bool mShutdown;
+
   ClientManagerService();
   ~ClientManagerService();
 
+  void
+  Shutdown();
+
 public:
   static already_AddRefed<ClientManagerService>
   GetOrCreateInstance();
 
+  // Returns nullptr if the service is not already created.
+  static already_AddRefed<ClientManagerService>
+  GetInstance();
+
   bool
   AddSource(ClientSourceParent* aSource);
 
   bool
   RemoveSource(ClientSourceParent* aSource);
 
   ClientSourceParent*
   FindSource(const nsID& aID,
              const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
 
+  void
+  AddManager(ClientManagerParent* aManager);
+
+  void
+  RemoveManager(ClientManagerParent* aManager);
+
   NS_INLINE_DECL_REFCOUNTING(mozilla::dom::ClientManagerService)
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // _mozilla_dom_ClientManagerService_h
--- a/dom/file/nsHostObjectProtocolHandler.cpp
+++ b/dom/file/nsHostObjectProtocolHandler.cpp
@@ -18,16 +18,17 @@
 #include "mozilla/LoadInfo.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SystemGroup.h"
 #include "nsClassHashtable.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsHostObjectURI.h"
+#include "nsIAsyncShutdown.h"
 #include "nsIMemoryReporter.h"
 #include "nsIPrincipal.h"
 #include "nsIUUIDGenerator.h"
 #include "nsNetUtil.h"
 
 #define RELEASING_TIMER 5000
 
 using namespace mozilla;
@@ -432,87 +433,166 @@ class BlobURLsReporter final : public ns
     }
   }
 };
 
 NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter)
 
 class ReleasingTimerHolder final : public nsITimerCallback
                                  , public nsINamed
+                                 , public nsIAsyncShutdownBlocker
 {
 public:
   NS_DECL_ISUPPORTS
 
   static void
   Create(const nsACString& aURI, bool aBroadcastToOtherProcesses)
   {
+    MOZ_ASSERT(NS_IsMainThread());
+
     RefPtr<ReleasingTimerHolder> holder =
       new ReleasingTimerHolder(aURI, aBroadcastToOtherProcesses);
+
+    auto raii = mozilla::MakeScopeExit([&] {
+      holder->CancelTimerAndRevokeURI();
+    });
+
     nsresult rv = NS_NewTimerWithCallback(getter_AddRefs(holder->mTimer),
                                           holder, RELEASING_TIMER,
                                           nsITimer::TYPE_ONE_SHOT,
                                           SystemGroup::EventTargetFor(TaskCategory::Other));
     NS_ENSURE_SUCCESS_VOID(rv);
+
+    nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase();
+    NS_ENSURE_TRUE_VOID(!!phase);
+
+    rv = phase->AddBlocker(holder, NS_LITERAL_STRING(__FILE__), __LINE__,
+                           NS_LITERAL_STRING("ReleasingTimerHolder shutdown"));
+    NS_ENSURE_SUCCESS_VOID(rv);
+
+    raii.release();
   }
 
+  // nsITimerCallback interface
+
   NS_IMETHOD
   Notify(nsITimer* aTimer) override
   {
+    RevokeURI(mBroadcastToOtherProcesses);
+    return NS_OK;
+  }
+
+  // nsINamed interface
+
+  NS_IMETHOD
+  GetName(nsACString& aName) override
+  {
+    aName.AssignLiteral("ReleasingTimerHolder");
+    return NS_OK;
+  }
+
+  // nsIAsyncShutdownBlocker interface
+
+  NS_IMETHOD
+  GetName(nsAString& aName) override
+  {
+    aName.AssignLiteral("ReleasingTimerHolder");
+    return NS_OK;
+  }
+
+  NS_IMETHOD
+  BlockShutdown(nsIAsyncShutdownClient* aClient) override
+  {
+    CancelTimerAndRevokeURI();
+    return NS_OK;
+  }
+
+  NS_IMETHOD
+  GetState(nsIPropertyBag**) override
+  {
+    return NS_OK;
+  }
+
+private:
+  ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses)
+    : mURI(aURI)
+    , mBroadcastToOtherProcesses(aBroadcastToOtherProcesses)
+  {}
+
+  ~ReleasingTimerHolder()
+  {}
+
+  void
+  RevokeURI(bool aBroadcastToOtherProcesses)
+  {
+    // Remove the shutting down blocker
+    nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase();
+    if (phase) {
+      phase->RemoveBlocker(this);
+    }
+
     // If we have to broadcast the unregistration, let's do it now.
-    if (mBroadcastToOtherProcesses) {
+    if (aBroadcastToOtherProcesses) {
       BroadcastBlobURLUnregistration(mURI);
     }
 
     DataInfo* info = GetDataInfo(mURI, true /* We care about revoked dataInfo */);
     if (!info) {
       // Already gone!
-      return NS_OK;
+      return;
     }
 
     MOZ_ASSERT(info->mRevoked);
 
     for (uint32_t i = 0; i < info->mURIs.Length(); ++i) {
       nsCOMPtr<nsIURI> uri = do_QueryReferent(info->mURIs[i]);
       if (uri) {
         static_cast<nsHostObjectURI*>(uri.get())->ForgetBlobImpl();
       }
     }
 
     gDataTable->Remove(mURI);
     if (gDataTable->Count() == 0) {
       delete gDataTable;
       gDataTable = nullptr;
     }
+  }
 
-    return NS_OK;
+  void
+  CancelTimerAndRevokeURI()
+  {
+    if (mTimer) {
+      mTimer->Cancel();
+      mTimer = nullptr;
+    }
+
+    RevokeURI(false /* aBroadcastToOtherProcesses */);
   }
 
-  NS_IMETHOD
-  GetName(nsACString& aName) override
+  static nsCOMPtr<nsIAsyncShutdownClient>
+  GetShutdownPhase()
   {
-    aName.AssignLiteral("ReleasingTimerHolder");
-    return NS_OK;
-  }
+    nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
+    NS_ENSURE_TRUE(!!svc, nullptr);
 
-private:
-  ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses)
-    : mURI(aURI)
-    , mBroadcastToOtherProcesses(aBroadcastToOtherProcesses)
-  {}
+    nsCOMPtr<nsIAsyncShutdownClient> phase;
+    nsresult rv = svc->GetXpcomWillShutdown(getter_AddRefs(phase));
+    NS_ENSURE_SUCCESS(rv, nullptr);
 
-  ~ReleasingTimerHolder()
-  {}
+    return Move(phase);
+  }
 
   nsCString mURI;
   bool mBroadcastToOtherProcesses;
 
   nsCOMPtr<nsITimer> mTimer;
 };
 
-NS_IMPL_ISUPPORTS(ReleasingTimerHolder, nsITimerCallback, nsINamed)
+NS_IMPL_ISUPPORTS(ReleasingTimerHolder, nsITimerCallback, nsINamed,
+                  nsIAsyncShutdownBlocker)
 
 } // namespace mozilla
 
 template<typename T>
 static nsresult
 AddDataEntryInternal(const nsACString& aURI, T aObject,
                      nsIPrincipal* aPrincipal)
 {
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -63,18 +63,18 @@ dictionary RTCDataChannelInit {
 dictionary RTCOfferAnswerOptions {
 //  boolean voiceActivityDetection = true; // TODO: support this (Bug 1184712)
 };
 
 dictionary RTCAnswerOptions : RTCOfferAnswerOptions {
 };
 
 dictionary RTCOfferOptions : RTCOfferAnswerOptions {
-  long    offerToReceiveVideo;
-  long    offerToReceiveAudio;
+  boolean offerToReceiveVideo;
+  boolean offerToReceiveAudio;
   boolean iceRestart = false;
 };
 
 interface RTCDataChannel;
 
 [Pref="media.peerconnection.enabled",
  JSImplementation="@mozilla.org/dom/peerconnection;1",
  Constructor (optional RTCConfiguration configuration,
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -975,16 +975,23 @@ BackgroundParentImpl::AllocPClientManage
 }
 
 bool
 BackgroundParentImpl::DeallocPClientManagerParent(mozilla::dom::PClientManagerParent* aActor)
 {
   return mozilla::dom::DeallocClientManagerParent(aActor);
 }
 
+mozilla::ipc::IPCResult
+BackgroundParentImpl::RecvPClientManagerConstructor(mozilla::dom::PClientManagerParent* aActor)
+{
+  mozilla::dom::InitClientManagerParent(aActor);
+  return IPC_OK();
+}
+
 } // namespace ipc
 } // namespace mozilla
 
 void
 TestParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   mozilla::ipc::AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -263,14 +263,17 @@ protected:
   virtual bool
   DeallocPHttpBackgroundChannelParent(PHttpBackgroundChannelParent *aActor) override;
 
   virtual PClientManagerParent*
   AllocPClientManagerParent() override;
 
   virtual bool
   DeallocPClientManagerParent(PClientManagerParent* aActor) override;
+
+  virtual mozilla::ipc::IPCResult
+  RecvPClientManagerConstructor(PClientManagerParent* aActor) override;
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 #endif // mozilla_ipc_backgroundparentimpl_h__
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/typedarray/typed-array-inline-cache.js
@@ -0,0 +1,53 @@
+// ECMA262 9.4.5.2 [[HasProperty]]
+function check_in(x, a) {
+    return (x in a);
+}
+
+function check_has_own(x, a) {
+    return a.hasOwnProperty(x);
+}
+
+//make sure baseline gets compiled
+function warmup(a) {
+    for (var i = 0; i < 1001; i++) {
+        check_in(i, a);
+        check_has_own(i, a);
+    }
+}
+
+function check_assertions(a) {
+    assertEq(check_in(1, a),      true);
+    assertEq(check_in("-0",a),    false); // -0 access
+    assertEq(check_in(-10,a),     false); // Negative access
+    assertEq(check_in(1012,a),    false); // OOB access
+
+
+    assertEq(check_has_own(1, a),      true);
+    assertEq(check_has_own("-0",a),    false); // -0 access
+    assertEq(check_has_own(-10,a),     false); // Negative access
+    assertEq(check_has_own(1012,a),    false); // OOB access
+}
+
+function test_with_no_protochain(a) {
+    var a = new Int32Array(1000).fill(1);
+    warmup(a);
+    check_assertions(a);
+}
+
+// Attempting to validate against this comment:
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1419372#c3
+//
+// "Out of bounds "in" or "hasOwnProperty" should always
+// return false, and not consider the prototype chain at all"
+function test_with_protochain(a) {
+    var a = new Int32Array(1000).fill(1);
+    // try to force the behaviour of 9.4.5.2
+    a[1012] = "1012";
+    a["-0"]   = "-0";
+    a[-10]  = "-10";
+    warmup(a);
+    check_assertions(a);
+}
+
+test_with_no_protochain();
+test_with_protochain();
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -2560,16 +2560,39 @@ HasPropIRGenerator::tryAttachUnboxedExpa
     writer.loadBooleanResult(true);
     writer.returnFromIC();
 
     trackAttached("UnboxedExpandoHasProp");
     return true;
 }
 
 bool
+HasPropIRGenerator::tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
+                                        uint32_t index, Int32OperandId indexId)
+{
+    if (!obj->is<TypedArrayObject>() && !IsPrimitiveArrayTypedObject(obj))
+        return false;
+
+    // Don't attach typed object stubs if the underlying storage could be
+    // detached, as the stub will always bail out.
+    if (IsPrimitiveArrayTypedObject(obj) && cx_->compartment()->detachedTypedObjects)
+        return false;
+
+    TypedThingLayout layout = GetTypedThingLayout(obj->getClass());
+    writer.guardShape(objId, obj->as<ShapedObject>().shape());
+
+    writer.loadTypedElementExistsResult(objId, indexId, layout);
+
+    writer.returnFromIC();
+
+    trackAttached("TypedArrayObject");
+    return true;
+}
+
+bool
 HasPropIRGenerator::tryAttachTypedObject(JSObject* obj, ObjOperandId objId,
                                          jsid key, ValOperandId keyId)
 {
     if (!obj->is<TypedObject>())
         return false;
 
     if (!obj->as<TypedObject>().typeDescr().hasProperty(cx_->names(), key))
         return false;
@@ -2688,16 +2711,18 @@ HasPropIRGenerator::tryAttachStub()
 
     uint32_t index;
     Int32OperandId indexId;
     if (maybeGuardInt32Index(idVal_, keyId, &index, &indexId)) {
         if (tryAttachDense(obj, objId, index, indexId))
             return true;
         if (tryAttachDenseHole(obj, objId, index, indexId))
             return true;
+        if (tryAttachTypedArray(obj, objId, index, indexId))
+            return true;
 
         trackNotAttached();
         return false;
     }
 
     trackNotAttached();
     return false;
 }
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -234,16 +234,17 @@ extern const char* CacheKindNames[];
     /* The *Result ops load a value into the cache's result register. */ \
     _(LoadFixedSlotResult)                \
     _(LoadDynamicSlotResult)              \
     _(LoadUnboxedPropertyResult)          \
     _(LoadTypedObjectResult)              \
     _(LoadDenseElementResult)             \
     _(LoadDenseElementHoleResult)         \
     _(LoadDenseElementExistsResult)       \
+    _(LoadTypedElementExistsResult)       \
     _(LoadDenseElementHoleExistsResult)   \
     _(LoadTypedElementResult)             \
     _(LoadInt32ArrayLengthResult)         \
     _(LoadArgumentsObjectArgResult)       \
     _(LoadArgumentsObjectLengthResult)    \
     _(LoadFunctionLengthResult)           \
     _(LoadStringCharResult)               \
     _(LoadStringLengthResult)             \
@@ -925,16 +926,21 @@ class MOZ_RAII CacheIRWriter : public JS
     void loadDenseElementHoleResult(ObjOperandId obj, Int32OperandId index) {
         writeOpWithOperandId(CacheOp::LoadDenseElementHoleResult, obj);
         writeOperandId(index);
     }
     void loadDenseElementExistsResult(ObjOperandId obj, Int32OperandId index) {
         writeOpWithOperandId(CacheOp::LoadDenseElementExistsResult, obj);
         writeOperandId(index);
     }
+    void loadTypedElementExistsResult(ObjOperandId obj, Int32OperandId index, TypedThingLayout layout) {
+        writeOpWithOperandId(CacheOp::LoadTypedElementExistsResult, obj);
+        writeOperandId(index);
+        buffer_.writeByte(uint32_t(layout));
+    }
     void loadDenseElementHoleExistsResult(ObjOperandId obj, Int32OperandId index) {
         writeOpWithOperandId(CacheOp::LoadDenseElementHoleExistsResult, obj);
         writeOperandId(index);
     }
     void loadTypedElementResult(ObjOperandId obj, Int32OperandId index, TypedThingLayout layout,
                                 Scalar::Type elementType) {
         writeOpWithOperandId(CacheOp::LoadTypedElementResult, obj);
         writeOperandId(index);
@@ -1434,16 +1440,18 @@ class MOZ_RAII HasPropIRGenerator : publ
 {
     HandleValue val_;
     HandleValue idVal_;
 
     bool tryAttachDense(HandleObject obj, ObjOperandId objId,
                         uint32_t index, Int32OperandId indexId);
     bool tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
                             uint32_t index, Int32OperandId indexId);
+    bool tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
+                             uint32_t index, Int32OperandId indexId);
     bool tryAttachNamedProp(HandleObject obj, ObjOperandId objId,
                             HandleId key, ValOperandId keyId);
     bool tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId);
     bool tryAttachNative(JSObject* obj, ObjOperandId objId,
                          jsid key, ValOperandId keyId,
                          PropertyResult prop, JSObject* holder);
     bool tryAttachUnboxed(JSObject* obj, ObjOperandId objId,
                           jsid key, ValOperandId keyId);
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -1949,16 +1949,40 @@ CacheIRCompiler::emitLoadDenseElementHol
     masm.bind(&hole);
     masm.moveValue(UndefinedValue(), output.valueReg());
 
     masm.bind(&done);
     return true;
 }
 
 bool
+CacheIRCompiler::emitLoadTypedElementExistsResult()
+{
+    AutoOutputRegister output(*this);
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Register index = allocator.useRegister(masm, reader.int32OperandId());
+    TypedThingLayout layout = reader.typedThingLayout();
+    AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
+
+    Label outOfBounds, done;
+
+    // Bound check.
+    LoadTypedThingLength(masm, layout, obj, scratch);
+    masm.branch32(Assembler::BelowOrEqual, scratch, index, &outOfBounds);
+    EmitStoreBoolean(masm, true, output);
+    masm.jump(&done);
+
+    masm.bind(&outOfBounds);
+    EmitStoreBoolean(masm, false, output);
+
+    masm.bind(&done);
+    return true;
+}
+
+bool
 CacheIRCompiler::emitLoadDenseElementExistsResult()
 {
     AutoOutputRegister output(*this);
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     Register index = allocator.useRegister(masm, reader.int32OperandId());
     AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
     FailurePath* failure;
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -45,16 +45,17 @@ namespace jit {
     _(LoadFunctionLengthResult)           \
     _(LoadStringLengthResult)             \
     _(LoadStringCharResult)               \
     _(LoadArgumentsObjectArgResult)       \
     _(LoadDenseElementResult)             \
     _(LoadDenseElementHoleResult)         \
     _(LoadDenseElementExistsResult)       \
     _(LoadDenseElementHoleExistsResult)   \
+    _(LoadTypedElementExistsResult)       \
     _(LoadTypedElementResult)             \
     _(LoadObjectResult)                   \
     _(LoadTypeOfObjectResult)             \
     _(CompareStringResult)                \
     _(CompareObjectResult)                \
     _(CompareSymbolResult)                \
     _(ArrayJoinResult)                    \
     _(CallPrintString)                    \
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1919,28 +1919,16 @@ if test "$MOZ_DEBUG"; then
 fi
 
 AC_SUBST(MOZ_DEV_EDITION)
 if test -n "$MOZ_DEV_EDITION"; then
     AC_DEFINE(MOZ_DEV_EDITION)
 fi
 
 dnl ========================================================
-dnl Determine options to use for running the preprocessor.
-dnl ========================================================
-
-if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then
-    PREPROCESS_OPTION="-P -Fi"
-else
-    PREPROCESS_OPTION="-E -o "
-fi
-
-AC_SUBST(PREPROCESS_OPTION)
-
-dnl ========================================================
 dnl JavaScript shell
 dnl ========================================================
 
 MOZ_CHECK_ALLOCATOR
 
 AC_CHECK_FUNCS(setlocale localeconv)
 
 AC_SUBST(MOZILLA_VERSION)
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -613,25 +613,88 @@ NativeObject::addDataPropertyInternal(JS
     MOZ_ASSERT(shape == obj->lastProperty());
 
     if (table)
         shape->updateDictionaryTable(table, entry, keep);
 
     return shape;
 }
 
+static MOZ_ALWAYS_INLINE Shape*
+PropertyTreeReadBarrier(Shape* parent, Shape* shape)
+{
+    JS::Zone* zone = shape->zone();
+    if (zone->needsIncrementalBarrier()) {
+        // We need a read barrier for the shape tree, since these are weak
+        // pointers.
+        Shape* tmp = shape;
+        TraceManuallyBarrieredEdge(zone->barrierTracer(), &tmp, "read barrier");
+        MOZ_ASSERT(tmp == shape);
+        return shape;
+    }
+
+    if (MOZ_LIKELY(!zone->isGCSweepingOrCompacting() ||
+                   !IsAboutToBeFinalizedUnbarriered(&shape)))
+    {
+        if (shape->isMarkedGray())
+            UnmarkGrayShapeRecursively(shape);
+        return shape;
+    }
+
+    // The shape we've found is unreachable and due to be finalized, so
+    // remove our weak reference to it and don't use it.
+    MOZ_ASSERT(parent->isMarkedAny());
+    parent->removeChild(shape);
+
+    return nullptr;
+}
+
 /* static */ Shape*
 NativeObject::addEnumerableDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id)
 {
     // Like addProperty(Internal), but optimized for the common case of adding a
     // new enumerable data property.
 
-    AutoKeepShapeTables keep(cx);
     AutoCheckShapeConsistency check(obj);
 
+    // Fast path for non-dictionary shapes with a single kid.
+    do {
+        AutoCheckCannotGC nogc;
+
+        Shape* lastProperty = obj->lastProperty();
+        if (lastProperty->inDictionary())
+            break;
+
+        KidsPointer* kidp = &lastProperty->kids;
+        if (!kidp->isShape())
+            break;
+
+        Shape* kid = kidp->toShape();
+        MOZ_ASSERT(!kid->inDictionary());
+
+        if (kid->propidRaw() != id ||
+            kid->isAccessorShape() ||
+            kid->attributes() != JSPROP_ENUMERATE ||
+            kid->base()->unowned() != lastProperty->base()->unowned())
+        {
+            break;
+        }
+
+        MOZ_ASSERT(kid->isDataProperty());
+
+        kid = PropertyTreeReadBarrier(lastProperty, kid);
+        if (!kid)
+            break;
+
+        if (!obj->setLastProperty(cx, kid))
+            return nullptr;
+        return kid;
+    } while (0);
+
+    AutoKeepShapeTables keep(cx);
     ShapeTable* table = nullptr;
     ShapeTable::Entry* entry = nullptr;
 
     if (!obj->inDictionaryMode()) {
         if (MOZ_UNLIKELY(ShouldConvertToDictionary(obj))) {
             if (!toDictionaryMode(cx, obj))
                 return nullptr;
             table = obj->lastProperty()->maybeTable(keep);
@@ -1671,40 +1734,19 @@ PropertyTree::inlinedGetChild(JSContext*
     } else if (kidp->isHash()) {
         if (KidsHash::Ptr p = kidp->toHash()->lookup(child))
             existingShape = *p;
     } else {
         /* If kidp->isNull(), we always insert. */
     }
 
     if (existingShape) {
-        JS::Zone* zone = existingShape->zone();
-        if (zone->needsIncrementalBarrier()) {
-            /*
-             * We need a read barrier for the shape tree, since these are weak
-             * pointers.
-             */
-            Shape* tmp = existingShape;
-            TraceManuallyBarrieredEdge(zone->barrierTracer(), &tmp, "read barrier");
-            MOZ_ASSERT(tmp == existingShape);
+        existingShape = PropertyTreeReadBarrier(parent, existingShape);
+        if (existingShape)
             return existingShape;
-        }
-        if (!zone->isGCSweepingOrCompacting() ||
-            !IsAboutToBeFinalizedUnbarriered(&existingShape))
-        {
-            if (existingShape->isMarkedGray())
-                UnmarkGrayShapeRecursively(existingShape);
-            return existingShape;
-        }
-        /*
-         * The shape we've found is unreachable and due to be finalized, so
-         * remove our weak reference to it and don't use it.
-         */
-        MOZ_ASSERT(parent->isMarkedAny());
-        parent->removeChild(existingShape);
     }
 
     RootedShape parentRoot(cx, parent);
     Shape* shape = Shape::new_(cx, child, parentRoot->numFixedSlots());
     if (!shape)
         return nullptr;
 
     if (!insertChild(cx, parentRoot, shape))
--- a/netwerk/dns/DNS.cpp
+++ b/netwerk/dns/DNS.cpp
@@ -2,17 +2,16 @@
  * 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/net/DNS.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/mozalloc.h"
 #include "mozilla/ArrayUtils.h"
-#include "nsString.h"
 #include <string.h>
 
 #ifdef XP_WIN
 #include "ws2tcpip.h"
 #endif
 
 namespace mozilla {
 namespace net {
@@ -287,67 +286,89 @@ NetAddrElement::NetAddrElement(const PRN
 
 NetAddrElement::NetAddrElement(const NetAddrElement& netAddr)
 {
   mAddress = netAddr.mAddress;
 }
 
 NetAddrElement::~NetAddrElement() = default;
 
-AddrInfo::AddrInfo(const nsACString& host, const PRAddrInfo *prAddrInfo,
-                   bool disableIPv4, bool filterNameCollision,
-                   const nsACString& cname)
-  : mHostName(host)
-  , mCanonicalName(cname)
+AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo,
+                   bool disableIPv4, bool filterNameCollision, const char *cname)
+  : mHostName(nullptr)
+  , mCanonicalName(nullptr)
   , ttl(NO_TTL_DATA)
 {
   MOZ_ASSERT(prAddrInfo, "Cannot construct AddrInfo with a null prAddrInfo pointer!");
   const uint32_t nameCollisionAddr = htonl(0x7f003535); // 127.0.53.53
 
+  Init(host, cname);
   PRNetAddr tmpAddr;
   void *iter = nullptr;
   do {
     iter = PR_EnumerateAddrInfo(iter, prAddrInfo, 0, &tmpAddr);
     bool addIt = iter &&
         (!disableIPv4 || tmpAddr.raw.family != PR_AF_INET) &&
         (!filterNameCollision || tmpAddr.raw.family != PR_AF_INET || (tmpAddr.inet.ip != nameCollisionAddr));
     if (addIt) {
         auto *addrElement = new NetAddrElement(&tmpAddr);
         mAddresses.insertBack(addrElement);
     }
   } while (iter);
 }
 
-AddrInfo::AddrInfo(const nsACString& host, const nsACString& cname)
-  : mHostName(host)
-  , mCanonicalName(cname)
+AddrInfo::AddrInfo(const char *host, const char *cname)
+  : mHostName(nullptr)
+  , mCanonicalName(nullptr)
   , ttl(NO_TTL_DATA)
 {
+  Init(host, cname);
 }
 
 AddrInfo::~AddrInfo()
 {
   NetAddrElement *addrElement;
   while ((addrElement = mAddresses.popLast())) {
     delete addrElement;
   }
+  free(mHostName);
+  free(mCanonicalName);
+}
+
+void
+AddrInfo::Init(const char *host, const char *cname)
+{
+  MOZ_ASSERT(host, "Cannot initialize AddrInfo with a null host pointer!");
+
+  ttl = NO_TTL_DATA;
+  size_t hostlen = strlen(host);
+  mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1));
+  memcpy(mHostName, host, hostlen + 1);
+  if (cname) {
+    size_t cnameLen = strlen(cname);
+    mCanonicalName = static_cast<char*>(moz_xmalloc(cnameLen + 1));
+    memcpy(mCanonicalName, cname, cnameLen + 1);
+  }
+  else {
+    mCanonicalName = nullptr;
+  }
 }
 
 void
 AddrInfo::AddAddress(NetAddrElement *address)
 {
   MOZ_ASSERT(address, "Cannot add the address to an uninitialized list");
 
   mAddresses.insertBack(address);
 }
 
 size_t
 AddrInfo::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
 {
   size_t n = mallocSizeOf(this);
-  n += mHostName.SizeOfExcludingThisIfUnshared(mallocSizeOf);
-  n += mCanonicalName.SizeOfExcludingThisIfUnshared(mallocSizeOf);
+  n += mallocSizeOf(mHostName);
+  n += mallocSizeOf(mCanonicalName);
   n += mAddresses.sizeOfExcludingThis(mallocSizeOf);
   return n;
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/dns/DNS.h
+++ b/netwerk/dns/DNS.h
@@ -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/. */
 
 #ifndef DNS_h_
 #define DNS_h_
 
 #include "nscore.h"
-#include "nsString.h"
 #include "prio.h"
 #include "prnetdb.h"
 #include "plstr.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/MemoryReporting.h"
 
 #if !defined(XP_WIN)
 #include <arpa/inet.h>
@@ -129,37 +128,38 @@ public:
   NetAddrElement(const NetAddrElement& netAddr);
   ~NetAddrElement();
 
   NetAddr mAddress;
 };
 
 class AddrInfo {
 public:
-  // Creates an AddrInfo object.
-  AddrInfo(const nsACString& host, const PRAddrInfo *prAddrInfo,
-           bool disableIPv4, bool filterNameCollision,
-           const nsACString& cname);
+  // Creates an AddrInfo object. It calls the AddrInfo(const char*, const char*)
+  // to initialize the host and the cname.
+  AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4,
+           bool filterNameCollision, const char *cname);
 
-  // Creates a basic AddrInfo object (initialize only the host and the
-  // cname).
-  AddrInfo(const nsACString& host, const nsACString& cname);
-
+  // Creates a basic AddrInfo object (initialize only the host and the cname).
+  AddrInfo(const char *host, const char *cname);
   ~AddrInfo();
 
   void AddAddress(NetAddrElement *address);
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
-  nsCString mHostName;
-  nsCString mCanonicalName;
+  char *mHostName;
+  char *mCanonicalName;
   uint32_t ttl;
   static const uint32_t NO_TTL_DATA = (uint32_t) -1;
 
   LinkedList<NetAddrElement> mAddresses;
+
+private:
+  void Init(const char *host, const char *cname);
 };
 
 // Copies the contents of a PRNetAddr to a NetAddr.
 // Does not do a ptr safety check!
 void PRNetAddrToNetAddr(const PRNetAddr *prAddr, NetAddr *addr);
 
 // Copies the contents of a NetAddr to a PRNetAddr.
 // Does not do a ptr safety check!
--- a/netwerk/dns/GetAddrInfo.cpp
+++ b/netwerk/dns/GetAddrInfo.cpp
@@ -246,19 +246,20 @@ static MOZ_ALWAYS_INLINE nsresult
 
 ////////////////////////////////////
 // PORTABLE RUNTIME IMPLEMENTATION//
 ////////////////////////////////////
 
 static MOZ_ALWAYS_INLINE nsresult
 _GetAddrInfo_Portable(const char* aCanonHost, uint16_t aAddressFamily,
                       uint16_t aFlags, const char* aNetworkInterface,
-                      UniquePtr<AddrInfo>& aAddrInfo)
+                      AddrInfo** aAddrInfo)
 {
   MOZ_ASSERT(aCanonHost);
+  MOZ_ASSERT(aAddrInfo);
 
   // We accept the same aFlags that nsHostResolver::ResolveHost accepts, but we
   // need to translate the aFlags into a form that PR_GetAddrInfoByName
   // accepts.
   int prFlags = PR_AI_ADDRCONFIG;
   if (!(aFlags & nsHostResolver::RES_CANON_NAME)) {
     prFlags |= PR_AI_NOCANONNAME;
   }
@@ -277,24 +278,24 @@ static MOZ_ALWAYS_INLINE nsresult
   }
 
   const char* canonName = nullptr;
   if (aFlags & nsHostResolver::RES_CANON_NAME) {
     canonName = PR_GetCanonNameFromAddrInfo(prai);
   }
 
   bool filterNameCollision = !(aFlags & nsHostResolver::RES_ALLOW_NAME_COLLISION);
-  auto ai = MakeUnique<AddrInfo>(nsCString(aCanonHost), prai, disableIPv4,
-                                 filterNameCollision, nsCString(canonName));
+  nsAutoPtr<AddrInfo> ai(new AddrInfo(aCanonHost, prai, disableIPv4,
+                                      filterNameCollision, canonName));
   PR_FreeAddrInfo(prai);
   if (ai->mAddresses.isEmpty()) {
     return NS_ERROR_UNKNOWN_HOST;
   }
 
-  aAddrInfo = Move(ai);
+  *aAddrInfo = ai.forget();
 
   return NS_OK;
 }
 
 //////////////////////////////////////
 // COMMON/PLATFORM INDEPENDENT CODE //
 //////////////////////////////////////
 nsresult
@@ -316,50 +317,49 @@ GetAddrInfoShutdown() {
   return _GetAddrInfoShutdown_Windows();
 #else
   return NS_OK;
 #endif
 }
 
 nsresult
 GetAddrInfo(const char* aHost, uint16_t aAddressFamily, uint16_t aFlags,
-            const char* aNetworkInterface,
-            UniquePtr<AddrInfo>& aAddrInfo, bool aGetTtl)
+            const char* aNetworkInterface, AddrInfo** aAddrInfo, bool aGetTtl)
 {
-  if (NS_WARN_IF(!aHost)) {
+  if (NS_WARN_IF(!aHost) || NS_WARN_IF(!aAddrInfo)) {
     return NS_ERROR_NULL_POINTER;
   }
 
 #if DNSQUERY_AVAILABLE
   // The GetTTLData needs the canonical name to function properly
   if (aGetTtl) {
     aFlags |= nsHostResolver::RES_CANON_NAME;
   }
 #endif
 
-  aAddrInfo = nullptr;
+  *aAddrInfo = nullptr;
   nsresult rv = _GetAddrInfo_Portable(aHost, aAddressFamily, aFlags,
                                       aNetworkInterface, aAddrInfo);
 
 #if DNSQUERY_AVAILABLE
   if (aGetTtl && NS_SUCCEEDED(rv)) {
     // Figure out the canonical name, or if that fails, just use the host name
     // we have.
     const char *name = nullptr;
-    if (aAddrInfo && !aAddrInfo->mCanonicalName.IsEmpty()) {
-      name = aAddrInfo->mCanonicalName.get();
+    if (*aAddrInfo != nullptr && (*aAddrInfo)->mCanonicalName) {
+      name = (*aAddrInfo)->mCanonicalName;
     } else {
       name = aHost;
     }
 
     LOG("Getting TTL for %s (cname = %s).", aHost, name);
     uint32_t ttl = 0;
     nsresult ttlRv = _GetTTLData_Windows(name, &ttl, aAddressFamily);
     if (NS_SUCCEEDED(ttlRv)) {
-      aAddrInfo->ttl = ttl;
+      (*aAddrInfo)->ttl = ttl;
       LOG("Got TTL %u for %s (name = %s).", ttl, aHost, name);
     } else {
       LOG_WARNING("Could not get TTL for %s (cname = %s).", aHost, name);
     }
   }
 #endif
 
   return rv;
--- a/netwerk/dns/GetAddrInfo.h
+++ b/netwerk/dns/GetAddrInfo.h
@@ -35,18 +35,17 @@ class AddrInfo;
  *     hostname (PR_AI_NOCANONNAME will be ignored if the TTL is retrieved).
  * @param aAddrInfo[out] Will point to the results of the host lookup, or be
  *     null if the lookup failed.
  * @param aGetTtl[in] If true, and TTL_AVAILABLE is truthy, the TTL will be
  *     retrieved if DNS provides the answers..
  */
 nsresult
 GetAddrInfo(const char* aHost, uint16_t aAddressFamily, uint16_t aFlags,
-            const char* aNetworkInterface,
-            UniquePtr<AddrInfo>& aAddrInfo, bool aGetTtl);
+            const char* aNetworkInterface, AddrInfo** aAddrInfo, bool aGetTtl);
 
 /**
  * Initialize the GetAddrInfo module.
  *
  * GetAddrInfoShutdown() should be called for every time this function is
  * called.
  */
 nsresult
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -83,31 +83,28 @@ NS_IMPL_ISUPPORTS(nsDNSRecord, nsIDNSRec
 
 NS_IMETHODIMP
 nsDNSRecord::GetCanonicalName(nsACString &result)
 {
     // this method should only be called if we have a CNAME
     NS_ENSURE_TRUE(mHostRecord->flags & nsHostResolver::RES_CANON_NAME,
                    NS_ERROR_NOT_AVAILABLE);
 
+    // if the record is for an IP address literal, then the canonical
+    // host name is the IP address literal.
+    const char *cname;
     {
         MutexAutoLock lock(mHostRecord->addr_info_lock);
-
-        // if the record is for an IP address literal, then the canonical
-        // host name is the IP address literal.
-        if (!mHostRecord->addr_info) {
-            result = mHostRecord->host;
-            return NS_OK;
-        }
-
-        if (mHostRecord->addr_info->mCanonicalName.IsEmpty()) {
-            result = mHostRecord->addr_info->mHostName;
-        } else {
-            result = mHostRecord->addr_info->mCanonicalName;
-        }
+        if (mHostRecord->addr_info)
+            cname = mHostRecord->addr_info->mCanonicalName ?
+                mHostRecord->addr_info->mCanonicalName :
+                mHostRecord->addr_info->mHostName;
+        else
+            cname = mHostRecord->host;
+        result.Assign(cname);
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr)
 {
     if (mDone) {
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -226,16 +226,17 @@ nsHostRecord::CopyExpirationTimesAndFlag
     mValidEnd = aFromHostRecord->mValidEnd;
     mGraceStart = aFromHostRecord->mGraceStart;
     mDoomed = aFromHostRecord->mDoomed;
 }
 
 nsHostRecord::~nsHostRecord()
 {
     Telemetry::Accumulate(Telemetry::DNS_BLACKLIST_COUNT, mBlacklistedCount);
+    delete addr_info;
 }
 
 bool
 nsHostRecord::Blacklisted(NetAddr *aQuery)
 {
     // must call locked
     LOG(("Checking blacklist for host [%s%s%s], host record [%p].\n",
           LOG_HOST(host, netInterface), this));
@@ -593,18 +594,17 @@ void
 nsHostResolver::ClearPendingQueue(PRCList *aPendingQ)
 {
     // loop through pending queue, erroring out pending lookups.
     if (!PR_CLIST_IS_EMPTY(aPendingQ)) {
         PRCList *node = aPendingQ->next;
         while (node != aPendingQ) {
             nsHostRecord *rec = static_cast<nsHostRecord *>(node);
             node = node->next;
-            OnLookupComplete(rec, NS_ERROR_ABORT,
-                             mozilla::UniquePtr<AddrInfo>(nullptr));
+            OnLookupComplete(rec, NS_ERROR_ABORT, nullptr);
         }
     }
 }
 
 //
 // FlushCache() is what we call when the network has changed. We must not
 // trust names that were resolved before this change. They may resolve
 // differently now.
@@ -865,31 +865,34 @@ nsHostResolver::ResolveHost(const char  
                         LOG(("  Trying AF_UNSPEC entry for host [%s%s%s] af: %s.\n",
                              LOG_HOST(host, netInterface),
                              (af == PR_AF_INET) ? "AF_INET" : "AF_INET6"));
 
                         // We need to lock in case any other thread is reading
                         // addr_info.
                         MutexAutoLock lock(he->rec->addr_info_lock);
 
+                        // XXX: note that this actually leaks addr_info.
+                        // For some reason, freeing the memory causes a crash in
+                        // nsDNSRecord::GetNextAddr - see bug 1422173
                         he->rec->addr_info = nullptr;
                         if (unspecHe->rec->negative) {
                             he->rec->negative = unspecHe->rec->negative;
                             he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec);
                         } else if (unspecHe->rec->addr_info) {
                             // Search for any valid address in the AF_UNSPEC entry
                             // in the cache (not blacklisted and from the right
                             // family).
                             NetAddrElement *addrIter =
                                 unspecHe->rec->addr_info->mAddresses.getFirst();
                             while (addrIter) {
                                 if ((af == addrIter->mAddress.inet.family) &&
                                      !unspecHe->rec->Blacklisted(&addrIter->mAddress)) {
                                     if (!he->rec->addr_info) {
-                                        he->rec->addr_info = mozilla::MakeUnique<AddrInfo>(
+                                        he->rec->addr_info = new AddrInfo(
                                             unspecHe->rec->addr_info->mHostName,
                                             unspecHe->rec->addr_info->mCanonicalName);
                                         he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec);
                                     }
                                     he->rec->addr_info->AddAddress(
                                         new NetAddrElement(*addrIter));
                                 }
                                 addrIter = addrIter->getNext();
@@ -1235,17 +1238,17 @@ nsHostResolver::PrepareRecordExpiration(
 
 static bool
 different_rrset(AddrInfo *rrset1, AddrInfo *rrset2)
 {
     if (!rrset1 || !rrset2) {
         return true;
     }
 
-    LOG(("different_rrset %s\n", rrset1->mHostName.get()));
+    LOG(("different_rrset %s\n", rrset1->mHostName));
     nsTArray<NetAddr> orderedSet1;
     nsTArray<NetAddr> orderedSet2;
 
     for (NetAddrElement *element = rrset1->mAddresses.getFirst();
          element; element = element->getNext()) {
         if (LOG_ENABLED()) {
             char buf[128];
             NetAddrToString(&element->mAddress, buf, 128);
@@ -1281,49 +1284,53 @@ different_rrset(AddrInfo *rrset1, AddrIn
     return false;
 }
 
 //
 // OnLookupComplete() checks if the resolving should be redone and if so it
 // returns LOOKUP_RESOLVEAGAIN, but only if 'status' is not NS_ERROR_ABORT.
 // takes ownership of AddrInfo parameter
 nsHostResolver::LookupStatus
-nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status,
-                                 mozilla::UniquePtr<AddrInfo>&& newRRSet)
+nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status, AddrInfo* newRRSet)
 {
     // get the list of pending callbacks for this lookup, and notify
     // them that the lookup is complete.
     PRCList cbs;
     PR_INIT_CLIST(&cbs);
     {
         MutexAutoLock lock(mLock);
 
         if (rec->mResolveAgain && (status != NS_ERROR_ABORT)) {
             LOG(("nsHostResolver record %p resolve again due to flushcache\n", rec));
             rec->mResolveAgain = false;
+            delete newRRSet;
             return LOOKUP_RESOLVEAGAIN;
         }
 
         // grab list of callbacks to notify
         MoveCList(rec->callbacks, cbs);
 
         // update record fields.  We might have a rec->addr_info already if a
         // previous lookup result expired and we're reresolving it..
+        AddrInfo  *old_addr_info;
         {
             MutexAutoLock lock(rec->addr_info_lock);
-            if (different_rrset(rec->addr_info.get(), newRRSet.get())) {
+            if (different_rrset(rec->addr_info, newRRSet)) {
                 LOG(("nsHostResolver record %p new gencnt\n", rec));
-                rec->addr_info = Move(newRRSet);
+                old_addr_info = rec->addr_info;
+                rec->addr_info = newRRSet;
                 rec->addr_info_gencnt++;
             } else {
                 if (rec->addr_info && newRRSet) {
                     rec->addr_info->ttl = newRRSet->ttl;
                 }
+                old_addr_info = newRRSet;
             }
         }
+        delete old_addr_info;
 
         rec->negative = !rec->addr_info;
         PrepareRecordExpiration(rec);
         rec->resolving = false;
 
         if (rec->usingAnyThread) {
             mActiveAnyThreadCount--;
             rec->usingAnyThread = false;
@@ -1463,34 +1470,34 @@ nsHostResolver::ThreadFunc(void *arg)
     AUTO_PROFILER_REGISTER_THREAD(name.BeginReading());
     NS_SetCurrentThreadName(name.BeginReading());
 
 #if defined(RES_RETRY_ON_FAILURE)
     nsResState rs;
 #endif
     nsHostResolver *resolver = (nsHostResolver *)arg;
     nsHostRecord *rec  = nullptr;
-    mozilla::UniquePtr<AddrInfo> ai = nullptr;
+    AddrInfo *ai = nullptr;
 
     while (rec || resolver->GetHostToLookup(&rec)) {
         LOG(("DNS lookup thread - Calling getaddrinfo for host [%s%s%s].\n",
              LOG_HOST(rec->host, rec->netInterface)));
 
         TimeStamp startTime = TimeStamp::Now();
 #if TTL_AVAILABLE
         bool getTtl = rec->mGetTtl;
 #else
         bool getTtl = false;
 #endif
 
         nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface,
-                                      ai, getTtl);
+                                      &ai, getTtl);
 #if defined(RES_RETRY_ON_FAILURE)
         if (NS_FAILED(status) && rs.Reset()) {
-            status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, ai,
+            status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, &ai,
                                  getTtl);
         }
 #endif
 
         {   // obtain lock to check shutdown and manage inter-module telemetry
             MutexAutoLock lock(resolver->mLock);
 
             if (!resolver->mShutdown) {
@@ -1516,18 +1523,17 @@ nsHostResolver::ThreadFunc(void *arg)
             }
         }
 
         // OnLookupComplete may release "rec", long before we lose it.
         LOG(("DNS lookup thread - lookup completed for host [%s%s%s]: %s.\n",
              LOG_HOST(rec->host, rec->netInterface),
              ai ? "success" : "failure: unknown host"));
 
-        if (LOOKUP_RESOLVEAGAIN == resolver->OnLookupComplete(rec, status,
-                                                              mozilla::Move(ai))) {
+        if (LOOKUP_RESOLVEAGAIN == resolver->OnLookupComplete(rec, status, ai)) {
             // leave 'rec' assigned and loop to make a renewed host resolve
             LOG(("DNS lookup thread - Re-resolving host [%s%s%s].\n",
                  LOG_HOST(rec->host, rec->netInterface)));
         } else {
             rec = nullptr;
         }
     }
     resolver->mThreadCount--;
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -70,17 +70,17 @@ public:
      * nsDNSService2 class.  |addr| doesn't change after it has been
      * assigned a value.  only the resolver worker thread modifies
      * nsHostRecord (and only in nsHostResolver::OnLookupComplete);
      * the other threads just read it.  therefore the resolver worker
      * thread doesn't need to lock when reading |addr_info|.
      */
     Mutex        addr_info_lock;
     int          addr_info_gencnt; /* generation count of |addr_info| */
-    mozilla::UniquePtr<mozilla::net::AddrInfo> addr_info;
+    mozilla::net::AddrInfo *addr_info;
     mozilla::UniquePtr<mozilla::net::NetAddr> addr;
     bool         negative;   /* True if this record is a cache of a failed lookup.
                                 Negative cache entries are valid just like any other
                                 (though never for more than 60 seconds), but a use
                                 of that negative entry forces an asynchronous refresh. */
 
     enum ExpirationStatus {
         EXP_VALID,
@@ -313,18 +313,17 @@ private:
     nsresult IssueLookup(nsHostRecord *);
     bool     GetHostToLookup(nsHostRecord **m);
 
     enum LookupStatus {
       LOOKUP_OK,
       LOOKUP_RESOLVEAGAIN,
     };
 
-    LookupStatus OnLookupComplete(nsHostRecord *, nsresult,
-                                  mozilla::UniquePtr<mozilla::net::AddrInfo>&&);
+    LookupStatus OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
     void     ClearPendingQueue(PRCList *aPendingQueue);
     nsresult ConditionallyCreateThread(nsHostRecord *rec);
 
     /**
      * Starts a new lookup in the background for entries that are in the grace
      * period with a failed connect or all cached entries are negative.
      */
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -2046,16 +2046,20 @@ WebSocketChannel::PrimeNewOutgoingMessag
                  "Not ping message!");
     else
       mCurrentOut = (OutboundMessage *)mOutgoingMessages.PopFront();
   }
 
   if (!mCurrentOut)
     return;
 
+  auto cleanupAfterFailure = MakeScopeExit([&] {
+    DeleteCurrentOutGoingMessage();
+  });
+
   WsMsgType msgType = mCurrentOut->GetMsgType();
 
   LOG(("WebSocketChannel::PrimeNewOutgoingMessage "
        "%p found queued msg %p [type=%s len=%d]\n",
        this, mCurrentOut, msgNames[msgType], mCurrentOut->Length()));
 
   mCurrentOutSent = 0;
   mHdrOut = mOutHeader;
@@ -2065,16 +2069,17 @@ WebSocketChannel::PrimeNewOutgoingMessag
 
   uint8_t *payload = nullptr;
 
   if (msgType == kMsgTypeFin) {
     // This is a demand to create a close message
     if (mClientClosed) {
       DeleteCurrentOutGoingMessage();
       PrimeNewOutgoingMessage();
+      cleanupAfterFailure.release();
       return;
     }
 
     mClientClosed = 1;
     mOutHeader[0] = kFinalFragBit | nsIWebSocketFrame::OPCODE_CLOSE;
     mOutHeader[1] = maskBit;
 
     // payload is offset 2 plus size of the mask
@@ -2253,16 +2258,18 @@ WebSocketChannel::PrimeNewOutgoingMessag
     mHdrOutToSend += len;
     mCurrentOutSent = len;
   }
 
   // Transmitting begins - mHdrOutToSend bytes from mOutHeader and
   // mCurrentOut->Length() bytes from mCurrentOut. The latter may be
   // coaleseced into the former for small messages or as the result of the
   // compression process.
+
+  cleanupAfterFailure.release();
 }
 
 void
 WebSocketChannel::DeleteCurrentOutGoingMessage()
 {
   delete mCurrentOut;
   mCurrentOut = nullptr;
   mCurrentOutSent = 0;
--- a/old-configure.in
+++ b/old-configure.in
@@ -4970,28 +4970,16 @@ HAVE_STATVFS
 HAVE_STATFS64
 HAVE_STATFS
 HAVE_SYS_STATVFS_H
 HAVE_SYS_STATFS_H
 HAVE_SYS_VFS_H
 HAVE_SYS_MOUNT_H
 "
 
-dnl ========================================================
-dnl Determine options to use for running the preprocessor.
-dnl ========================================================
-
-if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then
-    PREPROCESS_OPTION="-P -Fi"
-else
-    PREPROCESS_OPTION="-E -o "
-fi
-
-AC_SUBST(PREPROCESS_OPTION)
-
 # Avoid using obsolete NSPR features
 AC_DEFINE(NO_NSPR_10_SUPPORT)
 
 # Don't build NSS libpkix
 NSS_DISABLE_LIBPKIX=1
 AC_SUBST(NSS_DISABLE_LIBPKIX)
 
 MOZ_CREATE_CONFIG_STATUS()
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -476,17 +476,17 @@ win64-ccov/debug:
         product: firefox
         job-name: win64-ccov-debug
     treeherder:
         platform: windows2012-64/ccov
         symbol: tc(B)
         tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        max-run-time: 14400
+        max-run-time: 7200
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
     run:
         using: mozharness
         options: [append-env-variables-from-configs]
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/releng_base_firefox.py
--- a/taskcluster/ci/release-bouncer-aliases/kind.yml
+++ b/taskcluster/ci/release-bouncer-aliases/kind.yml
@@ -28,17 +28,17 @@ jobs:
          buildername: release-{branch}-fennec_bouncer_aliases
          release-promotion: true
       worker:
          properties:
             tuxedo_server_url:
                by-project:
                   mozilla-beta: https://bounceradmin.mozilla.com/api
                   mozilla-release: https://bounceradmin.mozilla.com/api
-                  maple: https://admin-bouncer.stage.mozaws.net/api/
+                  maple: https://admin-bouncer-releng.stage.mozaws.net/api/
                   default: http://localhost/api
       routes:
          - index.releases.v1.{branch}.latest.fennec.latest.bouncer_submitter
          - index.releases.v1.{branch}.{revision}.fennec.{underscore_version}.build{build_number}.bouncer_submitter
       index:
          type: release
          product: fennec
          job-name: android-api-16-opt
--- a/taskcluster/ci/release-uptake-monitoring/kind.yml
+++ b/taskcluster/ci/release-uptake-monitoring/kind.yml
@@ -30,17 +30,17 @@ jobs:
       worker:
          properties:
             # TODO: Calculate "platforms" dynamically
             platforms: "android-api-16, android-x86"
             tuxedo_server_url:
                by-project:
                   mozilla-beta: https://bounceradmin.mozilla.com/api
                   mozilla-release: https://bounceradmin.mozilla.com/api
-                  maple: https://admin-bouncer.stage.mozaws.net/api/
+                  maple: https://admin-bouncer-releng.stage.mozaws.net/api/
                   default: http://localhost/api
       routes:
          - index.releases.v1.{branch}.latest.fennec.latest.uptake_monitoring
          - index.releases.v1.{branch}.{revision}.fennec.{underscore_version}.build{build_number}.uptake_monitoring
       index:
          type: release
          product: fennec
          job-name: android-api-16-opt
--- a/taskcluster/ci/test/talos.yml
+++ b/taskcluster/ci/test/talos.yml
@@ -416,31 +416,22 @@ talos-tp6-stylo-threads:
     mozharness:
         extra-options:
             - --suite=tp6-stylo-threads
 
 talos-xperf:
     description: "Talos xperf"
     try-name: xperf
     treeherder-symbol: tc-T(x)
+    virtualization: virtual
     run-on-projects:
         by-test-platform:
             windows7-32.*: ['mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland', 'try']
             default: []
     mozharness:
         extra-options:
             - --suite=xperf
             - --add-option
             - --webServer,localhost
-
-talos-xperf-stylo-disabled:
-    description: "Talos Stylo disabled xperf"
-    try-name: xperf-stylo-disabled
-    treeherder-symbol: tc-Tsd(x)
-    run-on-projects:
-        by-test-platform:
-            windows7-32.*: ['mozilla-beta', 'mozilla-central', 'try']
-            default: []
-    mozharness:
-        extra-options:
-            - --suite=xperf-stylo-disabled
-            - --add-option
-            - --webServer,localhost
+        config:
+            by-test-platform:
+                windows.*:
+                    - talos/windows_vm_config.py
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -890,16 +890,18 @@ def set_worker_type(config, tests):
             test['worker-type'] = MACOSX_WORKER_TYPES['macosx64']
         elif test_platform.startswith('win'):
             win_worker_type_platform = WINDOWS_WORKER_TYPES[
                 test_platform.split('/')[0]
             ]
             if test.get('suite', '') == 'talos' and 'ccov' not in test['build-platform']:
                 if try_options.get('taskcluster_worker'):
                     test['worker-type'] = win_worker_type_platform['hardware']
+                elif test['virtualization'] == 'virtual':
+                    test['worker-type'] = win_worker_type_platform[test['virtualization']]
                 else:
                     test['worker-type'] = 'buildbot-bridge/buildbot-bridge'
             else:
                 test['worker-type'] = win_worker_type_platform[test['virtualization']]
         elif test_platform.startswith('linux') or test_platform.startswith('android'):
             if test.get('suite', '') == 'talos' and test['build-platform'] != 'linux64-ccov/opt':
                 if try_options.get('taskcluster_worker'):
                     test['worker-type'] = 'releng-hardware/gecko-t-linux-talos'
--- a/testing/geckodriver/CONTRIBUTING.md
+++ b/testing/geckodriver/CONTRIBUTING.md
@@ -224,9 +224,9 @@ Communication
 The mailing list for geckodriver discussion is
 tools-marionette@lists.mozilla.org ([subscribe], [archive]).
 
 If you prefer real-time chat, there is often someone in the #ateam IRC
 channel on irc.mozilla.org.  Don’t ask if you can ask a question, just
 ask, and please wait for an answer as we might not be in your timezone.
 
 [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette
-[archive]: http://groups.google.com/group/mozilla.tools.marionette
+[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/geckodriver/README.md
+++ b/testing/geckodriver/README.md
@@ -597,9 +597,9 @@ Contact
 
 The mailing list for geckodriver discussion is
 tools-marionette@lists.mozilla.org ([subscribe], [archive]).
 
 There is also an IRC channel to talk about using and developing
 geckodriver in #ateam on irc.mozilla.org.
 
 [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette
-[archive]: http://groups.google.com/group/mozilla.tools.marionette
+[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/CONTRIBUTING.md
+++ b/testing/marionette/CONTRIBUTING.md
@@ -199,9 +199,9 @@ Communication
 The mailing list for Marionette discussion is
 tools-marionette@lists.mozilla.org ([subscribe], [archive]).
 
 If you prefer real-time chat, there is often someone in the #ateam IRC
 channel on irc.mozilla.org.  Don’t ask if you can ask a question, just
 ask, and please wait for an answer as we might not be in your timezone.
 
 [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette
-[archive]: http://groups.google.com/group/mozilla.tools.marionette
+[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/README.md
+++ b/testing/marionette/README.md
@@ -60,9 +60,9 @@ for an answer as we might not be in your
 [clients]: #clients
 [protocol]: #protocol
 [command]: #command
 [response]: #response
 [error]: #error-object
 [WebDriver standard]: https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors
 [reference client]: client/
 [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette
-[archive]: http://groups.google.com/group/mozilla.tools.marionette
+[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/doc/index.rst
+++ b/testing/marionette/doc/index.rst
@@ -1,38 +1,71 @@
 ==========
 Marionette
 ==========
 
-Marionette is an automation driver for Mozilla's Gecko engine.
+Marionette is the remote protocol that lets OOP programs communicate
+with, instrument, and control Gecko.
+
+
+Description
+===========
+
+Marionette is an automation driver for Mozilla’s Gecko engine.
 It can remotely control either the UI or the internal JavaScript of
-a Gecko platform, such as Firefox.  It can control both the chrome
-(i.e. menus and functions) or the content (the webpage loaded inside
-the browsing context), giving a high level of control and ability
-to replicate user actions. In addition to performing actions on the
-browser, Marionette can also read the properties and attributes of
-the DOM.
+Gecko-based browsers, such as Firefox and Fennec.  It can control
+both the chrome and the content document, giving a high level of
+control and ability to replicate user interaction.  In addition
+to performing actions on the browser, Marionette can also ready
+properties and attributes of the DOM.
+
 
 For users
 =========
+
 .. toctree::
    :maxdepth: 1
 
    Intro.md
    Protocol.md
 
 
 See also:
 
-*   Documentation for `Marionette Python Client <http://marionette-client.readthedocs.io>`_,
-    which is used in-tree to write many kinds of Marionette-based tests.
-*   Documentation for `Firefox Puppeteer <http://firefox-puppeteer.readthedocs.io>`_, which is
-    used to in-tree to write Firefox UI tests.
+* Documentation for `Marionette Python client`_., which is used
+  in-tree to write many kinds of Marionette-based tests.
+* Documentation for `Firefox Puppeteer`_, which is used to in-tree
+  to write Firefox UI tests.
 
-For marionette developers
-==========================
+.. _Marionette Python client: http://marionette-client.readthedocs.io
+.. _Firefox Puppeteer: http://firefox-puppeteer.readthedocs.io
+
+
+For developers
+==============
+
 .. toctree::
    :maxdepth: 1
 
+   ../CONTRIBUTING.md
    NewContributors.md
    Debugging.md
    PythonTests.md
    SeleniumAtoms.md
+
+
+Bugs
+====
+
+Bugs are tracked in the `Testing :: Marionette` component.
+
+
+Communication
+=============
+
+The mailing list for discussion is tools-marionette@lists.mozilla.org
+(subscribe_, archive_).  If you prefer real-time chat, there
+is often someone in the #ateam IRC channel on irc.mozilla.org.
+Don’t ask if you can ask a question, just ask, and please wait
+for an answer as we might not be in your timezone.
+
+.. _subscribe: https://lists.mozilla.org/listinfo/tools-marionette
+.. _archive: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/talos/talos/xtalos/xperf_whitelist.json
+++ b/testing/talos/talos/xtalos/xperf_whitelist.json
@@ -6,16 +6,19 @@
     "ignore": true
   },
   "C:\\$Secure": {
     "ignore": true
   },
   "C:\\$logfile": {
     "ignore": true
   },
+  "Z:\\$logfile": {
+    "ignore": true
+  },
   "C:\\Windows\\Prefetch\\{prefetch}.pf": {
     "ignore": true
   },
   "c:\\program files\\desktop.ini": {
     "mincount": 2,
     "maxcount": 2,
     "minbytes": 352,
     "maxbytes": 352
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -96028,28 +96028,16 @@
       [
        "/css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
-   "css/compositing/mix-blend-mode/mix-blend-mode-transition.html": [
-    [
-     "/css/compositing/mix-blend-mode/mix-blend-mode-transition.html",
-     [
-      [
-       "/css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html": [
     [
      "/css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html",
      [
       [
        "/css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html",
        "!="
       ]
@@ -228108,21 +228096,16 @@
      {}
     ]
    ],
    "css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html": [
     [
      {}
     ]
    ],
-   "css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html": [
-    [
-     {}
-    ]
-   ],
    "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-notref.html": [
     [
      {}
     ]
    ],
    "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html": [
     [
      {}
@@ -463553,20 +463536,16 @@
   "css/compositing/mix-blend-mode/mix-blend-mode-stacking-context-creates-isolation.html": [
    "3e4bf24c8e89f3e127419eafafcee58b29e5d207",
    "reftest"
   ],
   "css/compositing/mix-blend-mode/mix-blend-mode-svg.html": [
    "b0cf703533a323305eb772c6def00afe21cdcdb8",
    "reftest"
   ],
-  "css/compositing/mix-blend-mode/mix-blend-mode-transition.html": [
-   "2a9c826f5db1d9eb5a4748351a7d411b4c65a93b",
-   "reftest"
-  ],
   "css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html": [
    "d9682264f4ce1859b0d7f22b8dfca5cc482028a8",
    "reftest"
   ],
   "css/compositing/mix-blend-mode/mix-blend-mode-video.html": [
    "53c1adad26086551ab5c7212c477d14aaf7ae672",
    "reftest"
   ],
@@ -463693,20 +463672,16 @@
   "css/compositing/mix-blend-mode/reference/mix-blend-mode-stacking-context-creates-isolation-ref.html": [
    "55faa83db514df5fad411f34ff98e9a487f0f46d",
    "support"
   ],
   "css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html": [
    "543892c3466ace307bd125801a2231dae3a95b92",
    "support"
   ],
-  "css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html": [
-   "2fdce2d337a053453bc339ffb7f9e0560c1f0095",
-   "support"
-  ],
   "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-notref.html": [
    "4407e55ee0412f2064caeee74acad93424a849c7",
    "support"
   ],
   "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html": [
    "de4eea01cbb8138c53aac94b5c3fea347a46c7d8",
    "support"
   ],
deleted file mode 100644
--- a/testing/web-platform/tests/css/compositing/mix-blend-mode/mix-blend-mode-transition.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>CSS Test: Blended element with transition</title>
-        <link rel="author" title="Mihai Tica" href="mailto:mitica@adobe.com">
-        <link rel="help" href="https://drafts.fxtf.org/compositing-1/#mix-blend-mode">
-        <meta name="assert" content="Test checks that an element having a transition applied on opacity blends with the parent element.">
-        <meta name="flags" content="dom"/>
-        <link rel="reviewer" title="Rik Cabanier" href="mailto:cabanier@adobe.com">
-        <link rel="reviewer" title="Mirela Budaes" href="mailto:mbudaes@adobe.com">
-        <link rel="match" href="reference/mix-blend-mode-transition-ref.html">
-        <style type="text/css">
-            div {
-                width: 100px;
-                height: 100px;
-                background: #FF0;
-            }
-
-            #blender {
-                background: #F00;
-                mix-blend-mode: difference;
-                transition: opacity 1s ease;
-            }
-
-            .opaqueBox {
-                opacity: 0.4;
-            }
-        </style>
-    </head>
-    <body>
-        <p>Test passes if you can see a fading green rectangle.</p>
-        <div><div id="blender"></div></div>
-        <script type="text/javascript">
-            setInterval(function(){ document.getElementById('blender').className = 'opaqueBox'; }, 100);
-        </script>
-    </body>
-</html>
deleted file mode 100644
--- a/testing/web-platform/tests/css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>CSS Test: Blended element with transition</title>
-        <link rel="author" title="Mihai Tica" href="mailto:mitica@adobe.com">
-        <meta name="flags" content="dom"/>
-        <style type="text/css">
-            div {
-                width: 100px;
-                height: 100px;
-            }
-
-            #blender {
-                background: #0F0;
-                transition: opacity 1s ease;
-            }
-
-            .opaqueBox {
-                opacity: 0.4;
-            }
-        </style>
-    </head>
-    <body>
-        <p>Test passes if you can see a fading green rectangle.</p>
-        <div style="background: #FF0;"><div id="blender"></div></div>
-        <script type="text/javascript">
-            setInterval(function(){ document.getElementById('blender').className = 'opaqueBox'; }, 100);
-        </script>
-    </body>
-</html>
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini
@@ -3,9 +3,10 @@ skip-if = os == "android" || (os == "win
 [test_ext_i18n_css.js]
 [test_ext_contentscript.js]
 [test_ext_contentscript_scriptCreated.js]
 skip-if = debug # Bug 1407501
 [test_ext_contentscript_triggeringPrincipal.js]
 skip-if = os == "android" && debug
 [test_ext_contentscript_xrays.js]
 [test_ext_contentScripts_register.js]
+skip-if = os == "android"
 [test_ext_adoption_with_xrays.js]
--- a/toolkit/components/windowcreator/test/mochitest.ini
+++ b/toolkit/components/windowcreator/test/mochitest.ini
@@ -4,10 +4,11 @@ support-files =
 
 [test_bug293834.html]
 skip-if = (toolkit == "cocoa" && e10s) # bug 1252223
 [test_bug499115.html]
 [test_nsFind.html]
 [test_private_window_from_content.html]
 [test_window_open_position_constraint.html]
 skip-if = toolkit == 'android'
+fail-if = (os == "win" && ccov) # bug 1421715
 [test_window_open_units.html]
 skip-if = toolkit == 'android'
--- a/toolkit/crashreporter/test/unit/xpcshell.ini
+++ b/toolkit/crashreporter/test/unit/xpcshell.ini
@@ -44,58 +44,65 @@ skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_push_nonvol.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_alloc_small.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 
 [test_crash_win64cfi_alloc_large.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_save_nonvol.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_save_nonvol_far.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 
 [test_crash_win64cfi_save_xmm128.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_save_xmm128_far.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 
 [test_crash_win64cfi_epilog.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
 
 [test_crash_win64cfi_infinite_entry_chain.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 support-files = test_crash_win64cfi_infinite_entry_chain.exe
 
 [test_crash_win64cfi_infinite_code_chain.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 support-files = test_crash_win64cfi_infinite_code_chain.exe
 
 [test_crash_win64cfi_invalid_exception_rva.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 support-files = test_crash_win64cfi_invalid_exception_rva.exe
 
 [test_crash_win64cfi_not_a_pe.js]
 head = head_crashreporter.js head_win64cfi.js
 skip-if = os != 'win' || bits != 64
+fail-if = os == 'win' && ccov
 support-files = test_crash_win64cfi_not_a_pe.exe
 
 
 
 
 
 
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -25,16 +25,17 @@ skip-if = appname != "firefox"
 tags = blocklist
 [test_provider_markSafe.js]
 [test_provider_shutdown.js]
 [test_provider_unsafe_access_shutdown.js]
 [test_provider_unsafe_access_startup.js]
 [test_ProductAddonChecker.js]
 [test_shutdown.js]
 [test_system_update_blank.js]
+fail-if = os == 'win' && ccov
 [test_system_update_checkSizeHash.js]
 [test_system_update_custom.js]
 [test_system_update_empty.js]
 skip-if = true # Failing intermittently due to a race condition in the test, see bug 1348981
 [test_system_update_fail.js]
 [test_system_update_newset.js]
 [test_system_update_overlapping.js]
 [test_system_update_upgrades.js]
--- a/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini
+++ b/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini
@@ -2,16 +2,17 @@
 # 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/.
 
 # Tests that require the updater binary and the maintenance service.
 
 [DEFAULT]
 tags = appupdate
 head = head_update.js
+fail-if = os == 'win' && ccov
 
 [bootstrapSvc.js]
 run-sequentially = Uses the Mozilla Maintenance Service.
 [invalidArgInstallDirPathTooLongFailureSvc.js]
 run-sequentially = Uses the Mozilla Maintenance Service.
 [invalidArgInstallDirPathTraversalFailureSvc.js]
 run-sequentially = Uses the Mozilla Maintenance Service.
 [invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js]