Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 08 Jul 2016 12:17:32 +0200
changeset 304256 00b612e67c091e3e5899fe5e8a60870ed1a910f2
parent 304255 806cd7a7b68de8777caf419239e2f4e671aaa80b (current diff)
parent 304203 45682df2d2d45e5a8385fd842579e661a4b60bc5 (diff)
child 304257 a30b1295e5968d8d45397eb94c42a00925b14c5c
push id79280
push userkwierso@gmail.com
push dateFri, 08 Jul 2016 22:04:28 +0000
treeherdermozilla-inbound@14b16ac38991 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone50.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 mozilla-central to fx-team
dom/bindings/mozwebidlcodegen/test/DummyBinding.webidl
dom/plugins/ipc/NestedLoopTimer.cpp
dom/plugins/ipc/NestedLoopTimer.h
dom/plugins/ipc/PluginHelperQt.cpp
dom/plugins/test/testplugin/nptest_qt.cpp
dom/system/qt/QTMLocationProvider.cpp
dom/system/qt/QTMLocationProvider.h
dom/system/qt/QtHapticFeedback.cpp
dom/system/qt/QtHapticFeedback.h
dom/system/qt/moz.build
dom/webidl/DummyBinding.webidl
image/decoders/icon/qt/gtkqticonsconverter.js
image/decoders/icon/qt/gtkqticonsconverter.manifest
image/decoders/icon/qt/moz.build
image/decoders/icon/qt/nsGtkQtIconsConverter.idl
image/decoders/icon/qt/nsIconChannel.cpp
image/decoders/icon/qt/nsIconChannel.h
netwerk/system/qt/moz.build
netwerk/system/qt/nsQtNetworkLinkService.cpp
netwerk/system/qt/nsQtNetworkLinkService.h
netwerk/system/qt/nsQtNetworkManager.cpp
netwerk/system/qt/nsQtNetworkManager.h
testing/web-platform/meta/cors/redirect-preflight.htm.ini
widget/qt/GfxInfo.cpp
widget/qt/GfxInfo.h
widget/qt/moz.build
widget/qt/mozqwidget.cpp
widget/qt/mozqwidget.h
widget/qt/nsAppShell.cpp
widget/qt/nsAppShell.h
widget/qt/nsBidiKeyboard.cpp
widget/qt/nsBidiKeyboard.h
widget/qt/nsClipboard.cpp
widget/qt/nsClipboard.h
widget/qt/nsDeviceContextSpecQt.cpp
widget/qt/nsDeviceContextSpecQt.h
widget/qt/nsIdleServiceQt.cpp
widget/qt/nsIdleServiceQt.h
widget/qt/nsLookAndFeel.cpp
widget/qt/nsLookAndFeel.h
widget/qt/nsPrintDialogQt.cpp
widget/qt/nsPrintDialogQt.h
widget/qt/nsPrintOptionsQt.cpp
widget/qt/nsPrintOptionsQt.h
widget/qt/nsPrintSettingsQt.cpp
widget/qt/nsPrintSettingsQt.h
widget/qt/nsQtKeyUtils.cpp
widget/qt/nsQtKeyUtils.h
widget/qt/nsScreenManagerQt.cpp
widget/qt/nsScreenManagerQt.h
widget/qt/nsScreenQt.cpp
widget/qt/nsScreenQt.h
widget/qt/nsWidgetFactory.cpp
widget/qt/nsWindow.cpp
widget/qt/nsWindow.h
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -301,17 +301,16 @@ def old_configure_options(*options):
     '--with-nspr-cflags',
     '--with-nspr-exec-prefix',
     '--with-nspr-libs',
     '--with-nspr-prefix',
     '--with-nss-exec-prefix',
     '--with-nss-prefix',
     '--with-pthreads',
     '--with-qemu-exe',
-    '--with-qtdir',
     '--with-servo',
     '--with-sixgill',
     '--with-soft-float',
     '--with-system-bz2',
     '--with-system-icu',
     '--with-system-jpeg',
     '--with-system-libevent',
     '--with-system-libvpx',
--- a/devtools/client/webconsole/new-console-output/utils/messages.js
+++ b/devtools/client/webconsole/new-console-output/utils/messages.js
@@ -59,30 +59,30 @@ function prepareMessage(packet) {
         data.arguments = [l10n.getStr("consoleCleared")];
       }
 
       allowRepeating = true;
       category = CATEGORY_CLASS_FRAGMENTS[CATEGORY_WEBDEV];
       messageType = "ConsoleApiCall";
       repeat = 1;
       repeatId = getRepeatId(data);
-      severity = SEVERITY_CLASS_FRAGMENTS[LEVELS[data.level]];
+      severity = SEVERITY_CLASS_FRAGMENTS[LEVELS[data.level]] || "log";
       break;
     case "pageError":
       data = Object.assign({}, packet.pageError);
       allowRepeating = true;
       category = CATEGORY_CLASS_FRAGMENTS[CATEGORY_JS];
       messageType = "PageError";
       repeat = 1;
       repeatId = getRepeatId(data);
 
       severity = SEVERITY_CLASS_FRAGMENTS[SEVERITY_ERROR];
       if (data.warning || data.strict) {
         severity = SEVERITY_CLASS_FRAGMENTS[SEVERITY_WARNING];
-      } else if (data.info) {
+      } else {
         severity = SEVERITY_CLASS_FRAGMENTS[SEVERITY_LOG];
       }
       break;
     case "evaluationResult":
     default:
       if (typeof packet.result === "object") {
         data = Object.assign({}, packet.result);
       } else {
--- a/devtools/client/webconsole/webconsole.js
+++ b/devtools/client/webconsole/webconsole.js
@@ -496,18 +496,19 @@ WebConsoleFrame.prototype = {
 
   /**
    * Find the Web Console UI elements and setup event listeners as needed.
    * @private
    */
   _initUI: function () {
     this.document = this.window.document;
     this.rootElement = this.document.documentElement;
-    this.NEW_CONSOLE_OUTPUT_ENABLED = !this.owner._browserConsole &&
-      Services.prefs.getBoolPref(PREF_NEW_FRONTEND_ENABLED);
+    this.NEW_CONSOLE_OUTPUT_ENABLED = !this.owner._browserConsole
+      && !this.owner.target.chrome
+      && Services.prefs.getBoolPref(PREF_NEW_FRONTEND_ENABLED);
 
     this._initDefaultFilterPrefs();
 
     // Register the controller to handle "select all" properly.
     this._commandController = new CommandController(this);
     this.window.controllers.insertControllerAt(0, this._commandController);
 
     this._contextMenuHandler = new ConsoleContextMenu(this);
--- a/devtools/shared/heapsnapshot/DeserializedNode.h
+++ b/devtools/shared/heapsnapshot/DeserializedNode.h
@@ -239,27 +239,25 @@ struct DeserializedStackFrame::HashPolic
 
 namespace JS {
 namespace ubi {
 
 using mozilla::devtools::DeserializedNode;
 using mozilla::devtools::DeserializedStackFrame;
 
 template<>
-struct Concrete<DeserializedNode> : public Base
+class Concrete<DeserializedNode> : public Base
 {
 protected:
   explicit Concrete(DeserializedNode* ptr) : Base(ptr) { }
   DeserializedNode& get() const {
     return *static_cast<DeserializedNode*>(ptr);
   }
 
 public:
-  static const char16_t concreteTypeName[];
-
   static void construct(void* storage, DeserializedNode* ptr) {
     new (storage) Concrete(ptr);
   }
 
   CoarseType coarseType() const final { return get().coarseType; }
   Id identifier() const override { return get().id; }
   bool isLive() const override { return false; }
   const char16_t* typeName() const override;
@@ -268,16 +266,18 @@ public:
   const char* scriptFilename() const final { return get().scriptFilename; }
 
   bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
   StackFrame allocationStack() const override;
 
   // We ignore the `bool wantNames` parameter because we can't control whether
   // the core dump was serialized with edge names or not.
   js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override;
+
+  static const char16_t concreteTypeName[];
 };
 
 template<>
 class ConcreteStackFrame<DeserializedStackFrame> : public BaseStackFrame
 {
 protected:
   explicit ConcreteStackFrame(DeserializedStackFrame* ptr)
     : BaseStackFrame(ptr)
--- a/devtools/shared/heapsnapshot/HeapSnapshot.h
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.h
@@ -41,17 +41,17 @@ using UniqueTwoByteString = UniquePtr<ch
 using UniqueOneByteString = UniquePtr<char[], NSFreePolicy>;
 
 class HeapSnapshot final : public nsISupports
                          , public nsWrapperCache
 {
   friend struct DeserializedNode;
   friend struct DeserializedEdge;
   friend struct DeserializedStackFrame;
-  friend struct JS::ubi::Concrete<JS::ubi::DeserializedNode>;
+  friend class JS::ubi::Concrete<JS::ubi::DeserializedNode>;
 
   explicit HeapSnapshot(JSContext* cx, nsISupports* aParent)
     : timestamp(Nothing())
     , rootId(0)
     , nodes(cx)
     , frames(cx)
     , mParent(aParent)
   {
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -18,16 +18,17 @@
 
 using mozilla::dom::AnyCallback;
 using mozilla::dom::DOMError;
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 using mozilla::dom::DOMCursor;
 using mozilla::dom::Promise;
 using mozilla::dom::AutoJSAPI;
+using mozilla::dom::GetJSRuntime;
 
 DOMRequest::DOMRequest(nsPIDOMWindowInner* aWindow)
   : DOMEventTargetHelper(aWindow)
   , mResult(JS::UndefinedValue())
   , mDone(false)
 {
 }
 
@@ -296,17 +297,17 @@ DOMRequestService::FireDetailedError(nsI
 }
 
 class FireSuccessAsyncTask : public mozilla::Runnable
 {
 
   FireSuccessAsyncTask(DOMRequest* aRequest,
                        const JS::Value& aResult) :
     mReq(aRequest),
-    mResult(nsContentUtils::RootingCxForThread(), aResult)
+    mResult(GetJSRuntime(), aResult)
   {
   }
 
 public:
 
   // Due to the fact that initialization can fail during shutdown (since we
   // can't fetch a js context), set up an initiatization function to make sure
   // we can return the failure appropriately
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -2,16 +2,17 @@
 /* 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 "mozilla/dom/ScriptSettings.h"
 #include "mozilla/ThreadLocal.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/CycleCollectedJSRuntime.h"
 
 #include "jsapi.h"
 #include "xpcpublic.h"
 #include "nsIGlobalObject.h"
 #include "nsIDocShell.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsContentUtils.h"
@@ -279,16 +280,30 @@ GetWebIDLCallerPrincipal()
 
 bool
 IsJSAPIActive()
 {
   ScriptSettingsStackEntry* topEntry = ScriptSettingsStack::Top();
   return topEntry && !topEntry->NoJSAPI();
 }
 
+namespace danger {
+JSContext*
+GetJSContext()
+{
+  return CycleCollectedJSRuntime::Get()->Context();
+}
+} // namespace danger
+
+JSRuntime*
+GetJSRuntime()
+{
+  return CycleCollectedJSRuntime::Get()->Runtime();
+}
+
 AutoJSAPI::AutoJSAPI()
   : ScriptSettingsStackEntry(nullptr, eJSAPI)
   , mCx(nullptr)
   , mIsMainThread(false) // For lack of anything better
 {
 }
 
 AutoJSAPI::~AutoJSAPI()
@@ -320,16 +335,17 @@ void
 WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage,
                          JSErrorReport* aRep);
 
 void
 AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
                         JSContext* aCx, bool aIsMainThread)
 {
   MOZ_ASSERT(aCx);
+  MOZ_ASSERT(aCx == danger::GetJSContext());
   MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
   MOZ_ASSERT(bool(aGlobalObject) == bool(aGlobal));
   MOZ_ASSERT_IF(aGlobalObject, aGlobalObject->GetGlobalJSObject() == aGlobal);
 #ifdef DEBUG
   bool haveException = JS_IsExceptionPending(aCx);
 #endif // DEBUG
 
   mCx = aCx;
@@ -413,38 +429,35 @@ AutoJSAPI::InitInternal(nsIGlobalObject*
     }
     MOZ_ASSERT(false, "We had an exception; we should not have");
   }
 #endif // DEBUG
 }
 
 AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
                      bool aIsMainThread,
-                     JSContext* aCx,
                      Type aType)
   : ScriptSettingsStackEntry(aGlobalObject, aType)
   , mIsMainThread(aIsMainThread)
 {
   MOZ_ASSERT(aGlobalObject);
   MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global");
-  MOZ_ASSERT(aCx);
   MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
 
-  InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(), aCx,
-               aIsMainThread);
+  InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(),
+               danger::GetJSContext(), aIsMainThread);
 }
 
 void
 AutoJSAPI::Init()
 {
   MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
 
   InitInternal(/* aGlobalObject */ nullptr, /* aGlobal */ nullptr,
-               nsContentUtils::GetDefaultJSContextForThread(),
-               NS_IsMainThread());
+               danger::GetJSContext(), NS_IsMainThread());
 }
 
 bool
 AutoJSAPI::Init(nsIGlobalObject* aGlobalObject, JSContext* aCx)
 {
   MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
   MOZ_ASSERT(aCx);
 
@@ -459,17 +472,17 @@ AutoJSAPI::Init(nsIGlobalObject* aGlobal
 
   InitInternal(aGlobalObject, global, aCx, NS_IsMainThread());
   return true;
 }
 
 bool
 AutoJSAPI::Init(nsIGlobalObject* aGlobalObject)
 {
-  return Init(aGlobalObject, nsContentUtils::GetDefaultJSContextForThread());
+  return Init(aGlobalObject, danger::GetJSContext());
 }
 
 bool
 AutoJSAPI::Init(JSObject* aObject)
 {
   return Init(xpc::NativeGlobal(aObject));
 }
 
@@ -629,37 +642,31 @@ bool
 AutoJSAPI::IsStackTop() const
 {
   return ScriptSettingsStack::TopNonIncumbentScript() == this;
 }
 #endif // DEBUG
 
 AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
                                  const char *aReason,
-                                 bool aIsMainThread,
-                                 JSContext* aCx)
-  : AutoJSAPI(aGlobalObject, aIsMainThread,
-              aCx ? aCx : nsContentUtils::GetSafeJSContext(),
-              eEntryScript)
+                                 bool aIsMainThread)
+  : AutoJSAPI(aGlobalObject, aIsMainThread, eEntryScript)
   , mWebIDLCallerPrincipal(nullptr)
 {
   MOZ_ASSERT(aGlobalObject);
-  MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
-  MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == nsContentUtils::GetSafeJSContext());
 
   if (aIsMainThread && gRunToCompletionListeners > 0) {
     mDocShellEntryMonitor.emplace(cx(), aReason);
   }
 }
 
 AutoEntryScript::AutoEntryScript(JSObject* aObject,
                                  const char *aReason,
-                                 bool aIsMainThread,
-                                 JSContext* aCx)
-  : AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread, aCx)
+                                 bool aIsMainThread)
+  : AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread)
 {
 }
 
 AutoEntryScript::~AutoEntryScript()
 {
   // GC when we pop a script entry point. This is a useful heuristic that helps
   // us out on certain (flawed) benchmarks like sunspider, because it lets us
   // avoid GCing during the timing loop.
@@ -771,17 +778,17 @@ AutoJSContext::AutoJSContext(MOZ_GUARD_O
 {
   JS::AutoSuppressGCAnalysis nogc;
   MOZ_ASSERT(!mCx, "mCx should not be initialized!");
   MOZ_ASSERT(NS_IsMainThread());
 
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
   if (IsJSAPIActive()) {
-    mCx = nsContentUtils::GetSafeJSContext();
+    mCx = danger::GetJSContext();
   } else {
     mJSAPI.Init();
     mCx = mJSAPI.cx();
   }
 }
 
 AutoJSContext::operator JSContext*() const
 {
--- a/dom/base/ScriptSettings.h
+++ b/dom/base/ScriptSettings.h
@@ -122,16 +122,27 @@ inline JSObject& IncumbentJSGlobal()
   return *GetIncumbentGlobal()->GetGlobalJSObject();
 }
 
 // Returns whether JSAPI is active right now.  If it is not, working with a
 // JSContext you grab from somewhere random is not OK and you should be doing
 // AutoJSAPI or AutoEntryScript to get yourself a properly set up JSContext.
 bool IsJSAPIActive();
 
+namespace danger {
+
+// Get the JSContext for this thread.  This is in the "danger" namespace because
+// we generally want people using AutoJSAPI instead, unless they really know
+// what they're doing.
+JSContext* GetJSContext();
+
+} // namespace danger
+
+JSRuntime* GetJSRuntime();
+
 class ScriptSettingsStack;
 class ScriptSettingsStackEntry {
   friend class ScriptSettingsStack;
 
 public:
   ~ScriptSettingsStackEntry();
 
   bool NoJSAPI() const { return mType == eNoJSAPI; }
@@ -273,23 +284,19 @@ public:
   bool PeekException(JS::MutableHandle<JS::Value> aVal);
 
   void ClearException() {
     MOZ_ASSERT(IsStackTop());
     JS_ClearPendingException(cx());
   }
 
 protected:
-  // Protected constructor, allowing subclasses to specify a particular cx to
-  // be used. This constructor initialises the AutoJSAPI, so Init must NOT be
-  // called on subclasses that use this.
-  // If aGlobalObject, its associated JS global or aCx are null this will cause
-  // an assertion, as will setting aIsMainThread incorrectly.
-  AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx,
-            Type aType);
+  // Protected constructor for subclasses.  This constructor initialises the
+  // AutoJSAPI, so Init must NOT be called on subclasses that use this.
+  AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, Type aType);
 
 private:
   mozilla::Maybe<JSAutoRequest> mAutoRequest;
   mozilla::Maybe<JSAutoNullableCompartment> mAutoNullableCompartment;
   JSContext *mCx;
 
   // Whether we're mainthread or not; set when we're initialized.
   bool mIsMainThread;
@@ -308,25 +315,21 @@ private:
  * |aReason| should be a statically-allocated C string naming the reason we're
  * invoking JavaScript code: "setTimeout", "event", and so on. The devtools use
  * these strings to label JS execution in timeline and profiling displays.
  */
 class MOZ_STACK_CLASS AutoEntryScript : public AutoJSAPI {
 public:
   AutoEntryScript(nsIGlobalObject* aGlobalObject,
                   const char *aReason,
-                  bool aIsMainThread = NS_IsMainThread(),
-                  // Note: aCx is mandatory off-main-thread.
-                  JSContext* aCx = nullptr);
+                  bool aIsMainThread = NS_IsMainThread());
 
   AutoEntryScript(JSObject* aObject, // Any object from the relevant global
                   const char *aReason,
-                  bool aIsMainThread = NS_IsMainThread(),
-                  // Note: aCx is mandatory off-main-thread.
-                  JSContext* aCx = nullptr);
+                  bool aIsMainThread = NS_IsMainThread());
 
   ~AutoEntryScript();
 
   void SetWebIDLCallerPrincipal(nsIPrincipal *aPrincipal) {
     mWebIDLCallerPrincipal = aPrincipal;
   }
 
 private:
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -5541,38 +5541,17 @@ nsContentUtils::GetContextForEventHandle
 JSContext *
 nsContentUtils::GetCurrentJSContext()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(IsInitialized());
   if (!IsJSAPIActive()) {
     return nullptr;
   }
-  return GetSafeJSContext();
-}
-
-/* static */
-JSContext *
-nsContentUtils::GetSafeJSContext()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(IsInitialized());
-  return sXPConnect->GetSafeJSContext();
-}
-
-/* static */
-JSContext *
-nsContentUtils::GetDefaultJSContextForThread()
-{
-  MOZ_ASSERT(IsInitialized());
-  if (MOZ_LIKELY(NS_IsMainThread())) {
-    return GetSafeJSContext();
-  } else {
-    return workers::GetCurrentThreadJSContext();
-  }
+  return danger::GetJSContext();
 }
 
 /* static */
 JSContext *
 nsContentUtils::GetCurrentJSContextForThread()
 {
   MOZ_ASSERT(IsInitialized());
   if (MOZ_LIKELY(NS_IsMainThread())) {
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1717,21 +1717,20 @@ public:
    */
   static nsresult ProcessViewportInfo(nsIDocument *aDocument,
                                       const nsAString &viewportInfo);
 
   static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
                                                       nsresult* aRv);
 
   static JSContext *GetCurrentJSContext();
-  static JSContext *GetSafeJSContext();
   static JSContext *GetCurrentJSContextForThread();
-  static JSContext *GetDefaultJSContextForThread();
-  inline static JSContext *RootingCx() { return GetSafeJSContext(); }
-  inline static JSContext *RootingCxForThread() { return GetDefaultJSContextForThread(); }
+  inline static JSContext *RootingCx() {
+    return mozilla::dom::danger::GetJSContext();
+  }
 
   /**
    * Case insensitive comparison between two strings. However it only ignores
    * case for ASCII characters a-z.
    */
   static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
                                     const nsAString& aStr2);
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2088,21 +2088,18 @@ nsFrameLoader::MaybeCreateDocShell()
       do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     webNav->SetSessionHistory(sessionHistory);
   }
 
   DocShellOriginAttributes attrs;
-
-  if (!mOwnerContent->IsXULElement(nsGkAtoms::browser)) {
-    nsCOMPtr<nsIPrincipal> parentPrin = doc->NodePrincipal();
-    PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
-    attrs.InheritFromDocToChildDocShell(poa);
+  if (docShell->ItemType() == mDocShell->ItemType()) {
+    attrs = nsDocShell::Cast(docShell)->GetOriginAttributes();
   }
 
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
     MOZ_ASSERT(!OwnerIsMozBrowserFrame());
 
     nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
     MOZ_ASSERT(ownApp);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3295,22 +3295,16 @@ nsGlobalWindow::GetTargetForEventTargetC
 }
 
 nsresult
 nsGlobalWindow::WillHandleEvent(EventChainPostVisitor& aVisitor)
 {
   return NS_OK;
 }
 
-JSContext*
-nsGlobalWindow::GetJSContextForEventHandlers()
-{
-  return nullptr;
-}
-
 nsresult
 nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   NS_PRECONDITION(IsInnerWindow(), "PreHandleEvent is used on outer window!?");
   EventMessage msg = aVisitor.mEvent->mMessage;
 
   aVisitor.mCanHandle = true;
   aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -112,17 +112,16 @@ public:
   {
     return mozilla::DOMEventTargetHelper::AddEventListener(aType, aListener,
                                                            aUseCapture,
                                                            aWantsUntrusted,
                                                            optional_argc);
   }
   using mozilla::DOMEventTargetHelper::AddEventListener;
 
-  virtual JSContext* GetJSContextForEventHandlers() override { return nsContentUtils::GetSafeJSContext(); }
   virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
   void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
   void FireUnloadEvent();
   void DisconnectEventListeners();
   void Disconnect();
   void SendMessageToParent(const nsString& aMessage, bool aSync,
                            const nsString& aJSON,
                            nsTArray<nsString>* aJSONRetVal);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -242,18 +242,18 @@ FindExceptionStackForConsoleReport(nsPID
   }
 
   if (win && win->InnerObjectsFreed()) {
     // Pretend like we have no stack, so we don't end up keeping the global
     // alive via the stack.
     return nullptr;
   }
 
-  JSContext* cx = nsContentUtils::RootingCxForThread();
-  JS::RootedObject exceptionObject(cx, &exceptionValue.toObject());
+  JSRuntime* rt = GetJSRuntime();
+  JS::RootedObject exceptionObject(rt, &exceptionValue.toObject());
   JSObject* stackObject = ExceptionStackOrNull(exceptionObject);
   if (stackObject) {
     return stackObject;
   }
 
   // It is not a JS Exception, try DOM Exception.
   RefPtr<Exception> exception;
   UNWRAP_OBJECT(DOMException, exceptionObject, exception);
@@ -264,17 +264,17 @@ FindExceptionStackForConsoleReport(nsPID
       return nullptr;
     }
   }
 
   nsCOMPtr<nsIStackFrame> stack = exception->GetLocation();
   if (!stack) {
     return nullptr;
   }
-  JS::RootedValue value(cx);
+  JS::RootedValue value(rt);
   stack->GetNativeSavedFrame(&value);
   if (value.isObject()) {
     return &value.toObject();
   }
   return nullptr;
 }
 
 } /* namespace xpc */
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -362,17 +362,17 @@ nsJSUtils::ResetTimeZone()
 }
 
 //
 // nsDOMJSUtils.h
 //
 
 bool nsAutoJSString::init(const JS::Value &v)
 {
-  JSContext* cx = nsContentUtils::RootingCxForThread();
-  if (!init(nsContentUtils::RootingCxForThread(), v)) {
+  JSContext* cx = nsContentUtils::RootingCx();
+  if (!init(cx, v)) {
     JS_ClearPendingException(cx);
     return false;
   }
 
   return true;
 }
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -354,17 +354,17 @@ ErrorResult::ClearDOMExceptionInfo()
   mUnionState = HasNothing;
 #endif // DEBUG
 }
 
 void
 ErrorResult::ClearUnionData()
 {
   if (IsJSException()) {
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
+    JSContext* cx = nsContentUtils::RootingCx();
     MOZ_ASSERT(cx);
     mJSException.setUndefined();
     js::RemoveRawValueRoot(cx, &mJSException);
 #ifdef DEBUG
     mUnionState = HasNothing;
 #endif // DEBUG
   } else if (IsErrorWithMessage()) {
     ClearMessage();
@@ -393,17 +393,17 @@ ErrorResult::operator=(ErrorResult&& aRH
 #ifdef DEBUG
   mMightHaveUnreportedJSException = aRHS.mMightHaveUnreportedJSException;
   aRHS.mMightHaveUnreportedJSException = false;
 #endif
   if (aRHS.IsErrorWithMessage()) {
     mMessage = aRHS.mMessage;
     aRHS.mMessage = nullptr;
   } else if (aRHS.IsJSException()) {
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
+    JSContext* cx = nsContentUtils::RootingCx();
     MOZ_ASSERT(cx);
     mJSException.setUndefined();
     if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
       MOZ_CRASH("Could not root mJSException, we're about to OOM");
     }
     mJSException = aRHS.mJSException;
     aRHS.mJSException.setUndefined();
     js::RemoveRawValueRoot(cx, &aRHS.mJSException);
@@ -448,17 +448,17 @@ ErrorResult::CloneTo(ErrorResult& aRv) c
     aRv.mUnionState = HasDOMExceptionInfo;
 #endif
     aRv.mDOMExceptionInfo = new DOMExceptionInfo(mDOMExceptionInfo->mRv,
                                                  mDOMExceptionInfo->mMessage);
   } else if (IsJSException()) {
 #ifdef DEBUG
     aRv.mUnionState = HasJSException;
 #endif
-    JSContext* cx = nsContentUtils::RootingCxForThread();
+    JSContext* cx = nsContentUtils::RootingCx();
     JS::Rooted<JS::Value> exception(cx, mJSException);
     aRv.ThrowJSException(cx, exception);
   }
 }
 
 void
 ErrorResult::SuppressException()
 {
@@ -2345,17 +2345,17 @@ ConstructJSImplementation(const char* aC
       return;
     }
     // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer
     // and our global is a window.
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
       do_QueryInterface(implISupports);
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
     if (gpi) {
-      JS::Rooted<JS::Value> initReturn(nsContentUtils::RootingCxForThread());
+      JS::Rooted<JS::Value> initReturn(GetJSRuntime());
       rv = gpi->Init(window, &initReturn);
       if (NS_FAILED(rv)) {
         aRv.Throw(rv);
         return;
       }
       // With JS-implemented WebIDL, the return value of init() is not used to determine
       // if init() failed, so init() should only return undefined. Any kind of permission
       // or pref checking must happen by adding an attribute to the WebIDL interface.
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -3,82 +3,54 @@
 # 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/.
 
 # DOM Bindings Configuration.
 #
 # The WebIDL interfaces are defined in dom/webidl. For interfaces requiring
 # special handling, there are corresponding entries in the configuration table
-# below. The configuration table maps each interface name to a |descriptor| or
-# list of |descriptor|s.
+# below. The configuration table maps each interface name to a |descriptor|.
 #
 # Valid fields for all descriptors:
 #   * nativeType - The native type (concrete class or XPCOM interface) that
 #                  instances of this interface will unwrap to.  If not
 #                  specified, defaults to 'nsIDOM' followed by the interface
-#                  name for external interfaces,
-#                  'mozilla::dom::workers::InterfaceName' for worker
-#                  non-callback interfaces, and 'mozilla::dom::InterfaceName'
-#                  for everything else.
+#                  name for external interfaces and
+#                  'mozilla::dom::InterfaceName' for everything else.
 #   * headerFile - The file in which the nativeType is declared (defaults
 #                  to an educated guess).
 #   * concrete - Indicates whether there exist JS objects with this interface as
 #                their primary interface (and hence whose prototype is this
 #                interface's prototype object).  Always False for callback
 #                interfaces.  Defaults to True otherwise.
-#   * workers - Indicates whether the descriptor is intended to be used solely
-#               for worker threads (defaults to false). If true the interface
-#               will not be made available on the main thread.
 #   * notflattened - The native type does not have nsIClassInfo, so when
 #                    wrapping it the right IID needs to be passed in.
 #                    Only relevant for callback interfaces.
 #   * register - True if this binding should be registered.  Defaults to true.
 #   * binaryNames - Dict for mapping method and attribute names to different
 #                   names when calling the native methods (defaults to an empty
 #                   dict). The keys are the property names as they appear in the
 #                   .webidl file and the values are the names as they should be
 #                   in the WebIDL.
 #   * wrapperCache: True if this object is a wrapper cache.  Objects that are
 #                   not can only be returned from a limited set of methods,
 #                   cannot be prefable, and must ensure that they disallow
 #                   XPConnect wrapping.  Always false for callback interfaces.
-#                   Always true for worker descriptors for non-callback
-#                   interfaces.  Defaults to true for non-worker non-callback
-#                   descriptors.
-#
-# A non-worker descriptor can have 'wantsXrays': False specified if it
-# should not have Xray hooks generated.  Make sure to have someone
-# familiar with Xrays review any use of this!
+#                   Defaults to true for non-callback descriptors.
 #
 # The following fields are either a string, an array (defaults to an empty
 # array) or a dictionary with three possible keys (all, getterOnly and
 # setterOnly) each having such an array as the value
 #
 #   * implicitJSContext - attributes and methods specified in the .webidl file
 #                         that require a JSContext as the first argument
 #
-# A descriptor can also have 'skipGen': True specified if it should be skipped
-# when deciding what header includes to generate and should never have an
-# implementation generated for it.  This is only needed in special cases like
-# worker descriptors for objects that will never actually appear in workers.
-#
-# The value for an interface can be a list or a dictionary, which affects which
-# bindings are generated for that interface.
-# - If the value for the interface is just a record, then a single binding for
-#   will be generated using those settings.
-# - If it is a list with a single record which has 'workers':True, then that
-#   record will be used to generate bindings for workers, plus the default
-#   settings will be used to generate bindings for the main thread.
-# - If it is a list with two records, then one should have 'workers':True,
-#   and the other should have 'workers':False (or left unset). These will
-#   be used to generate bindings for workers and for mainthread, as you would
-#   expect.
-# Nothing else is allowed.  If you have a list with a single 'workers':False
-# entry, just make it not a list.
+# The value for an interface is a dictionary which specifies the
+# descriptor to use when generating that interface's binding.
 
 DOMInterfaces = {
 
 'AbstractWorker': {
     'concrete': False
 },
 
 'AnimationEffectReadOnly': {
@@ -420,21 +392,16 @@ DOMInterfaces = {
 'DOMStringMap': {
     'nativeType': 'nsDOMStringMap'
 },
 
 'DOMTokenList': {
     'nativeType': 'nsDOMTokenList',
 },
 
-'DummyInterface': {
-    'skipGen': True,
-    'register': False,
-},
-
 'DynamicsCompressorNode': {
     'binaryNames': {
         'release': 'getRelease'
     },
 },
 
 'Event': {
     'implicitJSContext': [ 'defaultPrevented', 'preventDefault' ],
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -129,20 +129,17 @@ CallbackObject::CallSetup::CallSetup(Cal
     // null in some kind of teardown state.
     if (!globalObject->GetGlobalJSObject()) {
       aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
         NS_LITERAL_CSTRING("Refusing to execute function from global which is "
                            "being torn down."));
       return;
     }
 
-    // Off the main thread, AutoEntryScript expects us to pass a JSContext.
-    mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread,
-                             mIsMainThread ? nullptr
-                                           : workers::GetCurrentThreadJSContext());
+    mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread);
     mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
     nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
     if (incumbent) {
       // The callback object traces its incumbent JS global, so in general it
       // should be alive here. However, it's possible that we could run afoul
       // of the same IPC global weirdness described above, wherein the
       // nsIGlobalObject has severed its reference to the JS global. Let's just
       // be safe here, so that nobody has to waste a day debugging gaia-ui tests.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -36,17 +36,17 @@ def memberReservedSlot(member, descripto
             member.slotIndices[descriptor.interface.identifier.name])
 
 
 def toStringBool(arg):
     return str(not not arg).lower()
 
 
 def toBindingNamespace(arg):
-    return re.sub("((_workers)?$)", "Binding\\1", arg)
+    return arg + "Binding"
 
 
 def isTypeCopyConstructible(type):
     # Nullable and sequence stuff doesn't affect copy-constructibility
     type = type.unroll()
     return (type.isPrimitive() or type.isString() or type.isEnum() or
             (type.isUnion() and
              CGUnionStruct.isUnionCopyConstructible(type)) or
@@ -528,18 +528,16 @@ class CGDOMProxyJSClass(CGThing):
             objectMoved=objectMovedHook,
             descriptor=DOMClass(self.descriptor))
 
 
 def PrototypeIDAndDepth(descriptor):
     prototypeID = "prototypes::id::"
     if descriptor.interface.hasInterfacePrototypeObject():
         prototypeID += descriptor.interface.identifier.name
-        if descriptor.workers:
-            prototypeID += "_workers"
         depth = "PrototypeTraits<%s>::Depth" % prototypeID
     else:
         prototypeID += "_ID_Count"
         depth = "0"
     return (prototypeID, depth)
 
 
 def InterfacePrototypeObjectProtoGetter(descriptor):
@@ -975,26 +973,16 @@ class CGIncludeGuard(CGWrapper):
     def __init__(self, prefix, child):
         """|prefix| is the filename without the extension."""
         define = 'mozilla_dom_%s_h' % prefix
         CGWrapper.__init__(self, child,
                            declarePre='#ifndef %s\n#define %s\n\n' % (define, define),
                            declarePost='\n#endif // %s\n' % define)
 
 
-def getRelevantProviders(descriptor, config):
-    if descriptor is not None:
-        return [descriptor]
-    # Do both the non-worker and worker versions
-    return [
-        config.getDescriptorProvider(False),
-        config.getDescriptorProvider(True)
-    ]
-
-
 class CGHeaders(CGWrapper):
     """
     Generates the appropriate include statements.
     """
     def __init__(self, descriptors, dictionaries, callbacks,
                  callbackDescriptors,
                  declareIncludes, defineIncludes, prefix, child,
                  config=None, jsImplementedDescriptors=[]):
@@ -1047,22 +1035,21 @@ class CGHeaders(CGWrapper):
         if len(hasInstanceIncludes) > 0:
             hasInstanceIncludes.add("nsContentUtils.h")
 
         # Now find all the things we'll need as arguments because we
         # need to wrap or unwrap them.
         bindingHeaders = set()
         declareIncludes = set(declareIncludes)
 
-        def addHeadersForType((t, descriptor, dictionary)):
-            """
-            Add the relevant headers for this type.  We use descriptor and
-            dictionary, if passed, to decide what to do with interface types.
-            """
-            assert not descriptor or not dictionary
+        def addHeadersForType((t, dictionary)):
+            """
+            Add the relevant headers for this type.  We use dictionary, if
+            passed, to decide what to do with interface types.
+            """
             # Dictionaries have members that need to be actually
             # declared, not just forward-declared.
             if dictionary:
                 headerSet = declareIncludes
             else:
                 headerSet = bindingHeaders
             if t.nullable():
                 # Need to make sure that Nullable as a dictionary
@@ -1083,32 +1070,30 @@ class CGHeaders(CGWrapper):
                     if jsImplementedDescriptors:
                         # Since we can't forward-declare typed array types
                         # (because they're typedefs), we have to go ahead and
                         # just include their header if we need to have functions
                         # taking references to them declared in that header.
                         headerSet = declareIncludes
                     headerSet.add("mozilla/dom/TypedArray.h")
                 else:
-                    providers = getRelevantProviders(descriptor, config)
-                    for p in providers:
-                        try:
-                            typeDesc = p.getDescriptor(unrolled.inner.identifier.name)
-                        except NoSuchDescriptorError:
-                            continue
-                        # Dictionaries with interface members rely on the
-                        # actual class definition of that interface member
-                        # being visible in the binding header, because they
-                        # store them in RefPtr and have inline
-                        # constructors/destructors.
-                        #
-                        # XXXbz maybe dictionaries with interface members
-                        # should just have out-of-line constructors and
-                        # destructors?
-                        headerSet.add(typeDesc.headerFile)
+                    try:
+                        typeDesc = config.getDescriptor(unrolled.inner.identifier.name)
+                    except NoSuchDescriptorError:
+                        return
+                    # Dictionaries with interface members rely on the
+                    # actual class definition of that interface member
+                    # being visible in the binding header, because they
+                    # store them in RefPtr and have inline
+                    # constructors/destructors.
+                    #
+                    # XXXbz maybe dictionaries with interface members
+                    # should just have out-of-line constructors and
+                    # destructors?
+                    headerSet.add(typeDesc.headerFile)
             elif unrolled.isDictionary():
                 headerSet.add(self.getDeclarationFilename(unrolled.inner))
             elif unrolled.isCallback():
                 headerSet.add(self.getDeclarationFilename(unrolled.callback))
             elif unrolled.isFloat() and not unrolled.isUnrestricted():
                 # Restricted floats are tested for finiteness
                 bindingHeaders.add("mozilla/FloatingPoint.h")
                 bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
@@ -1119,17 +1104,17 @@ class CGHeaders(CGWrapper):
                 bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
             elif unrolled.isMozMap():
                 if dictionary or jsImplementedDescriptors:
                     declareIncludes.add("mozilla/dom/MozMap.h")
                 else:
                     bindingHeaders.add("mozilla/dom/MozMap.h")
                 # Also add headers for the type the MozMap is
                 # parametrized over, if needed.
-                addHeadersForType((t.inner, descriptor, dictionary))
+                addHeadersForType((t.inner, dictionary))
 
         map(addHeadersForType,
             getAllTypes(descriptors + callbackDescriptors, dictionaries,
                         callbacks))
 
         # Now make sure we're not trying to include the header from inside itself
         declareIncludes.discard(prefix + ".h")
 
@@ -1169,20 +1154,20 @@ class CGHeaders(CGWrapper):
             if desc.interface.maplikeOrSetlikeOrIterable:
                 # We need ToJSValue.h for maplike/setlike type conversions
                 bindingHeaders.add("mozilla/dom/ToJSValue.h")
                 # Add headers for the key and value types of the
                 # maplike/setlike/iterable, since they'll be needed for
                 # convenience functions
                 if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType():
                     addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
-                                       desc, None))
+                                       None))
                 if desc.interface.maplikeOrSetlikeOrIterable.hasValueType():
                     addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
-                                       desc, None))
+                                       None))
 
         for d in dictionaries:
             if d.parent:
                 declareIncludes.add(self.getDeclarationFilename(d.parent))
             bindingHeaders.add(self.getDeclarationFilename(d))
             for m in d.members:
                 addHeaderForFunc(PropertyDefiner.getStringAttr(m, "Func"),
                                  None)
@@ -1253,29 +1238,27 @@ def SortedDictValues(d):
     """
     Returns a list of values from the dict sorted by key.
     """
     return [v for k, v in sorted(d.items())]
 
 
 def UnionsForFile(config, webIDLFile):
     """
-    Returns a list of tuples each containing two elements (type and descriptor)
-    for all union types that are only used in webIDLFile. If webIDLFile is None
-    this will return the list of tuples for union types that are used in more
-    than one WebIDL file.
+    Returns a list of union types for all union types that are only used in
+    webIDLFile. If webIDLFile is None this will return the list of tuples for
+    union types that are used in more than one WebIDL file.
     """
     return config.unionsPerFilename.get(webIDLFile, [])
 
 
 def UnionTypes(unionTypes, config):
     """
-    The unionTypes argument should be a list of tuples, each containing two
-    elements: a union type and a descriptor. This is typically the list
-    generated by UnionsForFile.
+    The unionTypes argument should be a list of union types. This is typically
+    the list generated by UnionsForFile.
 
     Returns a tuple containing a set of header filenames to include in
     the header for the types in unionTypes, a set of header filenames to
     include in the implementation file for the types in unionTypes, a set
     of tuples containing a type declaration and a boolean if the type is a
     struct for member types of the union, a list of traverse methods,
     unlink methods and a list of union types. These last three lists only
     contain unique union types.
@@ -1283,49 +1266,47 @@ def UnionTypes(unionTypes, config):
 
     headers = set()
     implheaders = set()
     declarations = set()
     unionStructs = dict()
     traverseMethods = dict()
     unlinkMethods = dict()
 
-    for (t, descriptor) in unionTypes:
+    for t in unionTypes:
         name = str(t)
         if name not in unionStructs:
-            providers = getRelevantProviders(descriptor, config)
             unionStructs[name] = t
 
             def addHeadersForType(f):
                 if f.nullable():
                     headers.add("mozilla/dom/Nullable.h")
                 isSequence = f.isSequence()
                 f = f.unroll()
                 if f.isInterface():
                     if f.isSpiderMonkeyInterface():
                         headers.add("jsfriendapi.h")
                         headers.add("mozilla/dom/TypedArray.h")
                     else:
-                        for p in providers:
-                            try:
-                                typeDesc = p.getDescriptor(f.inner.identifier.name)
-                            except NoSuchDescriptorError:
-                                continue
-                            if typeDesc.interface.isCallback() or isSequence:
-                                # Callback interfaces always use strong refs, so
-                                # we need to include the right header to be able
-                                # to Release() in our inlined code.
-                                #
-                                # Similarly, sequences always contain strong
-                                # refs, so we'll need the header to handler
-                                # those.
-                                headers.add(typeDesc.headerFile)
-                            else:
-                                declarations.add((typeDesc.nativeType, False))
-                                implheaders.add(typeDesc.headerFile)
+                        try:
+                            typeDesc = config.getDescriptor(f.inner.identifier.name)
+                        except NoSuchDescriptorError:
+                            return
+                        if typeDesc.interface.isCallback() or isSequence:
+                            # Callback interfaces always use strong refs, so
+                            # we need to include the right header to be able
+                            # to Release() in our inlined code.
+                            #
+                            # Similarly, sequences always contain strong
+                            # refs, so we'll need the header to handler
+                            # those.
+                            headers.add(typeDesc.headerFile)
+                        else:
+                            declarations.add((typeDesc.nativeType, False))
+                            implheaders.add(typeDesc.headerFile)
                 elif f.isDictionary():
                     # For a dictionary, we need to see its declaration in
                     # UnionTypes.h so we have its sizeof and know how big to
                     # make our union.
                     headers.add(CGHeaders.getDeclarationFilename(f.inner))
                     # And if it needs rooting, we need RootedDictionary too
                     if typeNeedsRooting(f):
                         headers.add("mozilla/dom/RootedDictionary.h")
@@ -1370,53 +1351,50 @@ def UnionConversions(unionTypes, config)
     generated by UnionsForFile.
 
     Returns a tuple containing a list of headers and a CGThing to declare all
     union argument conversion helper structs.
     """
     headers = set()
     unionConversions = dict()
 
-    for (t, descriptor) in unionTypes:
+    for t in unionTypes:
         name = str(t)
         if name not in unionConversions:
-            providers = getRelevantProviders(descriptor, config)
-            unionConversions[name] = CGUnionConversionStruct(t, providers[0])
-
-            def addHeadersForType(f, providers):
+            unionConversions[name] = CGUnionConversionStruct(t, config)
+
+            def addHeadersForType(f):
                 f = f.unroll()
                 if f.isInterface():
                     if f.isSpiderMonkeyInterface():
                         headers.add("jsfriendapi.h")
                         headers.add("mozilla/dom/TypedArray.h")
                     elif f.inner.isExternal():
-                        providers = getRelevantProviders(descriptor, config)
-                        for p in providers:
-                            try:
-                                typeDesc = p.getDescriptor(f.inner.identifier.name)
-                            except NoSuchDescriptorError:
-                                continue
-                            headers.add(typeDesc.headerFile)
+                        try:
+                            typeDesc = config.getDescriptor(f.inner.identifier.name)
+                        except NoSuchDescriptorError:
+                            return
+                        headers.add(typeDesc.headerFile)
                     else:
                         headers.add(CGHeaders.getDeclarationFilename(f.inner))
                 elif f.isDictionary():
                     headers.add(CGHeaders.getDeclarationFilename(f.inner))
                 elif f.isPrimitive():
                     headers.add("mozilla/dom/PrimitiveConversions.h")
                 elif f.isMozMap():
                     headers.add("mozilla/dom/MozMap.h")
                     # And the internal type of the MozMap
-                    addHeadersForType(f.inner, providers)
+                    addHeadersForType(f.inner)
 
             # We plan to include UnionTypes.h no matter what, so it's
             # OK if we throw it into the set here.
             headers.add(CGHeaders.getUnionDeclarationFilename(config, t))
 
             for f in t.flatMemberTypes:
-                addHeadersForType(f, providers)
+                addHeadersForType(f)
 
     return (headers,
             CGWrapper(CGList(SortedDictValues(unionConversions), "\n"),
                       post="\n\n"))
 
 
 class Argument():
     """
@@ -2027,34 +2005,18 @@ class PropertyDefiner:
             return None
         # It's a list of strings
         assert len(attr) == 1
         assert attr[0] is not None
         return attr[0]
 
     @staticmethod
     def getControllingCondition(interfaceMember, descriptor):
-        # We do a slightly complicated thing for exposure sets to deal nicely
-        # with the situation of an [Exposed=Window] thing on an interface
-        # exposed in workers that has a worker-specific descriptor.  In that
-        # situation, we already skip generation of the member entirely in the
-        # worker binding, and shouldn't need to check for the various worker
-        # scopes in the non-worker binding.
         interface = descriptor.interface
         nonExposureSet = interface.exposureSet - interfaceMember.exposureSet
-        # Skip getting the descriptor if we're just exposed everywhere or not
-        # looking at the non-worker descriptor.
-        if len(nonExposureSet) and not descriptor.workers:
-            workerProvider = descriptor.config.getDescriptorProvider(True)
-            workerDesc = workerProvider.getDescriptor(interface.identifier.name)
-            if workerDesc.workers:
-                # Just drop all the worker interface names from the
-                # nonExposureSet, since we know we'll have a mainthread global
-                # of some sort.
-                nonExposureSet.difference_update(interface.getWorkerExposureSet())
 
         return MemberCondition(
             PropertyDefiner.getStringAttr(interfaceMember,
                                           "Pref"),
             PropertyDefiner.getStringAttr(interfaceMember,
                                           "Func"),
             interfaceMember.getExtendedAttribute("SecureContext") is not None,
             getAvailableInTestFunc(interfaceMember),
@@ -2181,22 +2143,16 @@ def overloadLength(arguments):
     return i
 
 
 def methodLength(method):
     signatures = method.signatures()
     return min(overloadLength(arguments) for retType, arguments in signatures)
 
 
-def isMaybeExposedIn(member, descriptor):
-    # All we can say for sure is that if this is a worker descriptor
-    # and member is not exposed in any worker, then it's not exposed.
-    return not descriptor.workers or member.isExposedInAnyWorker()
-
-
 def clearableCachedAttrs(descriptor):
     return (m for m in descriptor.interface.members if
             m.isAttr() and
             # Constants should never need clearing!
             m.dependsOn != "Nothing" and
             m.slotIndices is not None)
 
 
@@ -2224,26 +2180,23 @@ class MethodDefiner(PropertyDefiner):
         #       We should be able to check for special operations without an
         #       identifier. For now we check if the name starts with __
 
         # Ignore non-static methods for interfaces without a proto object
         if descriptor.interface.hasInterfacePrototypeObject() or static:
             methods = [m for m in descriptor.interface.members if
                        m.isMethod() and m.isStatic() == static and
                        MemberIsUnforgeable(m, descriptor) == unforgeable and
-                       not m.isIdentifierLess() and
-                       isMaybeExposedIn(m, descriptor)]
+                       not m.isIdentifierLess()]
         else:
             methods = []
         self.chrome = []
         self.regular = []
         for m in methods:
             if m.identifier.name == 'queryInterface':
-                if self.descriptor.workers:
-                    continue
                 if m.isStatic():
                     raise TypeError("Legacy queryInterface member shouldn't be static")
                 signatures = m.signatures()
 
                 def argTypeIsIID(arg):
                     return arg.type.inner.isExternal() and arg.type.inner.identifier.name == 'IID'
                 if len(signatures) > 1 or len(signatures[0][1]) > 1 or not argTypeIsIID(signatures[0][1][0]):
                     raise TypeError("There should be only one queryInterface method with 1 argument of type IID")
@@ -2310,18 +2263,17 @@ class MethodDefiner(PropertyDefiner):
                     any("@@iterator" == r["name"] for r in regular))
 
         # Check whether we need to output an @@iterator due to having an indexed
         # getter.  We only do this while outputting non-static and
         # non-unforgeable methods, since the @@iterator function will be
         # neither.
         if (not static and
             not unforgeable and
-            descriptor.supportsIndexedProperties() and
-            isMaybeExposedIn(descriptor.operations['IndexedGetter'], descriptor)):
+            descriptor.supportsIndexedProperties()):
             if hasIterator(methods, self.regular):
                 raise TypeError("Cannot have indexed getter/attr on "
                                 "interface %s with other members "
                                 "that generate @@iterator, such as "
                                 "maplike/setlike or aliased functions." %
                                 self.descriptor.interface.identifier.name)
             self.regular.append({
                 "name": "@@iterator",
@@ -2374,33 +2326,31 @@ class MethodDefiner(PropertyDefiner):
                 "flags": "JSPROP_ENUMERATE",
                 "condition": PropertyDefiner.getControllingCondition(m,
                                                                      descriptor)
             })
 
         if not static:
             stringifier = descriptor.operations['Stringifier']
             if (stringifier and
-                unforgeable == MemberIsUnforgeable(stringifier, descriptor) and
-                isMaybeExposedIn(stringifier, descriptor)):
+                unforgeable == MemberIsUnforgeable(stringifier, descriptor)):
                 toStringDesc = {
                     "name": "toString",
                     "nativeName": stringifier.identifier.name,
                     "length": 0,
                     "flags": "JSPROP_ENUMERATE",
                     "condition": PropertyDefiner.getControllingCondition(stringifier, descriptor)
                 }
                 if isChromeOnly(stringifier):
                     self.chrome.append(toStringDesc)
                 else:
                     self.regular.append(toStringDesc)
             jsonifier = descriptor.operations['Jsonifier']
             if (jsonifier and
-                unforgeable == MemberIsUnforgeable(jsonifier, descriptor) and
-                isMaybeExposedIn(jsonifier, descriptor)):
+                unforgeable == MemberIsUnforgeable(jsonifier, descriptor)):
                 toJSONDesc = {
                     "name": "toJSON",
                     "nativeName": jsonifier.identifier.name,
                     "length": 0,
                     "flags": "JSPROP_ENUMERATE",
                     "condition": PropertyDefiner.getControllingCondition(jsonifier, descriptor)
                 }
                 if isChromeOnly(jsonifier):
@@ -2543,17 +2493,16 @@ class AttrDefiner(PropertyDefiner):
         assert not (static and unforgeable)
         PropertyDefiner.__init__(self, descriptor, name)
         self.name = name
         # Ignore non-static attributes for interfaces without a proto object
         if descriptor.interface.hasInterfacePrototypeObject() or static:
             attributes = [m for m in descriptor.interface.members if
                           m.isAttr() and m.isStatic() == static and
                           MemberIsUnforgeable(m, descriptor) == unforgeable and
-                          isMaybeExposedIn(m, descriptor) and
                           not isNonExposedNavigatorObjectGetter(m, descriptor)]
         else:
             attributes = []
         self.chrome = [m for m in attributes if isChromeOnly(m)]
         self.regular = [m for m in attributes if not isChromeOnly(m)]
         self.static = static
         self.unforgeable = unforgeable
 
@@ -2631,18 +2580,17 @@ class AttrDefiner(PropertyDefiner):
 
 class ConstDefiner(PropertyDefiner):
     """
     A class for definining constants on the interface object
     """
     def __init__(self, descriptor, name):
         PropertyDefiner.__init__(self, descriptor, name)
         self.name = name
-        constants = [m for m in descriptor.interface.members if m.isConst() and
-                     isMaybeExposedIn(m, descriptor)]
+        constants = [m for m in descriptor.interface.members if m.isConst()]
         self.chrome = [m for m in constants if isChromeOnly(m)]
         self.regular = [m for m in constants if not isChromeOnly(m)]
 
     def generateArray(self, array, name, doIdArrays):
         if len(array) == 0:
             return ""
 
         def specData(const):
@@ -3294,26 +3242,16 @@ class CGDefineDOMInterfaceMethod(CGAbstr
     """
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'aCx'),
                 Argument('JS::Handle<JSObject*>', 'aGlobal'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('bool', 'aDefineOnGlobal')]
         CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'JSObject*', args)
 
-    def declare(self):
-        if self.descriptor.workers:
-            return ''
-        return CGAbstractMethod.declare(self)
-
-    def define(self):
-        if self.descriptor.workers:
-            return ''
-        return CGAbstractMethod.define(self)
-
     def definition_body(self):
         if len(self.descriptor.interface.namedConstructors) > 0:
             getConstructor = dedent("""
                 JSObject* interfaceObject = GetConstructorObjectHandle(aCx, aGlobal, aDefineOnGlobal);
                 if (!interfaceObject) {
                   return nullptr;
                 }
                 for (unsigned slot = DOM_INTERFACE_SLOTS_BASE; slot < JSCLASS_RESERVED_SLOTS(&sInterfaceObjectClass.mBase); ++slot) {
@@ -3824,23 +3762,16 @@ class CGWrapGlobalMethod(CGAbstractMetho
             properties = "sNativeProperties.Upcast()"
         else:
             properties = "nullptr"
         if self.properties.hasChromeOnly():
             chromeProperties = "nsContentUtils::ThreadsafeIsCallerChrome() ? sChromeOnlyNativeProperties.Upcast() : nullptr"
         else:
             chromeProperties = "nullptr"
 
-        if self.descriptor.workers:
-            fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
-// JS_FireOnNewGlobalObject(aCx, aReflector);
-"""
-        else:
-            fireOnNewGlobal = ""
-
         if self.descriptor.hasUnforgeableMembers:
             declareProto = "JS::Handle<JSObject*> canonicalProto =\n"
             assertProto = (
                 "MOZ_ASSERT(canonicalProto &&\n"
                 "           IsDOMIfaceAndProtoClass(js::GetObjectClass(canonicalProto)));\n")
         else:
             declareProto = ""
             assertProto = ""
@@ -3870,29 +3801,27 @@ class CGWrapGlobalMethod(CGAbstractMetho
             JSAutoCompartment ac(aCx, aReflector);
 
             if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
               return false;
             }
             $*{unforgeable}
 
             $*{slots}
-            $*{fireOnNewGlobal}
 
             return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             nativeType=self.descriptor.nativeType,
             declareProto=declareProto,
             assertProto=assertProto,
             properties=properties,
             chromeProperties=chromeProperties,
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
-            slots=InitMemberSlots(self.descriptor, True),
-            fireOnNewGlobal=fireOnNewGlobal)
+            slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'aCx'),
                 Argument('JS::Handle<JSObject*>', 'aWrapper'),
                 Argument(descriptor.nativeType + '*', 'aObject')]
         CGAbstractStaticMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
@@ -5381,35 +5310,32 @@ def getJSToNativeConversionInfo(type, de
                     promiseRv.MaybeSetPendingException(cx);
                     $*{exceptionCode}
                   }
                 #endif // SPIDERMONKEY_PROMISE
                 }
                 """,
                 getPromiseGlobal=getPromiseGlobal,
                 exceptionCode=exceptionCode)
-        elif not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
+        elif not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
             if failureCode is not None:
                 templateBody += str(CastableObjectUnwrapper(
                     descriptor,
                     "&${val}.toObject()",
                     "${declName}",
                     failureCode))
             else:
                 templateBody += str(FailureFatalCastableObjectUnwrapper(
                     descriptor,
                     "&${val}.toObject()",
                     "${declName}",
                     exceptionCode,
                     isCallbackReturnValue,
                     firstCap(sourceDescription)))
         else:
-            # Worker descriptors can't end up here, because all of our
-            # "external" stuff is not exposed in workers.
-            assert not descriptor.workers
             # Either external, or new-binding non-castable.  We always have a
             # holder for these, because we don't actually know whether we have
             # to addref when unwrapping or not.  So we just pass an
             # getter_AddRefs(RefPtr) to XPConnect and if we'll need a release
             # it'll put a non-null pointer in there.
             if forceOwningType:
                 # Don't return a holderType in this case; our declName
                 # will just own stuff.
@@ -6492,17 +6418,17 @@ def getWrapTemplateForType(type, descrip
         descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
         if type.nullable():
             wrappingCode = ("if (!%s) {\n" % (result) +
                             indent(setNull()) +
                             "}\n")
         else:
             wrappingCode = ""
 
-        if not descriptor.interface.isExternal() and not descriptor.skipGen:
+        if not descriptor.interface.isExternal():
             if descriptor.wrapperCache:
                 wrapMethod = "GetOrCreateDOMReflector"
                 wrapArgs = "cx, %s, ${jsvalHandle}" % result
             else:
                 # Hack: the "Promise" interface is OK to return from
                 # non-newobject things even when it's not wrappercached; that
                 # happens when using SpiderMonkey promises, and the WrapObject()
                 # method will just return the existing reflector, which is just
@@ -7686,41 +7612,17 @@ class CGMethodCall(CGThing):
         def getPerSignatureCall(signature, argConversionStartsAt=0):
             return CGPerSignatureCall(signature[0], signature[1],
                                       nativeMethodName, static, descriptor,
                                       method,
                                       argConversionStartsAt=argConversionStartsAt,
                                       isConstructor=isConstructor,
                                       useCounterName=useCounterName)
 
-        def filteredSignatures(signatures, descriptor):
-            def typeExposedInWorkers(type):
-                return (not type.isGeckoInterface() or
-                        type.inner.isExposedInAnyWorker())
-            if descriptor.workers:
-                # Filter out the signatures that should not be exposed in a
-                # worker.  The IDL parser enforces the return value being
-                # exposed correctly, but we have to check the argument types.
-                #
-                # If this code changes, adjust the self._deps
-                # computation in CGDDescriptor.__init__ as needed.
-                assert all(typeExposedInWorkers(sig[0]) for sig in signatures)
-                signatures = filter(
-                    lambda sig: all(typeExposedInWorkers(arg.type)
-                                    for arg in sig[1]),
-                    signatures)
-                if len(signatures) == 0:
-                    raise TypeError("%s.%s has a worker binding with no "
-                                    "signatures that take arguments exposed in "
-                                    "workers." %
-                                    (descriptor.interface.identifier.name,
-                                     method.identifier.name))
-            return signatures
-
-        signatures = filteredSignatures(method.signatures(), descriptor)
+        signatures = method.signatures()
         if len(signatures) == 1:
             # Special case: we can just do a per-signature method call
             # here for our one signature and not worry about switching
             # on anything.
             signature = signatures[0]
             self.cgRoot = CGList([getPerSignatureCall(signature)])
             requiredArgs = requiredArgCount(signature)
 
@@ -7740,27 +7642,23 @@ class CGMethodCall(CGThing):
             return
 
         # Need to find the right overload
         maxArgCount = method.maxArgCount
         allowedArgCounts = method.allowedArgCounts
 
         argCountCases = []
         for argCountIdx, argCount in enumerate(allowedArgCounts):
-            possibleSignatures = filteredSignatures(
-                method.signaturesForArgCount(argCount),
-                descriptor)
+            possibleSignatures = method.signaturesForArgCount(argCount)
 
             # Try to optimize away cases when the next argCount in the list
             # will have the same code as us; if it does, we can fall through to
             # that case.
             if argCountIdx+1 < len(allowedArgCounts):
-                nextPossibleSignatures = filteredSignatures(
-                    method.signaturesForArgCount(allowedArgCounts[argCountIdx+1]),
-                    descriptor)
+                nextPossibleSignatures = method.signaturesForArgCount(allowedArgCounts[argCountIdx+1])
             else:
                 nextPossibleSignatures = None
             if possibleSignatures == nextPossibleSignatures:
                 # Same set of signatures means we better have the same
                 # distinguishing index.  So we can in fact just fall through to
                 # the next case here.
                 assert (len(possibleSignatures) == 1 or
                         (method.distinguishingIndexForArgCount(argCount) ==
@@ -11976,31 +11874,16 @@ def memberProperties(m, descriptor):
 
 class CGDescriptor(CGThing):
     def __init__(self, descriptor):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
         self._deps = descriptor.interface.getDeps()
-        # If we have a worker descriptor, add dependencies on interface types we
-        # have as method arguments to overloaded methods.  See the
-        # filteredSignatures() bit in CGMethodCall.  Note that we have to add
-        # both interfaces that _are_ exposed in workers and ones that aren't;
-        # the idea is that we have to notice when the exposure set changes.
-        if descriptor.workers:
-            methods = (m for m in descriptor.interface.members if
-                       m.isMethod() and isMaybeExposedIn(m, descriptor) and
-                       len(m.signatures()) != 1)
-            for m in methods:
-                for sig in m.signatures():
-                    for arg in sig[1]:
-                        if (arg.type.isGeckoInterface() and
-                            not arg.type.inner.isExternal()):
-                            self._deps.add(arg.type.inner.filename())
 
         cgThings = []
         cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
                                   descriptor.nativeType))
         parent = descriptor.interface.parent
         if parent:
             cgThings.append(CGGeneric("static_assert(IsRefcounted<NativeType>::value == IsRefcounted<%s::NativeType>::value,\n"
                                       "              \"Can't inherit from an interface with a different ownership model.\");\n" %
@@ -12014,18 +11897,16 @@ class CGDescriptor(CGThing):
         crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
         unscopableNames = list()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,
                                                NamedConstructorName(n)))
         for m in descriptor.interface.members:
             if m.isMethod() and m.identifier.name == 'queryInterface':
                 continue
-            if not isMaybeExposedIn(m, descriptor):
-                continue
 
             props = memberProperties(m, descriptor)
 
             if m.isMethod():
                 if m.getExtendedAttribute("Unscopable"):
                     assert not m.isStatic()
                     unscopableNames.append(m.identifier.name)
                 if props.isJsonifier:
@@ -13065,35 +12946,19 @@ class CGDictionary(CGThing):
 class CGRegisterWorkerBindings(CGAbstractMethod):
     def __init__(self, config):
         CGAbstractMethod.__init__(self, None, 'RegisterWorkerBindings', 'bool',
                                   [Argument('JSContext*', 'aCx'),
                                    Argument('JS::Handle<JSObject*>', 'aObj')])
         self.config = config
 
     def definition_body(self):
-        # We have to be a bit careful: Some of the interfaces we want to expose
-        # in workers only have one descriptor, while others have both a worker
-        # and a non-worker descriptor.  When both are present we want the worker
-        # descriptor, but otherwise we want whatever descriptor we've got.
         descriptors = self.config.getDescriptors(hasInterfaceObject=True,
                                                  isExposedInAnyWorker=True,
-                                                 register=True,
-                                                 skipGen=False,
-                                                 workers=True)
-        workerDescriptorIfaceNames = set(d.interface.identifier.name for
-                                         d in descriptors)
-        descriptors.extend(
-            filter(
-                lambda d: d.interface.identifier.name not in workerDescriptorIfaceNames,
-                self.config.getDescriptors(hasInterfaceObject=True,
-                                           isExposedInAnyWorker=True,
-                                           register=True,
-                                           skipGen=False,
-                                           workers=False)))
+                                                 register=True)
         conditions = []
         for desc in descriptors:
             bindingNS = toBindingNamespace(desc.name)
             condition = "!%s::GetConstructorObject(aCx, aObj)" % bindingNS
             if desc.isExposedConditionally():
                 condition = (
                     "%s::ConstructorEnabled(aCx, aObj) && " % bindingNS
                     + condition)
@@ -13106,35 +12971,19 @@ class CGRegisterWorkerBindings(CGAbstrac
 class CGRegisterWorkerDebuggerBindings(CGAbstractMethod):
     def __init__(self, config):
         CGAbstractMethod.__init__(self, None, 'RegisterWorkerDebuggerBindings', 'bool',
                                   [Argument('JSContext*', 'aCx'),
                                    Argument('JS::Handle<JSObject*>', 'aObj')])
         self.config = config
 
     def definition_body(self):
-        # We have to be a bit careful: Some of the interfaces we want to expose
-        # in workers only have one descriptor, while others have both a worker
-        # and a non-worker descriptor.  When both are present we want the worker
-        # descriptor, but otherwise we want whatever descriptor we've got.
         descriptors = self.config.getDescriptors(hasInterfaceObject=True,
                                                  isExposedInWorkerDebugger=True,
-                                                 register=True,
-                                                 skipGen=False,
-                                                 workers=True)
-        workerDescriptorIfaceNames = set(d.interface.identifier.name for
-                                         d in descriptors)
-        descriptors.extend(
-            filter(
-                lambda d: d.interface.identifier.name not in workerDescriptorIfaceNames,
-                self.config.getDescriptors(hasInterfaceObject=True,
-                                           isExposedInWorkerDebugger=True,
-                                           register=True,
-                                           skipGen=False,
-                                           workers=False)))
+                                                 register=True)
         conditions = []
         for desc in descriptors:
             bindingNS = toBindingNamespace(desc.name)
             condition = "!%s::GetConstructorObject(aCx, aObj)" % bindingNS
             if desc.isExposedConditionally():
                 condition = (
                     "%s::ConstructorEnabled(aCx, aObj) && " % bindingNS
                     + condition)
@@ -13151,19 +13000,17 @@ class CGResolveSystemBinding(CGAbstractM
                                    Argument('JS::Handle<JSObject*>', 'aObj'),
                                    Argument('JS::Handle<jsid>', 'aId'),
                                    Argument('bool*', 'aResolvedp')])
         self.config = config
 
     def definition_body(self):
         descriptors = self.config.getDescriptors(hasInterfaceObject=True,
                                                  isExposedInSystemGlobals=True,
-                                                 workers=False,
-                                                 register=True,
-                                                 skipGen=False)
+                                                 register=True)
 
         def descNameToId(name):
             return "s%s_id" % name
         jsidNames = [descNameToId(desc.name) for desc in descriptors]
         jsidDecls = CGList(CGGeneric("static jsid %s;\n" % name)
                            for name in jsidNames)
 
         jsidInits = CGList(
@@ -13338,61 +13185,53 @@ class ForwardDeclarationBuilder:
         cg = CGList(decls, "\n")
         if not atTopLevel and len(decls) + len(self.decls) > 1:
             cg = CGWrapper(cg, pre='\n', post='\n')
         return cg
 
     def build(self):
         return self._build(atTopLevel=True)
 
-    def forwardDeclareForType(self, t, config, workerness='both'):
+    def forwardDeclareForType(self, t, config):
         t = t.unroll()
         if t.isGeckoInterface():
             name = t.inner.identifier.name
-            # Find and add the non-worker implementation, if any.
-            if workerness != 'workeronly':
-                try:
-                    desc = config.getDescriptor(name, False)
-                    self.add(desc.nativeType)
-                except NoSuchDescriptorError:
-                    pass
-            # Find and add the worker implementation, if any.
-            if workerness != 'mainthreadonly':
-                try:
-                    desc = config.getDescriptor(name, True)
-                    self.add(desc.nativeType)
-                except NoSuchDescriptorError:
-                    pass
+            try:
+                desc = config.getDescriptor(name)
+                self.add(desc.nativeType)
+            except NoSuchDescriptorError:
+                pass
+
         # Note: Spidermonkey interfaces are typedefs, so can't be
         # forward-declared
         elif t.isCallback():
             self.addInMozillaDom(t.callback.identifier.name)
         elif t.isDictionary():
             self.addInMozillaDom(t.inner.identifier.name, isStruct=True)
         elif t.isCallbackInterface():
             self.addInMozillaDom(t.inner.identifier.name)
         elif t.isUnion():
             # Forward declare both the owning and non-owning version,
             # since we don't know which one we might want
             self.addInMozillaDom(CGUnionStruct.unionTypeName(t, False))
             self.addInMozillaDom(CGUnionStruct.unionTypeName(t, True))
         elif t.isMozMap():
-            self.forwardDeclareForType(t.inner, config, workerness)
+            self.forwardDeclareForType(t.inner, config)
         # Don't need to do anything for void, primitive, string, any or object.
         # There may be some other cases we are missing.
 
 
 class CGForwardDeclarations(CGWrapper):
     """
     Code generate the forward declarations for a header file.
     additionalDeclarations is a list of tuples containing a classname and a
     boolean. If the boolean is true we will declare a struct, otherwise we'll
     declare a class.
     """
-    def __init__(self, config, descriptors, mainCallbacks, workerCallbacks,
+    def __init__(self, config, descriptors, callbacks,
                  dictionaries, callbackInterfaces, additionalDeclarations=[]):
         builder = ForwardDeclarationBuilder()
 
         # Needed for at least Wrap.
         for d in descriptors:
             # If this is a generated iterator interface, we only create these
             # in the generated bindings, and don't need to forward declare.
             if d.interface.isIteratorInterface():
@@ -13419,26 +13258,20 @@ class CGForwardDeclarations(CGWrapper):
         for d in descriptors:
             # Iterators have native types that are template classes, so
             # creating an 'Atoms' cache type doesn't work for them, and is one
             # of the cases where we don't need it anyways.
             if d.interface.isIteratorInterface():
                 continue
             builder.add(d.nativeType + "Atoms", isStruct=True)
 
-        for callback in mainCallbacks:
+        for callback in callbacks:
             builder.addInMozillaDom(callback.identifier.name)
             for t in getTypesFromCallback(callback):
-                builder.forwardDeclareForType(t, config,
-                                              workerness='mainthreadonly')
-
-        for callback in workerCallbacks:
-            builder.addInMozillaDom(callback.identifier.name)
-            for t in getTypesFromCallback(callback):
-                builder.forwardDeclareForType(t, config, workerness='workeronly')
+                builder.forwardDeclareForType(t, config)
 
         for d in callbackInterfaces:
             builder.add(d.nativeType)
             builder.add(d.nativeType + "Atoms", isStruct=True)
             for t in getTypesFromDescriptor(d):
                 builder.forwardDeclareForType(t, config)
 
         for d in dictionaries:
@@ -13466,18 +13299,17 @@ class CGBindingRoot(CGThing):
         bindingDeclareHeaders = dict.fromkeys((
             'mozilla/dom/BindingDeclarations.h',
             'mozilla/dom/Nullable.h',
             'mozilla/ErrorResult.h',
             ),
             True)
 
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
-                                            hasInterfaceOrInterfacePrototypeObject=True,
-                                            skipGen=False)
+                                            hasInterfaceOrInterfacePrototypeObject=True)
 
         unionTypes = UnionsForFile(config, webIDLFile)
 
         (unionHeaders, unionImplheaders, unionDeclarations, traverseMethods,
          unlinkMethods, unionStructs) = UnionTypes(unionTypes, config)
 
         bindingDeclareHeaders.update(dict.fromkeys(unionHeaders, True))
         bindingHeaders.update(dict.fromkeys(unionImplheaders, True))
@@ -13528,65 +13360,56 @@ class CGBindingRoot(CGThing):
                       (ctor and isChromeOnly(ctor)))) or
                     # JS-implemented interfaces with clearable cached
                     # attrs have chromeonly _clearFoo methods.
                     (desc.interface.isJSImplemented() and
                      any(clearableCachedAttrs(desc))))
 
         # XXXkhuey ugly hack but this is going away soon.
         bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl")
-        hasWorkerStuff = len(config.getDescriptors(webIDLFile=webIDLFile,
-                                                   workers=True)) != 0
-        bindingHeaders["WorkerPrivate.h"] = hasWorkerStuff
-
-        hasThreadChecks = hasWorkerStuff or any(d.hasThreadChecks() for d in descriptors)
+
+        hasThreadChecks = any(d.hasThreadChecks() for d in descriptors)
         bindingHeaders["nsThreadUtils.h"] = hasThreadChecks
 
-        dictionaries = config.getDictionaries(webIDLFile=webIDLFile)
+        dictionaries = config.getDictionaries(webIDLFile)
 
         def dictionaryHasChromeOnly(dictionary):
             while dictionary:
                 if (any(isChromeOnly(m) for m in dictionary.members)):
                     return True
                 dictionary = dictionary.parent
             return False
 
         bindingHeaders["nsContentUtils.h"] = (
             any(descriptorHasChromeOnly(d) for d in descriptors) or
             any(dictionaryHasChromeOnly(d) for d in dictionaries))
         hasNonEmptyDictionaries = any(
             len(dict.members) > 0 for dict in dictionaries)
-        mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
-                                            workers=False)
-        workerCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
-                                              workers=True)
+        callbacks = config.getCallbacks(webIDLFile)
         callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                     isCallback=True)
         jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
                                               isJSImplemented=True)
         bindingDeclareHeaders["nsWeakReference.h"] = jsImplemented
         bindingHeaders["nsIGlobalObject.h"] = jsImplemented
         bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
 
-        # Only mainthread things can have hasXPConnectImpls
-        provider = config.getDescriptorProvider(False)
-
         def descriptorClearsPropsInSlots(descriptor):
             if not descriptor.wrapperCache:
                 return False
             return any(m.isAttr() and m.getExtendedAttribute("StoreInSlot")
                        for m in descriptor.interface.members)
         bindingHeaders["nsJSUtils.h"] = any(descriptorClearsPropsInSlots(d) for d in descriptors)
 
         # Do codegen for all the enums
         enums = config.getEnums(webIDLFile)
         cgthings = [CGEnum(e) for e in enums]
 
         hasCode = (descriptors or callbackDescriptors or dictionaries or
-                   mainCallbacks or workerCallbacks)
+                   callbacks)
         bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode
         bindingHeaders["mozilla/OwningNonNull.h"] = hasCode
         bindingHeaders["mozilla/dom/BindingDeclarations.h"] = (
             not hasCode and enums)
 
         bindingHeaders["WrapperFactory.h"] = descriptors
         bindingHeaders["mozilla/dom/DOMJSClass.h"] = descriptors
         bindingHeaders["mozilla/dom/ScriptSettings.h"] = dictionaries  # AutoJSAPI
@@ -13641,46 +13464,37 @@ class CGBindingRoot(CGThing):
             if isinstance(unionTypeOrDictionary, IDLDictionary):
                 return unionTypeOrDictionary.identifier.name
 
             assert unionTypeOrDictionary.isType() and unionTypeOrDictionary.isUnion()
             return unionTypeOrDictionary.name
 
         for t in dependencySortObjects(dictionaries + unionStructs, getDependencies, getName):
             if t.isDictionary():
-                cgthings.append(CGDictionary(t, config.getDescriptorProvider(False)))
+                cgthings.append(CGDictionary(t, config))
             else:
                 assert t.isUnion()
-                # FIXME: Unions are broken in workers.  See bug 809899.
-                cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False)))
-                cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False), True))
+                cgthings.append(CGUnionStruct(t, config))
+                cgthings.append(CGUnionStruct(t, config, True))
 
         # Do codegen for all the callbacks.
-        cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False))
-                        for c in mainCallbacks)
+        cgthings.extend(CGCallbackFunction(c, config) for c in callbacks)
 
         cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c))
-                         for c in mainCallbacks])
-
-        cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True))
-                        for c in workerCallbacks if c not in mainCallbacks)
-
-        cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c))
-                         for c in workerCallbacks if c not in mainCallbacks])
+                         for c in callbacks])
 
         # Do codegen for all the descriptors
         cgthings.extend([CGDescriptor(x) for x in descriptors])
 
-        # Do codegen for all the callback interfaces.  Skip worker callbacks.
-        cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if
-                         not x.workers])
+        # Do codegen for all the callback interfaces.
+        cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors])
 
         cgthings.extend([CGNamespace('binding_detail',
                                      CGFastCallback(x.interface))
-                         for x in callbackDescriptors if not x.workers])
+                         for x in callbackDescriptors])
 
         # Do codegen for JS implemented classes
         def getParentDescriptor(desc):
             if not desc.interface.parent:
                 return set()
             return {desc.getDescriptor(desc.interface.parent.identifier.name)}
         for x in dependencySortObjects(jsImplemented, getParentDescriptor,
                                        lambda d: d.interface.identifier.name):
@@ -13690,34 +13504,34 @@ class CGBindingRoot(CGThing):
         # And make sure we have the right number of newlines at the end
         curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, pre="\n"))
 
         curr = CGList([CGForwardDeclarations(config, descriptors,
-                                             mainCallbacks, workerCallbacks,
+                                             callbacks,
                                              dictionaries,
                                              callbackDescriptors + jsImplemented,
                                              additionalDeclarations=unionDeclarations),
                        curr],
                       "\n")
 
         # Add header includes.
         bindingHeaders = [header
                           for header, include in bindingHeaders.iteritems()
                           if include]
         bindingDeclareHeaders = [header
                                  for header, include in bindingDeclareHeaders.iteritems()
                                  if include]
 
         curr = CGHeaders(descriptors,
                          dictionaries,
-                         mainCallbacks + workerCallbacks,
+                         callbacks,
                          callbackDescriptors,
                          bindingDeclareHeaders,
                          bindingHeaders,
                          prefix,
                          curr,
                          config,
                          jsImplemented)
 
@@ -14469,18 +14283,17 @@ class CGExampleClass(CGBindingImplClass)
 
 class CGExampleRoot(CGThing):
     """
     Root codegen class for example implementation generation.  Instantiate the
     class and call declare or define to generate header or cpp code,
     respectively.
     """
     def __init__(self, config, interfaceName):
-        # Let's assume we're not doing workers stuff
-        descriptor = config.getDescriptor(interfaceName, False)
+        descriptor = config.getDescriptor(interfaceName)
 
         self.root = CGWrapper(CGExampleClass(descriptor),
                               pre="\n", post="\n")
 
         self.root = CGNamespace.build(["mozilla", "dom"], self.root)
 
         builder = ForwardDeclarationBuilder()
         for member in descriptor.interface.members:
@@ -16436,23 +16249,21 @@ class GlobalGenRoots():
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
-                                                            workers=False,
                                                             isExposedInWindow=True,
                                                             register=True)]
         defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h')
         defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)
                                for desc in config.getDescriptors(isNavigatorProperty=True,
-                                                                 workers=False,
                                                                  register=True)])
         curr = CGHeaders([], [], [], [], [], defineIncludes, 'RegisterBindings',
                          curr)
 
         # Add include guards.
         curr = CGIncludeGuard('RegisterBindings', curr)
 
         # Done.
@@ -16467,18 +16278,17 @@ class GlobalGenRoots():
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
                                                             register=True,
-                                                            isExposedInAnyWorker=True,
-                                                            skipGen=False)]
+                                                            isExposedInAnyWorker=True)]
 
         curr = CGHeaders([], [], [], [], [], defineIncludes,
                          'RegisterWorkerBindings', curr)
 
         # Add include guards.
         curr = CGIncludeGuard('RegisterWorkerBindings', curr)
 
         # Done.
@@ -16493,18 +16303,17 @@ class GlobalGenRoots():
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
                                                             register=True,
-                                                            isExposedInWorkerDebugger=True,
-                                                            skipGen=False)]
+                                                            isExposedInWorkerDebugger=True)]
 
         curr = CGHeaders([], [], [], [], [], defineIncludes,
                          'RegisterWorkerDebuggerBindings', curr)
 
         # Add include guards.
         curr = CGIncludeGuard('RegisterWorkerDebuggerBindings', curr)
 
         # Done.
@@ -16519,18 +16328,17 @@ class GlobalGenRoots():
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
                                                             register=True,
-                                                            isExposedInSystemGlobals=True,
-                                                            skipGen=False)]
+                                                            isExposedInSystemGlobals=True)]
         defineIncludes.append("nsThreadUtils.h")  # For NS_IsMainThread
         defineIncludes.append("js/Id.h")  # For jsid
         defineIncludes.append("mozilla/dom/BindingUtils.h")  # AtomizeAndPinJSString
 
         curr = CGHeaders([], [], [], [], [], defineIncludes,
                          'ResolveSystemBinding', curr)
 
         # Add include guards.
@@ -16543,18 +16351,18 @@ class GlobalGenRoots():
     def UnionTypes(config):
         unionTypes = UnionsForFile(config, None)
         (includes, implincludes, declarations,
          traverseMethods, unlinkMethods,
          unionStructs) = UnionTypes(unionTypes, config)
 
         unions = CGList(traverseMethods +
                         unlinkMethods +
-                        [CGUnionStruct(t, config.getDescriptorProvider(False)) for t in unionStructs] +
-                        [CGUnionStruct(t, config.getDescriptorProvider(False), True) for t in unionStructs],
+                        [CGUnionStruct(t, config) for t in unionStructs] +
+                        [CGUnionStruct(t, config, True) for t in unionStructs],
                         "\n")
 
         includes.add("mozilla/OwningNonNull.h")
         includes.add("mozilla/dom/UnionMember.h")
         includes.add("mozilla/dom/BindingDeclarations.h")
         # Need BindingUtils.h for FakeString
         includes.add("mozilla/dom/BindingUtils.h")
         implincludes.add("mozilla/dom/PrimitiveConversions.h")
@@ -16579,17 +16387,17 @@ class GlobalGenRoots():
         # Done.
         return curr
 
     @staticmethod
     def UnionConversions(config):
         unionTypes = []
         for l in config.unionsPerFilename.itervalues():
             unionTypes.extend(l)
-        unionTypes.sort(key=lambda u: u[0].name)
+        unionTypes.sort(key=lambda u: u.name)
         headers, unions = UnionConversions(unionTypes,
                                            config)
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'], unions)
 
         curr = CGWrapper(curr, post='\n')
 
@@ -17107,18 +16915,17 @@ class CGEventClass(CGBindingImplClass):
         else:
             raise TypeError("Don't know how to declare event member of type %s" %
                             type)
         return nativeType
 
 
 class CGEventRoot(CGThing):
     def __init__(self, config, interfaceName):
-        # Let's assume we're not doing workers stuff, for now
-        descriptor = config.getDescriptor(interfaceName, False)
+        descriptor = config.getDescriptor(interfaceName)
 
         self.root = CGWrapper(CGEventClass(descriptor),
                               pre="\n", post="\n")
 
         self.root = CGNamespace.build(["mozilla", "dom"], self.root)
 
         self.root = CGList([CGClassForwardDeclare("JSContext", isStruct=True),
                             self.root])
@@ -17127,17 +16934,17 @@ class CGEventRoot(CGThing):
 
         # Throw in our #includes
         self.root = CGHeaders(
             [descriptor],
             [],
             [],
             [],
             [
-                config.getDescriptor(parent, False).headerFile,
+                config.getDescriptor(parent).headerFile,
                 "mozilla/Attributes.h",
                 "mozilla/ErrorResult.h",
                 "mozilla/dom/%sBinding.h" % interfaceName,
                 'mozilla/dom/BindingUtils.h',
                 ],
             [
                 "%s.h" % interfaceName,
                 "js/GCAPI.h",
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -4,22 +4,32 @@
 
 from WebIDL import IDLImplementsStatement
 import os
 from collections import defaultdict
 
 autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
 
 
-class Configuration:
+class DescriptorProvider:
+    """
+    A way of getting descriptors for interface names.  Subclasses must
+    have a getDescriptor method callable with the interface name only.
+    """
+    def __init__(self):
+        pass
+
+
+class Configuration(DescriptorProvider):
     """
     Represents global configuration state based on IDL parse data and
     the configuration file.
     """
     def __init__(self, filename, parseData, generatedEvents=[]):
+        DescriptorProvider.__init__(self)
 
         # Read the configuration file.
         glbl = {}
         execfile(filename, glbl)
         config = glbl['DOMInterfaces']
 
         # Build descriptors for all the interfaces we have in the parse data.
         # This allows callers to specify a subset of interfaces by filtering
@@ -62,86 +72,53 @@ class Configuration:
                 # if they have no interface object because chances are we
                 # don't need to do anything interesting with them.
                 if iface.isConsequential() and not iface.hasInterfaceObject():
                     self.optimizedOutDescriptorNames.add(iface.identifier.name)
                     continue
                 entry = {}
             else:
                 entry = config[iface.identifier.name]
-            if not isinstance(entry, list):
-                assert isinstance(entry, dict)
-                entry = [entry]
-            elif len(entry) == 1:
-                if entry[0].get("workers", False):
-                    # List with only a workers descriptor means we should
-                    # infer a mainthread descriptor.  If you want only
-                    # workers bindings, don't use a list here.
-                    entry.append({})
-                else:
-                    raise TypeError("Don't use a single-element list for "
-                                    "non-worker-only interface " + iface.identifier.name +
-                                    " in Bindings.conf")
-            elif len(entry) == 2:
-                if entry[0].get("workers", False) == entry[1].get("workers", False):
-                    raise TypeError("The two entries for interface " + iface.identifier.name +
-                                    " in Bindings.conf should not have the same value for 'workers'")
-            else:
-                raise TypeError("Interface " + iface.identifier.name +
-                                " should have no more than two entries in Bindings.conf")
-            descs = [Descriptor(self, iface, x) for x in entry]
-            self.descriptors.extend(descs)
+            assert not isinstance(entry, list)
+            desc = Descriptor(self, iface, entry)
+            self.descriptors.append(desc)
             # Setting up descriptorsByName while iterating through interfaces
             # means we can get the nativeType of iterable interfaces without
             # having to do multiple loops.
-            for d in descs:
-                self.descriptorsByName.setdefault(d.interface.identifier.name,
-                                                  []).append(d)
+            assert desc.interface.identifier.name not in self.descriptorsByName
+            self.descriptorsByName[desc.interface.identifier.name] = desc
 
         # Keep the descriptor list sorted for determinism.
         self.descriptors.sort(lambda x, y: cmp(x.name, y.name))
 
 
         self.descriptorsByFile = {}
         for d in self.descriptors:
             self.descriptorsByFile.setdefault(d.interface.filename(),
                                               []).append(d)
 
         self.enums = [e for e in parseData if e.isEnum()]
 
-        # Figure out what our main-thread and worker dictionaries and callbacks
-        # are.
-        mainTypes = set()
-        for descriptor in ([self.getDescriptor("DummyInterface", workers=False)] +
-                           self.getDescriptors(workers=False, isExternal=False, skipGen=False)):
-            mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
-        (mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
-
-        workerTypes = set()
-        for descriptor in (self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
-            workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
-        (workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
-
         self.dictionaries = [d for d in parseData if d.isDictionary()]
         self.callbacks = [c for c in parseData if
                           c.isCallback() and not c.isInterface()]
 
         # Dictionary mapping from a union type name to a set of filenames where
         # union types with that name are used.
         self.filenamesPerUnion = defaultdict(set)
 
-        # Dictionary mapping from a filename to a list of tuples containing a
-        # type and descriptor for the union types used in that file. If a union
-        # type is used in multiple files then it will be added to the list
-        # for the None key. Note that the list contains a tuple for every use of
-        # a union type, so there can be multiple tuples with union types that
-        # have the same name.
+        # Dictionary mapping from a filename to a list of types for
+        # the union types used in that file. If a union type is used
+        # in multiple files then it will be added to the list for the
+        # None key. Note that the list contains a type for every use
+        # of a union type, so there can be multiple entries with union
+        # types that have the same name.
         self.unionsPerFilename = defaultdict(list)
 
-        for (t, descriptor, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
+        for (t, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
             while True:
                 if t.isMozMap():
                     t = t.inner
                 elif t.unroll() != t:
                     t = t.unroll()
                 elif t.isPromise():
                     t = t.promiseInnerType()
                 else:
@@ -167,36 +144,28 @@ class Configuration:
                         if len(filenamesForUnion) == 1:
                             # This is the first time we found a union with this
                             # name in another file.
                             for f in filenamesForUnion:
                                 # Filter out unions with this name from the
                                 # unions for the file where we previously found
                                 # them.
                                 unionsForFilename = self.unionsPerFilename[f]
-                                unionsForFilename = filter(lambda u: u[0].name != t.name,
+                                unionsForFilename = filter(lambda u: u.name != t.name,
                                                            unionsForFilename)
                                 if len(unionsForFilename) == 0:
                                     del self.unionsPerFilename[f]
                                 else:
                                     self.unionsPerFilename[f] = unionsForFilename
                         # Unions with this name appear in multiple files, record
                         # the filename as None, so that we can detect that.
                         uniqueFilenameForUnion = None
-                    self.unionsPerFilename[uniqueFilenameForUnion].append((t, descriptor))
+                    self.unionsPerFilename[uniqueFilenameForUnion].append(t)
                     filenamesForUnion.add(t.filename())
 
-        def flagWorkerOrMainThread(items, main, worker):
-            for item in items:
-                if item in main:
-                    item.setUserData("mainThread", True)
-                if item in worker:
-                    item.setUserData("workers", True)
-        flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks)
-
     def getInterface(self, ifname):
         return self.interfaces[ifname]
 
     def getDescriptors(self, **filters):
         """Gets the descriptors that match the given filters."""
         curr = self.descriptors
         # Collect up our filters, because we may have a webIDLFile filter that
         # we always want to apply first.
@@ -240,92 +209,48 @@ class Configuration:
             tofilter.append((getter, val))
         for f in tofilter:
             curr = filter(lambda x: f[0](x) == f[1], curr)
         return curr
 
     def getEnums(self, webIDLFile):
         return filter(lambda e: e.filename() == webIDLFile, self.enums)
 
-    @staticmethod
-    def _filterForFileAndWorkers(items, filters):
-        """Gets the items that match the given filters."""
-        for key, val in filters.iteritems():
-            if key == 'webIDLFile':
-                items = filter(lambda x: x.filename() == val, items)
-            elif key == 'workers':
-                if val:
-                    items = filter(lambda x: x.getUserData("workers", False), items)
-                else:
-                    items = filter(lambda x: x.getUserData("mainThread", False), items)
-            else:
-                assert(0)  # Unknown key
-        return items
+    def getDictionaries(self, webIDLFile):
+        return filter(lambda d: d.filename() == webIDLFile, self.dictionaries)
 
-    def getDictionaries(self, **filters):
-        return self._filterForFileAndWorkers(self.dictionaries, filters)
+    def getCallbacks(self, webIDLFile):
+        return filter(lambda c: c.filename() == webIDLFile, self.callbacks)
 
-    def getCallbacks(self, **filters):
-        return self._filterForFileAndWorkers(self.callbacks, filters)
-
-    def getDescriptor(self, interfaceName, workers):
+    def getDescriptor(self, interfaceName):
         """
-        Gets the appropriate descriptor for the given interface name
-        and the given workers boolean.
+        Gets the appropriate descriptor for the given interface name.
         """
         # We may have optimized out this descriptor, but the chances of anyone
         # asking about it are then slim.  Put the check for that _after_ we've
-        # done our normal lookups.  But that means we have to do our normal
-        # lookups in a way that will not throw if they fail.
-        for d in self.descriptorsByName.get(interfaceName, []):
-            if d.workers == workers:
-                return d
-
-        if workers:
-            for d in self.descriptorsByName.get(interfaceName, []):
-                return d
+        # done our normal lookup.  But that means we have to do our normal
+        # lookup in a way that will not throw if it fails.
+        d = self.descriptorsByName.get(interfaceName, None)
+        if d:
+            return d
 
         if interfaceName in self.optimizedOutDescriptorNames:
             raise NoSuchDescriptorError(
                 "No descriptor for '%s', which is a mixin ([NoInterfaceObject] "
                 "and a consequential interface) without an explicit "
                 "Bindings.conf annotation." % interfaceName)
 
         raise NoSuchDescriptorError("For " + interfaceName + " found no matches")
 
-    def getDescriptorProvider(self, workers):
-        """
-        Gets a descriptor provider that can provide descriptors as needed,
-        for the given workers boolean
-        """
-        return DescriptorProvider(self, workers)
-
 
 class NoSuchDescriptorError(TypeError):
     def __init__(self, str):
         TypeError.__init__(self, str)
 
 
-class DescriptorProvider:
-    """
-    A way of getting descriptors for interface names
-    """
-    def __init__(self, config, workers):
-        self.config = config
-        self.workers = workers
-
-    def getDescriptor(self, interfaceName):
-        """
-        Gets the appropriate descriptor for the given interface name given the
-        context of the current descriptor. This selects the appropriate
-        implementation for cases like workers.
-        """
-        return self.config.getDescriptor(interfaceName, self.workers)
-
-
 def methodReturnsJSObject(method):
     assert method.isMethod()
     if method.returnsPromise():
         return True
 
     for signature in method.signatures():
         returnType = signature[0]
         if returnType.isObject() or returnType.isSpiderMonkeyInterface():
@@ -345,47 +270,38 @@ def MemberIsUnforgeable(member, descript
                  descriptor.interface.getExtendedAttribute("Unforgeable")))
 
 
 class Descriptor(DescriptorProvider):
     """
     Represents a single descriptor for an interface. See Bindings.conf.
     """
     def __init__(self, config, interface, desc):
-        DescriptorProvider.__init__(self, config, desc.get('workers', False))
+        DescriptorProvider.__init__(self)
+        self.config = config
         self.interface = interface
 
-        if self.workers:
-            assert 'wantsXrays' not in desc
-            self.wantsXrays = False
-        else:
-            self.wantsXrays = desc.get('wantsXrays', True)
+        self.wantsXrays = interface.isExposedInWindow()
 
         # Read the desc, and fill in the relevant defaults.
         ifaceName = self.interface.identifier.name
         # For generated iterator interfaces for other iterable interfaces, we
         # just use IterableIterator as the native type, templated on the
         # nativeType of the iterable interface. That way we can have a
         # templated implementation for all the duplicated iterator
         # functionality.
         if self.interface.isIteratorInterface():
             itrName = self.interface.iterableInterface.identifier.name
             itrDesc = self.getDescriptor(itrName)
             nativeTypeDefault = iteratorNativeType(itrDesc)
 
         elif self.interface.isExternal():
-            assert not self.workers
             nativeTypeDefault = "nsIDOM" + ifaceName
-        elif self.interface.isCallback():
-            nativeTypeDefault = "mozilla::dom::" + ifaceName
         else:
-            if self.workers:
-                nativeTypeDefault = "mozilla::dom::workers::" + ifaceName
-            else:
-                nativeTypeDefault = "mozilla::dom::" + ifaceName
+            nativeTypeDefault = "mozilla::dom::" + ifaceName
 
         self.nativeType = desc.get('nativeType', nativeTypeDefault)
         # Now create a version of nativeType that doesn't have extra
         # mozilla::dom:: at the beginning.
         prettyNativeType = self.nativeType.split("::")
         if prettyNativeType[0] == "mozilla":
             prettyNativeType.pop(0)
             if prettyNativeType[0] == "dom":
@@ -400,34 +316,30 @@ class Descriptor(DescriptorProvider):
         elif self.interface.isCallback() or self.interface.isJSImplemented():
             # A copy of CGHeaders.getDeclarationFilename; we can't
             # import it here, sadly.
             # Use our local version of the header, not the exported one, so that
             # test bindings, which don't export, will work correctly.
             basename = os.path.basename(self.interface.filename())
             headerDefault = basename.replace('.webidl', 'Binding.h')
         else:
-            if self.workers:
-                headerDefault = "mozilla/dom/workers/bindings/%s.h" % ifaceName
-            elif not self.interface.isExternal() and self.interface.getExtendedAttribute("HeaderFile"):
+            if not self.interface.isExternal() and self.interface.getExtendedAttribute("HeaderFile"):
                 headerDefault = self.interface.getExtendedAttribute("HeaderFile")[0]
             elif self.interface.isIteratorInterface():
                 headerDefault = "mozilla/dom/IterableIterator.h"
             else:
                 headerDefault = self.nativeType
                 headerDefault = headerDefault.replace("::", "/") + ".h"
         self.headerFile = desc.get('headerFile', headerDefault)
         self.headerIsDefault = self.headerFile == headerDefault
         if self.jsImplParent == self.nativeType:
             self.jsImplParentHeader = self.headerFile
         else:
             self.jsImplParentHeader = self.jsImplParent.replace("::", "/") + ".h"
 
-        self.skipGen = desc.get('skipGen', False)
-
         self.notflattened = desc.get('notflattened', False)
         self.register = desc.get('register', True)
 
         self.hasXPConnectImpls = desc.get('hasXPConnectImpls', False)
 
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         self.concrete = (not self.interface.isExternal() and
@@ -546,19 +458,17 @@ class Descriptor(DescriptorProvider):
         # Nasty temporary hack for supporting both DOM and SpiderMonkey promises
         # without too much pain
         if self.interface.identifier.name == "Promise":
             assert self.wrapperCache
             # But really, we're only wrappercached if we have an interface
             # object (that is, when we're not using SpiderMonkey promises).
             self.wrapperCache = self.interface.hasInterfaceObject()
 
-        def make_name(name):
-            return name + "_workers" if self.workers else name
-        self.name = make_name(interface.identifier.name)
+        self.name = interface.identifier.name
 
         # self.extendedAttributes is a dict of dicts, keyed on
         # all/getterOnly/setterOnly and then on member name. Values are an
         # array of extended attributes.
         self.extendedAttributes = {'all': {}, 'getterOnly': {}, 'setterOnly': {}}
 
         def addExtendedAttribute(attribute, config):
             def add(key, members, attribute):
@@ -686,43 +596,37 @@ class Descriptor(DescriptorProvider):
     def parentPrototypeName(self):
         if len(self.prototypeChain) == 1:
             return None
         return self.getDescriptor(self.prototypeChain[-2]).name
 
     def hasInterfaceOrInterfacePrototypeObject(self):
 
         # Forward-declared interfaces don't need either interface object or
-        # interface prototype object as they're going to use QI (on main thread)
-        # or be passed as a JSObject (on worker threads).
+        # interface prototype object as they're going to use QI.
         if self.interface.isExternal():
             return False
 
         return self.interface.hasInterfaceObject() or self.interface.hasInterfacePrototypeObject()
 
     @property
     def hasNamedPropertiesObject(self):
         if self.interface.isExternal():
             return False
 
         return self.isGlobal() and self.supportsNamedProperties()
 
     def getExtendedAttributes(self, member, getter=False, setter=False):
         def ensureValidThrowsExtendedAttribute(attr):
-            assert(attr is None or attr is True or len(attr) == 1)
-            if (attr is not None and attr is not True and
-                'Workers' not in attr and 'MainThread' not in attr):
+            if (attr is not None and attr is not True):
                 raise TypeError("Unknown value for 'Throws': " + attr[0])
 
         def maybeAppendInfallibleToAttrs(attrs, throws):
             ensureValidThrowsExtendedAttribute(throws)
-            if (throws is None or
-                (throws is not True and
-                 ('Workers' not in throws or not self.workers) and
-                 ('MainThread' not in throws or self.workers))):
+            if throws is None:
                 attrs.append("infallible")
 
         name = member.identifier.name
         throws = self.interface.isJSImplemented() or member.getExtendedAttribute("Throws")
         if member.isMethod():
             # JSObject-returning [NewObject] methods must be fallible,
             # since they have to (fallibly) allocate the new JSObject.
             if (member.getExtendedAttribute("NewObject") and
@@ -827,20 +731,25 @@ class Descriptor(DescriptorProvider):
                 return False
             iface = iface.parent
         return True
 
     @property
     def registersGlobalNamesOnWindow(self):
         return (not self.interface.isExternal() and
                 self.interface.hasInterfaceObject() and
-                not self.workers and
                 self.interface.isExposedInWindow() and
                 self.register)
 
+    def getDescriptor(self, interfaceName):
+        """
+        Gets the appropriate descriptor for the given interface name.
+        """
+        return self.config.getDescriptor(interfaceName)
+
 
 # Some utility methods
 def getTypesFromDescriptor(descriptor):
     """
     Get all argument and return types for all members of the descriptor
     """
     members = [m for m in descriptor.interface.members]
     if descriptor.interface.ctor():
@@ -887,62 +796,31 @@ def getTypesFromCallback(callback):
     types of its arguments.
     """
     sig = callback.signatures()[0]
     types = [sig[0]]  # Return type
     types.extend(arg.type for arg in sig[1])  # Arguments
     return types
 
 
-def findCallbacksAndDictionaries(inputTypes):
-    """
-    Ensure that all callbacks and dictionaries reachable from types end up in
-    the returned callbacks and dictionaries sets.
-
-    Note that we assume that our initial invocation already includes all types
-    reachable via descriptors in "types", so we only have to deal with things
-    that are themeselves reachable via callbacks and dictionaries.
-    """
-    def doFindCallbacksAndDictionaries(types, callbacks, dictionaries):
-        unhandledTypes = set()
-        for type in types:
-            if type.isCallback() and type.callback not in callbacks:
-                unhandledTypes |= getFlatTypes(getTypesFromCallback(type.callback))
-                callbacks.add(type.callback)
-            elif type.isDictionary() and type.inner not in dictionaries:
-                d = type.inner
-                unhandledTypes |= getFlatTypes(getTypesFromDictionary(d))
-                while d:
-                    dictionaries.add(d)
-                    d = d.parent
-        if len(unhandledTypes) != 0:
-            doFindCallbacksAndDictionaries(unhandledTypes, callbacks, dictionaries)
-
-    retCallbacks = set()
-    retDictionaries = set()
-    doFindCallbacksAndDictionaries(inputTypes, retCallbacks, retDictionaries)
-    return (retCallbacks, retDictionaries)
-
-
 def getAllTypes(descriptors, dictionaries, callbacks):
     """
     Generate all the types we're dealing with.  For each type, a tuple
-    containing type, descriptor, dictionary is yielded.  The
-    descriptor and dictionary can be None if the type does not come
-    from a descriptor or dictionary; they will never both be non-None.
+    containing type, dictionary is yielded.  The dictionary can be None if the
+    type does not come from a dictionary.
     """
     for d in descriptors:
         if d.interface.isExternal():
             continue
         for t in getTypesFromDescriptor(d):
-            yield (t, d, None)
+            yield (t, None)
     for dictionary in dictionaries:
         for t in getTypesFromDictionary(dictionary):
-            yield (t, None, dictionary)
+            yield (t, dictionary)
     for callback in callbacks:
         for t in getTypesFromCallback(callback):
-            yield (t, None, None)
+            yield (t, None)
 
 def iteratorNativeType(descriptor):
     assert descriptor.interface.isIterable()
     iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
     assert iterableDecl.isPairIterator()
     return "mozilla::dom::IterableIterator<%s>" % descriptor.nativeType
--- a/dom/bindings/SimpleGlobalObject.cpp
+++ b/dom/bindings/SimpleGlobalObject.cpp
@@ -4,23 +4,25 @@
  * 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/dom/SimpleGlobalObject.h"
 
 #include "jsapi.h"
 #include "js/Class.h"
 
-#include "nsContentUtils.h"
 #include "nsJSPrincipals.h"
 #include "nsNullPrincipal.h"
 #include "nsThreadUtils.h"
+#include "nsContentUtils.h"
 
 #include "xpcprivate.h"
 
+#include "mozilla/dom/ScriptSettings.h"
+
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(SimpleGlobalObject)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SimpleGlobalObject)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   tmp->UnlinkHostObjectURIs();
@@ -85,70 +87,77 @@ const js::Class SimpleGlobalClass = {
     &SimpleGlobalClassExtension,
     JS_NULL_OBJECT_OPS
 };
 
 // static
 JSObject*
 SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto)
 {
-  JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-  JSAutoRequest ar(cx);
-
-  JS::CompartmentOptions options;
-  options.creationOptions().setInvisibleToDebugger(true);
-
-  JS::Rooted<JSObject*> global(cx);
+  // We can't root our return value with our AutoJSAPI because the rooting
+  // analysis thinks ~AutoJSAPI can GC.  So we need to root in a scope outside
+  // the lifetime of the AutoJSAPI.
+  JS::Rooted<JSObject*> global(nsContentUtils::RootingCx());
 
-  if (NS_IsMainThread()) {
-    nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
-    options.creationOptions().setTrace(xpc::TraceXPCGlobal);
-    global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
-                                     nsJSPrincipals::get(principal),
-                                     options);
-  } else {
-    global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
-                                nullptr,
-                                JS::DontFireOnNewGlobalHook, options);
-  }
+  { // Scope to ensure the AutoJSAPI destructor runs before we end up returning
+    AutoJSAPI jsapi;
+    jsapi.Init();
+    JSContext* cx = jsapi.cx();
+
+    JS::CompartmentOptions options;
+    options.creationOptions().setInvisibleToDebugger(true);
 
-  if (!global) {
-    JS_ClearPendingException(cx);
-    return nullptr;
-  }
-
-  JSAutoCompartment ac(cx, global);
+    if (NS_IsMainThread()) {
+      nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
+      options.creationOptions().setTrace(xpc::TraceXPCGlobal);
+      global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
+                                       nsJSPrincipals::get(principal),
+                                       options);
+    } else {
+      global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
+                                  nullptr,
+                                  JS::DontFireOnNewGlobalHook, options);
+    }
 
-  // It's important to create the nsIGlobalObject for our new global before we
-  // start trying to wrap things like the prototype into its compartment,
-  // because the wrap operation relies on the global having its nsIGlobalObject
-  // already.
-  RefPtr<SimpleGlobalObject> globalObject =
-    new SimpleGlobalObject(global, globalType);
-
-  // Pass on ownership of globalObject to |global|.
-  JS_SetPrivate(global, globalObject.forget().take());
-
-  if (proto.isObjectOrNull()) {
-    JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
-    if (!JS_WrapObject(cx, &protoObj)) {
-      JS_ClearPendingException(cx);
+    if (!global) {
+      jsapi.ClearException();
       return nullptr;
     }
 
-    if (!JS_SplicePrototype(cx, global, protoObj)) {
-      JS_ClearPendingException(cx);
+    JSAutoCompartment ac(cx, global);
+
+    // It's important to create the nsIGlobalObject for our new global before we
+    // start trying to wrap things like the prototype into its compartment,
+    // because the wrap operation relies on the global having its
+    // nsIGlobalObject already.
+    RefPtr<SimpleGlobalObject> globalObject =
+      new SimpleGlobalObject(global, globalType);
+
+    // Pass on ownership of globalObject to |global|.
+    JS_SetPrivate(global, globalObject.forget().take());
+
+    if (proto.isObjectOrNull()) {
+      JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
+      if (!JS_WrapObject(cx, &protoObj)) {
+        jsapi.ClearException();
+        return nullptr;
+      }
+
+      if (!JS_SplicePrototype(cx, global, protoObj)) {
+        jsapi.ClearException();
+        return nullptr;
+      }
+    } else if (!proto.isUndefined()) {
+      // Bogus proto.
       return nullptr;
     }
-  } else if (!proto.isUndefined()) {
-    // Bogus proto.
-    return nullptr;
+
+    JS_FireOnNewGlobalObject(cx, global);
   }
 
-  JS_FireOnNewGlobalObject(cx, global);
   return global;
 }
 
 // static
 SimpleGlobalObject::GlobalType
 SimpleGlobalObject::SimpleGlobalType(JSObject* obj)
 {
   if (js::GetObjectClass(obj) != &SimpleGlobalClass) {
deleted file mode 100644
--- a/dom/bindings/mozwebidlcodegen/test/DummyBinding.webidl
+++ /dev/null
@@ -1,1 +0,0 @@
-interface DummyInterface {};
--- a/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py
+++ b/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py
@@ -100,17 +100,17 @@ class TestWebIDLCodegenManager(unittest.
         self.assertEqual(manager._state['version'],
                          WebIDLCodegenManagerState.VERSION)
         self.assertNotIn('foobar', manager._state)
 
     def test_generate_build_files(self):
         """generate_build_files() does the right thing from empty."""
         manager = self._get_manager()
         result = manager.generate_build_files()
-        self.assertEqual(len(result.inputs), 5)
+        self.assertEqual(len(result.inputs), 4)
 
         output = manager.expected_build_output_files()
         self.assertEqual(result.created, output)
         self.assertEqual(len(result.updated), 0)
         self.assertEqual(len(result.unchanged), 0)
 
         for f in output:
             self.assertTrue(os.path.isfile(f))
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -746,17 +746,17 @@ BluetoothHfpManager::HandleVoiceConnecti
                                              HFP_NETWORK_STATE_NOT_AVAILABLE;
   if (service != mService) {
     // Notify BluetoothRilListener of service change
     mListener->ServiceChanged(aClientId, service);
   }
   mService = service;
 
   // Signal
-  JS::Rooted<JS::Value> value(nsContentUtils::RootingCxForThread());
+  JS::Rooted<JS::Value> value(dom::GetJSRuntime());
   voiceInfo->GetRelSignalStrength(&value);
   if (value.isNumber()) {
     mSignal = (int)ceil(value.toNumber() / 20.0);
   }
 
   UpdateDeviceCIND();
 
   // Operator name
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -636,17 +636,17 @@ BluetoothHfpManager::HandleVoiceConnecti
   voiceInfo->GetState(regState);
   bool service = regState.EqualsLiteral("registered");
   if (service != sCINDItems[CINDType::SERVICE].value) {
     // Notify BluetoothRilListener of service change
     mListener->ServiceChanged(aClientId, service);
   }
   UpdateCIND(CINDType::SERVICE, service);
 
-  JS::Rooted<JS::Value> value(nsContentUtils::RootingCxForThread());
+  JS::Rooted<JS::Value> value(dom::GetJSRuntime());
   voiceInfo->GetRelSignalStrength(&value);
   if (value.isNumber()) {
     uint8_t signal = ceil(value.toNumber() / 20.0);
     UpdateCIND(CINDType::SIGNAL, signal);
   }
 
   /**
    * Possible return values for mode are:
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -5534,33 +5534,33 @@ CanvasRenderingContext2D::FillRuleChange
     mPath = nullptr;
   }
 }
 
 void
 CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
                                        double aDy, ErrorResult& aError)
 {
-  RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread());
+  RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCx());
   DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
   MOZ_ASSERT(inited);
 
   aError = PutImageData_explicit(JS::ToInt32(aDx), JS::ToInt32(aDy),
                                 aImageData.Width(), aImageData.Height(),
                                 &arr, false, 0, 0, 0, 0);
 }
 
 void
 CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
                                        double aDy, double aDirtyX,
                                        double aDirtyY, double aDirtyWidth,
                                        double aDirtyHeight,
                                        ErrorResult& aError)
 {
-  RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread());
+  RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCx());
   DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
   MOZ_ASSERT(inited);
 
   aError = PutImageData_explicit(JS::ToInt32(aDx), JS::ToInt32(aDy),
                                 aImageData.Width(), aImageData.Height(),
                                 &arr, true,
                                 JS::ToInt32(aDirtyX),
                                 JS::ToInt32(aDirtyY),
@@ -5806,18 +5806,24 @@ CanvasRenderingContext2D::GetBufferProvi
   }
 
   return mBufferProvider;
 }
 
 already_AddRefed<Layer>
 CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                          Layer *aOldLayer,
-                                         LayerManager *aManager)
-{
+                                         LayerManager *aManager,
+                                         bool aMirror /* = false */)
+{
+  if (aMirror) {
+    // Not supported for CanvasRenderingContext2D
+    return nullptr;
+  }
+
   if (mOpaque || mIsSkiaGL) {
     // If we're opaque then make sure we have a surface so we paint black
     // instead of transparent.
     // If we're using SkiaGL, then SkiaGLTex() below needs the target to
     // be accessible.
     EnsureTarget();
   }
 
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -461,17 +461,18 @@ public:
   }
 
   NS_IMETHOD SetIsOpaque(bool aIsOpaque) override;
   bool GetIsOpaque() override { return mOpaque; }
   NS_IMETHOD Reset() override;
   mozilla::layers::PersistentBufferProvider* GetBufferProvider(mozilla::layers::LayerManager* aManager);
   already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                          Layer* aOldLayer,
-                                         LayerManager* aManager) override;
+                                         LayerManager* aManager,
+                                         bool aMirror = false) override;
   virtual bool ShouldForceInactiveLayer(LayerManager* aManager) override;
   void MarkContextClean() override;
   void MarkContextCleanForFrameCapture() override;
   bool IsContextCleanForFrameCapture() override;
   NS_IMETHOD SetIsIPC(bool aIsIPC) override;
   // this rect is in canvas device space
   void Redraw(const mozilla::gfx::Rect& aR);
   NS_IMETHOD Redraw(const gfxRect& aR) override { Redraw(ToRect(aR)); return NS_OK; }
--- a/dom/canvas/ImageBitmapRenderingContext.cpp
+++ b/dom/canvas/ImageBitmapRenderingContext.cpp
@@ -209,18 +209,24 @@ ImageBitmapRenderingContext::Reset()
   mImage = nullptr;
 
   return NS_OK;
 }
 
 already_AddRefed<Layer>
 ImageBitmapRenderingContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                             Layer* aOldLayer,
-                                            LayerManager* aManager)
+                                            LayerManager* aManager,
+                                            bool aMirror /* = false */)
 {
+  if (aMirror) {
+    // Not supported for ImageBitmapRenderingContext
+    return nullptr;
+  }
+
   if (!mImage) {
     // No DidTransactionCallback will be received, so mark the context clean
     // now so future invalidations will be dispatched.
     MarkContextClean();
     return nullptr;
   }
 
   RefPtr<ImageLayer> imageLayer;
--- a/dom/canvas/ImageBitmapRenderingContext.h
+++ b/dom/canvas/ImageBitmapRenderingContext.h
@@ -65,17 +65,18 @@ public:
   virtual already_AddRefed<mozilla::gfx::SourceSurface>
   GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) override;
 
   NS_IMETHOD SetIsOpaque(bool aIsOpaque) override;
   virtual bool GetIsOpaque() override;
   NS_IMETHOD Reset() override;
   virtual already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  Layer* aOldLayer,
-                                                 LayerManager* aManager) override;
+                                                 LayerManager* aManager,
+                                                 bool aMirror = false) override;
   virtual void MarkContextClean() override;
 
   NS_IMETHOD Redraw(const gfxRect& aDirty) override;
   NS_IMETHOD SetIsIPC(bool aIsIPC) override;
 
   virtual void DidRefresh() override;
 
   virtual void MarkContextCleanForFrameCapture() override;
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1260,16 +1260,17 @@ WebGLContext::UpdateLastUseIndex()
     // not handling it as the handler code would never get exercised.
     if (!sIndex.isValid())
         NS_RUNTIMEABORT("Can't believe it's been 2^64 transactions already!");
 
     mLastUseIndex = sIndex.value();
 }
 
 static uint8_t gWebGLLayerUserData;
+static uint8_t gWebGLMirrorLayerUserData;
 
 class WebGLContextUserData : public LayerUserData
 {
 public:
     explicit WebGLContextUserData(HTMLCanvasElement* canvas)
         : mCanvas(canvas)
     {}
 
@@ -1302,35 +1303,36 @@ public:
 
 private:
     RefPtr<HTMLCanvasElement> mCanvas;
 };
 
 already_AddRefed<layers::Layer>
 WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
                              Layer* oldLayer,
-                             LayerManager* manager)
+                             LayerManager* manager,
+                             bool aMirror /*= false*/)
 {
     if (IsContextLost())
         return nullptr;
 
     if (!mResetLayer && oldLayer &&
-        oldLayer->HasUserData(&gWebGLLayerUserData)) {
+        oldLayer->HasUserData(aMirror ? &gWebGLMirrorLayerUserData : &gWebGLLayerUserData)) {
         RefPtr<layers::Layer> ret = oldLayer;
         return ret.forget();
     }
 
     RefPtr<CanvasLayer> canvasLayer = manager->CreateCanvasLayer();
     if (!canvasLayer) {
         NS_WARNING("CreateCanvasLayer returned null!");
         return nullptr;
     }
 
     WebGLContextUserData* userData = nullptr;
-    if (builder->IsPaintingToWindow() && mCanvasElement) {
+    if (builder->IsPaintingToWindow() && mCanvasElement && !aMirror) {
         // Make the layer tell us whenever a transaction finishes (including
         // the current transaction), so we can clear our invalidation state and
         // start invalidating again. We need to do this for the layer that is
         // being painted to a window (there shouldn't be more than one at a time,
         // and if there is, flushing the invalidation state more often than
         // necessary is harmless).
 
         // The layer will be destroyed when we tear down the presentation
@@ -1340,23 +1342,24 @@ WebGLContext::GetCanvasLayer(nsDisplayLi
         // the invalidation state to indicate that the canvas is up to date.
         userData = new WebGLContextUserData(mCanvasElement);
         canvasLayer->SetDidTransactionCallback(
             WebGLContextUserData::DidTransactionCallback, userData);
         canvasLayer->SetPreTransactionCallback(
             WebGLContextUserData::PreTransactionCallback, userData);
     }
 
-    canvasLayer->SetUserData(&gWebGLLayerUserData, userData);
+    canvasLayer->SetUserData(aMirror ? &gWebGLMirrorLayerUserData : &gWebGLLayerUserData, userData);
 
     CanvasLayer::Data data;
     data.mGLContext = gl;
     data.mSize = nsIntSize(mWidth, mHeight);
     data.mHasAlpha = gl->Caps().alpha;
     data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha;
+    data.mIsMirror = aMirror;
 
     canvasLayer->Initialize(data);
     uint32_t flags = gl->Caps().alpha ? 0 : Layer::CONTENT_OPAQUE;
     canvasLayer->SetContentFlags(flags);
     canvasLayer->Updated();
 
     mResetLayer = false;
 
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -328,17 +328,18 @@ public:
         const TexTarget texTarget = TexImageTargetToTexTarget(texImgTarget);
         return ActiveBoundTextureForTarget(texTarget);
     }
 
     void InvalidateResolveCacheForTextureWithTexUnit(const GLuint);
 
     already_AddRefed<Layer>
     GetCanvasLayer(nsDisplayListBuilder* builder, Layer* oldLayer,
-                   LayerManager* manager) override;
+                   LayerManager* manager,
+                   bool aMirror = false) override;
 
     // Note that 'clean' here refers to its invalidation state, not the
     // contents of the buffer.
     void MarkContextClean() override { mInvalidated = false; }
 
     void MarkContextCleanForFrameCapture() override { mCapturedFrameInvalidated = false; }
 
     bool IsContextCleanForFrameCapture() override { return !mCapturedFrameInvalidated; }
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -969,122 +969,127 @@ WebGLFramebuffer::ValidateAndInitAttachm
 
         mContext->ErrorInvalidFramebufferOperation("%s: %s.", funcName,
                                                    errorText.BeginReading());
         return false;
     }
 
     // Cool! We've checked out ok. Just need to initialize.
 
+    //////
     // Check if we need to initialize anything
-    {
-        bool hasUninitializedAttachments = false;
+
+    std::vector<WebGLFBAttachPoint*> tex3DToClear;
+
+    const auto fnGatherIf3D = [&](WebGLFBAttachPoint& attach) {
+        if (!attach.Texture())
+            return false;
 
-        if (mColorAttachment0.HasImage() && IsDrawBuffer(0))
-            hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData();
+        const auto& info = attach.Texture()->ImageInfoAt(attach.ImageTarget(),
+                                                         attach.MipLevel());
+        if (info.mDepth == 1)
+            return false;
+
+        tex3DToClear.push_back(&attach);
+        return true;
+    };
 
-        size_t i = 1;
-        for (const auto& cur : mMoreColorAttachments) {
-            if (cur.HasImage() && IsDrawBuffer(i))
-                hasUninitializedAttachments |= cur.HasUninitializedImageData();
+    //////
+
+    uint32_t clearBits = 0;
+    std::vector<GLenum> drawBuffersForClear(1 + mMoreColorAttachments.Size(),
+                                            LOCAL_GL_NONE);
+
+    std::vector<WebGLFBAttachPoint*> attachmentsToClear;
+    attachmentsToClear.reserve(1 + mMoreColorAttachments.Size() + 3);
 
-            ++i;
-        }
+    const auto fnGatherColor = [&](WebGLFBAttachPoint& attach, uint32_t colorAttachNum) {
+        if (!IsDrawBuffer(colorAttachNum) || !attach.HasUninitializedImageData())
+            return;
+
+        if (fnGatherIf3D(attach))
+            return;
+
+        attachmentsToClear.push_back(&attach);
+
+        clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
+        drawBuffersForClear[colorAttachNum] = LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachNum;
+    };
+
+    const auto fnGatherOther = [&](WebGLFBAttachPoint& attach, GLenum attachClearBits) {
+        if (!attach.HasUninitializedImageData())
+            return;
 
-        if (mDepthAttachment.HasImage())
-            hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData();
-        if (mStencilAttachment.HasImage())
-            hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData();
-        if (mDepthStencilAttachment.HasImage())
-            hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData();
+        if (fnGatherIf3D(attach))
+            return;
+
+        attachmentsToClear.push_back(&attach);
+
+        clearBits |= attachClearBits;
+    };
 
-        if (!hasUninitializedAttachments)
-            return true;
+    //////
+
+    fnGatherColor(mColorAttachment0, 0);
+
+    size_t colorAttachNum = 1;
+    for (auto& cur : mMoreColorAttachments) {
+        fnGatherColor(cur, colorAttachNum);
+        ++colorAttachNum;
     }
 
-    // Get buffer-bit-mask and color-attachment-mask-list
-    uint32_t clearBits = 0;
-    std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE);
-
-    if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
-        clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
-        tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0;
-    }
+    fnGatherOther(mDepthAttachment, LOCAL_GL_DEPTH_BUFFER_BIT);
+    fnGatherOther(mStencilAttachment, LOCAL_GL_STENCIL_BUFFER_BIT);
+    fnGatherOther(mDepthStencilAttachment,
+                  LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
 
-    size_t i = 1;
-    for (const auto& cur : mMoreColorAttachments) {
-        if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) {
-            clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
-            tempDrawBuffers[i] = LOCAL_GL_COLOR_ATTACHMENT0 + i;
-        }
-
-        ++i;
-    }
-
-    if (mDepthAttachment.HasUninitializedImageData() ||
-        mDepthStencilAttachment.HasUninitializedImageData())
-    {
-        clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
-    }
-
-    if (mStencilAttachment.HasUninitializedImageData() ||
-        mDepthStencilAttachment.HasUninitializedImageData())
-    {
-        clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
-    }
+    //////
 
     mContext->MakeContextCurrent();
 
-    const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
-        const GLenum* ptr = nullptr;
-        if (list.size()) {
-            ptr = &(list[0]);
+    if (clearBits) {
+        const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
+            this->mContext->gl->fDrawBuffers(list.size(), list.data());
+        };
+
+        const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
+        const bool hasDrawBuffers = (mContext->IsWebGL2() ||
+                                     mContext->IsExtensionEnabled(drawBufferExt));
+
+        if (hasDrawBuffers) {
+            fnDrawBuffers(drawBuffersForClear);
         }
-        this->mContext->gl->fDrawBuffers(list.size(), ptr);
-    };
+
+        ////////////
+
+        // Clear!
+        {
+            gl::ScopedBindFramebuffer autoBind(mContext->gl, mGLName);
 
-    const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
-    const bool hasDrawBuffers = (mContext->IsWebGL2() ||
-                                 mContext->IsExtensionEnabled(drawBufferExt));
+            mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
+        }
 
-    if (hasDrawBuffers) {
-        fnDrawBuffers(tempDrawBuffers);
+        if (hasDrawBuffers) {
+            fnDrawBuffers(mDrawBuffers);
+        }
+
+        for (auto* cur : attachmentsToClear) {
+            cur->SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
+        }
     }
 
-    // Clear!
-    {
-        // This FB maybe bind to GL_READ_FRAMEBUFFER and glClear only
-        // clear GL_DRAW_FRAMEBUFFER. So bind FB to GL_DRAW_FRAMEBUFFER
-        // here.
-        gl::ScopedBindFramebuffer autoFB(mContext->gl, mGLName);
-        mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
-    }
-
-    if (hasDrawBuffers) {
-        fnDrawBuffers(mDrawBuffers);
-    }
+    //////
 
-    // Mark all the uninitialized images as initialized.
-    if (mDepthAttachment.HasUninitializedImageData())
-        mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
-    if (mStencilAttachment.HasUninitializedImageData())
-        mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
-    if (mDepthStencilAttachment.HasUninitializedImageData())
-        mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
-
-    if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
-        mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
-    }
-
-    i = 1;
-    for (auto& cur : mMoreColorAttachments) {
-        if (cur.HasUninitializedImageData() && IsDrawBuffer(i))
-            cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
-
-        ++i;
+    for (auto* attach : tex3DToClear) {
+        auto* tex = attach->Texture();
+        if (!tex->InitializeImageData(funcName, attach->ImageTarget(),
+                                      attach->MipLevel()))
+        {
+            return false;
+        }
     }
 
     return true;
 }
 
 static void
 FinalizeDrawAndReadBuffers(gl::GLContext* gl, bool isColorBufferDefined)
 {
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -365,17 +365,17 @@ WebGLTexture::TexOrSubImage(bool isSubIm
     uint32_t rowLength, imageHeight;
     if (!mContext->GetUnpackValuesForImage(funcName, imageData->Width(),
                                            imageData->Height(), &rowLength, &imageHeight))
     {
         return;
     }
 
     dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(
-      nsContentUtils::RootingCxForThread());
+      nsContentUtils::RootingCx());
     const RefPtr<gfx::SourceSurface> surf = FromImageData(mContext, funcName, unpackType,
                                                           imageData, &scopedArr);
     if (!surf)
         return;
 
     // WhatWG "HTML Living Standard" (30 October 2015):
     // "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned as
     //  non-premultiplied alpha values."
--- a/dom/canvas/nsICanvasRenderingContextInternal.h
+++ b/dom/canvas/nsICanvasRenderingContextInternal.h
@@ -130,17 +130,18 @@ public:
   // Invalidate this context and release any held resources, in preperation
   // for possibly reinitializing with SetDimensions/InitializeWithSurface.
   NS_IMETHOD Reset() = 0;
 
   // Return the CanvasLayer for this context, creating
   // one for the given layer manager if not available.
   virtual already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* builder,
                                                  Layer *oldLayer,
-                                                 LayerManager *manager) = 0;
+                                                 LayerManager *manager,
+                                                 bool aMirror = false) = 0;
 
   // Return true if the canvas should be forced to be "inactive" to ensure
   // it can be drawn to the screen even if it's too large to be blitted by
   // an accelerated CanvasLayer.
   virtual bool ShouldForceInactiveLayer(LayerManager *manager) { return false; }
 
   virtual void MarkContextClean() = 0;
 
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -3970,18 +3970,17 @@ DeviceStorageRequestManager::Resolve(uin
     return NS_OK;
   }
 
   ListIndex i = Find(aId);
   if (NS_WARN_IF(i == mPending.Length())) {
     return NS_OK;
   }
 
-  JS::RootedValue value(nsContentUtils::RootingCxForThread(),
-                        JS_NumberValue((double)aValue));
+  JS::RootedValue value(GetJSRuntime(), JS_NumberValue((double)aValue));
   return ResolveInternal(i, value);
 }
 
 nsresult
 DeviceStorageRequestManager::Resolve(uint32_t aId, DeviceStorageFile* aFile,
                                      bool aForceDispatch)
 {
   MOZ_ASSERT(aFile);
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -287,19 +287,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTa
   virtual mozilla::EventListenerManager* GetOrCreateListenerManager() { \
     return _to GetOrCreateListenerManager(); \
   } \
   virtual mozilla::EventListenerManager* GetExistingListenerManager() const { \
     return _to GetExistingListenerManager(); \
   } \
   virtual nsIScriptContext * GetContextForEventHandlers(nsresult *aRv) { \
     return _to GetContextForEventHandlers(aRv); \
-  } \
-  virtual JSContext * GetJSContextForEventHandlers(void) { \
-    return _to GetJSContextForEventHandlers(); \
   }
 
 #define NS_REALLY_FORWARD_NSIDOMEVENTTARGET(_class) \
   using _class::AddEventListener;                   \
   using _class::RemoveEventListener;                \
   NS_FORWARD_NSIDOMEVENTTARGET(_class::)            \
   virtual mozilla::EventListenerManager*            \
   GetOrCreateListenerManager() override {           \
--- a/dom/events/JSEventHandler.cpp
+++ b/dom/events/JSEventHandler.cpp
@@ -149,17 +149,17 @@ JSEventHandler::HandleEvent(nsIDOMEvent*
       fileName = &file;
 
       lineNumber.Construct();
       lineNumber.Value() = scriptEvent->Lineno();
 
       columnNumber.Construct();
       columnNumber.Value() = scriptEvent->Colno();
 
-      error.Construct(nsContentUtils::RootingCxForThread());
+      error.Construct(GetJSRuntime());
       scriptEvent->GetError(&error.Value());
     } else {
       msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();
     }
 
     RefPtr<OnErrorEventHandlerNonNull> handler =
       mTypedHandler.OnErrorEventHandler();
     ErrorResult rv;
--- a/dom/filesystem/tests/mochitest.ini
+++ b/dom/filesystem/tests/mochitest.ini
@@ -2,8 +2,9 @@
 support-files =
   filesystem_commons.js
   script_fileList.js
   worker_basic.js
 
 [test_basic.html]
 [test_webkitdirectory.html]
 [test_worker_basic.html]
+skip-if = true # bug 1283344
--- a/dom/geolocation/moz.build
+++ b/dom/geolocation/moz.build
@@ -21,22 +21,16 @@ UNIFIED_SOURCES += [
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/ipc',
 ]
 
-if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
-    LOCAL_INCLUDES += [
-        '/dom/system/qt',
-    ]
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     LOCAL_INCLUDES += [
         '/dom/system/android',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     LOCAL_INCLUDES += [
         '/dom/system/gonk',
     ]
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -30,20 +30,16 @@
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/WakeLock.h"
 
 class nsIPrincipal;
 
-#ifdef MOZ_ENABLE_QT5GEOPOSITION
-#include "QTMLocationProvider.h"
-#endif
-
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidLocationProvider.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include "GonkGPSGeolocationProvider.h"
 #endif
 
@@ -693,20 +689,16 @@ nsresult nsGeolocationService::Init()
   // geolocation service can be enabled -> now register observer
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return NS_ERROR_FAILURE;
   }
 
   obs->AddObserver(this, "xpcom-shutdown", false);
 
-#ifdef MOZ_ENABLE_QT5GEOPOSITION
-  mProvider = new QTMLocationProvider();
-#endif
-
 #ifdef MOZ_WIDGET_ANDROID
   mProvider = new AndroidLocationProvider();
 #endif
 
 #ifdef MOZ_WIDGET_GONK
   // GonkGPSGeolocationProvider can be started at boot up time for initialization reasons.
   // do_getService gets hold of the already initialized component and starts
   // processing location requests immediately.
--- a/dom/icc/Icc.cpp
+++ b/dom/icc/Icc.cpp
@@ -89,17 +89,17 @@ nsresult
 Icc::NotifyEvent(const nsAString& aName)
 {
   return DispatchTrustedEvent(aName);
 }
 
 nsresult
 Icc::NotifyStkEvent(const nsAString& aName, nsIStkProactiveCmd* aStkProactiveCmd)
 {
-  JSContext* cx = nsContentUtils::RootingCxForThread();
+  JSContext* cx = nsContentUtils::RootingCx();
   JS::Rooted<JS::Value> value(cx);
 
   nsCOMPtr<nsIStkCmdFactory> cmdFactory =
     do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
   NS_ENSURE_TRUE(cmdFactory, NS_ERROR_UNEXPECTED);
 
   cmdFactory->CreateCommandMessage(aStkProactiveCmd, &value);
   NS_ENSURE_TRUE(value.isObject(), NS_ERROR_UNEXPECTED);
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -480,17 +480,17 @@ IndexedDatabaseManager::CommonPostHandle
 
   RefPtr<DOMError> error = request->GetErrorAfterResult();
 
   nsString errorName;
   if (error) {
     error->GetName(errorName);
   }
 
-  RootedDictionary<ErrorEventInit> init(nsContentUtils::RootingCxForThread());
+  RootedDictionary<ErrorEventInit> init(nsContentUtils::RootingCx());
   request->GetCallerLocation(init.mFilename, &init.mLineno, &init.mColno);
 
   init.mMessage = errorName;
   init.mCancelable = true;
   init.mBubbles = true;
 
   nsEventStatus status = nsEventStatus_eIgnore;
 
--- a/dom/interfaces/events/nsIDOMEventTarget.idl
+++ b/dom/interfaces/events/nsIDOMEventTarget.idl
@@ -269,31 +269,24 @@ interface nsIDOMEventTarget : nsISupport
 
   /**
    * Get the script context in which the event handlers should be run.
    * May return null.
    * @note Caller *must* check the value of aRv.
    */
   [notxpcom, nostdcall]
   nsIScriptContext GetContextForEventHandlers(out nsresult aRv);
-
-  /**
-   * If the method above returns null, but a success code, this method
-   * is called.
-   */
-  [notxpcom, nostdcall] JSContextPtr GetJSContextForEventHandlers();
 };
 
 %{C++
 
 #define NS_IMPL_DOMTARGET_DEFAULTS(_class) \
 mozilla::dom::EventTarget* _class::GetTargetForDOMEvent() { return this; } \
 mozilla::dom::EventTarget* _class::GetTargetForEventTargetChain() { return this; } \
-nsresult _class::WillHandleEvent(mozilla::EventChainPostVisitor& aVisitor) { return NS_OK; } \
-JSContext* _class::GetJSContextForEventHandlers() { return nullptr; }
+nsresult _class::WillHandleEvent(mozilla::EventChainPostVisitor& aVisitor) { return NS_OK; }
 
 #define NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(aClass) \
 NS_IMETHODIMP \
 aClass::RemoveSystemEventListener(const nsAString& aType, \
                                   nsIDOMEventListener *aListener, \
                                   bool aUseCapture) \
 { \
   mozilla::EventListenerManager* listenerManager = \
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3334,22 +3334,16 @@ TabChildGlobal::GetDocShell(nsIDocShell*
   *aDocShell = nullptr;
   if (!mTabChild)
     return NS_ERROR_NULL_POINTER;
   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mTabChild->WebNavigation());
   docShell.swap(*aDocShell);
   return NS_OK;
 }
 
-JSContext*
-TabChildGlobal::GetJSContextForEventHandlers()
-{
-  return nsContentUtils::GetSafeJSContext();
-}
-
 nsIPrincipal*
 TabChildGlobal::GetPrincipal()
 {
   if (!mTabChild)
     return nullptr;
   return mTabChild->GetPrincipal();
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -133,17 +133,16 @@ public:
 
   nsresult
   PreHandleEvent(EventChainPreVisitor& aVisitor) override
   {
     aVisitor.mForceContentDispatch = true;
     return NS_OK;
   }
 
-  virtual JSContext* GetJSContextForEventHandlers() override;
   virtual nsIPrincipal* GetPrincipal() override;
   virtual JSObject* GetGlobalJSObject() override;
 
   virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override
   {
     MOZ_CRASH("TabChildGlobal doesn't use DOM bindings!");
   }
 
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -714,17 +714,17 @@ GeckoMediaPluginServiceParent::UnloadPlu
         NS_LITERAL_CSTRING("Starting to unload plugins"));
 #endif
 
   nsTArray<RefPtr<GMPParent>> plugins;
   {
     MutexAutoLock lock(mMutex);
     // Move all plugins references to a local array. This way mMutex won't be
     // locked when calling CloseActive (to avoid inter-locking).
-    plugins = Move(mPlugins);
+    Swap(plugins, mPlugins);
   }
 
   LOGD(("%s::%s plugins:%u including async:%u", __CLASS__, __FUNCTION__,
         plugins.Length(), mAsyncShutdownPlugins.Length()));
 #ifdef DEBUG
   for (const auto& plugin : plugins) {
     LOGD(("%s::%s plugin: '%s'", __CLASS__, __FUNCTION__,
           plugin->GetDisplayName().get()));
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -1068,17 +1068,17 @@ Notification::ConstructFromFields(
     const nsAString& aTag,
     const nsAString& aIcon,
     const nsAString& aData,
     const nsAString& aServiceWorkerRegistrationScope,
     ErrorResult& aRv)
 {
   MOZ_ASSERT(aGlobal);
 
-  RootedDictionary<NotificationOptions> options(nsContentUtils::RootingCxForThread());
+  RootedDictionary<NotificationOptions> options(nsContentUtils::RootingCx());
   options.mDir = Notification::StringToDirection(nsString(aDir));
   options.mLang = aLang;
   options.mBody = aBody;
   options.mTag = aTag;
   options.mIcon = aIcon;
   RefPtr<Notification> notification = CreateInternal(aGlobal, aID, aTitle,
                                                      options);
 
deleted file mode 100644
--- a/dom/plugins/ipc/NestedLoopTimer.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <QtCore/QTimer>
-
-#include "NestedLoopTimer.h"
-#include "mozilla/plugins/PluginModuleChild.h"
-
-namespace mozilla {
-namespace plugins {
-
-NestedLoopTimer::NestedLoopTimer(PluginModuleChild *pmc):
-     QObject(), mModule(pmc), mQTimer(nullptr)
-{
-}
-
-NestedLoopTimer::~NestedLoopTimer()
-{
-    if (mQTimer) {
-        mQTimer->stop();
-        delete mQTimer;
-        mQTimer = nullptr;
-    }
-}
-
-void NestedLoopTimer::timeOut()
-{
-    // just detected a nested loop; start a timer that will
-    // periodically rpc-call back into the browser and process some
-    // events
-    mQTimer = new QTimer(this);
-    QObject::connect(mQTimer, SIGNAL(timeout()), this,
-                     SLOT(processSomeEvents()));
-    mQTimer->setInterval(kNestedLoopDetectorIntervalMs);
-    mQTimer->start();
-}
-
-void NestedLoopTimer::processSomeEvents()
-{
-    if (mModule)
-        mModule->CallProcessSomeEvents();
-}
-
-} /* namespace plugins */
-} /* namespace mozilla */
deleted file mode 100644
--- a/dom/plugins/ipc/NestedLoopTimer.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NESTEDLOOPTIMER_H
-#define NESTEDLOOPTIMER_H
-
-#include <QtCore/QObject>
-
-class QTimer;
-
-namespace mozilla {
-namespace plugins {
-
-class PluginModuleChild;
-
-class NestedLoopTimer: public QObject
-{
-    Q_OBJECT
-public:
-    NestedLoopTimer(PluginModuleChild *pmc);
-
-    virtual ~NestedLoopTimer();
-
-public Q_SLOTS:
-    virtual void timeOut();
-    virtual void processSomeEvents();
-   
-private:
-    PluginModuleChild *mModule;
-    QTimer *mQTimer;
-};
-
-} /* namespace plugins */
-} /* namespace mozilla */
-
-#undef slots
-
-#endif
deleted file mode 100644
--- a/dom/plugins/ipc/PluginHelperQt.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 "PluginHelperQt.h"
-#include <QtCore/QCoreApplication>
-#include <QtCore/QEventLoop>
-
-static const int kMaxtimeToProcessEvents = 30;
-
-bool
-PluginHelperQt::AnswerProcessSomeEvents()
-{
-    QCoreApplication::processEvents(QEventLoop::AllEvents, kMaxtimeToProcessEvents);
-    return true;
-}
--- a/dom/plugins/ipc/moz.build
+++ b/dom/plugins/ipc/moz.build
@@ -62,23 +62,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
         'hangui',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.plugins += [
         'PluginInterposeOSX.h',
     ]
 
-if CONFIG['MOZ_ENABLE_QT']:
-    SOURCES += [
-        '!moc_NestedLoopTimer.cpp',
-        'NestedLoopTimer.cpp',
-        'PluginHelperQt.cpp',
-    ]
-
 UNIFIED_SOURCES += [
     'BrowserStreamChild.cpp',
     'BrowserStreamParent.cpp',
     'ChildAsyncCall.cpp',
     'ChildTimer.cpp',
     'PluginAsyncSurrogate.cpp',
     'PluginBackgroundDestroyer.cpp',
     'PluginInstanceParent.cpp',
deleted file mode 100644
--- a/dom/plugins/test/testplugin/nptest_qt.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-#include "nptest_platform.h"
-#include "npapi.h"
-
-using namespace std;
-
-bool
-pluginSupportsWindowMode()
-{
-  return false;
-}
-
-bool
-pluginSupportsWindowlessMode()
-{
-  return true;
-}
-
-NPError
-pluginInstanceInit(InstanceData* instanceData)
-{
-  printf("NPERR_INCOMPATIBLE_VERSION_ERROR\n");
-  return NPERR_INCOMPATIBLE_VERSION_ERROR;
-}
-
-void
-pluginInstanceShutdown(InstanceData* instanceData)
-{
-  NPN_MemFree(instanceData->platformData);
-  instanceData->platformData = 0;
-}
-
-void
-pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
-{
-  instanceData->window = *newWindow;
-}
-
-void
-pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
-{
-  // XXX nothing here yet since we don't support windowed plugins
-}
-
-int16_t
-pluginHandleEvent(InstanceData* instanceData, void* event)
-{
-  return 0;
-}
-
-int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
-{
-  // XXX nothing here yet since we don't support windowed plugins
-  return NPTEST_INT32_ERROR;
-}
-
-int32_t pluginGetClipRegionRectCount(InstanceData* instanceData)
-{
-  // XXX nothing here yet since we don't support windowed plugins
-  return NPTEST_INT32_ERROR;
-}
-
-int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData, 
-    int32_t rectIndex, RectEdge edge)
-{
-  // XXX nothing here yet since we don't support windowed plugins
-  return NPTEST_INT32_ERROR;
-}
-
-void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
-{
-}
--- a/dom/plugins/test/testplugin/testplugin.mozbuild
+++ b/dom/plugins/test/testplugin/testplugin.mozbuild
@@ -21,20 +21,16 @@ if toolkit == 'cocoa':
 elif toolkit in ('gtk2', 'gtk3'):
     UNIFIED_SOURCES += [
         'nptest_gtk2.cpp',
     ]
 elif toolkit == 'android':
     UNIFIED_SOURCES += [
         'nptest_droid.cpp',
     ]
-elif toolkit == 'qt':
-    UNIFIED_SOURCES += [
-        'nptest_qt.cpp',
-    ]
 elif toolkit == 'windows':
     UNIFIED_SOURCES += [
         'nptest_windows.cpp',
     ]
     OS_LIBS += [
         'msimg32',
         'imm32'
     ]
@@ -56,23 +52,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
     CXXFLAGS += CONFIG['MOZ_GTK2_CFLAGS']
     CFLAGS += CONFIG['MOZ_GTK2_CFLAGS']
     OS_LIBS += CONFIG['MOZ_GTK2_LIBS']
     OS_LIBS += CONFIG['XLDFLAGS']
     OS_LIBS += CONFIG['XLIBS']
     OS_LIBS += CONFIG['XEXT_LIBS']
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-    CFLAGS += CONFIG['MOZ_QT_CFLAGS']
-    OS_LIBS += CONFIG['MOZ_QT_LIBS']
-    OS_LIBS += CONFIG['XLDFLAGS']
-    OS_LIBS += CONFIG['XLIBS']
-
 if CONFIG['_MSC_VER']:
     # This is intended as a temporary hack to support building with VS2015.
     # conversion from 'X' to 'Y' requires a narrowing conversion
     CXXFLAGS += ['-wd4838']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     FINAL_TARGET = 'dist/plugins/%s.plugin/Contents/MacOS' % cocoa_name
     OBJDIR_FILES.dist.plugins['%s.plugin' % cocoa_name].Contents += ['%s/Info.plist' % relative_path]
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -425,21 +425,18 @@ private:
   void RejectInternal(JSContext* aCx,
                       JS::Handle<JS::Value> aValue);
 #endif // SPIDERMONKEY_PROMISE
 
   template <typename T>
   void MaybeSomething(T& aArgument, MaybeFunc aFunc) {
     MOZ_ASSERT(PromiseObj()); // It was preserved!
 
-    AutoJSAPI jsapi;
-    if (!jsapi.Init(mGlobal)) {
-      return;
-    }
-    JSContext* cx = jsapi.cx();
+    AutoEntryScript aes(mGlobal, "Promise resolution or rejection");
+    JSContext* cx = aes.cx();
 
     JS::Rooted<JS::Value> val(cx);
     if (!ToJSValue(cx, aArgument, &val)) {
       HandleException(cx);
       return;
     }
 
     (this->*aFunc)(cx, val);
--- a/dom/security/SRICheck.cpp
+++ b/dom/security/SRICheck.cpp
@@ -319,16 +319,25 @@ SRICheckDataVerifier::VerifyHash(const S
     nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
                                     NS_LITERAL_CSTRING("Sub-resource Integrity"),
                                     aDocument,
                                     nsContentUtils::eSECURITY_PROPERTIES,
                                     "InvalidIntegrityLength");
     return NS_ERROR_SRI_CORRUPT;
   }
 
+  if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
+    nsAutoCString encodedHash;
+    nsresult rv = Base64Encode(mComputedHash, encodedHash);
+    if (NS_SUCCEEDED(rv)) {
+      SRILOG(("SRICheckDataVerifier::VerifyHash, mComputedHash=%s",
+              encodedHash.get()));
+    }
+  }
+
   if (!binaryHash.Equals(mComputedHash)) {
     SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] did not match", aHashIndex));
     return NS_ERROR_SRI_CORRUPT;
   }
 
   SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] verified successfully", aHashIndex));
   return NS_OK;
 }
--- a/dom/security/test/sri/iframe_style_sameorigin.html
+++ b/dom/security/test/sri/iframe_style_sameorigin.html
@@ -56,16 +56,35 @@
       ok(false, "We should load stylesheets using blob: URLs with the right hash!");
     }
     function good_invalidBlobBlocked() {
       ok(true, "A stylesheet was blocked successfully from a blob: URL with an invalid hash.");
     }
     function bad_invalidBlobLoaded() {
       ok(false, "We should not load stylesheets using blob: URLs when they have the wrong hash!");
     }
+
+    function good_correctUTF8HashLoaded() {
+      ok(true, "A UTF8 stylesheet was correctly loaded when integrity matched");
+    }
+    function bad_correctUTF8HashBlocked() {
+      ok(false, "We should load UTF8 stylesheets with hashes that match!");
+    }
+    function good_correctUTF8BOMHashLoaded() {
+      ok(true, "A UTF8 stylesheet (with BOM) was correctly loaded when integrity matched");
+    }
+    function bad_correctUTF8BOMHashBlocked() {
+      todo(false, "We should load UTF8 (with BOM) stylesheets with hashes that match!");
+    }
+    function good_correctUTF8ishHashLoaded() {
+      ok(true, "A UTF8ish stylesheet was correctly loaded when integrity matched");
+    }
+    function bad_correctUTF8ishHashBlocked() {
+      todo(false, "We should load UTF8ish stylesheets with hashes that match!");
+    }
   </script>
 
   <!-- valid sha256 hash. should trigger onload -->
   <link rel="stylesheet" href="style1.css"
         integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
         onerror="bad_correctHashBlocked()"
         onload="good_correctHashLoaded()">
 
@@ -75,16 +94,34 @@
         onerror="bad_emptyIntegrityBlocked()"
         onload="good_emptyIntegrityLoaded()">
 
   <!-- invalid sha256 hash. should trigger onerror -->
   <link rel="stylesheet" href="style3.css"
         integrity="sha256-bogus"
         onerror="good_incorrectHashBlocked()"
         onload="bad_incorrectHashLoaded()">
+
+  <!-- valid sha384 hash of a utf8 file. should trigger onload -->
+  <link rel="stylesheet" href="style4.css"
+        integrity="sha384-13rt+j7xMDLhohLukb7AZx8lDGS3hkahp0IoeuyvxSNVPyc1QQmTDcwXGhQZjoMH"
+        onerror="bad_correctUTF8HashBlocked()"
+        onload="good_correctUTF8HashLoaded()">
+
+  <!-- valid sha384 hash of a utf8 file with a BOM. should trigger onload -->
+  <link rel="stylesheet" href="style5.css"
+        integrity="sha384-udAqVKPIHf/OD1isAYKrgzsog/3Q6lSEL2nKhtLSTmHryiae0+y6x1akeTzEF446"
+        onerror="bad_correctUTF8BOMHashBlocked()"
+        onload="good_correctUTF8BOMHashLoaded()">
+
+  <!-- valid sha384 hash of a utf8 file with the wrong charset. should trigger onload -->
+  <link rel="stylesheet" href="style6.css"
+        integrity="sha384-Xli4ROFoVGCiRgXyl7y8jv5Vm2yuqj+8tkNL3cUI7AHaCocna75JLs5xID437W6C"
+        onerror="bad_correctUTF8ishHashBlocked()"
+        onload="good_correctUTF8ishHashLoaded()">
 </head>
 <body>
 
 <!-- valid sha256 for a blob: URL -->
 <script>
    var blob = new Blob(['.blue-text{color:blue}'],
                        {type: 'text/css'});
    var link = document.createElement('link');
@@ -104,17 +141,20 @@
    link.rel = 'stylesheet';
    link.href = window.URL.createObjectURL(blob);
    link.setAttribute('integrity', 'sha256-/F+EMVnTWYJOAzN5n7/21idiydu6nRi33LZOISZtwOM=');
    link.onerror = good_invalidBlobBlocked;
    link.onload = bad_invalidBlobLoaded;
    document.body.appendChild(link);
 </script>
 
-<p><span id="red-text">This should be red </span> and
+<p><span id="red-text">This should be red </span>,
+  <span id="purple-text">this should be purple</span>,
+  <span id="brown-text">this should be brown</span>,
+  <span id="orange-text">this should be orange</span>, and
   <span class="blue-text" id="blue-text-element">this should be blue.</span>
   However, <span id="black-text">this should stay black</span> and
   <span class="black-text" id="black-text-2">this should also stay black.</span>
 </p>
 
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
--- a/dom/security/test/sri/mochitest.ini
+++ b/dom/security/test/sri/mochitest.ini
@@ -23,16 +23,21 @@ support-files =
   script_302.js
   script_302.js^headers^
   script_401.js
   script_401.js^headers^
   style1.css
   style1.css^headers^
   style2.css
   style3.css
+  style4.css
+  style4.css^headers^
+  style5.css
+  style6.css
+  style6.css^headers^
   style_301.css
   style_301.css^headers^
 
 [test_script_sameorigin.html]
 [test_script_crossdomain.html]
 [test_sri_disabled.html]
 [test_style_crossdomain.html]
 [test_style_sameorigin.html]
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style4.css
@@ -0,0 +1,4 @@
+/* François was here. */
+#purple-text {
+  color: purple;
+}
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style4.css^headers^
@@ -0,0 +1,1 @@
+Content-Type: text/css; charset=utf-8
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style5.css
@@ -0,0 +1,4 @@
+/* François was here. */
+#orange-text {
+  color: orange;
+}
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style6.css
@@ -0,0 +1,4 @@
+/* François was here. */
+#brown-text {
+  color: brown;
+}
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/style6.css^headers^
@@ -0,0 +1,1 @@
+Content-Type: text/css; charset=iso-8859-8
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -591,17 +591,17 @@ AudioManager::Observe(nsISupports* aSubj
   else if (!strcmp(aTopic, AUDIO_CHANNEL_PROCESS_CHANGED)) {
     HandleAudioChannelProcessChanged();
     return NS_OK;
   }
 
   // To process the volume control on each volume categories according to
   // change of settings
   else if (!strcmp(aTopic, MOZ_SETTINGS_CHANGE_ID)) {
-    RootedDictionary<dom::SettingChangeNotification> setting(nsContentUtils::RootingCxForThread());
+    RootedDictionary<dom::SettingChangeNotification> setting(nsContentUtils::RootingCx());
     if (!WrappedJSToDictionary(aSubject, setting)) {
       return NS_OK;
     }
     if (!StringBeginsWith(setting.mKey, NS_LITERAL_STRING("audio.volume."))) {
       return NS_OK;
     }
     if (!setting.mValue.isNumber()) {
       return NS_OK;
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -242,17 +242,17 @@ AutoMounterSetting::Observe(nsISupports*
   }
 
   // Note that this function gets called for any and all settings changes,
   // so we need to carefully check if we have the one we're interested in.
   //
   // The string that we're interested in will be a JSON string that looks like:
   //  {"key":"ums.autoMount","value":true}
 
-  RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCxForThread());
+  RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCx());
   if (!WrappedJSToDictionary(aSubject, setting)) {
     return NS_OK;
   }
 
   // Check for ums.mode changes
   if (setting.mKey.EqualsASCII(UMS_MODE)) {
     if (!setting.mValue.isInt32()) {
       return NS_OK;
deleted file mode 100644
--- a/dom/system/qt/QTMLocationProvider.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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 "QTMLocationProvider.h"
-#include "nsGeoPosition.h"
-
-using namespace mozilla;
-
-NS_IMPL_ISUPPORTS(QTMLocationProvider, nsIGeolocationProvider)
-
-QTMLocationProvider::QTMLocationProvider()
-{
-    if (QMetaType::type("QGeoPositionInfo") == QMetaType::UnknownType) {
-        qRegisterMetaType<QGeoPositionInfo>("QGeoPositionInfo");
-    }
-    mLocation = QGeoPositionInfoSource::createDefaultSource(this);
-    if (mLocation)
-        connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
-}
-
-QTMLocationProvider::~QTMLocationProvider()
-{
-    delete mLocation;
-}
-
-void
-QTMLocationProvider::positionUpdated(const QGeoPositionInfo &geoPosition)
-{
-    if (!geoPosition.isValid()) {
-        NS_WARNING("Invalida geoposition received");
-        return;
-    }
-
-    QGeoCoordinate coord = geoPosition.coordinate();
-    double latitude = coord.latitude();
-    double longitude = coord.longitude();
-    double altitude = coord.altitude();
-    double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
-    double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy);
-    double heading = geoPosition.attribute(QGeoPositionInfo::Direction);
-
-    bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed);
-    double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed);
-
-    RefPtr<nsGeoPosition> p =
-        new nsGeoPosition(latitude, longitude,
-                          altitude, accuracy,
-                          altitudeAccuracy, heading,
-                          speed, geoPosition.timestamp().toTime_t());
-    if (mCallback) {
-        mCallback->Update(p);
-    }
-}
-
-NS_IMETHODIMP
-QTMLocationProvider::Startup()
-{
-    if (!mLocation)
-        return NS_ERROR_NOT_IMPLEMENTED;
-
-    // Not all versions of qt5positioning set default prefered method
-    // thus this workaround initializing QGeoPositionSource explicitly
-    SetHighAccuracy(false);
-    mLocation->startUpdates();
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
-{
-    mCallback = aCallback;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-QTMLocationProvider::Shutdown()
-{
-    if (!mLocation)
-        return NS_ERROR_NOT_IMPLEMENTED;
-
-    mLocation->stopUpdates();
-    mCallback = nullptr;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-QTMLocationProvider::SetHighAccuracy(bool aHigh)
-{
-    if (!mLocation)
-        return NS_ERROR_NOT_IMPLEMENTED;
-
-    mLocation->setPreferredPositioningMethods(aHigh ?
-                                              QGeoPositionInfoSource::SatellitePositioningMethods :
-                                              QGeoPositionInfoSource::AllPositioningMethods);
-    return NS_OK;
-}
deleted file mode 100644
--- a/dom/system/qt/QTMLocationProvider.h
+++ /dev/null
@@ -1,35 +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/. */
-
-#ifndef QTMLocationProvider_h
-#define QTMLocationProvider_h
-
-#include <QGeoPositionInfoSource>
-#include "nsGeolocation.h"
-#include "nsIGeolocationProvider.h"
-#include "nsCOMPtr.h"
-
-class QTMLocationProvider : public QObject,
-                            public nsIGeolocationProvider
-{
-    Q_OBJECT
-
-public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIGEOLOCATIONPROVIDER
-
-    QTMLocationProvider();
-
-public Q_SLOTS:
-    // QGeoPositionInfoSource
-    void positionUpdated(const QGeoPositionInfo&);
-
-private:
-    ~QTMLocationProvider();
-
-    QGeoPositionInfoSource* mLocation;
-    nsCOMPtr<nsIGeolocationUpdate> mCallback;
-};
-
-#endif /* QTMLocationProvider_h */
deleted file mode 100644
--- a/dom/system/qt/QtHapticFeedback.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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 <QFeedbackEffect>
-#include "QtHapticFeedback.h"
-
-NS_IMPL_ISUPPORTS(QtHapticFeedback, nsIHapticFeedback)
-
-NS_IMETHODIMP
-QtHapticFeedback::PerformSimpleAction(int32_t aType)
-{
-    if (aType == ShortPress)
-        QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressWeak);
-    if (aType == LongPress)
-        QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressStrong);
-
-    return NS_OK;
-}
deleted file mode 100644
--- a/dom/system/qt/QtHapticFeedback.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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 "nsIHapticFeedback.h"
-
-class QtHapticFeedback : public nsIHapticFeedback
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIHAPTICFEEDBACK
-protected:
-  virtual ~QtHapticFeedback() {}
-};
deleted file mode 100644
--- a/dom/system/qt/moz.build
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
-    SOURCES += [
-        '!moc_QTMLocationProvider.cpp',
-        'QTMLocationProvider.cpp',
-    ]
-
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-
-    LOCAL_INCLUDES += [
-        '/dom/geolocation',
-    ]
-
-if CONFIG['MOZ_ENABLE_QT5FEEDBACK']:
-    SOURCES += [
-        'QtHapticFeedback.cpp',
-    ]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
--- a/dom/webidl/CameraControl.webidl
+++ b/dom/webidl/CameraControl.webidl
@@ -484,18 +484,16 @@ dictionary CameraDetectedFaceInit
   boolean hasLeftEye = false;
   DOMPointInit leftEye;
   boolean hasRightEye = false;
   DOMPointInit rightEye;
   boolean hasMouth = false;
   DOMPointInit mouth;
 };
 
-callback CameraFaceDetectionCallback = void (sequence<CameraDetectedFace> faces);
-
 partial interface CameraControl
 {
   /* Starts the face detection. This should be called after the preview is
      started. The camera will periodically call 'onFacesDetected' with a
      sequence of zero or one or more detected faces in the preview frame.
 
      How often the callback is invoked is implementation dependent.
 
deleted file mode 100644
--- a/dom/webidl/DummyBinding.webidl
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-// Dummy bindings that we need to force generation of things that
-// aren't actually referenced anywhere in IDL yet but are used in C++.
-
-interface DummyInterface {
-  void lifecycleCallbacks(optional LifecycleCallbacks arg);
-  void promiseJobCallback(PromiseJobCallback arg);
-};
--- a/dom/webidl/OfflineAudioContext.webidl
+++ b/dom/webidl/OfflineAudioContext.webidl
@@ -5,18 +5,16 @@
  *
  * The origin of this IDL file is
  * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
-
 [Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)]
 interface OfflineAudioContext : AudioContext {
 
     [Throws]
     Promise<AudioBuffer> startRendering();
 
     attribute EventHandler oncomplete;
     readonly attribute unsigned long length;
--- a/dom/webidl/XMLHttpRequestEventTarget.webidl
+++ b/dom/webidl/XMLHttpRequestEventTarget.webidl
@@ -8,29 +8,22 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Exposed=(Window,DedicatedWorker,SharedWorker)]
 interface XMLHttpRequestEventTarget : EventTarget {
   // event handlers
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onloadstart;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onprogress;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onabort;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onerror;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onload;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler ontimeout;
 
-  [SetterThrows=Workers, GetterThrows=Workers]
   attribute EventHandler onloadend;
 };
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -139,17 +139,16 @@ WEBIDL_FILES = [
     'DOMRectList.webidl',
     'DOMRequest.webidl',
     'DOMStringList.webidl',
     'DOMStringMap.webidl',
     'DOMTokenList.webidl',
     'DOMTransaction.webidl',
     'Downloads.webidl',
     'DragEvent.webidl',
-    'DummyBinding.webidl',
     'DynamicsCompressorNode.webidl',
     'Element.webidl',
     'Event.webidl',
     'EventHandler.webidl',
     'EventListener.webidl',
     'EventSource.webidl',
     'EventTarget.webidl',
     'ExtendableEvent.webidl',
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -6179,17 +6179,17 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
     if (info->mIsInterval) {
       reason = "setInterval handler";
     } else {
       reason = "setTimeout handler";
     }
 
     { // scope for the AutoEntryScript, so it comes off the stack before we do
       // Promise::PerformMicroTaskCheckpoint.
-      AutoEntryScript aes(global, reason, false, aCx);
+      AutoEntryScript aes(global, reason, false);
       if (!info->mTimeoutCallable.isUndefined()) {
         JS::Rooted<JS::Value> rval(aCx);
         JS::HandleValueArray args =
           JS::HandleValueArray::fromMarkedLocation(info->mExtraArgVals.Length(),
                                                    info->mExtraArgVals.Elements()->address());
         JS::Rooted<JS::Value> callable(aCx, info->mTimeoutCallable);
         if (!JS_CallFunctionValue(aCx, global, callable, args, &rval) &&
             !JS_IsExceptionPending(aCx)) {
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -313,19 +313,17 @@ WorkerRunnable::Run()
   // http://www.whatwg.org/specs/web-apps/current-work/#run-a-worker
   // If we don't have a globalObject we have to use an AutoJSAPI instead, but
   // this is OK as we won't be running script in these circumstances.
   Maybe<mozilla::dom::AutoJSAPI> maybeJSAPI;
   Maybe<mozilla::dom::AutoEntryScript> aes;
   JSContext* cx;
   AutoJSAPI* jsapi;
   if (globalObject) {
-    aes.emplace(globalObject, "Worker runnable",
-                isMainThread,
-                isMainThread ? nullptr : GetCurrentThreadJSContext());
+    aes.emplace(globalObject, "Worker runnable", isMainThread);
     jsapi = aes.ptr();
     cx = aes->cx();
   } else {
     maybeJSAPI.emplace();
     maybeJSAPI->Init();
     jsapi = maybeJSAPI.ptr();
     cx = jsapi->cx();
   }
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -502,30 +502,30 @@ public:
   : MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy),
     StructuredCloneHolder(CloningSupported, TransferringNotSupported,
                           SameProcessDifferentThread),
     mType(aType), mResponse(JS::UndefinedValue()), mLoaded(aLoaded),
     mTotal(aTotal), mEventStreamId(aProxy->mInnerEventStreamId), mStatus(0),
     mReadyState(0), mUploadEvent(aUploadEvent), mProgressEvent(true),
     mLengthComputable(aLengthComputable), mUseCachedArrayBufferResponse(false),
     mResponseTextResult(NS_OK), mStatusResult(NS_OK), mResponseResult(NS_OK),
-    mScopeObj(nsContentUtils::RootingCxForThread(), aScopeObj)
+    mScopeObj(GetJSRuntime(), aScopeObj)
   { }
 
   EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType,
                 JS::Handle<JSObject*> aScopeObj)
   : MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy),
     StructuredCloneHolder(CloningSupported, TransferringNotSupported,
                           SameProcessDifferentThread),
     mType(aType), mResponse(JS::UndefinedValue()), mLoaded(0), mTotal(0),
     mEventStreamId(aProxy->mInnerEventStreamId), mStatus(0), mReadyState(0),
     mUploadEvent(aUploadEvent), mProgressEvent(false), mLengthComputable(0),
     mUseCachedArrayBufferResponse(false), mResponseTextResult(NS_OK),
     mStatusResult(NS_OK), mResponseResult(NS_OK),
-    mScopeObj(nsContentUtils::RootingCxForThread(), aScopeObj)
+    mScopeObj(GetJSRuntime(), aScopeObj)
   { }
 
 private:
   ~EventRunnable()
   { }
 
   virtual bool
   PreDispatch(WorkerPrivate* /* unused */) override final;
--- a/dom/xslt/xpath/txXPCOMExtensionFunction.cpp
+++ b/dom/xslt/xpath/txXPCOMExtensionFunction.cpp
@@ -13,17 +13,17 @@
 #include "txIFunctionEvaluationContext.h"
 #include "txIXPathContext.h"
 #include "txNodeSetAdaptor.h"
 #include "txXPathTreeWalker.h"
 #include "xptcall.h"
 #include "txXPathObjectAdaptor.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/UniquePtr.h"
-#include "nsContentUtils.h"
+#include "mozilla/dom/ScriptSettings.h"
 #include "nsIClassInfo.h"
 #include "nsIInterfaceInfo.h"
 #include "js/RootingAPI.h"
 
 NS_IMPL_ISUPPORTS(txXPathObjectAdaptor, txIXPathObject)
 
 class txFunctionEvaluationContext final : public txIFunctionEvaluationContext
 {
@@ -379,17 +379,17 @@ txXPCOMExtensionFunctionCall::evaluate(t
 
     const nsXPTMethodInfo *methodInfo;
     rv = info->GetMethodInfo(mMethodIndex, &methodInfo);
     NS_ENSURE_SUCCESS(rv, rv);
 
     uint8_t paramCount = methodInfo->GetParamCount();
     uint8_t inArgs = paramCount - 1;
 
-    JS::Rooted<txParamArrayHolder> invokeParams(nsContentUtils::RootingCxForThread());
+    JS::Rooted<txParamArrayHolder> invokeParams(mozilla::dom::GetJSRuntime());
     if (!invokeParams.get().Init(paramCount)) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     const nsXPTParamInfo &paramInfo = methodInfo->GetParam(0);
     txArgumentType type = GetParamType(paramInfo, info);
     if (type == eUNKNOWN) {
         return NS_ERROR_FAILURE;
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -471,16 +471,22 @@ CheckUserContextCompatibility(nsIDocShel
   nsCOMPtr<nsIPrincipal> subjectPrincipal =
     nsContentUtils::GetCurrentJSContext()
       ? nsContentUtils::SubjectPrincipal() : nullptr;
 
   if (!subjectPrincipal) {
     return false;
   }
 
+  // DocShell can have UsercontextID set but loading a document with system
+  // principal. In this case, we consider everything ok.
+  if (nsContentUtils::IsSystemPrincipal(subjectPrincipal)) {
+    return true;
+  }
+
   uint32_t principalUserContextId;
   nsresult rv = subjectPrincipal->GetUserContextId(&principalUserContextId);
   NS_ENSURE_SUCCESS(rv, false);
 
   return principalUserContextId == userContextId;
 }
 
 nsresult
--- a/gfx/cairo/cairo/src/moz.build
+++ b/gfx/cairo/cairo/src/moz.build
@@ -76,23 +76,16 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'be
     ]
 elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
     EXPORTS.cairo += [
         'cairo-ps.h',
     ]
     SOURCES += [
         'cairo-ps-surface.c',
     ]
-elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    EXPORTS.cairo += [
-        'cairo-qt.h',
-    ]
-    SOURCES += [
-        'cairo-qt-surface.cpp',
-    ]
 
 if CONFIG['MOZ_X11']:
     EXPORTS.cairo += [
         'cairo-xlib-xrender.h',
         'cairo-xlib.h',
     ]
     SOURCES += [
         'cairo-xlib-display.c',
@@ -244,18 +237,14 @@ if CONFIG['CLANG_CL']:
         '-Wno-unused-variable',
     ]
 
 # See bug 386897.
 if CONFIG['GNU_CC'] and CONFIG['OS_TARGET'] == 'Android' and CONFIG['MOZ_OPTIMIZE']:
     CFLAGS += ['-O2']
     CXXFLAGS += ['-O2']
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    CFLAGS += CONFIG['MOZ_QT_CFLAGS']
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-
 if CONFIG['MOZ_X11']:
     CFLAGS += CONFIG['XCFLAGS']
 
 if CONFIG['MOZ_ENABLE_CAIRO_FT']:
     CFLAGS += CONFIG['CAIRO_FT_CFLAGS']
     CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS']
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -32,16 +32,17 @@ namespace layers {
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
   CanvasLayer(aLayerManager, aImplData)
   , mGLFrontbuffer(nullptr)
   , mIsAlphaPremultiplied(true)
   , mOriginPos(gl::OriginPos::TopLeft)
+  , mIsMirror(false)
 {
   MOZ_COUNT_CTOR(CopyableCanvasLayer);
 }
 
 CopyableCanvasLayer::~CopyableCanvasLayer()
 {
   MOZ_COUNT_DTOR(CopyableCanvasLayer);
 }
@@ -50,16 +51,17 @@ void
 CopyableCanvasLayer::Initialize(const Data& aData)
 {
   NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
 
   if (aData.mGLContext) {
     mGLContext = aData.mGLContext;
     mIsAlphaPremultiplied = aData.mIsGLAlphaPremult;
     mOriginPos = gl::OriginPos::BottomLeft;
+    mIsMirror = aData.mIsMirror;
 
     MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
 
     if (aData.mFrontbufferGLTex) {
       gfx::IntSize size(aData.mSize.width, aData.mSize.height);
       mGLFrontbuffer = SharedSurface_Basic::Wrap(aData.mGLContext, size, aData.mHasAlpha,
                                                  aData.mFrontbufferGLTex);
       mBufferProvider = aData.mBufferProvider;
--- a/gfx/layers/CopyableCanvasLayer.h
+++ b/gfx/layers/CopyableCanvasLayer.h
@@ -53,16 +53,17 @@ protected:
   RefPtr<gl::GLContext> mGLContext;
   GLuint mCanvasFrontbufferTexID;
   RefPtr<PersistentBufferProvider> mBufferProvider;
 
   UniquePtr<gl::SharedSurface> mGLFrontbuffer;
 
   bool mIsAlphaPremultiplied;
   gl::OriginPos mOriginPos;
+  bool mIsMirror;
 
   RefPtr<gfx::DataSourceSurface> mCachedTempSurface;
 
   gfx::DataSourceSurface* GetTempSurface(const gfx::IntSize& aSize,
                                          const gfx::SurfaceFormat aFormat);
 
   void DiscardTempSurface();
 };
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -2370,16 +2370,17 @@ public:
     Data()
       : mBufferProvider(nullptr)
       , mGLContext(nullptr)
       , mRenderer(nullptr)
       , mFrontbufferGLTex(0)
       , mSize(0,0)
       , mHasAlpha(false)
       , mIsGLAlphaPremult(true)
+      , mIsMirror(false)
     { }
 
     // One of these three must be specified for Canvas2D, but never more than one
     PersistentBufferProvider* mBufferProvider; // A BufferProvider for the Canvas contents
     mozilla::gl::GLContext* mGLContext; // or this, for GL.
     AsyncCanvasRenderer* mRenderer; // or this, for OffscreenCanvas
 
     // Frontbuffer override
@@ -2388,16 +2389,20 @@ public:
     // The size of the canvas content
     gfx::IntSize mSize;
 
     // Whether the canvas drawingbuffer has an alpha channel.
     bool mHasAlpha;
 
     // Whether mGLContext contains data that is alpha-premultiplied.
     bool mIsGLAlphaPremult;
+
+    // Whether the canvas front buffer is already being rendered somewhere else.
+    // When true, do not swap buffers or Morph() to another factory on mGLContext
+    bool mIsMirror;
   };
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Initialize this CanvasLayer with the given data.  The data must
    * have either mSurface or mGLContext initialized (but not both), as
    * well as mSize.
    *
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -406,16 +406,21 @@ CanvasClientSharedSurface::UpdateRendere
   RefPtr<TextureClient> newFront;
 
   if (layer && layer->mGLFrontbuffer) {
     mShSurfClient = CloneSurface(layer->mGLFrontbuffer.get(), layer->mFactory.get());
     if (!mShSurfClient) {
       gfxCriticalError() << "Invalid canvas front buffer";
       return;
     }
+  } else if (layer && layer->mIsMirror) {
+    mShSurfClient = CloneSurface(gl->Screen()->Front()->Surf(), layer->mFactory.get());
+    if (!mShSurfClient) {
+      return;
+    }
   } else {
     mShSurfClient = gl->Screen()->Front();
     if (mShSurfClient && mShSurfClient->GetAllocator() &&
         mShSurfClient->GetAllocator()->AsCompositableForwarder() != GetForwarder()) {
       mShSurfClient = CloneSurface(mShSurfClient->Surf(), gl->Screen()->Factory());
     }
     if (!mShSurfClient) {
       return;
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -62,17 +62,17 @@ ClientCanvasLayer::Initialize(const Data
 
   mFlags = TextureFlags::ORIGIN_BOTTOM_LEFT;
   if (!aData.mIsGLAlphaPremult) {
     mFlags |= TextureFlags::NON_PREMULTIPLIED;
   }
 
   UniquePtr<SurfaceFactory> factory = GLScreenBuffer::CreateFactory(mGLContext, caps, forwarder, mFlags);
 
-  if (mGLFrontbuffer) {
+  if (mGLFrontbuffer || aData.mIsMirror) {
     // We're using a source other than the one in the default screen.
     // (SkiaGL)
     mFactory = Move(factory);
     if (!mFactory) {
       // Absolutely must have a factory here, so create a basic one
       mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps, mFlags);
     }
   } else {
--- a/gfx/src/moz.build
+++ b/gfx/src/moz.build
@@ -86,11 +86,8 @@ LOCAL_INCLUDES += [
 
 FINAL_LIBRARY = 'xul'
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 CXXFLAGS += CONFIG['TK_CFLAGS']
 
 if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
     CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS']
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
--- a/image/Decoder.cpp
+++ b/image/Decoder.cpp
@@ -65,16 +65,19 @@ Decoder::~Decoder()
  */
 
 void
 Decoder::Init()
 {
   // No re-initializing
   MOZ_ASSERT(!mInitialized, "Can't re-initialize a decoder!");
 
+  // All decoders must have a SourceBufferIterator.
+  MOZ_ASSERT(mIterator);
+
   // It doesn't make sense to decode anything but the first frame if we can't
   // store anything in the SurfaceCache, since only the last frame we decode
   // will be retrievable.
   MOZ_ASSERT(ShouldUseSurfaceCache() || IsFirstFrameDecode());
 
   // Implementation-specific initialization
   InitInternal();
 
@@ -235,16 +238,22 @@ Decoder::SetTargetSize(const nsIntSize& 
   }
 
   // Create a downscaler that we'll filter our output through.
   mDownscaler.emplace(aSize);
 
   return NS_OK;
 }
 
+Maybe<IntSize>
+Decoder::GetTargetSize()
+{
+  return mDownscaler ? Some(mDownscaler->TargetSize()) : Nothing();
+}
+
 nsresult
 Decoder::AllocateFrame(uint32_t aFrameNum,
                        const nsIntSize& aTargetSize,
                        const nsIntRect& aFrameRect,
                        gfx::SurfaceFormat aFormat,
                        uint8_t aPaletteDepth)
 {
   mCurrentFrame = AllocateFrameInternal(aFrameNum, aTargetSize, aFrameRect,
--- a/image/Decoder.h
+++ b/image/Decoder.h
@@ -109,34 +109,39 @@ public:
    *
    * If the provided size is unacceptable, an error is returned.
    *
    * Returning NS_OK from this method is a promise that the decoder will decode
    * the image to the requested target size unless it encounters an error.
    *
    * This must be called before Init() is called.
    */
-  nsresult SetTargetSize(const nsIntSize& aSize);
+  nsresult SetTargetSize(const gfx::IntSize& aSize);
+
+  /**
+   * If this decoder supports downscale-during-decode and is configured to
+   * downscale, returns the target size that the output size will be decoded to.
+   * Otherwise, returns Nothing().
+   */
+  Maybe<gfx::IntSize> GetTargetSize();
 
   /**
    * Set the requested sample size for this decoder. Used to implement the
    * -moz-sample-size media fragment.
    *
    *  XXX(seth): Support for -moz-sample-size will be removed in bug 1120056.
    */
   virtual void SetSampleSize(int aSampleSize) { }
 
   /**
    * Set an iterator to the SourceBuffer which will feed data to this decoder.
+   * This must always be called before calling Init(). (And only before Init().)
    *
-   * This should be called for almost all decoders; the exceptions are the
-   * contained decoders of an nsICODecoder, which will be fed manually via Write
-   * instead.
-   *
-   * This must be called before Init() is called.
+   * XXX(seth): We should eliminate this method and pass a SourceBufferIterator
+   * to the various decoder constructors instead.
    */
   void SetIterator(SourceBufferIterator&& aIterator)
   {
     MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
     mIterator.emplace(Move(aIterator));
   }
 
   /**
@@ -242,37 +247,34 @@ public:
     return mImageMetadata.GetSize();
   }
 
   virtual Telemetry::ID SpeedHistogram();
 
   ImageMetadata& GetImageMetadata() { return mImageMetadata; }
 
   /**
-   * Returns a weak pointer to the image associated with this decoder.
+   * @return a weak pointer to the image associated with this decoder. Illegal
+   * to call if this decoder is not associated with an image.
    */
   RasterImage* GetImage() const { MOZ_ASSERT(mImage); return mImage.get(); }
 
+  /**
+   * @return a possibly-null weak pointer to the image associated with this
+   * decoder. May be called even if this decoder is not associated with an
+   * image.
+   */
+  RasterImage* GetImageMaybeNull() const { return mImage.get(); }
+
   RawAccessFrameRef GetCurrentFrameRef()
   {
     return mCurrentFrame ? mCurrentFrame->RawAccessRef()
                          : RawAccessFrameRef();
   }
 
-  /**
-   * Writes data to the decoder. Only public for the benefit of nsICODecoder;
-   * other callers should use Decode().
-   *
-   * @param aBuffer buffer containing the data to be written
-   * @param aCount the number of bytes to write
-   *
-   * Any errors are reported by setting the appropriate state on the decoder.
-   */
-  void Write(const char* aBuffer, uint32_t aCount);
-
 
 protected:
   friend class nsICODecoder;
   friend class PalettedSurfaceSink;
   friend class SurfaceSink;
 
   virtual ~Decoder();
 
@@ -353,16 +355,26 @@ protected:
   // means a single iteration, stopping on the last frame.
   void PostDecodeDone(int32_t aLoopCount = 0);
 
   // Data errors are the fault of the source data, decoder errors are our fault
   void PostDataError();
   void PostDecoderError(nsresult aFailCode);
 
   /**
+   * Called by Decode() to write data to the decoder.
+   *
+   * @param aBuffer A buffer containing the data to be written.
+   * @param aCount The number of bytes to write.
+   *
+   * Any errors are reported by setting the appropriate state on the decoder.
+   */
+  void Write(const char* aBuffer, uint32_t aCount);
+
+  /**
    * CompleteDecode() finishes up the decoding process after Decode() determines
    * that we're finished. It records final progress and does all the cleanup
    * that's possible off-main-thread.
    */
   void CompleteDecode();
 
   /**
    * Allocates a new frame, making it our current frame if successful.
--- a/image/DecoderFactory.cpp
+++ b/image/DecoderFactory.cpp
@@ -223,16 +223,64 @@ DecoderFactory::CreateMetadataDecoder(De
     return nullptr;
   }
 
   RefPtr<IDecodingTask> task = new MetadataDecodingTask(WrapNotNull(decoder));
   return task.forget();
 }
 
 /* static */ already_AddRefed<Decoder>
+DecoderFactory::CreateDecoderForICOResource(DecoderType aType,
+                                            NotNull<SourceBuffer*> aSourceBuffer,
+                                            NotNull<nsICODecoder*> aICODecoder,
+                                            const Maybe<uint32_t>& aDataOffset
+                                              /* = Nothing() */)
+{
+  // Create the decoder.
+  RefPtr<Decoder> decoder;
+  switch (aType) {
+    case DecoderType::BMP:
+      MOZ_ASSERT(aDataOffset);
+      decoder = new nsBMPDecoder(aICODecoder->GetImageMaybeNull(), *aDataOffset);
+      break;
+
+    case DecoderType::PNG:
+      MOZ_ASSERT(!aDataOffset);
+      decoder = new nsPNGDecoder(aICODecoder->GetImageMaybeNull());
+      break;
+
+    default:
+      MOZ_ASSERT_UNREACHABLE("Invalid ICO resource decoder type");
+      return nullptr;
+  }
+
+  MOZ_ASSERT(decoder);
+
+  // Initialize the decoder, copying settings from @aICODecoder.
+  decoder->SetMetadataDecode(aICODecoder->IsMetadataDecode());
+  decoder->SetIterator(aSourceBuffer->Iterator());
+  decoder->SetDecoderFlags(aICODecoder->GetDecoderFlags());
+  decoder->SetSurfaceFlags(aICODecoder->GetSurfaceFlags());
+
+  // Set a target size for downscale-during-decode if applicable.
+  const Maybe<IntSize> targetSize = aICODecoder->GetTargetSize();
+  if (targetSize) {
+    DebugOnly<nsresult> rv = decoder->SetTargetSize(*targetSize);
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
+  }
+
+  decoder->Init();
+  if (NS_FAILED(decoder->GetDecoderError())) {
+    return nullptr;
+  }
+
+  return decoder.forget();
+}
+
+/* static */ already_AddRefed<Decoder>
 DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
                                        NotNull<SourceBuffer*> aSourceBuffer,
                                        const Maybe<IntSize>& aTargetSize,
                                        SurfaceFlags aSurfaceFlags)
 {
   if (aType == DecoderType::UNKNOWN) {
     return nullptr;
   }
--- a/image/DecoderFactory.h
+++ b/image/DecoderFactory.h
@@ -15,16 +15,17 @@
 #include "nsCOMPtr.h"
 #include "SurfaceFlags.h"
 
 namespace mozilla {
 namespace image {
 
 class Decoder;
 class IDecodingTask;
+class nsICODecoder;
 class RasterImage;
 class SourceBuffer;
 
 /**
  * The type of decoder; this is usually determined from a MIME type using
  * DecoderFactory::GetDecoderType().
  */
 enum class DecoderType
@@ -115,16 +116,39 @@ public:
    */
   static already_AddRefed<IDecodingTask>
   CreateMetadataDecoder(DecoderType aType,
                         NotNull<RasterImage*> aImage,
                         NotNull<SourceBuffer*> aSourceBuffer,
                         int aSampleSize);
 
   /**
+   * Creates and initializes a decoder for an ICO resource, which may be either
+   * a BMP or PNG image.
+   *
+   * @param aType Which type of decoder to create. This must be either BMP or
+   *              PNG.
+   * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+   *                      from.
+   * @param aICODecoder The ICO decoder which is controlling this resource
+   *                    decoder. @aICODecoder's settings will be copied to the
+   *                    resource decoder, so the two decoders will have the
+   *                    same decoder flags, surface flags, target size, and
+   *                    other parameters.
+   * @param aDataOffset If @aType is BMP, specifies the offset at which data
+   *                    begins in the BMP resource. Must be Some() if and only
+   *                    if @aType is BMP.
+   */
+  static already_AddRefed<Decoder>
+  CreateDecoderForICOResource(DecoderType aType,
+                              NotNull<SourceBuffer*> aSourceBuffer,
+                              NotNull<nsICODecoder*> aICODecoder,
+                              const Maybe<uint32_t>& aDataOffset = Nothing());
+
+  /**
    * Creates and initializes an anonymous decoder (one which isn't associated
    * with an Image object). Only the first frame of the image will be decoded.
    *
    * @param aType Which type of decoder to create - JPEG, PNG, etc.
    * @param aSourceBuffer The SourceBuffer which the decoder will read its data
    *                      from.
    * @param aTargetSize If not Nothing(), the target size which the image should
    *                    be scaled to during decoding. It's an error to specify
--- a/image/SourceBuffer.cpp
+++ b/image/SourceBuffer.cpp
@@ -133,16 +133,23 @@ SourceBuffer::Compact()
   }
 
   // We can compact our buffer. Determine the total length.
   size_t length = 0;
   for (uint32_t i = 0 ; i < mChunks.Length() ; ++i) {
     length += mChunks[i].Length();
   }
 
+  // If our total length is zero (which means ExpectLength() got called, but no
+  // data ever actually got written) then just empty our chunk list.
+  if (MOZ_UNLIKELY(length == 0)) {
+    mChunks.Clear();
+    return NS_OK;
+  }
+
   Maybe<Chunk> newChunk = CreateChunk(length, /* aRoundUp = */ false);
   if (MOZ_UNLIKELY(!newChunk || newChunk->AllocationFailed())) {
     NS_WARNING("Failed to allocate chunk for SourceBuffer compacting - OOM?");
     return NS_OK;
   }
 
   // Copy our old chunks into the new chunk.
   for (uint32_t i = 0 ; i < mChunks.Length() ; ++i) {
deleted file mode 100644
--- a/image/decoders/icon/qt/gtkqticonsconverter.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 cin et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-
-function GtkQtIconsConverter()
-{ };
-GtkQtIconsConverter.prototype =
-{
-  classID:          Components.ID("{c0783c34-a831-40c6-8c03-98c9f74cca45}"),
-  QueryInterface: XPCOMUtils.generateQI(
-                                [Components.interfaces.nsIGtkQtIconsConverter]),
-  convert: function(icon) { return this._gtk_qt_icons_table[icon]; },
-  _gtk_qt_icons_table:
-  {
-    'about':
-    0,
-    'add':
-    0,
-    'apply':
-    44, // QStyle::SP_DialogApplyButton
-    'cancel':
-    39, // QStyle::SP_DialogCancelButton
-    'clear':
-    45, // QStyle::SP_DialogResetButton
-    'color-picker':
-    0,
-    'copy':
-    0,
-    'close':
-    43, // QStyle::SP_DialogCloseButton
-    'cut':
-    0,
-    'delete':
-    0,
-    'dialog-error':
-    0,
-    'dialog-info':
-    0,
-    'dialog-question':
-    12, // QStyle::SP_MessageBoxQuestion
-    'dialog-warning':
-    10, // QStyle::SP_MessageBoxWarning
-    'directory':
-    37, // QStyle::SP_DirIcon
-    'file':
-    24, // QStyle::SP_FileIcon
-    'find':
-    0,
-    'go-back-ltr':
-    53, // QStyle::SP_ArrowBack
-    'go-back-rtl':
-    53, // QStyle::SP_ArrowBack
-    'go-back':
-    53, // QStyle::SP_ArrowBack
-    'go-forward-ltr':
-    54, // QStyle::SP_ArrowForward
-    'go-forward-rtl':
-    54, // QStyle::SP_ArrowForward
-    'go-forward':
-    54, // QStyle::SP_ArrowForward
-    'go-up':
-    49, // QStyle::SP_ArrowUp
-    'goto-first':
-    0,
-    'goto-last':
-    0,
-    'help':
-    7, // QStyle::SP_TitleBarContextHelpButton
-    'home':
-    55, // QStyle::SP_DirHomeIcon
-    'info':
-    9, // QStyle::SP_MessageBoxInformation
-    'jump-to':
-    0,
-    'media-pause':
-    0,
-    'media-play':
-    0,
-    'network':
-    20, // QStyle::SP_DriveNetIcon
-    'no':
-    48, // QStyle::SP_DialogNoButton
-    'ok':
-    38, // QStyle::SP_DialogOkButton
-    'open':
-    21, // QStyle::SP_DirOpenIcon
-    'orientation-landscape':
-    0,
-    'orientation-portrait':
-    0,
-    'paste':
-    0,
-    'preferences':
-    34, // QStyle::SP_FileDialogContentsView
-    'print-preview':
-    0,
-    'print':
-    0,
-    'properties':
-    0,
-    'quit':
-    0,
-    'redo':
-    0,
-    'refresh':
-    58, // QStyle::SP_BrowserReload
-    'remove':
-    0,
-    'revert-to-saved':
-    0,
-    'save-as':
-    42, // QStyle::SP_DialogSaveButton
-    'save':
-    42, // QStyle::SP_DialogSaveButton
-    'select-all':
-    0,
-    'select-font':
-    0,
-    'stop':
-    59, // QStyle::SP_BrowserStop
-    'undelete':
-    0,
-    'undo':
-    0,
-    'yes':
-    47, // QStyle::SP_DialogYesButton
-    'zoom-100':
-    0,
-    'zoom-in':
-    0,
-    'zoom-out':
-    0
-  },
-}
-var components = [GtkQtIconsConverter];
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
-
deleted file mode 100644
--- a/image/decoders/icon/qt/gtkqticonsconverter.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {c0783c34-a831-40c6-8c03-98c9f74cca45} gtkqticonsconverter.js
-contract @mozilla.org/gtkqticonsconverter;1 {c0783c34-a831-40c6-8c03-98c9f74cca45}
deleted file mode 100644
--- a/image/decoders/icon/qt/moz.build
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-XPIDL_SOURCES += [
-    'nsGtkQtIconsConverter.idl',
-]
-
-XPIDL_MODULE = 'gtkqticonsconverter'
-
-SOURCES += [
-    'nsIconChannel.cpp',
-]
-
-EXTRA_COMPONENTS += [
-    'gtkqticonsconverter.manifest',
-]
-
-EXTRA_PP_COMPONENTS += [
-    'gtkqticonsconverter.js',
-]
-
-FINAL_LIBRARY = 'xul'
-
-CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
deleted file mode 100644
--- a/image/decoders/icon/qt/nsGtkQtIconsConverter.idl
+++ /dev/null
@@ -1,12 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 cin et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(c0783c34-a831-40c6-8c03-98c9f74cca45)]
-interface nsIGtkQtIconsConverter : nsISupports
-{
-  long convert(in string icon);
-};
deleted file mode 100644
--- a/image/decoders/icon/qt/nsIconChannel.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 cin et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <QIcon>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "mozilla/EndianUtils.h"
-
-#include "nsMimeTypes.h"
-#include "nsIMIMEService.h"
-
-#include "nsIStringBundle.h"
-
-#include "nsNetUtil.h"
-#include "nsNullPrincipal.h"
-#include "nsIURL.h"
-
-#include "nsIconChannel.h"
-#include "nsGtkQtIconsConverter.h"
-
-NS_IMPL_ISUPPORTS(nsIconChannel,
-                  nsIRequest,
-                  nsIChannel)
-
-static nsresult
-moz_qicon_to_channel(QImage* image, nsIURI* aURI,
-                     nsIChannel** aChannel)
-{
-  NS_ENSURE_ARG_POINTER(image);
-
-  int width = image->width();
-  int height = image->height();
-
-  NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0,
-                 NS_ERROR_UNEXPECTED);
-
-  const int n_channels = 4;
-  long int buf_size = 2 + n_channels * height * width;
-  uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size);
-  NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
-  uint8_t* out = buf;
-
-  *(out++) = width;
-  *(out++) = height;
-
-  const uchar* const pixels = image->bits();
-  int rowextra = image->bytesPerLine() - width * n_channels;
-
-  // encode the RGB data and the A data
-  const uchar* in = pixels;
-  for (int y = 0; y < height; ++y, in += rowextra) {
-    for (int x = 0; x < width; ++x) {
-      uint8_t r = *(in++);
-      uint8_t g = *(in++);
-      uint8_t b = *(in++);
-      uint8_t a = *(in++);
-#define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
-#if MOZ_LITTLE_ENDIAN
-      *(out++) = DO_PREMULTIPLY(b);
-      *(out++) = DO_PREMULTIPLY(g);
-      *(out++) = DO_PREMULTIPLY(r);
-      *(out++) = a;
-#else
-      *(out++) = a;
-      *(out++) = DO_PREMULTIPLY(r);
-      *(out++) = DO_PREMULTIPLY(g);
-      *(out++) = DO_PREMULTIPLY(b);
-#endif
-#undef DO_PREMULTIPLY
-    }
-  }
-
-  NS_ASSERTION(out == buf + buf_size, "size miscalculation");
-
-  nsresult rv;
-  nsCOMPtr<nsIStringInputStream> stream =
-    do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = stream->AdoptData((char*)buf, buf_size);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
-  // this iconChannel. Use the most restrictive security settings for the
-  // temporary loadInfo to make sure the channel can not be openend.
-  nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
-  return NS_NewInputStreamChannel(aChannel,
-                                  aURI,
-                                  stream,
-                                  nullPrincipal,
-                                  nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
-                                  nsIContentPolicy::TYPE_INTERNAL_IMAGE,
-                                  NS_LITERAL_CSTRING(IMAGE_ICON_MS));
-}
-
-nsresult
-nsIconChannel::Init(nsIURI* aURI)
-{
-
-  nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
-  NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
-
-  nsAutoCString stockIcon;
-  iconURI->GetStockIcon(stockIcon);
-
-  nsAutoCString iconSizeString;
-  iconURI->GetIconSize(iconSizeString);
-
-  uint32_t desiredImageSize;
-  iconURI->GetImageSize(&desiredImageSize);
-
-  nsAutoCString iconStateString;
-  iconURI->GetIconState(iconStateString);
-  bool disabled = iconStateString.EqualsLiteral("disabled");
-
-  // This is a workaround for
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=662299
-  // Try to find corresponding freedesktop icon and fallback to empty QIcon
-  // if failed.
-  QIcon icon = QIcon::fromTheme(QString(stockIcon.get()).replace("gtk-",
-                                                                 "edit-"));
-  QPixmap pixmap = icon.pixmap(desiredImageSize, desiredImageSize,
-                               disabled ? QIcon::Disabled : QIcon::Normal);
-
-  QImage image = pixmap.toImage();
-
-  return moz_qicon_to_channel(&image, iconURI,
-                              getter_AddRefs(mRealChannel));
-}
deleted file mode 100644
--- a/image/decoders/icon/qt/nsIconChannel.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 cin et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_image_encoders_icon_qt_nsIconChannel_h
-#define mozilla_image_encoders_icon_qt_nsIconChannel_h
-
-#include "mozilla/Attributes.h"
-
-#include "nsIChannel.h"
-#include "nsIStreamListener.h"
-#include "nsIURI.h"
-#include "nsIIconURI.h"
-#include "nsCOMPtr.h"
-
-/// This class is the gnome implementation of nsIconChannel. It basically asks
-/// qt for an icon, and creates a new channel for
-/// that file to which all calls will be proxied.
-class nsIconChannel final : public nsIChannel {
-  public:
-    NS_DECL_ISUPPORTS
-    NS_FORWARD_NSIREQUEST(mRealChannel->)
-    NS_FORWARD_NSICHANNEL(mRealChannel->)
-
-    nsIconChannel() { };
-
-    /// Called by nsIconProtocolHandler after it creates this channel.
-    /// Must be called before calling any other function on this object.
-    /// If this method fails, no other function must be called on this object.
-    nsresult Init(nsIURI* aURI);
-  private:
-    ~nsIconChannel() { };
-
-    /// The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html).
-    /// Will always be non-null after a successful Init.
-    nsCOMPtr<nsIChannel> mRealChannel;
-};
-
-#endif // mozilla_image_encoders_icon_qt_nsIconChannel_h
--- a/image/decoders/moz.build
+++ b/image/decoders/moz.build
@@ -5,18 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
 
 # The Icon Channel stuff really shouldn't live in decoders/icon, but we'll
 # fix that another time.
 if 'gtk' in toolkit:
     DIRS += ['icon/gtk', 'icon']
-elif toolkit == 'qt':
-    DIRS += ['icon/qt', 'icon']
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['icon/win', 'icon']
 
 if toolkit == 'cocoa':
     DIRS += ['icon/mac', 'icon']
 elif toolkit == 'android':
     DIRS += ['icon/android', 'icon']
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -151,38 +151,35 @@ public:
 
   virtual void WriteInternal(const char* aBuffer,
                              uint32_t aCount) override;
   virtual void BeforeFinishInternal() override;
   virtual void FinishInternal() override;
 
 private:
   friend class DecoderFactory;
-  friend class nsICODecoder;
 
   enum class State {
     FILE_HEADER,
     INFO_HEADER_SIZE,
     INFO_HEADER_REST,
     BITFIELDS,
     COLOR_TABLE,
     GAP,
     AFTER_GAP,
     PIXEL_ROW,
     RLE_SEGMENT,
     RLE_DELTA,
     RLE_ABSOLUTE
   };
 
-  // This is the constructor used by DecoderFactory.
+  // This is the constructor used for normal BMP images.
   explicit nsBMPDecoder(RasterImage* aImage);
 
-  // This is the constructor used by nsICODecoder.
-  // XXX(seth): nsICODecoder is temporarily an exception to the rule that
-  //            decoders should only be instantiated via DecoderFactory.
+  // This is the constructor used for BMP resources in ICO images.
   nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
 
   // Helper constructor called by the other two.
   nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength);
 
   int32_t AbsoluteHeight() const { return abs(mH.mHeight); }
 
   uint32_t* RowBuffer();
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -49,16 +49,17 @@ nsICODecoder::GetNumColors()
     }
   }
   return numColors;
 }
 
 nsICODecoder::nsICODecoder(RasterImage* aImage)
   : Decoder(aImage)
   , mLexer(Transition::To(ICOState::HEADER, ICOHEADERSIZE))
+  , mDoNotResume(WrapNotNull(new DoNotResume))
   , mBiggestResourceColorDepth(0)
   , mBestResourceDelta(INT_MIN)
   , mBestResourceColorDepth(0)
   , mNumIcons(0)
   , mCurrIcon(0)
   , mBPP(0)
   , mMaskRowSize(0)
   , mCurrMaskLine(0)
@@ -83,19 +84,28 @@ nsICODecoder::FinishWithErrorInternal()
 
 void
 nsICODecoder::GetFinalStateFromContainedDecoder()
 {
   if (!mContainedDecoder) {
     return;
   }
 
-  // Finish the internally used decoder.
-  mContainedDecoder->CompleteDecode();
+  MOZ_ASSERT(mContainedSourceBuffer,
+             "Should have a SourceBuffer if we have a decoder");
 
+  // Let the contained decoder finish up if necessary.
+  if (!mContainedSourceBuffer->IsComplete()) {
+    mContainedSourceBuffer->Complete(NS_OK);
+    if (NS_FAILED(mContainedDecoder->Decode(mDoNotResume))) {
+      PostDataError();
+    }
+  }
+
+  // Make our state the same as the state of the contained decoder.
   mDecodeDone = mContainedDecoder->GetDecodeDone();
   mDataError = mDataError || mContainedDecoder->HasDataError();
   mFailCode = NS_SUCCEEDED(mFailCode) ? mContainedDecoder->GetDecoderError()
                                       : mFailCode;
   mDecodeAborted = mContainedDecoder->WasAborted();
   mProgress |= mContainedDecoder->TakeProgress();
   mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
   mCurrentFrame = mContainedDecoder->GetCurrentFrameRef();
@@ -286,24 +296,22 @@ LexerTransition<ICOState>
 nsICODecoder::SniffResource(const char* aData)
 {
   // We use the first PNGSIGNATURESIZE bytes to determine whether this resource
   // is a PNG or a BMP.
   bool isPNG = !memcmp(aData, nsPNGDecoder::pngSignatureBytes,
                        PNGSIGNATURESIZE);
   if (isPNG) {
     // Create a PNG decoder which will do the rest of the work for us.
-    mContainedDecoder = new nsPNGDecoder(mImage);
-    mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
-    mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
-    mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
-    if (mDownscaler) {
-      mContainedDecoder->SetTargetSize(mDownscaler->TargetSize());
-    }
-    mContainedDecoder->Init();
+    mContainedSourceBuffer = new SourceBuffer();
+    mContainedSourceBuffer->ExpectLength(mDirEntry.mBytesInRes);
+    mContainedDecoder =
+      DecoderFactory::CreateDecoderForICOResource(DecoderType::PNG,
+                                                  WrapNotNull(mContainedSourceBuffer),
+                                                  WrapNotNull(this));
 
     if (!WriteToContainedDecoder(aData, PNGSIGNATURESIZE)) {
       return Transition::TerminateFailure();
     }
 
     if (mDirEntry.mBytesInRes <= PNGSIGNATURESIZE) {
       return Transition::TerminateFailure();
     }
@@ -366,25 +374,25 @@ nsICODecoder::ReadBIH(const char* aData)
     if (numColors == (uint16_t)-1) {
       return Transition::TerminateFailure();
     }
     dataOffset += 4 * numColors;
   }
 
   // Create a BMP decoder which will do most of the work for us; the exception
   // is the AND mask, which isn't present in standalone BMPs.
-  RefPtr<nsBMPDecoder> bmpDecoder = new nsBMPDecoder(mImage, dataOffset);
-  mContainedDecoder = bmpDecoder;
-  mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
-  mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
-  mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
-  if (mDownscaler) {
-    mContainedDecoder->SetTargetSize(mDownscaler->TargetSize());
-  }
-  mContainedDecoder->Init();
+  mContainedSourceBuffer = new SourceBuffer();
+  mContainedSourceBuffer->ExpectLength(mDirEntry.mBytesInRes);
+  mContainedDecoder =
+    DecoderFactory::CreateDecoderForICOResource(DecoderType::BMP,
+                                                WrapNotNull(mContainedSourceBuffer),
+                                                WrapNotNull(this),
+                                                Some(dataOffset));
+  RefPtr<nsBMPDecoder> bmpDecoder =
+    static_cast<nsBMPDecoder*>(mContainedDecoder.get());
 
   // Verify that the BIH width and height values match the ICO directory entry,
   // and fix the BIH height value to compensate for the fact that the underlying
   // BMP decoder doesn't know about AND masks.
   if (!CheckAndFixBitmapSize(reinterpret_cast<int8_t*>(mBIHraw))) {
     return Transition::TerminateFailure();
   }
 
@@ -634,22 +642,38 @@ nsICODecoder::WriteInternal(const char* 
   if (terminalState == Some(TerminalState::FAILURE)) {
     PostDataError();
   }
 }
 
 bool
 nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount)
 {
-  mContainedDecoder->Write(aBuffer, aCount);
+  MOZ_ASSERT(mContainedDecoder);
+  MOZ_ASSERT(mContainedSourceBuffer);
+
+  // Append the provided data to the SourceBuffer that the contained decoder is
+  // reading from.
+  mContainedSourceBuffer->Append(aBuffer, aCount);
+
+  // Write to the contained decoder. If we run out of data, the ICO decoder will
+  // get resumed when there's more data available, as usual, so we don't need
+  // the contained decoder to get resumed too. To avoid that, we provide an
+  // IResumable which just does nothing.
+  if (NS_FAILED(mContainedDecoder->Decode(mDoNotResume))) {
+    PostDataError();
+  }
+
+  // Make our state the same as the state of the contained decoder.
   mProgress |= mContainedDecoder->TakeProgress();
   mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
   if (mContainedDecoder->HasDataError()) {
     PostDataError();
   }
   if (mContainedDecoder->HasDecoderError()) {
     PostDecoderError(mContainedDecoder->GetDecoderError());
   }
+
   return !HasError();
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/decoders/nsICODecoder.h
+++ b/image/decoders/nsICODecoder.h
@@ -5,20 +5,21 @@
 
 
 #ifndef mozilla_image_decoders_nsICODecoder_h
 #define mozilla_image_decoders_nsICODecoder_h
 
 #include "StreamingLexer.h"
 #include "Decoder.h"
 #include "imgFrame.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/NotNull.h"
 #include "nsBMPDecoder.h"
 #include "nsPNGDecoder.h"
 #include "ICOFileHeaders.h"
-#include "mozilla/gfx/2D.h"
 
 namespace mozilla {
 namespace image {
 
 class RasterImage;
 
 enum class ICOState
 {
@@ -105,18 +106,32 @@ private:
   LexerTransition<ICOState> ReadPNG(const char* aData, uint32_t aLen);
   LexerTransition<ICOState> ReadBIH(const char* aData);
   LexerTransition<ICOState> ReadBMP(const char* aData, uint32_t aLen);
   LexerTransition<ICOState> PrepareForMask();
   LexerTransition<ICOState> ReadMaskRow(const char* aData);
   LexerTransition<ICOState> FinishMask();
   LexerTransition<ICOState> FinishResource();
 
+  // A helper implementation of IResumable which just does nothing; see
+  // WriteToContainedDecoder() for more details.
+  class DoNotResume final : public IResumable
+  {
+  public:
+    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DoNotResume, override)
+    void Resume() override { }
+
+  private:
+    virtual ~DoNotResume() { }
+  };
+
   StreamingLexer<ICOState, 32> mLexer; // The lexer.
   RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
+  RefPtr<SourceBuffer> mContainedSourceBuffer;  // SourceBuffer for mContainedDecoder.
+  NotNull<RefPtr<IResumable>> mDoNotResume;  // IResumable helper for SourceBuffer.
   UniquePtr<uint8_t[]> mMaskBuffer;    // A temporary buffer for the alpha mask.
   char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
   IconDirEntry mDirEntry;              // The dir entry for the selected resource.
   gfx::IntSize mBiggestResourceSize;   // Used to select the intrinsic size.
   gfx::IntSize mBiggestResourceHotSpot; // Used to select the intrinsic size.
   uint16_t mBiggestResourceColorDepth; // Used to select the intrinsic size.
   int32_t mBestResourceDelta;          // Used to select the best resource.
   uint16_t mBestResourceColorDepth;    // Used to select the best resource.
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -993,11 +993,43 @@ nsPNGDecoder::warning_callback(png_struc
 }
 
 Telemetry::ID
 nsPNGDecoder::SpeedHistogram()
 {
   return Telemetry::IMAGE_DECODE_SPEED_PNG;
 }
 
+bool
+nsPNGDecoder::IsValidICO() const
+{
+  // Only 32-bit RGBA PNGs are valid ICO resources; see here:
+  //   http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
+
+  // If there are errors in the call to png_get_IHDR, the error_callback in
+  // nsPNGDecoder.cpp is called.  In this error callback we do a longjmp, so
+  // we need to save the jump buffer here. Oterwise we'll end up without a
+  // proper callstack.
+  if (setjmp(png_jmpbuf(mPNG))) {
+    // We got here from a longjmp call indirectly from png_get_IHDR
+    return false;
+  }
+
+  png_uint_32
+      png_width,  // Unused
+      png_height; // Unused
+
+  int png_bit_depth,
+      png_color_type;
+
+  if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
+                   &png_color_type, nullptr, nullptr, nullptr)) {
+
+    return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+             png_color_type == PNG_COLOR_TYPE_RGB) &&
+            png_bit_depth == 8);
+  } else {
+    return false;
+  }
+}
 
 } // namespace image
 } // namespace mozilla
--- a/image/decoders/nsPNGDecoder.h
+++ b/image/decoders/nsPNGDecoder.h
@@ -21,22 +21,23 @@ class nsPNGDecoder : public Decoder
 {
 public:
   virtual ~nsPNGDecoder();
 
   virtual void InitInternal() override;
   virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
   virtual Telemetry::ID SpeedHistogram() override;
 
+  /// @return true if this PNG is a valid ICO resource.
+  bool IsValidICO() const;
+
 private:
   friend class DecoderFactory;
-  friend class nsICODecoder;
 
   // Decoders should only be instantiated via DecoderFactory.
-  // XXX(seth): nsICODecoder is temporarily an exception to this rule.
   explicit nsPNGDecoder(RasterImage* aImage);
 
   nsresult CreateFrame(gfx::SurfaceFormat aFormat,
                        const gfx::IntRect& aFrameRect,
                        bool aIsInterlaced);
   void EndImageFrame();
 
   enum class TransparencyType
@@ -49,47 +50,16 @@ private:
   TransparencyType GetTransparencyType(gfx::SurfaceFormat aFormat,
                                        const gfx::IntRect& aFrameRect);
   void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
 
   void PostInvalidationIfNeeded();
 
   void WriteRow(uint8_t* aRow);
 
-  // Check if PNG is valid ICO (32bpp RGBA)
-  // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
-  bool IsValidICO() const
-  {
-    // If there are errors in the call to png_get_IHDR, the error_callback in
-    // nsPNGDecoder.cpp is called.  In this error callback we do a longjmp, so
-    // we need to save the jump buffer here. Oterwise we'll end up without a
-    // proper callstack.
-    if (setjmp(png_jmpbuf(mPNG))) {
-      // We got here from a longjmp call indirectly from png_get_IHDR
-      return false;
-    }
-
-    png_uint_32
-        png_width,  // Unused
-        png_height; // Unused
-
-    int png_bit_depth,
-        png_color_type;
-
-    if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
-                     &png_color_type, nullptr, nullptr, nullptr)) {
-
-      return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
-               png_color_type == PNG_COLOR_TYPE_RGB) &&
-              png_bit_depth == 8);
-    } else {
-      return false;
-    }
-  }
-
   enum class State
   {
     PNG_DATA,
     FINISHED_PNG_DATA
   };
 
   LexerTransition<State> ReadPNGData(const char* aData, size_t aLength);
   LexerTransition<State> FinishedPNGData();
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -61,11 +61,8 @@ RESOURCE_FILES += [
 ]
 
 GENERATED_FILES += [
     'langGroups.properties.h',
 ]
 langgroups = GENERATED_FILES['langGroups.properties.h']
 langgroups.script = 'props2arrays.py'
 langgroups.inputs = ['langGroups.properties']
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
--- a/intl/unicharutil/tables/moz.build
+++ b/intl/unicharutil/tables/moz.build
@@ -5,12 +5,8 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 RESOURCE_FILES.entityTables = [
     'html40Latin1.properties',
     'html40Special.properties',
     'html40Symbols.properties',
     'mathml20.properties',
 ]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    CFLAGS += CONFIG['MOZ_QT_CFLAGS']
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -134,21 +134,16 @@ if os_linux:
         if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
             DEFINES['HAVE_ANDROID_OS'] = True
 
 if os_bsd or os_linux:
     if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
         SOURCES += [
             'src/base/message_pump_glib.cc',
         ]
-    if CONFIG['MOZ_ENABLE_QT']:
-        SOURCES += [
-            '!moc_message_pump_qt.cc',
-            'src/base/message_pump_qt.cc',
-        ]
 
 ost = CONFIG['OS_TEST']
 if '86' not in ost and 'arm' not in ost and 'aarch64' != ost and 'mips' not in ost:
     SOURCES += [
         'src/base/atomicops_internals_mutex.cc',
     ]
 
 CXXFLAGS += CONFIG['TK_CFLAGS']
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -573,16 +573,21 @@ class Base {
     // This must always return Concrete<T>::concreteTypeName; we use that
     // pointer as a tag for this particular referent type.
     virtual const char16_t* typeName() const = 0;
 
     // Return the size of this node, in bytes. Include any structures that this
     // node owns exclusively that are not exposed as their own ubi::Nodes.
     // |mallocSizeOf| should be a malloc block sizing function; see
     // |mfbt/MemoryReporting.h|.
+    //
+    // Because we can use |JS::ubi::Node|s backed by a snapshot that was taken
+    // on a 64-bit platform when we are currently on a 32-bit platform, we
+    // cannot rely on |size_t| for node sizes. Instead, |Size| is uint64_t on
+    // all platforms.
     using Size = uint64_t;
     virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; }
 
     // Return an EdgeRange that initially contains all the referent's outgoing
     // edges. The caller takes ownership of the EdgeRange.
     //
     // If wantNames is true, compute names for edges. Doing so can be expensive
     // in time and memory.
@@ -636,38 +641,38 @@ class Base {
     virtual const char* scriptFilename() const { return nullptr; }
 
   private:
     Base(const Base& rhs) = delete;
     Base& operator=(const Base& rhs) = delete;
 };
 
 // A traits template with a specialization for each referent type that
-// ubi::Node supports. The specialization must be the concrete subclass of
-// Base that represents a pointer to the referent type. It must also
-// include the members described here.
+// ubi::Node supports. The specialization must be the concrete subclass of Base
+// that represents a pointer to the referent type. It must include these
+// members:
+//
+//    // The specific char16_t array returned by Concrete<T>::typeName().
+//    static const char16_t concreteTypeName[];
+//
+//    // Construct an instance of this concrete class in |storage| referring
+//    // to |referent|. Implementations typically use a placement 'new'.
+//    //
+//    // In some cases, |referent| will contain dynamic type information that
+//    // identifies it a some more specific subclass of |Referent|. For
+//    // example, when |Referent| is |JSObject|, then |referent->getClass()|
+//    // could tell us that it's actually a JSFunction. Similarly, if
+//    // |Referent| is |nsISupports|, we would like a ubi::Node that knows its
+//    // final implementation type.
+//    //
+//    // So we delegate the actual construction to this specialization, which
+//    // knows Referent's details.
+//    static void construct(void* storage, Referent* referent);
 template<typename Referent>
-struct Concrete {
-    // The specific char16_t array returned by Concrete<T>::typeName.
-    static const char16_t concreteTypeName[];
-
-    // Construct an instance of this concrete class in |storage| referring
-    // to |referent|. Implementations typically use a placement 'new'.
-    //
-    // In some cases, |referent| will contain dynamic type information that
-    // identifies it a some more specific subclass of |Referent|. For example,
-    // when |Referent| is |JSObject|, then |referent->getClass()| could tell us
-    // that it's actually a JSFunction. Similarly, if |Referent| is
-    // |nsISupports|, we would like a ubi::Node that knows its final
-    // implementation type.
-    //
-    // So, we delegate the actual construction to this specialization, which
-    // knows Referent's details.
-    static void construct(void* storage, Referent* referent);
-};
+class Concrete;
 
 // A container for a Base instance; all members simply forward to the contained
 // instance.  This container allows us to pass ubi::Node instances by value.
 class Node {
     // Storage in which we allocate Base subclasses.
     mozilla::AlignedStorage2<Base> storage;
     Base* base() { return storage.addr(); }
     const Base* base() const { return storage.addr(); }
@@ -989,43 +994,42 @@ class MOZ_STACK_CLASS RootList {
     // edgeName.
     MOZ_MUST_USE bool addRoot(Node node, const char16_t* edgeName = nullptr);
 };
 
 
 /*** Concrete classes for ubi::Node referent types ************************************************/
 
 template<>
-struct Concrete<RootList> : public Base {
-    js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
-    const char16_t* typeName() const override { return concreteTypeName; }
-
+class Concrete<RootList> : public Base {
   protected:
     explicit Concrete(RootList* ptr) : Base(ptr) { }
     RootList& get() const { return *static_cast<RootList*>(ptr); }
 
   public:
+    static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); }
+
+    js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
     static const char16_t concreteTypeName[];
-    static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); }
 };
 
 // A reusable ubi::Concrete specialization base class for types supported by
 // JS::TraceChildren.
 template<typename Referent>
 class TracerConcrete : public Base {
-    const char16_t* typeName() const override { return concreteTypeName; }
     js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
     JS::Zone* zone() const override;
 
   protected:
     explicit TracerConcrete(Referent* ptr) : Base(ptr) { }
     Referent& get() const { return *static_cast<Referent*>(ptr); }
 
   public:
-    static const char16_t concreteTypeName[];
     static void construct(void* storage, Referent* ptr) { new (storage) TracerConcrete(ptr); }
 };
 
 // For JS::TraceChildren-based types that have a 'compartment' method.
 template<typename Referent>
 class TracerConcreteWithCompartment : public TracerConcrete<Referent> {
     typedef TracerConcrete<Referent> TracerBase;
     JSCompartment* compartment() const override;
@@ -1037,90 +1041,103 @@ class TracerConcreteWithCompartment : pu
     static void construct(void* storage, Referent* ptr) {
         new (storage) TracerConcreteWithCompartment(ptr);
     }
 };
 
 // Define specializations for some commonly-used public JSAPI types.
 // These can use the generic templates above.
 template<>
-struct Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> {
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-
+class Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> {
   protected:
     explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { }
 
   public:
     static void construct(void* storage, JS::Symbol* ptr) {
         new (storage) Concrete(ptr);
     }
+
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
-template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
-    CoarseType coarseType() const final { return CoarseType::Script; }
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-    const char* scriptFilename() const final;
-
+template<>
+class Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
   protected:
     explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { }
 
   public:
     static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); }
+
+    CoarseType coarseType() const final { return CoarseType::Script; }
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    const char* scriptFilename() const final;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 // The JSObject specialization.
 template<>
 class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
+  protected:
+    explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { }
+
+  public:
+    static void construct(void* storage, JSObject* ptr) {
+        new (storage) Concrete(ptr);
+    }
+
     const char* jsObjectClassName() const override;
     MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName)
         const override;
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
 
     bool hasAllocationStack() const override;
     StackFrame allocationStack() const override;
 
     CoarseType coarseType() const final { return CoarseType::Object; }
 
-  protected:
-    explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { }
-
-  public:
-    static void construct(void* storage, JSObject* ptr) {
-        new (storage) Concrete(ptr);
-    }
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 // For JSString, we extend the generic template with a 'size' implementation.
-template<> struct Concrete<JSString> : TracerConcrete<JSString> {
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-
-    CoarseType coarseType() const final { return CoarseType::String; }
-
+template<>
+class Concrete<JSString> : TracerConcrete<JSString> {
   protected:
     explicit Concrete(JSString *ptr) : TracerConcrete<JSString>(ptr) { }
 
   public:
     static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); }
+
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+    CoarseType coarseType() const final { return CoarseType::String; }
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 // The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts.
 template<>
 class Concrete<void> : public Base {
     const char16_t* typeName() const override;
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
     js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
     JS::Zone* zone() const override;
     JSCompartment* compartment() const override;
     CoarseType coarseType() const final;
 
     explicit Concrete(void* ptr) : Base(ptr) { }
 
   public:
     static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); }
-    static const char16_t concreteTypeName[];
 };
 
 
 } // namespace ubi
 } // namespace JS
 
 namespace js {
 
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -541,17 +541,17 @@ JSVAL_TO_OBJECT_IMPL(jsval_layout l)
 {
     return l.s.payload.obj;
 }
 
 static inline jsval_layout
 OBJECT_TO_JSVAL_IMPL(JSObject* obj)
 {
     jsval_layout l;
-    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42);
+    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x48);
     l.s.tag = JSVAL_TAG_OBJECT;
     l.s.payload.obj = obj;
     return l;
 }
 
 static inline bool
 JSVAL_IS_NULL_IMPL(jsval_layout l)
 {
@@ -823,17 +823,17 @@ JSVAL_TO_OBJECT_IMPL(jsval_layout l)
     return (JSObject*)ptrBits;
 }
 
 static inline jsval_layout
 OBJECT_TO_JSVAL_IMPL(JSObject* obj)
 {
     jsval_layout l;
     uint64_t objBits = (uint64_t)obj;
-    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42);
+    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x48);
     MOZ_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
     l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;
     return l;
 }
 
 static inline bool
 JSVAL_IS_NULL_IMPL(jsval_layout l)
 {
@@ -1547,17 +1547,17 @@ ObjectValue(JSObject& obj)
     v.setObject(obj);
     return v;
 }
 
 static inline Value
 ObjectValueCrashOnTouch()
 {
     Value v;
-    v.setObject(*reinterpret_cast<JSObject*>(0x42));
+    v.setObject(*reinterpret_cast<JSObject*>(0x48));
     return v;
 }
 
 static inline Value
 MagicValue(JSWhyMagic why)
 {
     Value v;
     v.setMagic(why);
--- a/js/src/jit/ExecutableAllocator.h
+++ b/js/src/jit/ExecutableAllocator.h
@@ -291,16 +291,21 @@ class ExecutableAllocator
             "add     r7, r7, #0x2\n"
             "mov     r2, #0x0\n"
             "svc     0x0\n"
             "pop     {r7}\n"
             :
             : "r" (code), "r" (reinterpret_cast<char*>(code) + size)
             : "r0", "r1", "r2");
     }
+#elif defined(JS_CODEGEN_ARM64) && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
+    static void cacheFlush(void* code, size_t size)
+    {
+	__clear_cache(code, (void *)((size_t)code + size));
+    }
 #elif JS_CPU_SPARC
     static void cacheFlush(void* code, size_t size)
     {
         sync_instruction_memory((caddr_t)code, size);
     }
 #endif
 
   private:
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -3328,17 +3328,17 @@ PerThreadData::setAutoFlushICache(AutoFl
 // Set the range for the merging of flushes.  The flushing is deferred until the end of
 // the AutoFlushICache context.  Subsequent flushing within this range will is also
 // deferred.  This is only expected to be defined once for each AutoFlushICache
 // context.  It assumes the range will be flushed is required to be within an
 // AutoFlushICache context.
 void
 AutoFlushICache::setRange(uintptr_t start, size_t len)
 {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     AutoFlushICache* afc = TlsPerThreadData.get()->PerThreadData::autoFlushICache();
     MOZ_ASSERT(afc);
     MOZ_ASSERT(!afc->start_);
     JitSpewCont(JitSpew_CacheFlush, "(%x %x):", start, len);
 
     uintptr_t stop = start + len;
     afc->start_ = start;
     afc->stop_ = stop;
@@ -3415,39 +3415,39 @@ AutoFlushICache::setInhibit()
 // code.  Flushing within the set code range can be inhibited within the AutoFlushICache
 // dynamic context by setting an inhibit flag.
 //
 // The JS compiler can be re-entered while within an AutoFlushICache dynamic context and
 // it is assumed that code being assembled or patched is not executed before the exit of
 // the respective AutoFlushICache dynamic context.
 //
 AutoFlushICache::AutoFlushICache(const char* nonce, bool inhibit)
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
   : start_(0),
     stop_(0),
     name_(nonce),
     inhibit_(inhibit)
 #endif
 {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     PerThreadData* pt = TlsPerThreadData.get();
     AutoFlushICache* afc = pt->PerThreadData::autoFlushICache();
     if (afc)
         JitSpew(JitSpew_CacheFlush, "<%s,%s%s ", nonce, afc->name_, inhibit ? " I" : "");
     else
         JitSpewCont(JitSpew_CacheFlush, "<%s%s ", nonce, inhibit ? " I" : "");
 
     prev_ = afc;
     pt->PerThreadData::setAutoFlushICache(this);
 #endif
 }
 
 AutoFlushICache::~AutoFlushICache()
 {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     PerThreadData* pt = TlsPerThreadData.get();
     MOZ_ASSERT(pt->PerThreadData::autoFlushICache() == this);
 
     if (!inhibit_ && start_)
         ExecutableAllocator::cacheFlush((void*)start_, size_t(stop_ - start_));
 
     JitSpewCont(JitSpew_CacheFlush, "%s%s>", name_, start_ ? "" : " U");
     JitSpewFin(JitSpew_CacheFlush);
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -746,17 +746,17 @@ struct IonScriptCounts
     }
 };
 
 struct VMFunction;
 
 struct AutoFlushICache
 {
   private:
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     uintptr_t start_;
     uintptr_t stop_;
     const char* name_;
     bool inhibit_;
     AutoFlushICache* prev_;
 #endif
 
   public:
@@ -783,31 +783,34 @@ IsMarked(const jit::VMFunction*)
 
 } // namespace js
 
 // JS::ubi::Nodes can point to js::jit::JitCode instances; they're js::gc::Cell
 // instances with no associated compartment.
 namespace JS {
 namespace ubi {
 template<>
-struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
+class Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
+  protected:
+    explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { }
+
+  public:
+    static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
+
     CoarseType coarseType() const final { return CoarseType::Script; }
 
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override {
         Size size = js::gc::Arena::thingSize(get().asTenured().getAllocKind());
         size += get().bufferSize();
         size += get().headerSize();
         return size;
     }
 
-  protected:
-    explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { }
-
-  public:
-    static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 } // namespace ubi
 
 template <>
 struct DeletePolicy<js::jit::IonScript>
 {
     explicit DeletePolicy(JSRuntime* rt) : rt_(rt) {}
--- a/js/src/jit/arm64/Trampoline-arm64.cpp
+++ b/js/src/jit/arm64/Trampoline-arm64.cpp
@@ -267,16 +267,17 @@ JitRuntime::generateEnterJIT(JSContext* 
 
     // Restore old frame pointer.
     masm.pop(r30, r29);
 
     // Return using the value popped into x30.
     masm.abiret();
 
     Linker linker(masm);
+    AutoFlushICache afc("EnterJIT");
     JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "EnterJIT");
 #endif
 
     return code;
 }
@@ -308,16 +309,17 @@ JitRuntime::generateInvalidator(JSContex
     masm.Add(masm.GetStackPointer64(), masm.GetStackPointer64(),
              Operand(sizeof(InvalidationBailoutStack)));
     masm.syncStackPtr();
 
     JitCode* bailoutTail = cx->runtime()->jitRuntime()->getBailoutTail();
     masm.branch(bailoutTail);
 
     Linker linker(masm);
+    AutoFlushICache afc("Invalidator");
     return linker.newCode<NoGC>(cx, OTHER_CODE);
 }
 
 JitCode*
 JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
 {
     MacroAssembler masm;
 
@@ -415,16 +417,17 @@ JitRuntime::generateArgumentsRectifier(J
     // add that onto the stack pointer.
     masm.Add(masm.GetStackPointer64(), masm.GetStackPointer64(),
              Operand(x4, vixl::LSR, FRAMESIZE_SHIFT));
 
     // Pop the return address from earlier and branch.
     masm.ret();
 
     Linker linker(masm);
+    AutoFlushICache afc("ArgumentsRectifier");
     JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
 
     if (returnAddrOut)
         *returnAddrOut = (void*) (code->raw() + returnOffset);
 
     return code;
 }
 
@@ -522,30 +525,32 @@ GenerateBailoutThunk(JSContext* cx, Macr
 
 JitCode*
 JitRuntime::generateBailoutTable(JSContext* cx, uint32_t frameClass)
 {
     // FIXME: Implement.
     MacroAssembler masm;
     masm.breakpoint();
     Linker linker(masm);
+    AutoFlushICache afc("BailoutTable");
     return linker.newCode<NoGC>(cx, OTHER_CODE);
 }
 
 JitCode*
 JitRuntime::generateBailoutHandler(JSContext* cx)
 {
     MacroAssembler masm(cx);
     GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutHandler");
 #endif
 
     Linker linker(masm);
+    AutoFlushICache afc("BailoutHandler");
     return linker.newCode<NoGC>(cx, OTHER_CODE);
 }
 
 JitCode*
 JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
 {
     MOZ_ASSERT(functionWrappers_);
     MOZ_ASSERT(functionWrappers_->initialized());
@@ -722,16 +727,17 @@ JitRuntime::generateVMWrapper(JSContext*
     }
 
     masm.leaveExitFrame();
     masm.retn(Imm32(sizeof(ExitFrameLayout) +
               f.explicitStackSlots() * sizeof(void*) +
               f.extraValuesToPop * sizeof(Value)));
 
     Linker linker(masm);
+    AutoFlushICache afc("VMWrapper");
     JitCode* wrapper = linker.newCode<NoGC>(cx, OTHER_CODE);
     if (!wrapper)
         return nullptr;
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(wrapper, "VMWrapper");
 #endif
 
@@ -765,16 +771,17 @@ JitRuntime::generatePreBarrier(JSContext
     masm.callWithABI(IonMarkFunction(type));
 
     // Pop the volatile regs and restore LR.
     masm.PopRegsInMask(regs);
 
     masm.abiret();
 
     Linker linker(masm);
+    AutoFlushICache afc("PreBarrier");
     return linker.newCode<NoGC>(cx, OTHER_CODE);
 }
 
 typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
 static const VMFunction HandleDebugTrapInfo = FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap);
 
 JitCode*
 JitRuntime::generateDebugTrapHandler(JSContext* cx)
@@ -819,16 +826,17 @@ JitRuntime::generateDebugTrapHandler(JSC
                    JSReturnOperand);
     masm.Mov(masm.GetStackPointer64(), BaselineFrameReg64);
 
     masm.pop(BaselineFrameReg, lr);
     masm.syncStackPtr();
     masm.abiret();
 
     Linker linker(masm);
+    AutoFlushICache afc("DebugTrapHandler");
     JitCode* codeDbg = linker.newCode<NoGC>(cx, OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(codeDbg, "DebugTrapHandler");
 #endif
 
     return codeDbg;
 }
@@ -836,16 +844,17 @@ JitRuntime::generateDebugTrapHandler(JSC
 JitCode*
 JitRuntime::generateExceptionTailStub(JSContext* cx, void* handler)
 {
     MacroAssembler masm(cx);
 
     masm.handleFailureWithHandlerTail(handler);
 
     Linker linker(masm);
+    AutoFlushICache afc("ExceptionTailStub");
     JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "ExceptionTailStub");
 #endif
 
     return code;
 }
@@ -853,16 +862,17 @@ JitRuntime::generateExceptionTailStub(JS
 JitCode*
 JitRuntime::generateBailoutTailStub(JSContext* cx)
 {
     MacroAssembler masm(cx);
 
     masm.generateBailoutTail(r1, r2);
 
     Linker linker(masm);
+    AutoFlushICache afc("BailoutTailStub");
     JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutTailStub");
 #endif
 
     return code;
 }
--- a/js/src/jsapi-tests/testUbiNode.cpp
+++ b/js/src/jsapi-tests/testUbiNode.cpp
@@ -36,34 +36,35 @@ struct FakeNode
         return edges.emplaceBack(nullptr, node);
     }
 };
 
 namespace JS {
 namespace ubi {
 
 template<>
-struct Concrete<FakeNode> : public Base
+class Concrete<FakeNode> : public Base
 {
-    static const char16_t concreteTypeName[];
-    const char16_t* typeName() const override { return concreteTypeName; }
+  protected:
+    explicit Concrete(FakeNode* ptr) : Base(ptr) { }
+    FakeNode& get() const { return *static_cast<FakeNode*>(ptr); }
+
+  public:
+    static void construct(void* storage, FakeNode* ptr) { new (storage) Concrete(ptr); }
 
     UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override {
         return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
     }
 
     Node::Size size(mozilla::MallocSizeOf) const override {
         return 1;
     }
 
-    static void construct(void* storage, FakeNode* ptr) { new (storage) Concrete(ptr); }
-
-  protected:
-    explicit Concrete(FakeNode* ptr) : Base(ptr) { }
-    FakeNode& get() const { return *static_cast<FakeNode*>(ptr); }
+    static const char16_t concreteTypeName[];
+    const char16_t* typeName() const override { return concreteTypeName; }
 };
 
 const char16_t Concrete<FakeNode>::concreteTypeName[] = MOZ_UTF16("FakeNode");
 
 } // namespace ubi
 } // namespace JS
 
 // ubi::Node::zone works
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1831,25 +1831,29 @@ JS_NewGlobalObject(JSContext* cx, const 
     return GlobalObject::new_(cx, Valueify(clasp), principals, hookOption, options);
 }
 
 JS_PUBLIC_API(void)
 JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global)
 {
     MOZ_ASSERT(global->is<GlobalObject>());
 
-    // Off thread parsing and compilation tasks create a dummy global which is then
-    // merged back into the host compartment. Since it used to be a global, it will still
-    // have this trace hook, but it does not have a meaning relative to its new compartment.
-    // We can safely skip it.
-    if (!global->isOwnGlobal())
+    // Off thread parsing and compilation tasks create a dummy global which is
+    // then merged back into the host compartment. Since it used to be a
+    // global, it will still have this trace hook, but it does not have a
+    // meaning relative to its new compartment. We can safely skip it.
+    //
+    // Similarly, if we GC when creating the global, we may not have set that
+    // global's compartment's global pointer yet. In this case, the compartment
+    // will not yet contain anything that needs to be traced.
+    if (!global->isOwnGlobal(trc))
         return;
 
-    // Trace the compartment for any GC things that should only stick around if we know the
-    // compartment is live.
+    // Trace the compartment for any GC things that should only stick around if
+    // we know the compartment is live.
     global->compartment()->trace(trc);
 
     if (JSTraceOp trace = global->compartment()->creationOptions().getTrace())
         trace(trc, global);
 }
 
 JS_PUBLIC_API(void)
 JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global)
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3826,18 +3826,17 @@ JS::ubi::Concrete<JSObject>::size(mozill
     if (!obj.isTenured())
         return obj.sizeOfIncludingThisInNursery();
 
     JS::ClassInfo info;
     obj.addSizeOfExcludingThis(mallocSizeOf, &info);
     return obj.tenuredSizeOfThis() + info.sizeOfAllThings();
 }
 
-template<> const char16_t JS::ubi::TracerConcrete<JSObject>::concreteTypeName[] =
-    MOZ_UTF16("JSObject");
+const char16_t JS::ubi::Concrete<JSObject>::concreteTypeName[] = MOZ_UTF16("JSObject");
 
 void
 JSObject::traceChildren(JSTracer* trc)
 {
     TraceEdge(trc, &group_, "group");
 
     const Class* clasp = group_->clasp();
     if (clasp->isNative()) {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -461,17 +461,30 @@ class JSObject : public js::gc::Cell
     /*
      * Get the enclosing scope of an object. When called on non-scope object,
      * this will just be the global (the name "enclosing scope" still applies
      * in this situation because non-scope objects can be on the scope chain).
      */
     inline JSObject* enclosingScope() const;
 
     inline js::GlobalObject& global() const;
-    inline bool isOwnGlobal() const;
+
+    // In some rare cases the global object's compartment's global may not be
+    // the same global object. For this reason, we need to take extra care when
+    // tracing.
+    //
+    // These cases are:
+    //  1) The off-thread parsing task uses a dummy global since it cannot
+    //     share with the actual global being used concurrently on the main
+    //     thread.
+    //  2) A GC may occur when creating the GlobalObject, in which case the
+    //     compartment global pointer may not yet be set. In this case there is
+    //     nothing interesting to trace in the compartment.
+    inline bool isOwnGlobal(JSTracer*) const;
+    inline js::GlobalObject* globalForTracing(JSTracer*) const;
 
     /*
      * ES5 meta-object properties and operations.
      */
 
   public:
     // Indicates whether a non-proxy is extensible.  Don't call on proxies!
     // This method really shouldn't exist -- but there are a few internal
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -416,20 +416,26 @@ JSObject::global() const
      * The global is read-barriered so that it is kept live by access through
      * the JSCompartment. When accessed through a JSObject, however, the global
      * will be already be kept live by the black JSObject's parent pointer, so
      * does not need to be read-barriered.
      */
     return *compartment()->unsafeUnbarrieredMaybeGlobal();
 }
 
+inline js::GlobalObject*
+JSObject::globalForTracing(JSTracer*) const
+{
+    return compartment()->unsafeUnbarrieredMaybeGlobal();
+}
+
 inline bool
-JSObject::isOwnGlobal() const
+JSObject::isOwnGlobal(JSTracer* trc) const
 {
-    return &global() == this;
+    return globalForTracing(trc) == this;
 }
 
 inline bool
 JSObject::hasAllFlags(js::BaseShape::Flag flags) const
 {
     MOZ_ASSERT(flags);
     if (js::Shape* shape = maybeShape())
         return shape->hasAllObjectFlags(flags);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3558,17 +3558,19 @@ js::detail::CopyScript(JSContext* cx, Ha
 
     /* Now that all fallible allocation is complete, do the copying. */
 
     dst->bindings = bindings;
 
     /* This assignment must occur before all the Rebase calls. */
     dst->data = data.forget();
     dst->dataSize_ = size;
-    memcpy(dst->data, src->data, size);
+    MOZ_ASSERT(bool(dst->data) == bool(src->data));
+    if (dst->data)
+        memcpy(dst->data, src->data, size);
 
     /* Script filenames, bytecodes and atoms are runtime-wide. */
     dst->setCode(src->code());
     dst->atoms = src->atoms;
 
     dst->setLength(src->length());
     dst->lineno_ = src->lineno();
     dst->mainOffset_ = src->mainOffset();
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -2547,23 +2547,26 @@ CloneGlobalScript(JSContext* cx, Handle<
 
 } /* namespace js */
 
 // JS::ubi::Nodes can point to js::LazyScripts; they're js::gc::Cell instances
 // with no associated compartment.
 namespace JS {
 namespace ubi {
 template<>
-struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> {
-    CoarseType coarseType() const final { return CoarseType::Script; }
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-    const char* scriptFilename() const final;
-
+class Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> {
   protected:
     explicit Concrete(js::LazyScript *ptr) : TracerConcrete<js::LazyScript>(ptr) { }
 
   public:
     static void construct(void *storage, js::LazyScript *ptr) { new (storage) Concrete(ptr); }
+
+    CoarseType coarseType() const final { return CoarseType::Script; }
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    const char* scriptFilename() const final;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 } // namespace ubi
 } // namespace JS
 
 #endif /* jsscript_h */
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -36,17 +36,17 @@ class TenuringTracer;
  * in debug builds and crash in release builds. Instead, we use a safe-for-crash
  * pointer.
  */
 static MOZ_ALWAYS_INLINE void
 Debug_SetValueRangeToCrashOnTouch(Value* beg, Value* end)
 {
 #ifdef DEBUG
     for (Value* v = beg; v != end; ++v)
-        v->setObject(*reinterpret_cast<JSObject*>(0x42));
+        v->setObject(*reinterpret_cast<JSObject*>(0x48));
 #endif
 }
 
 static MOZ_ALWAYS_INLINE void
 Debug_SetValueRangeToCrashOnTouch(Value* vec, size_t len)
 {
 #ifdef DEBUG
     Debug_SetValueRangeToCrashOnTouch(vec, vec + len);
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -533,17 +533,17 @@ class Shape : public gc::TenuredCell
     friend class ::JSFunction;
     friend class Bindings;
     friend class NativeObject;
     friend class PropertyTree;
     friend class StaticBlockScope;
     friend class TenuringTracer;
     friend struct StackBaseShape;
     friend struct StackShape;
-    friend struct JS::ubi::Concrete<Shape>;
+    friend class JS::ubi::Concrete<Shape>;
     friend class js::gc::RelocationOverlay;
 
   protected:
     GCPtrBaseShape base_;
     PreBarrieredId propid_;
 
     enum SlotInfo : uint32_t
     {
@@ -1454,32 +1454,40 @@ ReshapeForAllocKind(JSContext* cx, Shape
 #pragma warning(pop)
 #endif
 
 // JS::ubi::Nodes can point to Shapes and BaseShapes; they're js::gc::Cell
 // instances that occupy a compartment.
 namespace JS {
 namespace ubi {
 
-template<> struct Concrete<js::Shape> : TracerConcreteWithCompartment<js::Shape> {
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-
+template<>
+class Concrete<js::Shape> : TracerConcreteWithCompartment<js::Shape> {
   protected:
     explicit Concrete(js::Shape *ptr) : TracerConcreteWithCompartment<js::Shape>(ptr) { }
 
   public:
     static void construct(void *storage, js::Shape *ptr) { new (storage) Concrete(ptr); }
+
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
-template<> struct Concrete<js::BaseShape> : TracerConcreteWithCompartment<js::BaseShape> {
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-
+template<>
+class Concrete<js::BaseShape> : TracerConcreteWithCompartment<js::BaseShape> {
   protected:
     explicit Concrete(js::BaseShape *ptr) : TracerConcreteWithCompartment<js::BaseShape>(ptr) { }
 
   public:
     static void construct(void *storage, js::BaseShape *ptr) { new (storage) Concrete(ptr); }
+
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 } // namespace ubi
 } // namespace JS
 
 #endif /* vm_Shape_h */
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -77,18 +77,17 @@ JS::ubi::Concrete<JSString>::size(mozill
     // We can't use mallocSizeof on things in the nursery. At the moment,
     // strings are never in the nursery, but that may change.
     MOZ_ASSERT(!IsInsideNursery(&str));
     size += str.sizeOfExcludingThis(mallocSizeOf);
 
     return size;
 }
 
-template<> const char16_t JS::ubi::TracerConcrete<JSString>::concreteTypeName[] =
-    MOZ_UTF16("JSString");
+const char16_t JS::ubi::Concrete<JSString>::concreteTypeName[] = MOZ_UTF16("JSString");
 
 #ifdef DEBUG
 
 template <typename CharT>
 /*static */ void
 JSString::dumpChars(const CharT* s, size_t n, FILE* fp)
 {
     if (n == SIZE_MAX) {
--- a/js/src/vm/TypeInference.h
+++ b/js/src/vm/TypeInference.h
@@ -1320,22 +1320,25 @@ PrintTypes(JSContext* cx, JSCompartment*
 } /* namespace js */
 
 // JS::ubi::Nodes can point to object groups; they're js::gc::Cell instances
 // with no associated compartment.
 namespace JS {
 namespace ubi {
 
 template<>
-struct Concrete<js::ObjectGroup> : TracerConcrete<js::ObjectGroup> {
-    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
-
+class Concrete<js::ObjectGroup> : TracerConcrete<js::ObjectGroup> {
   protected:
     explicit Concrete(js::ObjectGroup *ptr) : TracerConcrete<js::ObjectGroup>(ptr) { }
 
   public:
     static void construct(void *storage, js::ObjectGroup *ptr) { new (storage) Concrete(ptr); }
+
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+
+    const char16_t* typeName() const override { return concreteTypeName; }
+    static const char16_t concreteTypeName[];
 };
 
 } // namespace ubi
 } // namespace JS
 
 #endif /* vm_TypeInference_h */
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -303,36 +303,54 @@ class SimpleEdgeRange : public EdgeRange
 
 template<typename Referent>
 JS::Zone*
 TracerConcrete<Referent>::zone() const
 {
     return get().zoneFromAnyThread();
 }
 
+template JS::Zone* TracerConcrete<JSScript>::zone() const;
+template JS::Zone* TracerConcrete<js::LazyScript>::zone() const;
+template JS::Zone* TracerConcrete<js::Shape>::zone() const;
+template JS::Zone* TracerConcrete<js::BaseShape>::zone() const;
+template JS::Zone* TracerConcrete<JS::Symbol>::zone() const;
+template JS::Zone* TracerConcrete<JSString>::zone() const;
+
 template<typename Referent>
 UniquePtr<EdgeRange>
 TracerConcrete<Referent>::edges(JSRuntime* rt, bool wantNames) const {
     UniquePtr<SimpleEdgeRange, JS::DeletePolicy<SimpleEdgeRange>> range(js_new<SimpleEdgeRange>());
     if (!range)
         return nullptr;
 
     if (!range->init(rt, ptr, JS::MapTypeToTraceKind<Referent>::kind, wantNames))
         return nullptr;
 
     return UniquePtr<EdgeRange>(range.release());
 }
 
+template UniquePtr<EdgeRange> TracerConcrete<JSScript>::edges(JSRuntime* rt, bool wantNames) const;
+template UniquePtr<EdgeRange> TracerConcrete<js::LazyScript>::edges(JSRuntime* rt, bool wantNames) const;
+template UniquePtr<EdgeRange> TracerConcrete<js::Shape>::edges(JSRuntime* rt, bool wantNames) const;
+template UniquePtr<EdgeRange> TracerConcrete<js::BaseShape>::edges(JSRuntime* rt, bool wantNames) const;
+template UniquePtr<EdgeRange> TracerConcrete<JS::Symbol>::edges(JSRuntime* rt, bool wantNames) const;
+template UniquePtr<EdgeRange> TracerConcrete<JSString>::edges(JSRuntime* rt, bool wantNames) const;
+
 template<typename Referent>
 JSCompartment*
 TracerConcreteWithCompartment<Referent>::compartment() const
 {
     return TracerBase::get().compartment();
 }
 
+template JSCompartment* TracerConcreteWithCompartment<JSScript>::compartment() const;
+template JSCompartment* TracerConcreteWithCompartment<js::Shape>::compartment() const;
+template JSCompartment* TracerConcreteWithCompartment<js::BaseShape>::compartment() const;
+
 bool
 Concrete<JSObject>::hasAllocationStack() const
 {
     return !!js::Debugger::getObjectAllocationSite(get());
 }
 
 StackFrame
 Concrete<JSObject>::allocationStack() const
@@ -366,47 +384,23 @@ Concrete<JSObject>::jsObjectConstructorN
     mozilla::Range<char16_t> chars(outName.get(), size);
     if (!JS_CopyStringChars(cx, chars, name))
         return false;
 
     outName[len] = '\0';
     return true;
 }
 
-template<> const char16_t TracerConcrete<JS::Symbol>::concreteTypeName[] =
-    MOZ_UTF16("JS::Symbol");
-template<> const char16_t TracerConcrete<JSScript>::concreteTypeName[] =
-    MOZ_UTF16("JSScript");
-template<> const char16_t TracerConcrete<js::LazyScript>::concreteTypeName[] =
-    MOZ_UTF16("js::LazyScript");
-template<> const char16_t TracerConcrete<js::jit::JitCode>::concreteTypeName[] =
-    MOZ_UTF16("js::jit::JitCode");
-template<> const char16_t TracerConcrete<js::Shape>::concreteTypeName[] =
-    MOZ_UTF16("js::Shape");
-template<> const char16_t TracerConcrete<js::BaseShape>::concreteTypeName[] =
-    MOZ_UTF16("js::BaseShape");
-template<> const char16_t TracerConcrete<js::ObjectGroup>::concreteTypeName[] =
-    MOZ_UTF16("js::ObjectGroup");
-
-
-// Instantiate all the TracerConcrete and templates here, where
-// we have the member functions' definitions in scope.
-namespace JS {
-namespace ubi {
-template class TracerConcreteWithCompartment<JSObject>;
-template class TracerConcrete<JSString>;
-template class TracerConcrete<JS::Symbol>;
-template class TracerConcreteWithCompartment<JSScript>;
-template class TracerConcrete<js::LazyScript>;
-template class TracerConcrete<js::jit::JitCode>;
-template class TracerConcreteWithCompartment<js::Shape>;
-template class TracerConcreteWithCompartment<js::BaseShape>;
-template class TracerConcrete<js::ObjectGroup>;
-} // namespace ubi
-} // namespace JS
+const char16_t Concrete<JS::Symbol>::concreteTypeName[] = MOZ_UTF16("JS::Symbol");
+const char16_t Concrete<JSScript>::concreteTypeName[] = MOZ_UTF16("JSScript");
+const char16_t Concrete<js::LazyScript>::concreteTypeName[] = MOZ_UTF16("js::LazyScript");
+const char16_t Concrete<js::jit::JitCode>::concreteTypeName[] = MOZ_UTF16("js::jit::JitCode");
+const char16_t Concrete<js::Shape>::concreteTypeName[] = MOZ_UTF16("js::Shape");
+const char16_t Concrete<js::BaseShape>::concreteTypeName[] = MOZ_UTF16("js::BaseShape");
+const char16_t Concrete<js::ObjectGroup>::concreteTypeName[] = MOZ_UTF16("js::ObjectGroup");
 
 namespace JS {
 namespace ubi {
 
 RootList::RootList(JSRuntime* rt, Maybe<AutoCheckCannotGC>& noGC, bool wantNames /* = false */)
   : noGC(noGC),
     rt(rt),
     edges(),
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -412,18 +412,16 @@ interface nsIXPConnect : nsISupports
     nsIXPConnectWrappedNative
     getWrappedNativeOfJSObject(in JSContextPtr aJSContext,
                                in JSObjectPtr  aJSObj);
 
     [noscript, notxpcom] nsISupports
     getNativeOfWrapper(in JSContextPtr aJSContext,
                        in JSObjectPtr  aJSObj);
 
-    [noscript,notxpcom,nostdcall] JSContextPtr getSafeJSContext();
-
     // Will return null if there is no JS stack right now.
     readonly attribute nsIStackFrame                CurrentJSStack;
     readonly attribute nsAXPCNativeCallContextPtr   CurrentNativeCallContext;
 
     void debugDump(in short depth);
     void debugDumpObject(in nsISupports aCOMObj, in short depth);
     void debugDumpJSStack(in boolean showArgs,
                           in boolean showLocals,
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -340,16 +340,21 @@ ResolveModuleObjectProperty(JSContext* a
         }
     }
     return aModObj;
 }
 
 const mozilla::Module*
 mozJSComponentLoader::LoadModule(FileLocation& aFile)
 {
+    if (!NS_IsMainThread()) {
+        MOZ_ASSERT(false, "Don't use JS components off the main thread");
+        return nullptr;
+    }
+
     nsCOMPtr<nsIFile> file = aFile.GetBaseFile();
 
     nsCString spec;
     aFile.GetURIString(spec);
     ComponentLoaderInfo info(spec);
     nsresult rv = info.EnsureURI();
     NS_ENSURE_SUCCESS(rv, nullptr);
 
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -974,23 +974,16 @@ nsXPConnect::JSToVariant(JSContext* ctx,
     RefPtr<XPCVariant> variant = XPCVariant::newVariant(ctx, value);
     variant.forget(_retval);
     if (!(*_retval))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
-/* virtual */
-JSContext*
-nsXPConnect::GetSafeJSContext()
-{
-    return GetRuntime()->Context();
-}
-
 nsIPrincipal*
 nsXPConnect::GetPrincipal(JSObject* obj, bool allowShortCircuit) const
 {
     MOZ_ASSERT(IS_WN_REFLECTOR(obj), "What kind of wrapper is this?");
 
     XPCWrappedNative* xpcWrapper = XPCWrappedNative::Get(obj);
     if (xpcWrapper) {
         if (allowShortCircuit) {
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -874,18 +874,20 @@ void nsDisplayListBuilder::MarkOutOfFlow
    /**
     * Add a fuzz factor to the overflow rectangle so that elements only just
     * out of view are pulled into the display list, so they can be
     * prerendered if necessary.
     */
     overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32));
   }
 
-  if (!dirty.IntersectRect(dirty, overflowRect))
+  if (!dirty.IntersectRect(dirty, overflowRect) &&
+      !(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
     return;
+  }
 
   const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
   const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
   OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
   aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
 
   MarkFrameForDisplay(aFrame, aDirtyFrame);
 }
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -208,13 +208,10 @@ RESOURCE_FILES.html = [
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 
 if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
     CXXFLAGS += CONFIG['TK_CFLAGS']
 
-if CONFIG['MOZ_ENABLE_QT']:
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -3399,17 +3399,17 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
       // reflow again.
       if (!replacedBlock) {
         break;
       }
 
       LogicalRect oldFloatAvailableSpaceRect(floatAvailableSpace.mRect);
       floatAvailableSpace = aState.GetFloatAvailableSpaceForBSize(
                               aState.mBCoord + bStartMargin,
-                              brc.GetMetrics().Height(),
+                              brc.GetMetrics().BSize(wm),
                               &floatManagerState);
       NS_ASSERTION(floatAvailableSpace.mRect.BStart(wm) ==
                      oldFloatAvailableSpaceRect.BStart(wm),
                    "yikes");
       // Restore the height to the position of the next band.
       floatAvailableSpace.mRect.BSize(wm) =
         oldFloatAvailableSpaceRect.BSize(wm);
       // Determine whether the available space shrunk on either side,
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1422,19 +1422,19 @@ skip-if(B2G||Mulet) fuzzy-if(Android,5,1
 == 513153-1a.html 513153-1-ref.html
 == 513153-1b.html 513153-1-ref.html
 == 513153-2a.html 513153-2-ref.html
 == 513153-2b.html 513153-2-ref.html
 skip-if((B2G&&browserIsRemote)||Mulet) == 513318-1.xul 513318-1-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fails-if(Android&&(!asyncPan)) != 513318-2.xul 513318-2-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 == 514917-1.html 514917-1-ref.html
 HTTP(..) == 518172-1a.html 518172-a-ref.html
-fuzzy-if(winWidget,73,133) fuzzy-if(browserIsRemote&&cocoaWidget,103,133) HTTP(..) == 518172-1b.html 518172-b-ref.html
+fuzzy-if(winWidget,73,133) fuzzy-if(cocoaWidget,103,133) HTTP(..) == 518172-1b.html 518172-b-ref.html
 HTTP(..) == 518172-2a.html 518172-a-ref.html
-fuzzy-if(browserIsRemote&&winWidget,73,133) fuzzy-if(browserIsRemote&&cocoaWidget,103,133) HTTP(..) == 518172-2b.html 518172-b-ref.html
+fuzzy-if(winWidget,73,133) fuzzy-if(cocoaWidget,103,133) HTTP(..) == 518172-2b.html 518172-b-ref.html
 == 520421-1.html 520421-1-ref.html
 == 520563-1.xhtml 520563-1-ref.xhtml
 fuzzy-if(skiaContent,1,3) == 521525-1.html 521525-1-ref.html
 == 521525-2.html 521525-2-ref.html
 == 521539-1.html 521539-1-ref.html
 == 521542-1.xhtml 521542-1-ref.xhtml
 == 521602.html 521602-ref.html
 == 521685-1.html 521685-1-ref.html
--- a/layout/style/FontFaceSetIterator.h
+++ b/layout/style/FontFaceSetIterator.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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_FontFaceSetIterator_h
 #define mozilla_dom_FontFaceSetIterator_h
 
+#include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/dom/FontFaceSetBinding.h"
 #include "mozilla/dom/NonRefcountedDOMObject.h"
 
 namespace mozilla {
 namespace dom {
 
 class FontFaceSetIterator final
 {
--- a/layout/style/SheetType.h
+++ b/layout/style/SheetType.h
@@ -3,16 +3,18 @@
  * 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/. */
 
 /* enum to represent a level in the cascade */
 
 #ifndef mozilla_SheetType_h
 #define mozilla_SheetType_h
 
+#include <stdint.h>
+
 namespace mozilla {
 
 // The "origins" of the CSS cascade, from lowest precedence to
 // highest (for non-!important rules).
 //
 // Be sure to update NS_RULE_NODE_LEVEL_MASK when changing the number
 // of sheet types; static assertions enforce this.
 enum class SheetType : uint8_t {
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -49,17 +49,17 @@ StyleSheet::SetComplete()
     mDocument->BeginUpdate(UPDATE_STYLE);
     mDocument->SetStyleSheetApplicableState(AsHandle(), true);
     mDocument->EndUpdate(UPDATE_STYLE);
   }
 
   if (mOwningNode && !mDisabled &&
       mOwningNode->HasFlag(NODE_IS_IN_SHADOW_TREE) &&
       mOwningNode->IsContent()) {
-    ShadowRoot* shadowRoot = mOwningNode->AsContent()->GetContainingShadow();
+    dom::ShadowRoot* shadowRoot = mOwningNode->AsContent()->GetContainingShadow();
     shadowRoot->StyleSheetChanged();
   }
 }
 
 StyleSheetInfo&
 StyleSheet::SheetInfo()
 {
   if (IsServo()) {
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3294,28 +3294,28 @@ CSSParserImpl::ParseAtRule(RuleAppendFun
   }
 
   // Inside of @-rules, only the rules that can occur anywhere
   // are allowed.
   bool unnestable = aInAtRule && newSection != eCSSSection_General;
   if (unnestable) {
     REPORT_UNEXPECTED_TOKEN(PEGroupRuleNestedAtRule);
   }
-  
+
   if (unnestable || !(this->*parseFunc)(aAppendFunc, aData)) {
     // Skip over invalid at rule, don't advance section
     OUTPUT_ERROR();
     return SkipAtRule(aInAtRule);
   }
 
   // Nested @-rules don't affect the top-level rule chain requirement
   if (!aInAtRule) {
     mSection = newSection;
   }
-  
+
   return true;
 }
 
 bool
 CSSParserImpl::ParseCharsetRule(RuleAppendFunc aAppendFunc,
                                 void* aData)
 {
   uint32_t linenum, colnum;
@@ -3829,17 +3829,17 @@ CSSParserImpl::ParseMozDocumentRule(Rule
   }
 
   do {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PEMozDocRuleEOF);
       delete urls;
       return false;
     }
-        
+
     if (!(eCSSToken_URL == mToken.mType ||
           (eCSSToken_Function == mToken.mType &&
            (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix") ||
             mToken.mIdent.LowerCaseEqualsLiteral("domain") ||
             mToken.mIdent.LowerCaseEqualsLiteral("regexp"))))) {
       REPORT_UNEXPECTED_TOKEN(PEMozDocRuleBadFunc2);
       UngetToken();
       delete urls;
@@ -7795,19 +7795,19 @@ CSSParserImpl::ParseVariant(nsCSSValue& 
     return CSSParseResult::Ok;
   }
   if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE |
                         VARIANT_FREQUENCY | VARIANT_TIME)) != 0 &&
        eCSSToken_Dimension == tk->mType) ||
       ((aVariantMask & (VARIANT_LENGTH | VARIANT_ZERO_ANGLE)) != 0 &&
        eCSSToken_Number == tk->mType &&
        tk->mNumber == 0.0f)) {
-    if (((aVariantMask & VARIANT_POSITIVE_DIMENSION) != 0 && 
+    if (((aVariantMask & VARIANT_POSITIVE_DIMENSION) != 0 &&
          tk->mNumber <= 0.0) ||
-        ((aVariantMask & VARIANT_NONNEGATIVE_DIMENSION) != 0 && 
+        ((aVariantMask & VARIANT_NONNEGATIVE_DIMENSION) != 0 &&
          tk->mNumber < 0.0)) {
         UngetToken();
         AssertNextTokenAt(lineBefore, colBefore);
         return CSSParseResult::NotFound;
     }
     if (TranslateDimension(aValue, aVariantMask, tk->mNumber, tk->mIdent)) {
       return CSSParseResult::Ok;
     }
@@ -8249,17 +8249,17 @@ CSSParserImpl::ParseImageOrientation(nsC
                                 nsCSSProps::kImageOrientationFlipKTable)) {
       RefPtr<nsCSSValue::Array> array = nsCSSValue::Array::Create(2);
       array->Item(0) = angle;
       array->Item(1) = flip;
       aValue.SetArrayValue(array, eCSSUnit_Array);
     } else {
       aValue = angle;
     }
-    
+
     return true;
   }
 
   // The remaining possibilities (bare 'flip' and 'from-image') are both
   // keywords, so we can handle them at the same time.
   nsCSSValue keyword;
   if (ParseSingleTokenVariant(keyword, VARIANT_KEYWORD,
                               nsCSSProps::kImageOrientationKTable)) {
@@ -8425,17 +8425,17 @@ CSSParserImpl::ParseFlex()
   }
 
   if (!doneParsing) {
     // (c) OK -- the last thing we parsed was flex-grow, so look for a
     //     flex-shrink in the next position.
     if (ParseNonNegativeNumber(tmpVal)) {
       flexShrink = tmpVal;
     }
- 
+
     // d) Finally: If we didn't get flex-basis at the beginning, try to parse
     //    it now, at the end.
     //
     // NOTE: If we encounter unitless 0 in this final position, we'll parse it
     // as a 'flex-basis' value.  That's OK, because we know it must have
     // been "preceded by 2 flex factors" (justification below), which gets us
     // out of the spec's requirement of otherwise having to treat unitless 0
     // as a flex factor.
@@ -9838,17 +9838,17 @@ CSSParserImpl::ParseJustifyItems()
       }
     }
   }
   AppendValue(eCSSProperty_justify_items, value);
   return true;
 }
 
 // normal | stretch | <baseline-position> |
-// [ <overflow-position>? && <self-position> ] 
+// [ <overflow-position>? && <self-position> ]
 bool
 CSSParserImpl::ParseAlignItems()
 {
   nsCSSValue value;
   if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
     if (!ParseEnum(value, nsCSSProps::kAlignNormalStretchBaseline)) {
       if (!ParseAlignJustifyPosition(value, nsCSSProps::kAlignSelfPosition) ||
           value.GetUnit() == eCSSUnit_Null) {
@@ -9856,17 +9856,17 @@ CSSParserImpl::ParseAlignItems()
       }
     }
   }
   AppendValue(eCSSProperty_align_items, value);
   return true;
 }
 
 // auto | normal | stretch | <baseline-position> |
-// [ <overflow-position>? && <self-position> ] 
+// [ <overflow-position>? && <self-position> ]
 bool
 CSSParserImpl::ParseAlignJustifySelf(nsCSSProperty aPropID)
 {
   nsCSSValue value;
   if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
     if (!ParseEnum(value, nsCSSProps::kAlignAutoNormalStretchBaseline)) {
       if (!ParseAlignJustifyPosition(value, nsCSSProps::kAlignSelfPosition) ||
           value.GetUnit() == eCSSUnit_Null) {
@@ -13096,17 +13096,17 @@ CSSParserImpl::ParseBorderImage()
           bool foundBorderImageWidth = ParseBorderImageWidth(false);
 
           // [ / <border-image-outset>
           if (ExpectSymbol('/', true)) {
             if (!ParseBorderImageOutset(false)) {
               return false;
             }
           } else if (!foundBorderImageWidth) {
-            // If this part has an trailing slash, the whole declaration is 
+            // If this part has an trailing slash, the whole declaration is
             // invalid.
             return false;
           }
         }
 
         continue;
       } else {
         // If we consumed some tokens for <border-image-slice> but did not
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -34,16 +34,18 @@
 #include "nsStyleSet.h"
 #include "mozilla/RestyleManagerHandle.h"
 #include "mozilla/RestyleManagerHandleInlines.h"
 #include "nsDOMMutationObserver.h"
 
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 using mozilla::dom::Animation;
+using mozilla::dom::AnimationPlayState;
+using mozilla::dom::CSSTransition;
 using mozilla::dom::KeyframeEffectReadOnly;
 
 using namespace mozilla;
 using namespace mozilla::css;
 
 double
 ElementPropertyTransition::CurrentValuePortion() const
 {
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -111,17 +111,17 @@ function OnInitialLoad()
     var initInfo = SendContentReady();
     gBrowserIsRemote = initInfo.remote;
 
     addEventListener("load", OnDocumentLoad, true);
 
     addEventListener("MozPaintWait", PaintWaitListener, true);
     addEventListener("MozPaintWaitFinished", PaintWaitFinishedListener, true);
 
-    LogWarning("Using browser remote="+ gBrowserIsRemote +"\n");
+    LogInfo("Using browser remote="+ gBrowserIsRemote +"\n");
 }
 
 function SetFailureTimeout(cb, timeout)
 {
   var targetTime = Date.now() + timeout;
 
   var wrapper = function() {
     // Timeouts can fire prematurely in some cases (e.g. in chaos mode). If this
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -1953,17 +1953,17 @@ void NrTcpSocketIpc::connect_i(const nsA
                                const nsACString &local_addr,
                                uint16_t local_port) {
   ASSERT_ON_THREAD(io_thread_);
   mirror_state_ = NR_CONNECTING;
 
   dom::TCPSocketChild* child = new dom::TCPSocketChild(NS_ConvertUTF8toUTF16(remote_addr), remote_port);
   socket_child_ = child;
 
-  socket_child_->SetFilterName(nsCString(NS_NETWORK_SOCKET_FILTER_HANDLER_STUN_SUFFIX));
+  // Bug 1285330: put filtering back in here
 
   // XXX remove remote!
   socket_child_->SendWindowlessOpenBind(this,
                                         remote_addr, remote_port,
                                         local_addr, local_port,
                                         /* use ssl */ false);
 }
 
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -666,16 +666,21 @@ void NrIceCtx::internal_DeinitializeGlob
 }
 
 void NrIceCtx::internal_SetTimerAccelarator(int divider) {
   ctx_->test_timer_divider = divider;
 }
 
 NrIceCtx::~NrIceCtx() {
   MOZ_MTLOG(ML_DEBUG, "Destroying ICE ctx '" << name_ <<"'");
+  for (auto stream = streams_.begin(); stream != streams_.end(); stream++) {
+    if (*stream) {
+      (*stream)->Close();
+    }
+  }
   nr_ice_peer_ctx_destroy(&peer_);
   nr_ice_ctx_destroy(&ctx_);
   delete ice_handler_vtbl_;
   delete ice_handler_;
 }
 
 void
 NrIceCtx::SetStream(size_t index, NrIceMediaStream* stream) {
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -593,15 +593,18 @@ void NrIceMediaStream::Ready() {
     MOZ_MTLOG(ML_DEBUG, "Stream ready callback fired again for '" << name_ << "'");
   }
 }
 
 void NrIceMediaStream::Close() {
   MOZ_MTLOG(ML_DEBUG, "Marking stream closed '" << name_ << "'");
   state_ = ICE_CLOSED;
 
-  int r = nr_ice_remove_media_stream(ctx_, &stream_);
-  if (r) {
-    MOZ_ASSERT(false, "Failed to remove stream");
-    MOZ_MTLOG(ML_ERROR, "Failed to remove stream, error=" << r);
+  if (stream_) {
+    int r = nr_ice_remove_media_stream(ctx_, &stream_);
+    if (r) {
+      MOZ_ASSERT(false, "Failed to remove stream");
+      MOZ_MTLOG(ML_ERROR, "Failed to remove stream, error=" << r);
+    }
   }
 }
+
 }  // close namespace
--- a/media/mtransport/transportlayerdtls.cpp
+++ b/media/mtransport/transportlayerdtls.cpp
@@ -363,16 +363,17 @@ static const struct PRIOMethods Transpor
   TransportLayerConnectContinue,
   TransportLayerReserved,
   TransportLayerReserved,
   TransportLayerReserved,
   TransportLayerReserved
 };
 
 TransportLayerDtls::~TransportLayerDtls() {
+  nspr_io_adapter_->SetEnabled(false);
   if (timer_) {
     timer_->Cancel();
   }
 }
 
 nsresult TransportLayerDtls::InitInternal() {
   // Get the transport service as an event target
   nsresult rv;
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -298,20 +298,16 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'an
         'nsNetworkInfoService.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     SOURCES += [
         'NetworkInfoServiceLinux.cpp',
         'nsNetworkInfoService.cpp',
     ]
 
-if CONFIG['MOZ_ENABLE_QTNETWORK']:
-    SOURCES += [
-    ]
-
 EXTRA_COMPONENTS += [
     'PACGenerator.js',
     'PACGenerator.manifest'
 ]
 
 EXTRA_JS_MODULES += [
     'NetUtil.jsm',
 ]
@@ -327,18 +323,10 @@ LOCAL_INCLUDES += [
 ]
 
 if 'rtsp' in CONFIG['NECKO_PROTOCOLS']:
     LOCAL_INCLUDES += [
         '/netwerk/protocol/rtsp/controller',
         '/netwerk/protocol/rtsp/rtsp',
     ]
 
-if CONFIG['MOZ_ENABLE_QTNETWORK']:
-    LOCAL_INCLUDES += [
-        '/netwerk/system/qt',
-    ]
-
-if CONFIG['MOZ_ENABLE_QTNETWORK']:
-    CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
-
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
--- a/netwerk/base/security-prefs.js
+++ b/netwerk/base/security-prefs.js
@@ -87,8 +87,13 @@ pref("security.pki.netscape_step_up_poli
 
 pref("security.webauth.u2f", false);
 pref("security.webauth.u2f_enable_softtoken", false);
 pref("security.webauth.u2f_enable_usbtoken", false);
 
 pref("security.ssl.errorReporting.enabled", true);
 pref("security.ssl.errorReporting.url", "https://incoming.telemetry.mozilla.org/submit/sslreports/");
 pref("security.ssl.errorReporting.automatic", false);
+
+// Impose a maximum age on HPKP headers, to avoid sites getting permanently
+// blacking themselves out by setting a bad pin.  (60 days by default)
+// https://tools.ietf.org/html/rfc7469#section-4.1
+pref("security.cert_pinning.max_max_age_seconds", 5184000);
--- a/netwerk/build/moz.build
+++ b/netwerk/build/moz.build
@@ -38,21 +38,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
         '/netwerk/system/win32',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     LOCAL_INCLUDES += [
         '/netwerk/system/mac',
     ]
 
-if CONFIG['MOZ_ENABLE_QTNETWORK']:
-    LOCAL_INCLUDES += [
-        '/netwerk/system/qt',
-    ]
-
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     LOCAL_INCLUDES += [
         '/netwerk/system/android',
     ]
 
 elif CONFIG['OS_ARCH'] == 'Linux':
     LOCAL_INCLUDES += [
         '/netwerk/system/linux',
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -410,19 +410,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsID
 
 ///////////////////////////////////////////////////////////////////////////////
 #if defined(XP_WIN)
 #include "nsNotifyAddrListener.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNotifyAddrListener, Init)
 #elif defined(MOZ_WIDGET_COCOA)
 #include "nsNetworkLinkService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNetworkLinkService, Init)
-#elif defined(MOZ_ENABLE_QTNETWORK)
-#include "nsQtNetworkLinkService.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsQtNetworkLinkService, Init)
 #elif defined(MOZ_WIDGET_ANDROID)
 #include "nsAndroidNetworkLinkService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidNetworkLinkService)
 #elif defined(XP_LINUX)
 #include "nsNotifyAddrListener_Linux.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNotifyAddrListener, Init)
 #endif
 
@@ -851,18 +848,16 @@ NS_DEFINE_NAMED_CID(NS_WEBSOCKETSSLPROTO
 #endif
 #ifdef NECKO_PROTOCOL_rtsp
 NS_DEFINE_NAMED_CID(NS_RTSPPROTOCOLHANDLER_CID);
 #endif
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_WIDGET_COCOA)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
-#elif defined(MOZ_ENABLE_QTNETWORK)
-NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_WIDGET_ANDROID)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(XP_LINUX)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
 NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
 NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
@@ -1006,18 +1001,16 @@ static const mozilla::Module::CIDEntry k
 #endif
 #ifdef NECKO_PROTOCOL_rtsp
     { &kNS_RTSPPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::RtspHandlerConstructor },
 #endif
 #if defined(XP_WIN)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
 #elif defined(MOZ_WIDGET_COCOA)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNetworkLinkServiceConstructor },
-#elif defined(MOZ_ENABLE_QTNETWORK)
-    { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsQtNetworkLinkServiceConstructor },
 #elif defined(MOZ_WIDGET_ANDROID)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsAndroidNetworkLinkServiceConstructor },
 #elif defined(XP_LINUX)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
 #endif
     { &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
     { &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
     { &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
@@ -1166,18 +1159,16 @@ static const mozilla::Module::ContractID
 #endif
 #ifdef NECKO_PROTOCOL_rtsp
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "rtsp", &kNS_RTSPPROTOCOLHANDLER_CID },
 #endif
 #if defined(XP_WIN)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_WIDGET_COCOA)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
-#elif defined(MOZ_ENABLE_QTNETWORK)
-    { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_WIDGET_ANDROID)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(XP_LINUX)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #endif
     { NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
     { NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID, &kNS_CACHE_STORAGE_SERVICE_CID },
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -379,16 +379,27 @@ Http2Session::AddStream(nsAHttpTransacti
     MOZ_ASSERT(false, "AddStream duplicate transaction pointer");
     return false;
   }
 
   if (!mConnection) {
     mConnection = aHttpTransaction->Connection();
   }
 
+  if (mClosed || mShouldGoAway) {
+    nsHttpTransaction *trans = aHttpTransaction->QueryHttpTransaction();
+    if (trans && !trans->GetPushedStream()) {
+      LOG3(("Http2Session::AddStream %p atrans=%p trans=%p session unusable - resched.\n",
+            this, aHttpTransaction, trans));
+      aHttpTransaction->SetConnection(nullptr);
+      gHttpHandler->InitiateTransaction(trans, trans->Priority());
+      return true;
+    }
+  }
+
   aHttpTransaction->SetConnection(this);
 
   if (aUseTunnel) {
     LOG3(("Http2Session::AddStream session=%p trans=%p OnTunnel",
           this, aHttpTransaction));
     DispatchOnTunnel(aHttpTransaction, aCallbacks);
     return true;
   }
--- a/netwerk/protocol/http/SpdySession31.cpp
+++ b/netwerk/protocol/http/SpdySession31.cpp
@@ -333,16 +333,27 @@ SpdySession31::AddStream(nsAHttpTransact
     MOZ_ASSERT(false, "AddStream duplicate transaction pointer");
     return false;
   }
 
   if (!mConnection) {
     mConnection = aHttpTransaction->Connection();
   }
 
+  if (mClosed || mShouldGoAway) {
+    nsHttpTransaction *trans = aHttpTransaction->QueryHttpTransaction();
+    if (trans && !trans->GetPushedStream()) {
+      LOG3(("SpdySession31::AddStream %p atrans=%p trans=%p session unusable - resched.\n",
+            this, aHttpTransaction, trans));
+      aHttpTransaction->SetConnection(nullptr);
+      gHttpHandler->InitiateTransaction(trans, trans->Priority());
+      return true;
+    }
+  }
+
   aHttpTransaction->SetConnection(this);
 
   if (aUseTunnel) {
     LOG3(("SpdySession31::AddStream session=%p trans=%p OnTunnel",
           this, aHttpTransaction));
     DispatchOnTunnel(aHttpTransaction, aCallbacks);
     return true;
   }
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1856,16 +1856,18 @@ nsHttpConnectionMgr::ProcessNewTransacti
         LOG(("  transaction was canceled... dropping event!\n"));
         return NS_OK;
     }
 
     trans->SetPendingTime();
 
     Http2PushedStream *pushedStream = trans->GetPushedStream();
     if (pushedStream) {
+        LOG(("  ProcessNewTransaction %p tied to h2 session push %p\n",
+             trans, pushedStream->Session()));
         return pushedStream->Session()->
             AddStream(trans, trans->Priority(), false, nullptr) ?
             NS_OK : NS_ERROR_UNEXPECTED;
     }
 
     nsresult rv = NS_OK;
     nsHttpConnectionInfo *ci = trans->ConnectionInfo();
     MOZ_ASSERT(ci);
--- a/netwerk/system/moz.build
+++ b/netwerk/system/moz.build
@@ -5,16 +5,13 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['win32']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     DIRS += ['mac']
 
-if CONFIG['MOZ_ENABLE_QTNETWORK']:
-    DIRS += ['qt']
-
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DIRS += ['android']
 
 elif CONFIG['OS_ARCH'] == 'Linux':
     DIRS += ['linux']
deleted file mode 100644
--- a/netwerk/system/qt/moz.build
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-SOURCES += [
-    '!moc_nsQtNetworkManager.cpp',
-    'nsQtNetworkLinkService.cpp',
-    'nsQtNetworkManager.cpp',
-]
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
-    '/netwerk/base',
-]
-
-CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
deleted file mode 100644
--- a/netwerk/system/qt/nsQtNetworkLinkService.cpp
+++ /dev/null
@@ -1,98 +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/. */
-
-#include "nsQtNetworkManager.h"
-#include "nsQtNetworkLinkService.h"
-#include "nsCOMPtr.h"
-#include "nsIObserverService.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-#include "mozilla/Services.h"
-#include "nsCRT.h"
-
-NS_IMPL_ISUPPORTS(nsQtNetworkLinkService,
-                  nsINetworkLinkService,
-                  nsIObserver)
-
-nsQtNetworkLinkService::nsQtNetworkLinkService()
-{
-}
-
-nsQtNetworkLinkService::~nsQtNetworkLinkService()
-{
-}
-
-NS_IMETHODIMP
-nsQtNetworkLinkService::GetIsLinkUp(bool* aIsUp)
-{
-  *aIsUp = nsQtNetworkManager::get()->isOnline();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsQtNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown)
-{
-  *aIsKnown = nsQtNetworkManager::get()->isOnline();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsQtNetworkLinkService::GetLinkType(uint32_t *aLinkType)
-{
-  NS_ENSURE_ARG_POINTER(aLinkType);
-
-  // XXX This function has not yet been implemented for this platform
-  *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsQtNetworkLinkService::Observe(nsISupports* aSubject,
-                                const char* aTopic,
-                                const char16_t* aData)
-{
-  if (!strcmp(aTopic, "xpcom-shutdown")) {
-    Shutdown();
-    nsQtNetworkManager::get()->destroy();
-  }
-
-  if (!strcmp(aTopic, "browser-lastwindow-close-granted")) {
-    Shutdown();
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsQtNetworkLinkService::Init(void)
-{
-  nsCOMPtr<nsIObserverService> observerService =
-    mozilla::services::GetObserverService();
-  if (!observerService) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsQtNetworkManager::create();
-  nsresult rv;
-
-  rv = observerService->AddObserver(this, "xpcom-shutdown", false);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  rv = observerService->AddObserver(this, "browser-lastwindow-close-granted", false);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_FAILURE;
-  }
-
-
-  return NS_OK;
-}
-
-nsresult
-nsQtNetworkLinkService::Shutdown()
-{
-  nsQtNetworkManager::get()->closeSession();
-  return NS_OK;
-}
deleted file mode 100644
--- a/netwerk/system/qt/nsQtNetworkLinkService.h
+++ /dev/null
@@ -1,29 +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/. */
-
-#ifndef NSQTNETWORKLINKSERVICE_H_
-#define NSQTNETWORKLINKSERVICE_H_
-
-#include "nsINetworkLinkService.h"
-#include "nsIObserver.h"
-
-class nsQtNetworkLinkService: public nsINetworkLinkService,
-                              public nsIObserver
-{
-
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSINETWORKLINKSERVICE
-  NS_DECL_NSIOBSERVER
-
-  nsQtNetworkLinkService();
-
-  nsresult Init();
-  nsresult Shutdown();
-
-private:
-  virtual ~nsQtNetworkLinkService();
-};
-
-#endif /* NSQTNETWORKLINKSERVICE_H_ */
deleted file mode 100644
--- a/netwerk/system/qt/nsQtNetworkManager.cpp
+++ /dev/null
@@ -1,162 +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/. */
-
-#include "nsQtNetworkManager.h"
-
-#include "nsCOMPtr.h"
-#include "nsThreadUtils.h"
-#include "nsINetworkLinkService.h"
-#include "nsIOService.h"
-#include "nsIObserverService.h"
-#include "nsIOService.h"
-
-#include <QHostInfo>
-#include <QHostAddress>
-#include <QTime>
-
-nsQtNetworkManager* nsQtNetworkManager::gQtNetworkManager = nullptr;
-
-void nsQtNetworkManager::create()
-{
-    if (!gQtNetworkManager) {
-        gQtNetworkManager = new nsQtNetworkManager();
-        connect(gQtNetworkManager, SIGNAL(openConnectionSignal()),
-                gQtNetworkManager, SLOT(openSession()),
-                Qt::BlockingQueuedConnection);
-        connect(&gQtNetworkManager->networkConfigurationManager,
-                SIGNAL(onlineStateChanged(bool)), gQtNetworkManager,
-                SLOT(onlineStateChanged(bool)));
-    }
-}
-
-void nsQtNetworkManager::destroy()
-{
-    delete gQtNetworkManager;
-    gQtNetworkManager = nullptr;
-}
-
-nsQtNetworkManager::nsQtNetworkManager(QObject* parent)
-  : QObject(parent), networkSession(0)
-{
-    mOnline = networkConfigurationManager.isOnline();
-    NS_ASSERTION(NS_IsMainThread(), "nsQtNetworkManager can only initiated in Main Thread");
-}
-
-nsQtNetworkManager::~nsQtNetworkManager()
-{
-    closeSession();
-    networkSession->deleteLater();
-}
-
-bool
-nsQtNetworkManager::isOnline()
-{
-    static bool sForceOnlineUSB = getenv("MOZ_MEEGO_NET_ONLINE") != 0;
-    return sForceOnlineUSB || mOnline;
-}
-
-void
-nsQtNetworkManager::onlineStateChanged(bool online)
-{
-    mOnline = online;
-}
-
-/*
-  This function is called from different threads, we need to make sure that
-  the attempt to create a network connection is done in the mainthread
-
-  In case this function is called by another thread than the mainthread
-  we emit a signal which is connected through "BlockingQueue"-Connection Type.
-
-  This cause that the current thread is blocked and waiting for the result.
-
-  Of course, in case this gets called from the mainthread we must not emit the signal,
-  but call the slot directly.
-*/
-
-bool
-nsQtNetworkManager::openConnection(const QString& host)
-{
-    // we are already online -> return true.
-    if (isOnline()) {
-        return true;
-    }
-
-    if (NS_IsMainThread()) {
-        openSession();
-    } else {
-        // jump to mainthread and do the work there
-        Q_EMIT openConnectionSignal();
-    }
-
-    // if its claiming its online -> send one resolve request ahead.
-    // this is important because on mobile the first request can take up to 10 seconds
-    // sending here one will help to avoid trouble and timeouts later
-    if (isOnline()) {
-        QHostInfo::fromName(host);
-    }
-
-    return isOnline();
-}
-
-void
-nsQtNetworkManager::openSession()
-{
-    if (mBlockTimer.isActive()) {
-        // if openSession is called within 200 ms again, we forget this attempt since
-        // its mostlike an automatic connection attempt which was not successful or canceled 200ms ago.
-        // we reset the timer and start it again.
-
-        // As example: Go in firefox mobile into AwesomeView, see that the icons are not always cached and
-        // get loaded on the fly. Not having the 200 ms rule here would mean that instantly
-        // after the user dismissed the one connection dialog once another
-        // would get opened. The user will never be able to close / leave the view until each such attempt is gone through.
-
-        // Basically 200 ms are working fine, its huge enough for automatic attempts to get covered and small enough to
-        // still be able to react on direct user request.
-
-        mBlockTimer.stop();
-        mBlockTimer.setSingleShot(true);
-        mBlockTimer.start(200);
-        return;
-    }
-
-    if (isOnline()) {
-        return;
-    }
-
-    // this only means we did not shutdown before...
-    // renew Session every time
-    // fix/workaround for prestart bug
-    if (networkSession) {
-        networkSession->close();
-        networkSession->deleteLater();
-    }
-
-    // renew always to react on changed Configurations
-    networkConfigurationManager.updateConfigurations();
-    // go always with default configuration
-    networkConfiguration = networkConfigurationManager.defaultConfiguration();
-    networkSession = new QNetworkSession(networkConfiguration);
-
-    networkSession->open();
-    QTime current;
-    current.start();
-    networkSession->waitForOpened(-1);
-
-    if (current.elapsed() < 1000) {
-        NS_WARNING("Connection Creation was to fast, something is not right.");
-    }
-
-    mBlockTimer.setSingleShot(true);
-    mBlockTimer.start(200);
-}
-
-void
-nsQtNetworkManager::closeSession()
-{
-    if (networkSession) {
-        networkSession->close();
-    }
-}
deleted file mode 100644
--- a/netwerk/system/qt/nsQtNetworkManager.h
+++ /dev/null
@@ -1,56 +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/. */
-
-#ifndef NSQTNETWORKMANAGER_H_
-#define NSQTNETWORKMANAGER_H_
-
-#include <QNetworkConfigurationManager>
-#include <QObject>
-#include <QTimer>
-#include <QNetworkConfiguration>
-#include <QNetworkSession>
-#include "nscore.h"
-
-class nsQtNetworkManager;
-
-
-
-class nsQtNetworkManager : public QObject
-{
-  Q_OBJECT
-  public:
-    static void create();
-    static void destroy();
-    virtual ~nsQtNetworkManager();
-
-    static nsQtNetworkManager* get() { return gQtNetworkManager; }
-
-    static bool IsConnected();
-    static bool GetLinkStatusKnown();
-    static void enableInstance();
-    bool openConnection(const QString&);
-    bool isOnline();
-  Q_SIGNALS:
-    void openConnectionSignal();
-
-  public Q_SLOTS:
-    void closeSession();
-    void onlineStateChanged(bool);
-
-  private Q_SLOTS:
-    void openSession();
-
-  private:
-    explicit nsQtNetworkManager(QObject* parent = 0);
-
-    static nsQtNetworkManager* gQtNetworkManager;
-    QNetworkSession* networkSession;
-    QNetworkConfiguration networkConfiguration;
-    QNetworkConfigurationManager networkConfigurationManager;
-    QTimer mBlockTimer;
-    bool mOnline;
-};
-
-#endif /* NSQTNETWORKMANAGER_H_ */
-
--- a/old-configure.in
+++ b/old-configure.in
@@ -2860,22 +2860,16 @@ dnl ====================================
 MOZ_ARG_HEADER(Toolkit Options)
 
 dnl ========================================================
 dnl = Enable the toolkit as needed                         =
 dnl ========================================================
 
 case "$MOZ_WIDGET_TOOLKIT" in
 
-qt)
-    MOZ_ENABLE_QT=1
-
-    AC_DEFINE(QT_NO_KEYWORDS)
-    ;;
-
 cocoa)
     LDFLAGS="$LDFLAGS -framework Cocoa -lobjc"
     # Use -Wl as a trick to avoid -framework and framework names from
     # being separated by AC_SUBST_LIST.
     TK_LIBS='-Wl,-framework,CoreLocation -Wl,-framework,QuartzCore -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,AddressBook -Wl,-framework,OpenGL -Wl,-framework,Security -Wl,-framework,ServiceManagement'
     TK_CFLAGS=""
     CFLAGS="$CFLAGS $TK_CFLAGS"
     CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
@@ -2980,184 +2974,19 @@ if test -n "$MOZ_IOS" -a -n "$NS_PRINTIN
    AC_MSG_ERROR([Printing is not supported on iOS.])
 fi
 
 if test "$NS_PRINTING"; then
     AC_DEFINE(NS_PRINTING)
     AC_DEFINE(NS_PRINT_PREVIEW)
 fi
 
-dnl ========================================================
-dnl = QT support
-dnl ========================================================
-if test "$MOZ_ENABLE_QT"
-then
-    MOZ_ARG_WITH_STRING(qtdir,
-    [  --with-qtdir=\$dir       Specify Qt directory ],
-    [ QTDIR=$withval])
-
-    if test -z "$QTDIR"; then
-        AC_CHECK_PROGS(HOST_QMAKE, $HOST_QMAKE qmake, "")
-    else
-        HOST_QMAKE="$QTDIR/bin/qmake"
-    fi
-    QT_VERSION=`$HOST_QMAKE -v | grep 'Using Qt version' | egrep -o '[[0-9]]+\.[[0-9]]+\.[[0-9]]+'`
-
-    if test -z "$QTDIR"; then
-        case $QT_VERSION in
-        5.*)
-            AC_MSG_RESULT("Using qt5: $QT_VERSION")
-            PKG_CHECK_MODULES(MOZ_QT, Qt5Gui Qt5Network Qt5Core Qt5Quick, ,
-            [
-              AC_MSG_ERROR([$MOZ_QT_PKG_ERRORS Need qtbase development packages, (On Ubuntu, you might try installing the packages qtbase5-dev libqt5opengl5-dev.)])
-            ])
-            QT5INCDIR=`pkg-config --variable=includedir Qt5Gui`
-            MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QT5INCDIR/QtGui/$QT_VERSION/QtGui"
-            if test "$NS_PRINTING"; then
-                PKG_CHECK_MODULES(MOZ_QT_WIDGETS, Qt5PrintSupport, ,
-                [
-                  AC_MSG_ERROR([$MOZ_QT_PKG_ERRORS Need qt5 printsupport development package])
-                ])
-                MOZ_QT_LIBS="$MOZ_QT_LIBS $MOZ_QT_WIDGETS_LIBS"
-                MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $MOZ_QT_WIDGETS_CFLAGS"
-            fi
-            ;;
-        *)
-            AC_MSG_ERROR([* * * Unsupported Qt Version: $QT_VERSION])
-            ;;
-        esac
-
-        AC_CHECK_PROGS(HOST_MOC, $MOC moc, "")
-        AC_CHECK_PROGS(HOST_RCC, $RCC rcc, "")
-    else
-        MOZ_QT_CFLAGS="-DQT_SHARED"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtCore"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtNetwork"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtXml"
-        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtDeclarative"
-        case $QT_VERSION in
-        5.*)
-            AC_MSG_RESULT("Using qt5: $QT_VERSION")
-            MOZ_QT_LIBS="$MOZ_QT_LIBS -L$QTDIR/lib/ -lQt5Gui -lQt5Network -lQt5Core -lQt5Xml"
-            MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui/$QT_VERSION/QtGui"
-            if test "$NS_PRINTING"; then
-                MOZ_QT_LIBS="$MOZ_QT_LIBS -lQt5Widgets -lQt5PrintSupport"
-                MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtPrintSupport"
-            fi
-            ;;
-        *)
-            AC_MSG_ERROR([* * * Unsupported Qt Version: $QT_VERSION])
-            ;;
-        esac
-
-        HOST_MOC="$QTDIR/bin/moc"
-        HOST_RCC="$QTDIR/bin/rcc"
-    fi
-    if test -z "$HOST_MOC"; then
-        AC_MSG_ERROR([No acceptable moc preprocessor found. Qt SDK is not installed or --with-qt is incorrect])
-    fi
-    if test -z "$HOST_RCC"; then
-        AC_MSG_ERROR([No acceptable rcc preprocessor found. Qt SDK is not installed or --with-qt is incorrect])
-    fi
-
-    MOC=$HOST_MOC
-    RCC=$HOST_RCC
-
-    MOZ_ENABLE_QMSYSTEM2=
-    PKG_CHECK_MODULES(_QMSYSTEM2, qmsystem2,
-                      MOZ_ENABLE_QMSYSTEM2=1,
-                      MOZ_ENABLE_QMSYSTEM2=)
-
-    if test "$MOZ_ENABLE_QMSYSTEM2"; then
-      MOZ_ENABLE_QMSYSTEM2=1
-      MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QMSYSTEM2_CFLAGS"
-      MOZ_QT_LIBS="$MOZ_QT_LIBS $_QMSYSTEM2_LIBS"
-      AC_DEFINE(MOZ_ENABLE_QMSYSTEM2)
-    fi
-
-    MOZ_ENABLE_QTNETWORK=
-    PKG_CHECK_MODULES(_QTNETWORK, QtNetwork >= 4.7,
-                      MOZ_ENABLE_QTNETWORK=1,
-                      MOZ_ENABLE_QTNETWORK=)
-
-    if test "$MOZ_ENABLE_QTNETWORK"; then
-      MOZ_ENABLE_QTNETWORK=1
-      AC_DEFINE(MOZ_ENABLE_QTNETWORK)
-    fi
-
-    MOZ_ENABLE_QTMOBILITY=
-    PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback QtLocation,
-                      MOZ_ENABLE_QTMOBILITY=1,
-                      MOZ_ENABLE_QTMOBILITY=)
-    if test "$MOZ_ENABLE_QTMOBILITY"; then
-       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QTMOBILITY_CFLAGS"
-       MOZ_QT_LIBS="$MOZ_QT_LIBS $_QTMOBILITY_LIBS"
-    else
-       AC_CHECK_LIB(QtSensors, main, [
-          MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtMobility"
-          MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtSensors"
-          MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtFeedback"
-          MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtLocation"
-          MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback -lQtLocation"
-       ])
-    fi
-
-    MOZ_ENABLE_QT5FEEDBACK=
-    PKG_CHECK_MODULES(_QT5FEEDBACK, Qt0Feedback,
-                      MOZ_ENABLE_QT5FEEDBACK=1,
-                      MOZ_ENABLE_QT5FEEDBACK=)
-    if test "$MOZ_ENABLE_QT5FEEDBACK"; then
-       MOZ_ENABLE_QT5FEEDBACK=1
-       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QT5FEEDBACK_CFLAGS"
-       MOZ_QT_LIBS="$MOZ_QT_LIBS $_QT5FEEDBACK_LIBS"
-       AC_DEFINE(MOZ_ENABLE_QT5FEEDBACK)
-       AC_SUBST(MOZ_ENABLE_QT5FEEDBACK)
-    fi
-
-    MOZ_ENABLE_QT5GEOPOSITION=
-    PKG_CHECK_MODULES(_QT5GEOPOSITION, Qt5Positioning,
-                      MOZ_ENABLE_QT5GEOPOSITION=1,
-                      MOZ_ENABLE_QT5GEOPOSITION=)
-    if test "$MOZ_ENABLE_QT5GEOPOSITION"; then
-       MOZ_ENABLE_QT5GEOPOSITION=1
-       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QT5GEOPOSITION_CFLAGS"
-       MOZ_QT_LIBS="$MOZ_QT_LIBS $_QT5GEOPOSITION_LIBS"
-       AC_DEFINE(MOZ_ENABLE_QT5GEOPOSITION)
-       AC_SUBST(MOZ_ENABLE_QT5GEOPOSITION)
-    fi
-
-    if test "$MOZ_ENABLE_CONTENTACTION"; then
-      MOZ_ENABLE_CONTENTACTION=1
-      AC_DEFINE(MOZ_ENABLE_CONTENTACTION)
-    fi
-
-    MOZ_ENABLE_CONTENTACTION=
-    PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
-    if test "$MOZ_ENABLE_CONTENTACTION"; then
-       MOZ_ENABLE_CONTENTACTION=1
-       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_CONTENTACTION_CFLAGS"
-       MOZ_QT_LIBS="$MOZ_QT_LIBS $_CONTENTACTION_LIBS"
-       AC_DEFINE(MOZ_ENABLE_CONTENTACTION)
-       AC_SUBST(MOZ_ENABLE_CONTENTACTION)
-    fi
-    TK_CFLAGS=$MOZ_QT_CFLAGS
-    TK_LIBS=$MOZ_QT_LIBS
-fi
-
 AC_SUBST_LIST(TK_CFLAGS)
 AC_SUBST_LIST(TK_LIBS)
 
-AC_SUBST(MOZ_ENABLE_QT)
-AC_SUBST(MOZ_ENABLE_QTNETWORK)
-AC_SUBST(MOZ_ENABLE_QMSYSTEM2)
-AC_SUBST_LIST(MOZ_QT_CFLAGS)
-AC_SUBST_LIST(MOZ_QT_LIBS)
-
 AC_SUBST(MOC)
 AC_SUBST(RCC)
 
 dnl ========================================================
 dnl =
 dnl = Components & Features
 dnl =
 dnl ========================================================
@@ -3224,17 +3053,17 @@ dnl ====================================
 MOZ_ANDROID_GOOGLE_PLAY_SERVICES
 MOZ_ANDROID_GOOGLE_CLOUD_MESSAGING
 MOZ_ANDROID_INSTALL_TRACKING
 
 
 dnl ========================================================
 dnl = Pango
 dnl ========================================================
-if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
+if test "$MOZ_ENABLE_GTK"
 then
     PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
 
     PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
 fi
 
 dnl ========================================================
 dnl = GIO and GConf support module
@@ -3309,17 +3138,17 @@ then
 
     AC_SUBST(MOZ_ENABLE_GCONF)
 fi
 
 dnl ========================================================
 dnl = libproxy support
 dnl ========================================================
 
-if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
+if test "$MOZ_ENABLE_GTK"
 then
     MOZ_ENABLE_LIBPROXY=
 
     MOZ_ARG_ENABLE_BOOL(libproxy,
     [  --enable-libproxy         Enable libproxy support ],
     MOZ_ENABLE_LIBPROXY=1,
     MOZ_ENABLE_LIBPROXY=)
 
@@ -3362,17 +3191,17 @@ then
 fi
 
 AC_SUBST(MOZ_ENABLE_GNOMEUI)
 
 dnl ========================================================
 dnl = dbus support
 dnl ========================================================
 
-if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
+if test "$MOZ_ENABLE_GTK"
 then
     MOZ_ENABLE_DBUS=1
 
     MOZ_ARG_DISABLE_BOOL(dbus,
     [  --disable-dbus          Disable dbus support ],
         MOZ_ENABLE_DBUS=,
         MOZ_ENABLE_DBUS=1)
 
@@ -3384,17 +3213,17 @@ then
     fi
 fi
 AC_SUBST(MOZ_ENABLE_DBUS)
 
 dnl ========================================================
 dnl = speech-dispatcher support
 dnl ========================================================
 
-if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
+if test "$MOZ_ENABLE_GTK"
 then
     MOZ_SYNTH_SPEECHD=1
 
     MOZ_ARG_DISABLE_BOOL(synth-speechd,
     [  --disable-synth-speechd Disable speech-dispatcher support ],
         MOZ_SYNTH_SPEECHD=,
         MOZ_SYNTH_SPEECHD=1)
 fi
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -254,17 +254,17 @@ nsNSSCertificateDB::getCertsFromPackage(
                              collectArgs) != SECSuccess) {
     return nullptr;
   }
 
   return collectArgs;
 }
 
 nsresult
-nsNSSCertificateDB::handleCACertDownload(nsIArray *x509Certs,
+nsNSSCertificateDB::handleCACertDownload(NotNull<nsIArray*> x509Certs,
                                          nsIInterfaceRequestor *ctx,
                                          const nsNSSShutDownPreventionLock &proofOfLock)
 {
   // First thing we have to do is figure out which certificate we're 
   // gonna present to the user.  The CA may have sent down a list of 
   // certs which may or may not be a chained list of certs.  Until
   // the day we can design some solid UI for the general case, we'll
   // code to the > 90% case.  That case is where a CA sends down a
@@ -279,17 +279,16 @@ nsNSSCertificateDB::handleCACertDownload
   uint32_t numCerts;
 
   x509Certs->GetLength(&numCerts);
   NS_ASSERTION(numCerts > 0, "Didn't get any certs to import.");
   if (numCerts == 0)
     return NS_OK; // Nothing to import, so nothing to do.
 
   nsCOMPtr<nsIX509Cert> certToShow;
-  nsCOMPtr<nsISupports> isupports;
   uint32_t selCertIndex;
   if (numCerts == 1) {
     // There's only one cert, so let's show it.
     selCertIndex = 0;
     certToShow = do_QueryElementAt(x509Certs, selCertIndex);
   } else {
     nsCOMPtr<nsIX509Cert> cert0;    // first cert
     nsCOMPtr<nsIX509Cert> cert1;    // second cert
@@ -332,38 +331,22 @@ nsNSSCertificateDB::handleCACertDownload
 
   if (!certToShow)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsICertificateDialogs> dialogs;
   nsresult rv = ::getNSSDialogs(getter_AddRefs(dialogs), 
                                 NS_GET_IID(nsICertificateDialogs),
                                 NS_CERTIFICATEDIALOGS_CONTRACTID);
-                       
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
     return rv;
- 
-  SECItem der;
-  rv=certToShow->GetRawDER(&der.len, (uint8_t **)&der.data);
-
-  if (NS_FAILED(rv))
-    return rv;
+  }
 
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Creating temp cert\n"));
-  CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
-  UniqueCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
+  UniqueCERTCertificate tmpCert(certToShow->GetCert());
   if (!tmpCert) {
-    tmpCert.reset(CERT_NewTempCertificate(certdb, &der, nullptr, false, true));
-  }
-  free(der.data);
-  der.data = nullptr;
-  der.len = 0;
-
-  if (!tmpCert) {
-    NS_ERROR("Couldn't create cert from DER blob");
     return NS_ERROR_FAILURE;
   }
 
   if (!CERT_IsCACert(tmpCert.get(), nullptr)) {
     DisplayCertificateAlert(ctx, "NotACACert", certToShow, proofOfLock);
     return NS_ERROR_FAILURE;
   }
 
@@ -387,22 +370,20 @@ nsNSSCertificateDB::handleCACertDownload
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Created nick \"%s\"\n", nickname.get()));
 
   nsNSSCertTrust trust;
   trust.SetValidCA();
   trust.AddCATrust(!!(trustBits & nsIX509CertDB::TRUSTED_SSL),
                    !!(trustBits & nsIX509CertDB::TRUSTED_EMAIL),
                    !!(trustBits & nsIX509CertDB::TRUSTED_OBJSIGN));
 
-  SECStatus srv = __CERT_AddTempCertToPerm(tmpCert.get(),
-                                           const_cast<char*>(nickname.get()),
-                                           trust.GetTrust());
-
-  if (srv != SECSuccess)
+  if (CERT_AddTempCertToPerm(tmpCert.get(), nickname.get(),
+                             trust.GetTrust()) != SECSuccess) {
     return NS_ERROR_FAILURE;
+  }
 
   // Import additional delivered certificates that can be verified.
 
   // build a CertList for filtering
   UniqueCERTCertList certList(CERT_NewCertList());
   if (!certList) {
     return NS_ERROR_FAILURE;
   }
@@ -410,32 +391,31 @@ nsNSSCertificateDB::handleCACertDownload
   // get all remaining certs into temp store
 
   for (uint32_t i=0; i<numCerts; i++) {
     if (i == selCertIndex) {
       // we already processed that one
       continue;
     }
 
-    certToShow = do_QueryElementAt(x509Certs, i);
-    certToShow->GetRawDER(&der.len, (uint8_t **)&der.data);
-
-    CERTCertificate *tmpCert2 = 
-      CERT_NewTempCertificate(certdb, &der, nullptr, false, true);
+    nsCOMPtr<nsIX509Cert> remainingCert = do_QueryElementAt(x509Certs, i);
+    if (!remainingCert) {
+      continue;
+    }
 
-    free(der.data);
-    der.data = nullptr;
-    der.len = 0;
-
+    UniqueCERTCertificate tmpCert2(remainingCert->GetCert());
     if (!tmpCert2) {
-      NS_ERROR("Couldn't create temp cert from DER blob");
       continue;  // Let's try to import the rest of 'em
     }
 
-    CERT_AddCertToListTail(certList.get(), tmpCert2);
+    if (CERT_AddCertToListTail(certList.get(), tmpCert2.get()) != SECSuccess) {
+      continue;
+    }
+
+    Unused << tmpCert2.release();
   }
 
   return ImportValidCACertsInList(certList, ctx, proofOfLock);
 }
 
 NS_IMETHODIMP
 nsNSSCertificateDB::ImportCertificates(uint8_t* data, uint32_t length,
                                        uint32_t type,
@@ -476,17 +456,17 @@ nsNSSCertificateDB::ImportCertificates(u
       return NS_ERROR_FAILURE;
     }
     nsresult rv = array->AppendElement(cert, false);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
-  return handleCACertDownload(array, ctx, locker);
+  return handleCACertDownload(WrapNotNull(array), ctx, locker);
 }
 
 /**
  * Filters an array of certs by usage and imports them into temporary storage.
  *
  * @param numcerts
  *        Size of the |certs| array.
  * @param certs
@@ -1355,76 +1335,59 @@ nsNSSCertificateDB::get_default_nickname
     }
     if (!dummycert) {
       break;
     }
     count++;
   }
 }
 
-NS_IMETHODIMP nsNSSCertificateDB::AddCertFromBase64(const char* aBase64,
-                                                    const char* aTrust,
-                                                    const char* aName)
+NS_IMETHODIMP
+nsNSSCertificateDB::AddCertFromBase64(const char* aBase64, const char* aTrust,
+                                      const char* /*aName*/)
 {
   NS_ENSURE_ARG_POINTER(aBase64);
-  nsCOMPtr <nsIX509Cert> newCert;
+  NS_ENSURE_ARG_POINTER(aTrust);
 
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsNSSCertTrust trust;
+  if (CERT_DecodeTrustString(trust.GetTrust(), aTrust) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
 
-  // need to calculate the trust bits from the aTrust string.
-  SECStatus stat = CERT_DecodeTrustString(trust.GetTrust(),
-    /* this is const, but not declared that way */(char *) aTrust);
-  NS_ENSURE_STATE(stat == SECSuccess); // if bad trust passed in, return error.
-
-
+  nsCOMPtr<nsIX509Cert> newCert;
   nsresult rv = ConstructX509FromBase64(aBase64, getter_AddRefs(newCert));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  SECItem der;
-  rv = newCert->GetRawDER(&der.len, (uint8_t **)&der.data);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Creating temp cert\n"));
-  CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
-  UniqueCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
+  UniqueCERTCertificate tmpCert(newCert->GetCert());
   if (!tmpCert) {
-    tmpCert.reset(CERT_NewTempCertificate(certdb, &der, nullptr, false, true));
-  }
-  free(der.data);
-  der.data = nullptr;
-  der.len = 0;
-
-  if (!tmpCert) {
-    NS_ERROR("Couldn't create cert from DER blob");
-    return MapSECStatus(SECFailure);
+    return NS_ERROR_FAILURE;
   }
 
-   // If there's already a certificate that matches this one in the database,
-   // we still want to set its trust to the given value.
+  // If there's already a certificate that matches this one in the database, we
+  // still want to set its trust to the given value.
   if (tmpCert->isperm) {
     return SetCertTrustFromString(newCert, aTrust);
   }
 
   UniquePORTString nickname(CERT_MakeCANickname(tmpCert.get()));
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Created nick \"%s\"\n", nickname.get()));
 
   rv = attemptToLogInWithDefaultPassword();
   if (NS_WARN_IF(rv != NS_OK)) {
     return rv;
   }
 
-  SECStatus srv = __CERT_AddTempCertToPerm(tmpCert.get(),
-                                           const_cast<char*>(nickname.get()),
-                                           trust.GetTrust());
+  SECStatus srv = CERT_AddTempCertToPerm(tmpCert.get(), nickname.get(),
+                                         trust.GetTrust());
   return MapSECStatus(srv);
 }
 
 NS_IMETHODIMP
 nsNSSCertificateDB::AddCert(const nsACString & aCertDER, const char *aTrust,
                             const char *aName)
 {
   nsCString base64;
--- a/security/manager/ssl/nsNSSCertificateDB.h
+++ b/security/manager/ssl/nsNSSCertificateDB.h
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsNSSCertificateDB_h
 #define nsNSSCertificateDB_h
 
 #include "ScopedNSSTypes.h"
 #include "certt.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/NotNull.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsIX509CertDB.h"
 #include "nsNSSShutDown.h"
 #include "nsString.h"
 
 class nsCString;
 class nsIArray;
@@ -53,17 +54,17 @@ private:
 
   static void DisplayCertificateAlert(nsIInterfaceRequestor *ctx, 
                                       const char *stringID, nsIX509Cert *certToShow,
                                       const nsNSSShutDownPreventionLock &proofOfLock);
 
   CERTDERCerts* getCertsFromPackage(const mozilla::UniquePLArenaPool& arena,
                                     uint8_t* data, uint32_t length,
                                     const nsNSSShutDownPreventionLock& proofOfLock);
-  nsresult handleCACertDownload(nsIArray *x509Certs, 
+  nsresult handleCACertDownload(mozilla::NotNull<nsIArray*> x509Certs,
                                 nsIInterfaceRequestor *ctx,
                                 const nsNSSShutDownPreventionLock &proofOfLock);
 
   // We don't own any NSS objects here, so no need to clean up
   virtual void virtualDestroyNSSReference() override { };
 };
 
 #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \
--- a/security/manager/ssl/nsSiteSecurityService.cpp
+++ b/security/manager/ssl/nsSiteSecurityService.cpp
@@ -199,18 +199,21 @@ SiteHPKPState::ToString(nsCString& aStri
   aString.Append(',');
   for (unsigned int i = 0; i < mSHA256keys.Length(); i++) {
     aString.Append(mSHA256keys[i]);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+const uint64_t kSixtyDaysInSeconds = 60 * 24 * 60 * 60;
+
 nsSiteSecurityService::nsSiteSecurityService()
-  : mUsePreloadList(true)
+  : mMaxMaxAge(kSixtyDaysInSeconds)
+  , mUsePreloadList(true)
   , mPreloadListTimeOffset(0)
 {
 }
 
 nsSiteSecurityService::~nsSiteSecurityService()
 {
 }
 
@@ -222,16 +225,20 @@ nsresult
 nsSiteSecurityService::Init()
 {
   // Don't access Preferences off the main thread.
   if (!NS_IsMainThread()) {
     NS_NOTREACHED("nsSiteSecurityService initialized off main thread");
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
+  mMaxMaxAge = mozilla::Preferences::GetInt(
+    "security.cert_pinning.max_max_age_seconds", kSixtyDaysInSeconds);
+  mozilla::Preferences::AddStrongObserver(this,
+    "security.cert_pinning.max_max_age_seconds");
   mUsePreloadList = mozilla::Preferences::GetBool(
     "network.stricttransportsecurity.preloadlist", true);
   mozilla::Preferences::AddStrongObserver(this,
     "network.stricttransportsecurity.preloadlist");
   mProcessPKPHeadersFromNonBuiltInRoots = mozilla::Preferences::GetBool(
     "security.cert_pinning.process_headers_from_non_builtin_roots", false);
   mozilla::Preferences::AddStrongObserver(this,
     "security.cert_pinning.process_headers_from_non_builtin_roots");
@@ -292,19 +299,19 @@ SetStorageKey(nsAutoCString& storageKey,
     default:
       NS_ASSERTION(false, "SSS:SetStorageKey got invalid type");
   }
 }
 
 // Expire times are in millis.  Since Headers max-age is in seconds, and
 // PR_Now() is in micros, normalize the units at milliseconds.
 static int64_t
-ExpireTimeFromMaxAge(int64_t maxAge)
+ExpireTimeFromMaxAge(uint64_t maxAge)
 {
-  return (PR_Now() / PR_USEC_PER_MSEC) + (maxAge * PR_MSEC_PER_SEC);
+  return (PR_Now() / PR_USEC_PER_MSEC) + ((int64_t)maxAge * PR_MSEC_PER_SEC);
 }
 
 nsresult
 nsSiteSecurityService::SetHSTSState(uint32_t aType,
                                     nsIURI* aSourceURI,
                                     int64_t maxage,
                                     bool includeSubdomains,
                                     uint32_t flags)
@@ -503,17 +510,17 @@ nsSiteSecurityService::ProcessHeaderInte
 }
 
 static uint32_t
 ParseSSSHeaders(uint32_t aType,
                 const char* aHeader,
                 bool& foundIncludeSubdomains,
                 bool& foundMaxAge,
                 bool& foundUnrecognizedDirective,
-                int64_t& maxAge,
+                uint64_t& maxAge,
                 nsTArray<nsCString>& sha256keys)
 {
   // Strict transport security and Public Key Pinning have very similar
   // Header formats.
 
   // "Strict-Transport-Security" ":" OWS
   //      STS-d  *( OWS ";" OWS STS-d  OWS)
   //
@@ -585,22 +592,22 @@ ParseSSSHeaders(uint32_t aType,
       for (size_t i = 0; i < len; i++) {
         char chr = directive->mValue.CharAt(i);
         if (chr < '0' || chr > '9') {
           SSSLOG(("SSS: invalid value for max-age directive"));
           return nsISiteSecurityService::ERROR_INVALID_MAX_AGE;
         }
       }
 
-      if (PR_sscanf(directive->mValue.get(), "%lld", &maxAge) != 1) {
+      if (PR_sscanf(directive->mValue.get(), "%llu", &maxAge) != 1) {
         SSSLOG(("SSS: could not parse delta-seconds"));
         return nsISiteSecurityService::ERROR_INVALID_MAX_AGE;
       }
 
-      SSSLOG(("SSS: parsed delta-seconds: %lld", maxAge));
+      SSSLOG(("SSS: parsed delta-seconds: %llu", maxAge));
     } else if (directive->mName.Length() == include_subd_var.Length() &&
                directive->mName.EqualsIgnoreCase(include_subd_var.get(),
                                                  include_subd_var.Length())) {
       if (foundIncludeSubdomains) {
         SSSLOG(("SSS: found two includeSubdomains directives"));
         return nsISiteSecurityService::ERROR_MULTIPLE_INCLUDE_SUBDOMAINS;
       }
 
@@ -657,17 +664,17 @@ nsSiteSecurityService::ProcessPKPHeader(
   }
   SSSLOG(("SSS: processing HPKP header '%s'", aHeader));
   NS_ENSURE_ARG(aSSLStatus);
 
   const uint32_t aType = nsISiteSecurityService::HEADER_HPKP;
   bool foundMaxAge = false;
   bool foundIncludeSubdomains = false;
   bool foundUnrecognizedDirective = false;
-  int64_t maxAge = 0;
+  uint64_t maxAge = 0;
   nsTArray<nsCString> sha256keys;
   uint32_t sssrv = ParseSSSHeaders(aType, aHeader, foundIncludeSubdomains,
                                    foundMaxAge, foundUnrecognizedDirective,
                                    maxAge, sha256keys);
   if (sssrv != nsISiteSecurityService::Success) {
     if (aFailureResult) {
       *aFailureResult = sssrv;
     }
@@ -737,16 +744,21 @@ nsSiteSecurityService::ProcessPKPHeader(
     return NS_ERROR_FAILURE;
   }
 
   // if maxAge == 0 we must delete all state, for now no hole-punching
   if (maxAge == 0) {
     return RemoveState(aType, aSourceURI, aFlags);
   }
 
+  // clamp maxAge to the maximum set by pref
+  if (maxAge > mMaxMaxAge) {
+    maxAge = mMaxMaxAge;
+  }
+
   bool chainMatchesPinset;
   rv = PublicKeyPinningService::ChainMatchesPinset(certList, sha256keys,
                                                    chainMatchesPinset);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (!chainMatchesPinset) {
     // is invalid
@@ -780,30 +792,30 @@ nsSiteSecurityService::ProcessPKPHeader(
       *aFailureResult = nsISiteSecurityService::ERROR_NO_BACKUP_PIN;
     }
     return NS_ERROR_FAILURE;
   }
 
   int64_t expireTime = ExpireTimeFromMaxAge(maxAge);
   SiteHPKPState dynamicEntry(expireTime, SecurityPropertySet,
                              foundIncludeSubdomains, sha256keys);
-  SSSLOG(("SSS: about to set pins for  %s, expires=%ld now=%ld maxAge=%ld\n",
+  SSSLOG(("SSS: about to set pins for  %s, expires=%ld now=%ld maxAge=%lu\n",
            host.get(), expireTime, PR_Now() / PR_USEC_PER_MSEC, maxAge));
 
   rv = SetHPKPState(host.get(), dynamicEntry, aFlags);
   if (NS_FAILED(rv)) {
     SSSLOG(("SSS: failed to set pins for %s\n", host.get()));
     if (aFailureResult) {
       *aFailureResult = nsISiteSecurityService::ERROR_COULD_NOT_SAVE_STATE;
     }
     return rv;
   }
 
   if (aMaxAge != nullptr) {
-    *aMaxAge = (uint64_t)maxAge;
+    *aMaxAge = maxAge;
   }
 
   if (aIncludeSubdomains != nullptr) {
     *aIncludeSubdomains = foundIncludeSubdomains;
   }
 
   return foundUnrecognizedDirective
            ? NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
@@ -822,17 +834,17 @@ nsSiteSecurityService::ProcessSTSHeader(
     *aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
   }
   SSSLOG(("SSS: processing HSTS header '%s'", aHeader));
 
   const uint32_t aType = nsISiteSecurityService::HEADER_HSTS;
   bool foundMaxAge = false;
   bool foundIncludeSubdomains = false;
   bool foundUnrecognizedDirective = false;
-  int64_t maxAge = 0;
+  uint64_t maxAge = 0;
   nsTArray<nsCString> unusedSHA256keys; // Required for sane internal interface
 
   uint32_t sssrv = ParseSSSHeaders(aType, aHeader, foundIncludeSubdomains,
                                    foundMaxAge, foundUnrecognizedDirective,
                                    maxAge, unusedSHA256keys);
   if (sssrv != nsISiteSecurityService::Success) {
     if (aFailureResult) {
       *aFailureResult = sssrv;
@@ -857,17 +869,17 @@ nsSiteSecurityService::ProcessSTSHeader(
     SSSLOG(("SSS: failed to set STS state"));
     if (aFailureResult) {
       *aFailureResult = nsISiteSecurityService::ERROR_COULD_NOT_SAVE_STATE;
     }
     return rv;
   }
 
   if (aMaxAge != nullptr) {
-    *aMaxAge = (uint64_t)maxAge;
+    *aMaxAge = maxAge;
   }
 
   if (aIncludeSubdomains != nullptr) {
     *aIncludeSubdomains = foundIncludeSubdomains;
   }
 
   return foundUnrecognizedDirective
            ? NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
@@ -1197,12 +1209,14 @@ nsSiteSecurityService::Observe(nsISuppor
 
   if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
     mUsePreloadList = mozilla::Preferences::GetBool(
       "network.stricttransportsecurity.preloadlist", true);
     mPreloadListTimeOffset =
       mozilla::Preferences::GetInt("test.currentTimeOffsetSeconds", 0);
     mProcessPKPHeadersFromNonBuiltInRoots = mozilla::Preferences::GetBool(
       "security.cert_pinning.process_headers_from_non_builtin_roots", false);
+    mMaxMaxAge = mozilla::Preferences::GetInt(
+      "security.cert_pinning.max_max_age_seconds", kSixtyDaysInSeconds);
   }
 
   return NS_OK;
 }
--- a/security/manager/ssl/nsSiteSecurityService.h
+++ b/security/manager/ssl/nsSiteSecurityService.h
@@ -140,15 +140,16 @@ private:
   nsresult ProcessPKPHeader(nsIURI* aSourceURI, const char* aHeader,
                             nsISSLStatus* aSSLStatus, uint32_t flags,
                             uint64_t* aMaxAge, bool* aIncludeSubdomains,
                             uint32_t* aFailureResult);
   nsresult SetHPKPState(const char* aHost, SiteHPKPState& entry, uint32_t flags);
 
   const nsSTSPreload *GetPreloadListEntry(const char *aHost);
 
+  uint64_t mMaxMaxAge;
   bool mUsePreloadList;
   int64_t mPreloadListTimeOffset;
   bool mProcessPKPHeadersFromNonBuiltInRoots;
   RefPtr<mozilla::DataStorage> mSiteStateStorage;
 };
 
 #endif // __nsSiteSecurityService_h__
--- a/security/manager/ssl/tests/unit/test_pinning_header_parsing.js
+++ b/security/manager/ssl/tests/unit/test_pinning_header_parsing.js
@@ -27,72 +27,84 @@ function checkFailParseInvalidPin(pinVal
                         certFromFile('a.pinning2.example.com-pinningroot'));
   let uri = Services.io.newURI("https://a.pinning2.example.com", null, null);
   throws(() => {
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
                              pinValue, sslStatus, 0);
   }, /NS_ERROR_FAILURE/, `Invalid pin "${pinValue}" should be rejected`);
 }
 
-function checkPassValidPin(pinValue, settingPin) {
+function checkPassValidPin(pinValue, settingPin, expectedMaxAge) {
   let sslStatus = new FakeSSLStatus(
                         certFromFile('a.pinning2.example.com-pinningroot'));
   let uri = Services.io.newURI("https://a.pinning2.example.com", null, null);
+  let maxAge = {};
 
   // setup preconditions for the test, if setting ensure there is no previous
   // state, if removing ensure there is a valid pin in place.
   if (settingPin) {
     gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
   } else {
     // add a known valid pin!
     let validPinValue = "max-age=5000;" + VALID_PIN1 + BACKUP_PIN1;
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
                              validPinValue, sslStatus, 0);
   }
   try {
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                             pinValue, sslStatus, 0);
+                             pinValue, sslStatus, 0, maxAge);
     ok(true, "Valid pin should be accepted");
   } catch (e) {
     ok(false, "Valid pin should have been accepted");
   }
+
+  // check that maxAge was processed correctly
+  if (settingPin && expectedMaxAge) {
+    ok(maxAge.value == expectedMaxAge, `max-age value should be ${expectedMaxAge}`);
+  }
+
   // after processing ensure that the postconditions are true, if setting
   // the host must be pinned, if removing the host must not be pinned
   let hostIsPinned = gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
                                              "a.pinning2.example.com", 0);
   if (settingPin) {
     ok(hostIsPinned, "Host should be considered pinned");
   } else {
     ok(!hostIsPinned, "Host should not be considered pinned");
   }
 }
 
-function checkPassSettingPin(pinValue) {
-  return checkPassValidPin(pinValue, true);
+function checkPassSettingPin(pinValue, expectedMaxAge) {
+  return checkPassValidPin(pinValue, true, expectedMaxAge);
 }
 
 function checkPassRemovingPin(pinValue) {
   return checkPassValidPin(pinValue, false);
 }
 
+const MAX_MAX_AGE_SECONDS = 100000;
+const GOOD_MAX_AGE_SECONDS = 69403;
+const LONG_MAX_AGE_SECONDS = 2 * MAX_MAX_AGE_SECONDS;
 const NON_ISSUED_KEY_HASH1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
 const NON_ISSUED_KEY_HASH2 = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ=";
 const PINNING_ROOT_KEY_HASH = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=";
 const MAX_AGE_ZERO = "max-age=0;";
 const VALID_PIN1 = `pin-sha256="${PINNING_ROOT_KEY_HASH}";`;
 const BACKUP_PIN1 = `pin-sha256="${NON_ISSUED_KEY_HASH1}";`;
 const BACKUP_PIN2 = `pin-sha256="${NON_ISSUED_KEY_HASH2}";`;
 const BROKEN_PIN1 = "pin-sha256=\"jdjsjsjs\";";
-const GOOD_MAX_AGE = "max-age=69403;";
+const GOOD_MAX_AGE = `max-age=${GOOD_MAX_AGE_SECONDS};`;
+const LONG_MAX_AGE = `max-age=${LONG_MAX_AGE_SECONDS};`;
 const INCLUDE_SUBDOMAINS = "includeSubdomains;";
 const REPORT_URI = "report-uri=\"https://www.example.com/report/\";";
 const UNRECOGNIZED_DIRECTIVE = "unreconized-dir=12343;";
 
 function run_test() {
   Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
+  Services.prefs.setIntPref("security.cert_pinning.max_max_age_seconds", MAX_MAX_AGE_SECONDS);
   Services.prefs.setBoolPref("security.cert_pinning.process_headers_from_non_builtin_roots", true);
 
   loadCert("pinningroot", "CTu,CTu,CTu");
   loadCert("badca", "CTu,CTu,CTu");
 
   checkFailParseInvalidPin("max-age=INVALID");
   // check that incomplete headers are failure
   checkFailParseInvalidPin(GOOD_MAX_AGE);
@@ -110,16 +122,19 @@ function run_test() {
   checkFailParseInvalidPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN1 + REPORT_URI + REPORT_URI);
   checkFailParseInvalidPin("thisisinvalidtest");
   checkFailParseInvalidPin("invalid" + GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN1);
 
   checkPassRemovingPin("max-age=0"); //test removal without terminating ';'
   checkPassRemovingPin(MAX_AGE_ZERO);
   checkPassRemovingPin(MAX_AGE_ZERO + VALID_PIN1);
 
+  checkPassSettingPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN1, GOOD_MAX_AGE_SECONDS);
+  checkPassSettingPin(LONG_MAX_AGE + VALID_PIN1 + BACKUP_PIN1, MAX_MAX_AGE_SECONDS);
+
   checkPassRemovingPin(VALID_PIN1 + MAX_AGE_ZERO + VALID_PIN1);
   checkPassSettingPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN1);
   checkPassSettingPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN2);
   checkPassSettingPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN2 + INCLUDE_SUBDOMAINS);
   checkPassSettingPin(VALID_PIN1 + GOOD_MAX_AGE + BACKUP_PIN2 + INCLUDE_SUBDOMAINS);
   checkPassSettingPin(VALID_PIN1 + GOOD_MAX_AGE + BACKUP_PIN2 + REPORT_URI + INCLUDE_SUBDOMAINS);
   checkPassSettingPin(INCLUDE_SUBDOMAINS + VALID_PIN1 + GOOD_MAX_AGE + BACKUP_PIN2);
   checkPassSettingPin(GOOD_MAX_AGE + VALID_PIN1 + BACKUP_PIN1 + UNRECOGNIZED_DIRECTIVE);
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -675,17 +675,17 @@ class Marionette(object):
                     data["parameters"] = params
                 self.client.send(data)
                 msg = self.client.receive()
 
             else:
                 msg = self.client.request(name, params)
 
         except IOError:
-            if self.instance and not hasattr(self.instance, 'detached'):
+            if self.instance:
                 # If we've launched the binary we've connected to, wait
                 # for it to shut down.
                 returncode = self.instance.runner.wait(timeout=self.DEFAULT_STARTUP_TIMEOUT)
                 raise IOError("process died with returncode %s" % returncode)
             raise
 
         except socket.timeout:
             self.session = None
@@ -1033,26 +1033,30 @@ class Marionette(object):
             # Values here correspond to constants in nsIAppStartup.
             # See http://mzl.la/1X0JZsC
             restart_flags = [
                 "eForceQuit",
                 "eRestart",
             ]
             self._send_message("quitApplication", {"flags": restart_flags})
             self.client.close()
-            # The instance is restarting itself; we will no longer be able to
-            # track it by pid, so mark it as 'detached'.
-            self.instance.detached = True
         else:
             self.delete_session()
             self.instance.restart(clean=clean)
+
         self.raise_for_port(self.wait_for_port())
         self.start_session(session_id=self.session_id)
         self._reset_timeouts()
 
+        if in_app:
+            # In some cases Firefox restarts itself by spawning into a new process group.
+            # As long as mozprocess cannot track that behavior (bug 1284864) we assist by
+            # informing about the new process id.
+            self.instance.runner.process_handler.check_for_detached(self.session['processId'])
+
     def absolute_url(self, relative_url):
         '''
         Returns an absolute url for files served from Marionette's www directory.
 
         :param relative_url: The url of a static file, relative to Marionette's www directory.
         '''
         return "%s%s" % (self.baseurl, relative_url)
 
--- a/testing/marionette/client/requirements.txt
+++ b/testing/marionette/client/requirements.txt
@@ -1,1 +1,1 @@
-mozrunner >= 6.9
+mozrunner >= 6.12
deleted file mode 100644
--- a/testing/web-platform/meta/cors/redirect-preflight.htm.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[redirect-preflight.htm]
-  type: testharness
-  [Disallow redirect 301 after succesful (200) preflight]
-    expected: FAIL
-
-  [Disallow redirect 302 after succesful (200) preflight]
-    expected: FAIL
-
-  [Disallow redirect 303 after succesful (200) preflight]
-    expected: FAIL
-
-  [Disallow redirect 307 after succesful (200) preflight]
-    expected: FAIL
-
-  [Disallow redirect 308 after succesful (200) preflight]
-    expected: FAIL
-
--- a/testing/web-platform/tests/cors/resources/cors-makeheader.py
+++ b/testing/web-platform/tests/cors/resources/cors-makeheader.py
@@ -23,17 +23,21 @@ def main(request, response):
     #Preflight
     if 'headers' in request.GET:
         response.headers.set("Access-Control-Allow-Headers", request.GET.first('headers'))
     if 'credentials' in request.GET:
         response.headers.set("Access-Control-Allow-Credentials", request.GET.first('credentials'))
     if 'methods' in request.GET:
         response.headers.set("Access-Control-Allow-Methods", request.GET.first('methods'))
 
-    code = request.GET.first('code', None)
+    code_raw = request.GET.first('code', None)
+    if code_raw:
+        code = int(code_raw)
+    else:
+        code = None
     if request.method == 'OPTIONS':
         #Override the response code if we're in a preflight and it's asked
         if 'preflight' in request.GET:
             code = int(request.GET.first('preflight'))
 
         #Log that the preflight actually happened if we have an ident
         if 'token' in request.GET:
             request.server.stash.put(request.GET['token'], True)
@@ -56,9 +60,8 @@ def main(request, response):
     headers['get_value'] = request.GET.first('get_value', '')
 
     body = json.dumps(headers)
 
     if code:
         return (code, "StatusText"), [], body
     else:
         return body
-
--- a/toolkit/components/extensions/NativeMessaging.jsm
+++ b/toolkit/components/extensions/NativeMessaging.jsm
@@ -197,23 +197,25 @@ this.NativeApp = class extends EventEmit
           // here.  If it is relative, we get the proper absolute path here.
           command = OS.Path.join(OS.Path.dirname(hostInfo.path), command);
         }
 
         let subprocessOpts = {
           command: command,
           arguments: [hostInfo.path],
           workdir: OS.Path.dirname(command),
+          stderr: "pipe",
         };
         return Subprocess.call(subprocessOpts);
       }).then(proc => {
         this.startupPromise = null;
         this.proc = proc;
         this._startRead();
         this._startWrite();
+        this._startStderrRead();
       }).catch(err => {
         this.startupPromise = null;
         Cu.reportError(err.message);
         this._cleanup(err);
       });
   }
 
   // A port is definitely "alive" if this.proc is non-null.  But we have
@@ -263,16 +265,42 @@ this.NativeApp = class extends EventEmit
       this.writePromise = null;
       this._startWrite();
     }).catch(err => {
       Cu.reportError(err.message);
       this._cleanup(err);
     });
   }
 
+  _startStderrRead() {
+    let proc = this.proc;
+    let app = this.name;
+    Task.spawn(function* () {
+      let partial = "";
+      while (true) {
+        let data = yield proc.stderr.readString();
+        if (data.length == 0) {
+          // We have hit EOF, just stop reading
+          if (partial) {
+            Services.console.logStringMessage(`stderr output from native app ${app}: ${partial}`);
+          }
+          break;
+        }
+
+        let lines = data.split(/\r?\n/);
+        lines[0] = partial + lines[0];
+        partial = lines.pop();
+
+        for (let line of lines) {
+          Services.console.logStringMessage(`stderr output from native app ${app}: ${line}`);
+        }
+      }
+    });
+  }
+
   send(msg) {
     if (this._isDisconnected) {
       throw new this.context.cloneScope.Error("Attempt to postMessage on disconnected port");
     }
 
     let json;
     try {
       json = this.context.jsonStringify(msg);
--- a/toolkit/components/extensions/test/mochitest/.eslintrc
+++ b/toolkit/components/extensions/test/mochitest/.eslintrc
@@ -4,14 +4,15 @@
   "env": {
     "webextensions": true,
   },
 
   "globals": {
     "sendAsyncMessage": false,
 
     "waitForLoad": true,
+    "promiseConsoleOutput": true,
 
     "ExtensionTestUtils": false,
     "NetUtil": true,
     "XPCOMUtils": true,
   },
 }
--- a/toolkit/components/extensions/test/mochitest/chrome.ini
+++ b/toolkit/components/extensions/test/mochitest/chrome.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 support-files =
+  head.js
   file_download.html
   file_download.txt
   interruptible.sjs
   file_sample.html
 
 [test_chrome_ext_background_debug_global.html]
 skip-if = (os == 'android') # android doesn't have devtools
 [test_chrome_ext_background_page.html]
--- a/toolkit/components/extensions/test/mochitest/head.js
+++ b/toolkit/components/extensions/test/mochitest/head.js
@@ -5,8 +5,9 @@
 function waitForLoad(win) {
   return new Promise(resolve => {
     win.addEventListener("load", function listener() {
       win.removeEventListener("load", listener, true);
       resolve();
     }, true);
   });
 }
+
--- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_native_messaging.html
+++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_native_messaging.html
@@ -1,38 +1,66 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>WebExtension test</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
   <script type="text/javascript" src="head.js"></script>
-  <script type="text/javascript" src="test_constants.js"></script>
   <link rel="stylesheet" href="chrome://mochikit/contents/tests/SimpleTest/test.css"/>
 </head>
 <body>
 
 <script type="text/javascript">
 "use strict";
 
 /* globals OS */
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 let {Subprocess, SubprocessImpl} = Cu.import("resource://gre/modules/Subprocess.jsm");
+Components.utils.import("resource://gre/modules/Task.jsm");
 
 if (AppConstants.platform == "win") {
   Cu.import("resource://testing-common/MockRegistry.jsm");
 }
 
+var promiseConsoleOutput = Task.async(function* (task) {
+  const DONE = "=== extension test console listener done ===";
+
+  let listener;
+  let messages = [];
+  let awaitListener = new Promise(resolve => {
+    listener = msg => {
+      if (msg == DONE) {
+        resolve();
+      } else if (msg instanceof Ci.nsIConsoleMessage) {
+        messages.push(msg.message);
+      }
+    };
+  });
+
+  Services.console.registerListener(listener);
+  try {
+    let result = yield task();
+
+    Services.console.logStringMessage(DONE);
+    yield awaitListener;
+
+    return {messages, result};
+  } finally {
+    Services.console.unregisterListener(listener);
+  }
+});
+
 const PREF_MAX_READ = "webextensions.native-messaging.max-input-message-bytes";
 const PREF_MAX_WRITE = "webextensions.native-messaging.max-output-message-bytes";
 
 function getSubprocessCount() {
   return SubprocessImpl.Process.getWorker().call("getProcesses", [])
                        .then(result => result.size);
 }
 function waitForSubprocessExit() {
@@ -91,32 +119,52 @@ while True:
         signal.pause()
     msglen = struct.unpack('@I', rawlen)[0]
     msg = sys.stdin.read(msglen)
 
     sys.stdout.write(struct.pack('@I', msglen))
     sys.stdout.write(msg)
 `;
 
+const STDERR_LINES = ["hello stderr", "this should be a separate line"];
+let STDERR_MSG = STDERR_LINES.join("\\n");
+
+// Python apparently line-buffers stderr even with the -u arg on
+// Windows 7.  Dealing with that is more hassle than its worth but
+// on other platforms, we want to keep testing partial lines.
+if (AppConstants.isPlatformAndVersionAtMost("win", "7")) {
+  STDERR_MSG += "\\n";
+}
+
+const STDERR_BODY = String.raw`
+import sys
+sys.stderr.write("${STDERR_MSG}")
+`;
+
 const SCRIPTS = [
   {
     name: "echo",
     description: "a native app that echoes back messages it receives",
     script: ECHO_BODY,
   },
   {
     name: "info",
     description: "a native app that gives some info about how it was started",
     script: INFO_BODY,
   },
   {
     name: "wontdie",
     description: "a native app that does not exit when stdin closes or on SIGTERM",
     script: WONTDIE_BODY,
   },
+  {
+    name: "stderr",
+    description: "a native app that writes to stderr and then exits",
+    script: STDERR_BODY,
+  },
 ];
 
 add_task(function* setup() {
   const PERMS = {unixMode: 0o755};
   let pythonPath = yield Subprocess.pathSearch("python2.7").catch(err => {
     if (err.errorCode != Subprocess.ERROR_BAD_EXECUTABLE) {
       throw err;
     }
@@ -605,12 +653,41 @@ add_task(function* test_unresponsive_nat
   let exitPromise = waitForSubprocessExit();
   yield extension.unload();
   yield exitPromise;
 
   procCount = yield getSubprocessCount();
   is(procCount, 0, "subprocess was succesfully killed");
 });
 
+add_task(function* test_stderr() {
+  function background() {
+    let port = browser.runtime.connectNative("stderr");
+    port.onDisconnect.addListener(() => {
+      browser.test.sendMessage("finished");
+    });
+  }
+
+  let {messages} = yield promiseConsoleOutput(function* () {
+    let extension = ExtensionTestUtils.loadExtension({
+      background: `(${background})()`,
+      manifest: {
+        permissions: ["nativeMessaging"],
+      },
+    }, ID);
+
+    yield extension.startup();
+    yield extension.awaitMessage("finished");
+    yield extension.unload();
+  });
+
+  let lines = STDERR_LINES.map(line => messages.findIndex(msg => msg.includes(line)));
+  isnot(lines[0], -1, "Saw first line of stderr output on the console");
+  isnot(lines[1], -1, "Saw second line of stderr output on the console");
+  isnot(lines[0], lines[1], "Stderr output lines are separated in the console");
+
+  yield waitForSubprocessExit();
+});
+
 </script>
 
 </body>
 </html>
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -9569,33 +9569,33 @@
     "kind": "enumerated",
     "n_values": 64,
     "description": "Count of scroll actions triggered by different input methods. See gfx/layers/apz/util/ScrollInputMethods.h for a list of possible values and their meanings."
   },
   "WEB_NOTIFICATION_CLICKED": {
     "releaseChannelCollection": "opt-out",
     "alert_emails": ["firefox-dev@mozilla.org"],
     "bug_numbers": [1225336],
-    "expires_in_version": "50",
+    "expires_in_version": "55",
     "kind": "count",
     "description": "Count of times a web notification was clicked"
   },
   "WEB_NOTIFICATION_MENU": {
     "alert_emails": ["firefox-dev@mozilla.org"],
     "bug_numbers": [1225336],
     "expires_in_version": "50",
     "kind": "enumerated",
     "n_values": 5,
     "description": "Count of times a contextual menu item was used from a Notification (0: DND, 1: Disable, 2: Settings)"
   },
   "WEB_NOTIFICATION_SHOWN": {
     "releaseChannelCollection": "opt-out",
     "alert_emails": ["firefox-dev@mozilla.org"],
     "bug_numbers": [1225336],
-    "expires_in_version": "50",
+    "expires_in_version": "55",
     "kind": "count",
     "description": "Count of times a Notification was rendered (accounting for XUL DND). A system backend may put the notification directly into the tray if its own DND is on."
   },
   "WEBFONT_DOWNLOAD_TIME": {
     "alert_emails": ["jdaggett@mozilla.com"],
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 60000,
@@ -9687,17 +9687,17 @@
     "expires_in_version": "50",
     "kind": "count",
     "description": "Number of times the Notification Permissions dialog has been opened."
   },
   "WEB_NOTIFICATION_PERMISSIONS": {
     "releaseChannelCollection": "opt-out",
     "alert_emails": ["firefox-dev@mozilla.org"],
     "bug_numbers": [1219030],
-    "expires_in_version": "50",
+    "expires_in_version": "55",
     "kind": "enumerated",
     "n_values": 10,
     "description": "Number of origins with the web notifications permission (0 = denied, 1 = allowed)."
   },
   "WEB_NOTIFICATION_PERMISSION_REMOVED": {
     "alert_emails": ["firefox-dev@mozilla.org"],
     "bug_numbers": [1219030],
     "expires_in_version": "50",
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
@@ -122,17 +122,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3
         'mozgtk_stub',
     ]
 
 if CONFIG['MOZ_JPROF']:
     USE_LIBS += [
         'jprof',
     ]
 
-if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT'] or CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt' or \
+if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT'] or \
         CONFIG['MOZ_TREE_FREETYPE']:
     USE_LIBS += [
         'freetype',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     CXXFLAGS += CONFIG['TK_CFLAGS']
 
@@ -297,23 +297,16 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']
     OS_LIBS += CONFIG['XLIBS']
     OS_LIBS += CONFIG['XEXT_LIBS']
     OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
     OS_LIBS += CONFIG['XT_LIBS']
     OS_LIBS += [
         'gthread-2.0',
     ]
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    OS_LIBS += CONFIG['XLDFLAGS']
-    OS_LIBS += CONFIG['XLIBS']
-    OS_LIBS += CONFIG['XT_LIBS']
-    OS_LIBS += CONFIG['MOZ_QT_LIBS']
-    OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
-
 if CONFIG['MOZ_ENABLE_STARTUP_NOTIFICATION']:
     OS_LIBS += CONFIG['MOZ_STARTUP_NOTIFICATION_LIBS']
 
 if CONFIG['MOZ_ENABLE_LIBPROXY']:
     OS_LIBS += CONFIG['MOZ_LIBPROXY_LIBS']
 
 if CONFIG['OS_ARCH'] == 'SunOS':
     OS_LIBS += [
@@ -359,19 +352,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
         'locationapi',
         'sapi',
     ]
     if CONFIG['ACCESSIBILITY']:
         OS_LIBS += [
             'oleacc',
         ]
 
-if CONFIG['MOZ_ENABLE_QT']:
-    OS_LIBS += CONFIG['XEXT_LIBS']
-
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     OS_LIBS += [
         'usp10',
         'oleaut32',
     ]
 
 # This needs to be last
 USE_LIBS += ['StaticXULComponentsEnd']
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -93,17 +93,17 @@ set_config('L10NBASEDIR', l10n_base)
 # ==============================================================
 # Normally, we'd want to use the `default` field on the option, but that
 # requires --target to be resolved at --help time, which requires to run
 # config.guess, which we want to avoid. Even better, we could actually set
 # `choices` depending on the target, but that doesn't pan out for the same
 # reason.
 option('--enable-default-toolkit', nargs=1,
        choices=('cairo-windows', 'cairo-gtk2', 'cairo-gtk2-x11', 'cairo-gtk3',
-                'cairo-qt', 'cairo-cocoa', 'cairo-uikit', 'cairo-android',
+                'cairo-cocoa', 'cairo-uikit', 'cairo-android',
                 'cairo-gonk'),
        help='Select default toolkit')
 
 @depends('--enable-default-toolkit', target)
 def toolkit(value, target):
     # Define possible choices for each platform. The default is the first one
     # listed when there are several.
     os = target.os
@@ -116,18 +116,17 @@ def toolkit(value, target):
     elif target.os == 'Android':
         if value.origin == 'implied':
             # Trust values coming from imply_option() (used in
             # b2g/moz.configure).
             platform_choices = tuple(value)
         else:
             platform_choices = ('cairo-android',)
     else:
-        platform_choices = ('cairo-gtk3', 'cairo-gtk2', 'cairo-gtk2-x11',
-                            'cairo-qt')
+        platform_choices = ('cairo-gtk3', 'cairo-gtk2', 'cairo-gtk2-x11')
 
     if value:
         if value[0] not in platform_choices:
             die('`%s` is not a valid value for --enable-default-toolkit on %s\n'
                 'Valid values: %s', value[0], os, ', '.join(platform_choices))
         return value[0]
 
     return platform_choices[0]
@@ -160,20 +159,20 @@ def toolkit_define(toolkit):
 
 set_define(toolkit_define, True)
 
 
 option('--without-x', env='WITHOUT_X', help='Disable X11 support')
 
 @depends('--without-x', toolkit)
 def x11(value, toolkit):
-    if not value and toolkit != 'qt':
-        die('--without-x is only valid with --enable-default-toolkit=qt')
+    if not value:
+        die('--without-x is not supported')
 
-    x11_toolkits = ('gtk2', 'gtk3', 'qt')
+    x11_toolkits = ('gtk2', 'gtk3')
     if value and value.origin != 'default' and toolkit not in x11_toolkits:
         die('--with-x is only valid with --enable-default-toolkit={%s}',
             ','.join(x11_toolkits))
 
     return True if value and toolkit in x11_toolkits else None
 
 set_config('MOZ_ENABLE_XREMOTE', x11)
 set_define('MOZ_ENABLE_XREMOTE', x11)
@@ -214,17 +213,17 @@ def gl_provider_define(provider):
 
 set_define(gl_provider_define, True)
 
 
 # PDF printing
 # ==============================================================
 @depends(toolkit)
 def pdf_printing(toolkit):
-    if toolkit in ('windows', 'gtk2', 'gtk3', 'qt', 'android', 'gonk'):
+    if toolkit in ('windows', 'gtk2', 'gtk3', 'android', 'gonk'):
         return True
 
 @depends(pdf_printing)
 def pdf_surface_feature(pdf_printing):
     if pdf_printing:
         return '#define CAIRO_HAS_PDF_SURFACE 1'
     else:
         # CONFIGURE_SUBST_FILES need explicit empty values.
@@ -251,17 +250,17 @@ set_define('MOZ_INSTRUMENT_EVENT_LOOP', 
 
 # Fontconfig Freetype
 # ==============================================================
 option(env='USE_FC_FREETYPE',
        help='Force-enable the use of fontconfig freetype')
 
 @depends('USE_FC_FREETYPE', toolkit)
 def fc_freetype(value, toolkit):
-    if value or (toolkit in ('gtk2', 'gtk3', 'qt') and
+    if value or (toolkit in ('gtk2', 'gtk3') and
                  value.origin == 'default'):
         return True
 
 add_old_configure_assignment('USE_FC_FREETYPE', fc_freetype)
 
 
 # Apple platform decoder support
 # ==============================================================
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -605,153 +605,16 @@ ProcessDDE(nsINativeAppSupport* aNative,
  * @return true in all environments
 */
 static bool
 CanShowProfileManager()
 {
   return true;
 }
 
-#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
-static already_AddRefed<nsIFile>
-GetAndCleanTempDir()
-{
-  // Get the directory within which we'll place the
-  // sandbox-writable temp directory
-  nsCOMPtr<nsIFile> tempDir;
-  nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
-                                       getter_AddRefs(tempDir));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-
-  // If the NS_APP_CONTENT_PROCESS_TEMP_DIR is the real temp directory, don't
-  // attempt to delete it.
-  nsCOMPtr<nsIFile> realTempDir;
-  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(realTempDir));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-  bool isRealTemp;
-  rv = tempDir->Equals(realTempDir, &isRealTemp);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-  if (isRealTemp) {
-    return tempDir.forget();
-  }
-
-  // Don't return an error if the directory doesn't exist.
-  // Windows Remove() returns NS_ERROR_FILE_NOT_FOUND while
-  // OS X returns NS_ERROR_FILE_TARGET_DOES_NOT_EXIST.
-  rv = tempDir->Remove(/* aRecursive */ true);
-  if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND &&
-      rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
-    NS_WARNING("Failed to delete temp directory.");
-    return nullptr;
-  }
-
-  return tempDir.forget();
-}
-
-static void
-SetUpSandboxEnvironment()
-{
-  // Setup a sandbox-writable temp directory. i.e., a directory
-  // that is writable by a sandboxed content process. This
-  // only applies when e10s is enabled, depending on the platform
-  // and setting of security.sandbox.content.level.
-  if (!BrowserTabsRemoteAutostart()) {
-    return;
-  }
-
-#if defined(XP_WIN)
-  // For Windows, the temp dir only makes sense for Vista and later
-  // with a sandbox pref level >= 1
-  if (!IsVistaOrLater() ||
-      (Preferences::GetInt("security.sandbox.content.level") < 1)) {
-    return;
-  }
-#endif
-
-#if defined(XP_MACOSX)
-  // For OSX, we just require sandbox pref level >= 1.
-  if (Preferences::GetInt("security.sandbox.content.level") < 1) {
-    return;
-  }
-#endif
-
-  // Get (and create if blank) temp directory suffix pref.
-  nsresult rv;
-  nsAdoptingString tempDirSuffix =
-    Preferences::GetString("security.sandbox.content.tempDirSuffix");
-  if (tempDirSuffix.IsEmpty()) {
-    nsCOMPtr<nsIUUIDGenerator> uuidgen =
-      do_GetService("@mozilla.org/uuid-generator;1", &rv);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    nsID uuid;
-    rv = uuidgen->GenerateUUIDInPlace(&uuid);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    char uuidChars[NSID_LENGTH];
-    uuid.ToProvidedString(uuidChars);
-    tempDirSuffix.AssignASCII(uuidChars);
-
-    // Save the pref to be picked up later.
-    rv = Preferences::SetCString("security.sandbox.content.tempDirSuffix",
-                                 uuidChars);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      // If we fail to save the pref we don't want to create the temp dir,
-      // because we won't be able to clean it up later.
-      return;
-    }
-
-    nsCOMPtr<nsIPrefService> prefsvc = Preferences::GetService();
-    if (!prefsvc || NS_FAILED(prefsvc->SavePrefFile(nullptr))) {
-      // Again, if we fail to save the pref file we might not be able to clean
-      // up the temp directory, so don't create one.
-      NS_WARNING("Failed to save pref file, cannot create temp dir.");
-      return;
-    }
-  }
-
-  // Get (and clean up if still there) the sandbox-writable temp directory.
-  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
-  if (!tempDir) {
-    NS_WARNING("Failed to get or clean sandboxed temp directory.");
-    return;
-  }
-
-  rv = tempDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-}
-
-static void
-CleanUpSandboxEnvironment()
-{
-#if defined(XP_WIN)
-  // We can't have created the temp directory before Vista.
-  if (!IsVistaOrLater()) {
-    return;
-  }
-#endif
-
-  // Get and remove the sandbox-writable temp directory.
-  // This function already warns if the deletion fails.
-  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
-}
-#endif
-
 bool gSafeMode = false;
 
 /**
  * The nsXULAppInfo object implements nsIFactory so that it can be its own
  * singleton.
  */
 class nsXULAppInfo : public nsIXULAppInfo,
                      public nsIObserver,
@@ -4377,32 +4240,25 @@ XREMain::XRE_mainRun()
   }
 #endif /* MOZ_INSTRUMENT_EVENT_LOOP */
 
 #if defined(MOZ_SANDBOX) && defined(XP_LINUX) && !defined(ANDROID)
   // If we're on Linux, we now have information about the OS capabilities
   // available to us.
   SandboxInfo::SubmitTelemetry();
 #endif
-#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
-  SetUpSandboxEnvironment();
-#endif
 
   {
     rv = appStartup->Run();
     if (NS_FAILED(rv)) {
       NS_ERROR("failed to run appstartup");
       gLogConsoleErrors = true;
     }
   }
 
-#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
-  CleanUpSandboxEnvironment();
-#endif
-
   return rv;
 }
 
 #if MOZ_WIDGET_GTK == 2
 void XRE_GlibInit()
 {
   static bool ran_once = false;
 
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -55,26 +55,39 @@
 #endif
 #ifdef XP_UNIX
 #include <ctype.h>
 #endif
 #ifdef XP_IOS
 #include "UIKitDirProvider.h"
 #endif
 
+#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+#include "nsIUUIDGenerator.h"
+#include "mozilla/unused.h"
+#endif
+
 #if defined(XP_MACOSX)
 #define APP_REGISTRY_NAME "Application Registry"
 #elif defined(XP_WIN)
 #define APP_REGISTRY_NAME "registry.dat"
 #else
 #define APP_REGISTRY_NAME "appreg"
 #endif
 
 #define PREF_OVERRIDE_DIRNAME "preferences"
 
+#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+static already_AddRefed<nsIFile> GetContentProcessSandboxTempDir();
+static nsresult DeleteDirIfExists(nsIFile *dir);
+static bool IsContentSandboxDisabled();
+static const char* GetContentProcessTempBaseDirKey();
+static already_AddRefed<nsIFile> CreateContentProcessSandboxTempDir();
+#endif
+
 static already_AddRefed<nsIFile>
 CloneAndAppend(nsIFile* aFile, const char* name)
 {
   nsCOMPtr<nsIFile> file;
   aFile->Clone(getter_AddRefs(file));
   file->AppendNative(nsDependentCString(name));
   return file.forget();
 }
@@ -721,61 +734,176 @@ GetContentProcessTempBaseDirKey()
 {
 #if defined(XP_WIN)
   return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
 #else
   return NS_OS_TEMP_DIR;
 #endif
 }
 
+//
+// Sets mContentTempDir so that it refers to the appropriate temp dir.
+// If the sandbox is enabled, NS_APP_CONTENT_PROCESS_TEMP_DIR, otherwise
+// NS_OS_TEMP_DIR is used.
+//
 nsresult
 nsXREDirProvider::LoadContentProcessTempDir()
 {
+  mContentTempDir = GetContentProcessSandboxTempDir();
+  if (mContentTempDir) {
+    return NS_OK;
+  } else {
+    return NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
+                                  getter_AddRefs(mContentTempDir));
+  }
+}
+
+static bool
+IsContentSandboxDisabled()
+{
+  if (!BrowserTabsRemoteAutostart()) {
+    return false;
+  }
 #if defined(XP_WIN)
   const bool isSandboxDisabled = !mozilla::IsVistaOrLater() ||
     (Preferences::GetInt("security.sandbox.content.level") < 1);
 #elif defined(XP_MACOSX)
   const bool isSandboxDisabled =
     Preferences::GetInt("security.sandbox.content.level") < 1;
 #endif
+  return isSandboxDisabled;
+}
 
-  if (isSandboxDisabled) {
-    // Just use the normal temp directory if sandboxing is turned off
-    return NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
-                                  getter_AddRefs(mContentTempDir));
+//
+// If a content process sandbox temp dir is to be used, returns an nsIFile
+// for the directory. Returns null if the content sandbox is disabled or
+// an error occurs.
+//
+static already_AddRefed<nsIFile>
+GetContentProcessSandboxTempDir()