merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 16 Jun 2015 16:08:27 +0200
changeset 279839 abaec2f7ed2c10724f6b1d51a7d6c4a397a3daf8
parent 279728 95b628befd287933e2098988e49c564a17c999dc (current diff)
parent 279838 1dd9a9b94341076bae710cd36b57f7e57aebdc8c (diff)
child 279840 5d9ffe1fcb5cfa8eeee4c30215aea3f63aff7b42
child 279843 769314fc5bca72728d6a5efcfcb996fe0485a8a9
child 279865 54bb7f9b3d92f923fceb6b5f67c3e08778ba04a4
child 279903 7299b8b5a8a165731ce3dd7dfc7a372c5bb9f68f
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.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-inbound to mozilla-central a=merge
dom/media/wmf/DXVA2Manager.cpp
dom/media/wmf/DXVA2Manager.h
dom/media/wmf/WMF.h
dom/media/wmf/WMFByteStream.cpp
dom/media/wmf/WMFByteStream.h
dom/media/wmf/WMFDecoder.cpp
dom/media/wmf/WMFDecoder.h
dom/media/wmf/WMFReader.cpp
dom/media/wmf/WMFReader.h
dom/media/wmf/WMFSourceReaderCallback.cpp
dom/media/wmf/WMFSourceReaderCallback.h
dom/media/wmf/WMFUtils.cpp
dom/media/wmf/WMFUtils.h
dom/media/wmf/moz.build
mobile/android/tests/browser/robocop/testBrowserProviderPerf.java
mobile/android/tests/browser/robocop/testCheck.java
mobile/android/tests/browser/robocop/testPan.java
security/manager/ssl/tests/unit/test_pinning_dynamic/badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-a.pinning2.example.com-badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-a.pinning2.example.com-pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-b.pinning2.example.com-badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-b.pinning2.example.com-pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-www.example.com-alt-a.pinning2.example-badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-www.example.com-alt-a.pinning2.example-pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-x.a.pinning2.example.com-badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-x.a.pinning2.example.com-pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-x.b.pinning2.example.com-badca.der
security/manager/ssl/tests/unit/test_pinning_dynamic/cn-x.b.pinning2.example.com-pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/generate.py
security/manager/ssl/tests/unit/test_pinning_dynamic/pinning_root_generate.py
security/manager/ssl/tests/unit/test_pinning_dynamic/pinningroot.der
security/manager/ssl/tests/unit/test_pinning_dynamic/pinningroot.key
--- a/browser/config/version.txt
+++ b/browser/config/version.txt
@@ -1,3 +1,1 @@
 41.0a1
-# Version to display in the about box:
-41.0a1
new file mode 100644
--- /dev/null
+++ b/browser/config/version_about.txt
@@ -0,0 +1,1 @@
+41.0a1
--- a/build/clang-plugin/clang-plugin.cpp
+++ b/build/clang-plugin/clang-plugin.cpp
@@ -122,29 +122,30 @@ std::string getDeclarationNamespace(cons
 }
 
 bool isInIgnoredNamespaceForImplicitCtor(const Decl *decl) {
   std::string name = getDeclarationNamespace(decl);
   if (name == "") {
     return false;
   }
 
-  return name == "std" ||              // standard C++ lib
-         name == "__gnu_cxx" ||        // gnu C++ lib
-         name == "boost" ||            // boost
-         name == "webrtc" ||           // upstream webrtc
-         name == "icu_52" ||           // icu
-         name == "google" ||           // protobuf
-         name == "google_breakpad" ||  // breakpad
-         name == "soundtouch" ||       // libsoundtouch
-         name == "stagefright" ||      // libstagefright
-         name == "MacFileUtilities" || // MacFileUtilities
-         name == "dwarf2reader" ||     // dwarf2reader
-         name == "arm_ex_to_module" || // arm_ex_to_module
-         name == "testing";            // gtest
+
+  return name == "std" ||               // standard C++ lib
+         name == "__gnu_cxx" ||         // gnu C++ lib
+         name == "boost" ||             // boost
+         name == "webrtc" ||            // upstream webrtc
+         name.substr(0, 4) == "icu_" || // icu
+         name == "google" ||            // protobuf
+         name == "google_breakpad" ||   // breakpad
+         name == "soundtouch" ||        // libsoundtouch
+         name == "stagefright" ||       // libstagefright
+         name == "MacFileUtilities" ||  // MacFileUtilities
+         name == "dwarf2reader" ||      // dwarf2reader
+         name == "arm_ex_to_module" ||  // arm_ex_to_module
+         name == "testing";             // gtest
 }
 
 bool isInIgnoredNamespaceForImplicitConversion(const Decl *decl) {
   std::string name = getDeclarationNamespace(decl);
   if (name == "") {
     return false;
   }
 
--- a/configure.in
+++ b/configure.in
@@ -1953,18 +1953,18 @@ esac
 dnl ==============================================================
 dnl Get mozilla version from central milestone file
 dnl ==============================================================
 MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
 MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
 MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
 
 dnl Get version of various core apps from the version files.
-FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt|head -1`
-FIREFOX_VERSION_ABOUT=`cat $_topsrcdir/browser/config/version.txt|tail -1`
+FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
+FIREFOX_VERSION_ABOUT=`cat $_topsrcdir/browser/config/version_about.txt`
 
 if test -z "$FIREFOX_VERSION"; then
     AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
 fi
 
 if test -z "$FIREFOX_VERSION_ABOUT"; then
     AC_MSG_ERROR([FIREFOX_VERSION_ABOUT is unexpectedly blank.])
 fi
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -198,16 +198,17 @@ this.DOMApplicationRegistry = {
   children: [ ],
   allAppsLaunchable: false,
   _updateHandlers: [ ],
   _pendingUninstalls: {},
   _contentActions: new Map(),
   dirKey: DIRECTORY_NAME,
 
   init: function() {
+    // Keep the messages in sync with the lazy-loading in browser.js (bug 1171013).
     this.messages = ["Webapps:Install",
                      "Webapps:Uninstall",
                      "Webapps:GetSelf",
                      "Webapps:CheckInstalled",
                      "Webapps:GetInstalled",
                      "Webapps:GetNotInstalled",
                      "Webapps:Launch",
                      "Webapps:LocationChange",
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -526,23 +526,23 @@ File::GetLastModifiedDate(ErrorResult& a
 
 int64_t
 File::GetLastModified(ErrorResult& aRv)
 {
   return mImpl->GetLastModified(aRv);
 }
 
 void
-File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv)
+File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv) const
 {
   mImpl->GetMozFullPath(aFilename, aRv);
 }
 
 void
-File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
+File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
 {
   mImpl->GetMozFullPathInternal(aFileName, aRv);
 }
 
 // Makes sure that aStart and aEnd is less then or equal to aSize and greater
 // than 0
 static void
 ParseSize(int64_t aSize, int64_t& aStart, int64_t& aEnd)
@@ -730,17 +730,17 @@ BlobImplBase::GetName(nsAString& aName)
 void
 BlobImplBase::GetPath(nsAString& aPath, ErrorResult& aRv)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   aPath = mPath;
 }
 
 void
-BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv)
+BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv) const
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
   aFileName.Truncate();
 
   if (NS_IsMainThread()) {
     if (nsContentUtils::IsCallerChrome()) {
       GetMozFullPathInternal(aFileName, aRv);
@@ -754,17 +754,17 @@ BlobImplBase::GetMozFullPath(nsAString& 
   MOZ_ASSERT(workerPrivate);
 
   if (workerPrivate->UsesSystemPrincipal()) {
     GetMozFullPathInternal(aFileName, aRv);
   }
 }
 
 void
-BlobImplBase::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
+BlobImplBase::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
 {
   if (!mIsFile) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   aFileName.Truncate();
 }
@@ -945,17 +945,17 @@ BlobImplFile::CreateSlice(uint64_t aStar
                           ErrorResult& aRv)
 {
   nsRefPtr<BlobImpl> impl =
     new BlobImplFile(this, aStart, aLength, aContentType);
   return impl.forget();
 }
 
 void
-BlobImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv)
+BlobImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv) const
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   aRv = mFile->GetPath(aFilename);
 }
 
 uint64_t
 BlobImplFile::GetSize(ErrorResult& aRv)
 {
--- a/dom/base/File.h
+++ b/dom/base/File.h
@@ -256,19 +256,19 @@ public:
   void GetName(nsAString& aName);
 
   int64_t GetLastModified(ErrorResult& aRv);
 
   Date GetLastModifiedDate(ErrorResult& aRv);
 
   void GetPath(nsAString& aName, ErrorResult& aRv);
 
-  void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv);
+  void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv) const;
 
-  void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv);
+  void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv) const;
 
 protected:
   virtual bool HasFileInterface() const override { return true; }
 
 private:
   // File constructor should never be used directly. Use Blob::Create or
   // File::Create.
   File(nsISupports* aParent, BlobImpl* aImpl);
@@ -288,19 +288,19 @@ public:
   virtual void GetName(nsAString& aName) = 0;
 
   virtual void GetPath(nsAString& aName, ErrorResult& aRv) = 0;
 
   virtual int64_t GetLastModified(ErrorResult& aRv) = 0;
 
   virtual void SetLastModified(int64_t aLastModified) = 0;
 
-  virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) = 0;
+  virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) const = 0;
 
-  virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) = 0;
+  virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const = 0;
 
   virtual uint64_t GetSize(ErrorResult& aRv) = 0;
 
   virtual void GetType(nsAString& aType) = 0;
 
   /**
    * An effectively-unique serial number identifying this instance of FileImpl.
    *
@@ -429,20 +429,20 @@ public:
   virtual void GetName(nsAString& aName) override;
 
   virtual void GetPath(nsAString& aName, ErrorResult& aRv) override;
 
   virtual int64_t GetLastModified(ErrorResult& aRv) override;
 
   virtual void SetLastModified(int64_t aLastModified) override;
 
-  virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) override;
+  virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) const override;
 
   virtual void GetMozFullPathInternal(nsAString& aFileName,
-                                      ErrorResult& aRv) override;
+                                      ErrorResult& aRv) const override;
 
   virtual uint64_t GetSize(ErrorResult& aRv) override
   {
     return mLength;
   }
 
   virtual void GetType(nsAString& aType) override;
 
@@ -817,17 +817,17 @@ public:
   }
 
   // Overrides
   virtual uint64_t GetSize(ErrorResult& aRv) override;
   virtual void GetType(nsAString& aType) override;
   virtual int64_t GetLastModified(ErrorResult& aRv) override;
   virtual void SetLastModified(int64_t aLastModified) override;
   virtual void GetMozFullPathInternal(nsAString& aFullPath,
-                                      ErrorResult& aRv) override;
+                                      ErrorResult& aRv) const override;
   virtual void GetInternalStream(nsIInputStream** aInputStream,
                                  ErrorResult& aRv) override;
 
   void SetPath(const nsAString& aFullPath);
 
 protected:
   virtual ~BlobImplFile() {
     if (mFile && mIsTemporary) {
--- a/dom/base/MultipartBlobImpl.cpp
+++ b/dom/base/MultipartBlobImpl.cpp
@@ -235,17 +235,17 @@ MultipartBlobImpl::SetLengthAndModifiedD
     // could fail.
     mLastModificationDate =
       lastModifiedSet ? lastModified * PR_USEC_PER_MSEC : JS_Now();
   }
 }
 
 void
 MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
-                                          ErrorResult& aRv)
+                                          ErrorResult& aRv) const
 {
   if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
     BlobImplBase::GetMozFullPathInternal(aFilename, aRv);
     return;
   }
 
   BlobImpl* blobImpl = mBlobImpls.ElementAt(0).get();
   if (!blobImpl) {
--- a/dom/base/MultipartBlobImpl.h
+++ b/dom/base/MultipartBlobImpl.h
@@ -96,17 +96,17 @@ public:
                                  ErrorResult& aRv) override;
 
   virtual const nsTArray<nsRefPtr<BlobImpl>>* GetSubBlobImpls() const override
   {
     return &mBlobImpls;
   }
 
   virtual void GetMozFullPathInternal(nsAString& aFullPath,
-                                      ErrorResult& aRv) override;
+                                      ErrorResult& aRv) const override;
 
   virtual nsresult
   SetMutable(bool aMutable) override;
 
   void SetName(const nsAString& aName)
   {
     mName = aName;
   }
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -308,44 +308,17 @@ AutoJSAPI::AutoJSAPI()
 {
 }
 
 AutoJSAPI::~AutoJSAPI()
 {
   if (mOwnErrorReporting) {
     MOZ_ASSERT(NS_IsMainThread(), "See corresponding assertion in TakeOwnershipOfErrorReporting()");
 
-    if (HasException()) {
-
-      // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
-      // compartment when the destructor is called. However, the JS engine
-      // requires us to be in a compartment when we fetch the pending exception.
-      // In this case, we enter the privileged junk scope and don't dispatch any
-      // error events.
-      JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
-      if (!errorGlobal)
-        errorGlobal = xpc::PrivilegedJunkScope();
-      JSAutoCompartment ac(cx(), errorGlobal);
-      nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
-      JS::Rooted<JS::Value> exn(cx());
-      js::ErrorReport jsReport(cx());
-      if (StealException(&exn) && jsReport.init(cx(), exn)) {
-        nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
-        xpcReport->Init(jsReport.report(), jsReport.message(),
-                        nsContentUtils::IsCallerChrome(),
-                        win ? win->WindowID() : 0);
-        if (win) {
-          DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
-        } else {
-          xpcReport->LogToConsole();
-        }
-      } else {
-        NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
-      }
-    }
+    ReportException();
 
     // We need to do this _after_ processing the existing exception, because the
     // JS engine can throw while doing that, and uses this bit to determine what
     // to do in that case: squelch the exception if the bit is set, otherwise
     // call the error reporter. Calling WarningOnlyErrorReporter with a
     // non-warning will assert, so we need to make sure we do the former.
     JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting);
   }
@@ -503,16 +476,51 @@ AutoJSAPI::TakeOwnershipOfErrorReporting
   mOwnErrorReporting = true;
 
   JSRuntime *rt = JS_GetRuntime(cx());
   mOldAutoJSAPIOwnsErrorReporting = JS::ContextOptionsRef(cx()).autoJSAPIOwnsErrorReporting();
   JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(true);
   JS_SetErrorReporter(rt, WarningOnlyErrorReporter);
 }
 
+void
+AutoJSAPI::ReportException()
+{
+  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
+  if (!HasException()) {
+    return;
+  }
+
+  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
+  // compartment when the destructor is called. However, the JS engine
+  // requires us to be in a compartment when we fetch the pending exception.
+  // In this case, we enter the privileged junk scope and don't dispatch any
+  // error events.
+  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
+  if (!errorGlobal)
+    errorGlobal = xpc::PrivilegedJunkScope();
+  JSAutoCompartment ac(cx(), errorGlobal);
+  nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
+  JS::Rooted<JS::Value> exn(cx());
+  js::ErrorReport jsReport(cx());
+  if (StealException(&exn) && jsReport.init(cx(), exn)) {
+    nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
+    xpcReport->Init(jsReport.report(), jsReport.message(),
+                    nsContentUtils::IsCallerChrome(),
+                    win ? win->WindowID() : 0);
+    if (win) {
+      DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
+    } else {
+      xpcReport->LogToConsole();
+    }
+  } else {
+    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
+  }
+}
+
 bool
 AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal)
 {
     MOZ_ASSERT(CxPusherIsStackTop());
     MOZ_ASSERT(HasException());
     MOZ_ASSERT(js::GetContextCompartment(cx()));
     if (!JS_GetPendingException(cx(), aVal)) {
       return false;
--- a/dom/base/ScriptSettings.h
+++ b/dom/base/ScriptSettings.h
@@ -269,16 +269,19 @@ public:
   bool CxPusherIsStackTop() const { return mCxPusher->IsStackTop(); }
 
   // We're moving towards a world where the AutoJSAPI always handles
   // exceptions that bubble up from the JS engine. In order to make this
   // process incremental, we allow consumers to opt-in to the new behavior
   // while keeping the old behavior as the default.
   void TakeOwnershipOfErrorReporting();
   bool OwnsErrorReporting() { return mOwnErrorReporting; }
+  // If HasException, report it.  Otherwise, a no-op.  This must be
+  // called only if OwnsErrorReporting().
+  void ReportException();
 
   bool HasException() const {
     MOZ_ASSERT(CxPusherIsStackTop());
     return JS_IsExceptionPending(cx());
   };
 
   // Transfers ownership of the current exception from the JS engine to the
   // caller. Callers must ensure that HasException() is true, and that cx()
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -63,17 +63,17 @@ nsContentPolicy::~nsContentPolicy()
 
 #define WARN_IF_URI_UNINITIALIZED(uri,name)
 
 #endif // defined(DEBUG)
 
 inline nsresult
 nsContentPolicy::CheckPolicy(CPMethod          policyMethod,
                              SCPMethod         simplePolicyMethod,
-                             uint32_t          contentType,
+                             nsContentPolicyType contentType,
                              nsIURI           *contentLocation,
                              nsIURI           *requestingLocation,
                              nsISupports      *requestingContext,
                              const nsACString &mimeType,
                              nsISupports      *extra,
                              nsIPrincipal     *requestPrincipal,
                              int16_t           *decision)
 {
@@ -105,27 +105,30 @@ nsContentPolicy::CheckPolicy(CPMethod   
         if (!doc) {
             doc = do_QueryInterface(requestingContext);
         }
         if (doc) {
             requestingLocation = doc->GetDocumentURI();
         }
     }
 
+    nsContentPolicyType externalType =
+        nsContentUtils::InternalContentPolicyTypeToExternal(contentType);
+
     /* 
      * Enumerate mPolicies and ask each of them, taking the logical AND of
      * their permissions.
      */
     nsresult rv;
     nsCOMArray<nsIContentPolicy> entries;
     mPolicies.GetEntries(entries);
     int32_t count = entries.Count();
     for (int32_t i = 0; i < count; i++) {
         /* check the appropriate policy */
-        rv = (entries[i]->*policyMethod)(contentType, contentLocation,
+        rv = (entries[i]->*policyMethod)(externalType, contentLocation,
                                          requestingLocation, requestingContext,
                                          mimeType, extra, requestPrincipal,
                                          decision);
 
         if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
             /* policy says no, no point continuing to check */
             return NS_OK;
         }
@@ -161,17 +164,17 @@ nsContentPolicy::CheckPolicy(CPMethod   
         }
     }
 
     nsCOMArray<nsISimpleContentPolicy> simpleEntries;
     mSimplePolicies.GetEntries(simpleEntries);
     count = simpleEntries.Count();
     for (int32_t i = 0; i < count; i++) {
         /* check the appropriate policy */
-        rv = (simpleEntries[i]->*simplePolicyMethod)(contentType, contentLocation,
+        rv = (simpleEntries[i]->*simplePolicyMethod)(externalType, contentLocation,
                                                      requestingLocation,
                                                      topFrameElement, isTopLevel,
                                                      mimeType, extra, requestPrincipal,
                                                      decision);
 
         if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
             /* policy says no, no point continuing to check */
             return NS_OK;
--- a/dom/base/nsContentPolicy.h
+++ b/dom/base/nsContentPolicy.h
@@ -44,17 +44,17 @@ class nsContentPolicy : public nsIConten
                          ShouldProcess,
                          (uint32_t, nsIURI*, nsIURI*, nsIDOMElement*, bool,
                            const nsACString &, nsISupports*, nsIPrincipal*,
                            int16_t*));
 
     //Helper method that applies policyMethod across all policies in mPolicies
     // with the given parameters
     nsresult CheckPolicy(CPMethod policyMethod, SCPMethod simplePolicyMethod,
-                         uint32_t contentType,
+                         nsContentPolicyType contentType,
                          nsIURI *aURI, nsIURI *origURI,
                          nsISupports *requestingContext,
                          const nsACString &mimeGuess, nsISupports *extra,
                          nsIPrincipal *requestPrincipal,
                          int16_t *decision);
 };
 
 nsresult
--- a/dom/base/nsContentPolicyUtils.h
+++ b/dom/base/nsContentPolicyUtils.h
@@ -87,38 +87,48 @@ NS_CP_ResponseName(int16_t response)
  *
  * @param contentType the content type code
  * @return the name of the given content type code
  */
 inline const char *
 NS_CP_ContentTypeName(uint32_t contentType)
 {
   switch (contentType) {
-    CASE_RETURN( TYPE_OTHER             );
-    CASE_RETURN( TYPE_SCRIPT            );
-    CASE_RETURN( TYPE_IMAGE             );
-    CASE_RETURN( TYPE_STYLESHEET        );
-    CASE_RETURN( TYPE_OBJECT            );
-    CASE_RETURN( TYPE_DOCUMENT          );
-    CASE_RETURN( TYPE_SUBDOCUMENT       );
-    CASE_RETURN( TYPE_REFRESH           );
-    CASE_RETURN( TYPE_XBL               );
-    CASE_RETURN( TYPE_PING              );
-    CASE_RETURN( TYPE_XMLHTTPREQUEST    );
-    CASE_RETURN( TYPE_OBJECT_SUBREQUEST );
-    CASE_RETURN( TYPE_DTD               );
-    CASE_RETURN( TYPE_FONT              );
-    CASE_RETURN( TYPE_MEDIA             );
-    CASE_RETURN( TYPE_WEBSOCKET         );
-    CASE_RETURN( TYPE_CSP_REPORT        );
-    CASE_RETURN( TYPE_XSLT              );
-    CASE_RETURN( TYPE_BEACON            );
-    CASE_RETURN( TYPE_FETCH             );
-    CASE_RETURN( TYPE_IMAGESET          );
-    CASE_RETURN( TYPE_WEB_MANIFEST      );
+    CASE_RETURN( TYPE_OTHER                  );
+    CASE_RETURN( TYPE_SCRIPT                 );
+    CASE_RETURN( TYPE_IMAGE                  );
+    CASE_RETURN( TYPE_STYLESHEET             );
+    CASE_RETURN( TYPE_OBJECT                 );
+    CASE_RETURN( TYPE_DOCUMENT               );
+    CASE_RETURN( TYPE_SUBDOCUMENT            );
+    CASE_RETURN( TYPE_REFRESH                );
+    CASE_RETURN( TYPE_XBL                    );
+    CASE_RETURN( TYPE_PING                   );
+    CASE_RETURN( TYPE_XMLHTTPREQUEST         );
+    CASE_RETURN( TYPE_OBJECT_SUBREQUEST      );
+    CASE_RETURN( TYPE_DTD                    );
+    CASE_RETURN( TYPE_FONT                   );
+    CASE_RETURN( TYPE_MEDIA                  );
+    CASE_RETURN( TYPE_WEBSOCKET              );
+    CASE_RETURN( TYPE_CSP_REPORT             );
+    CASE_RETURN( TYPE_XSLT                   );
+    CASE_RETURN( TYPE_BEACON                 );
+    CASE_RETURN( TYPE_FETCH                  );
+    CASE_RETURN( TYPE_IMAGESET               );
+    CASE_RETURN( TYPE_WEB_MANIFEST           );
+    CASE_RETURN( TYPE_INTERNAL_SCRIPT        );
+    CASE_RETURN( TYPE_INTERNAL_WORKER        );
+    CASE_RETURN( TYPE_INTERNAL_SHARED_WORKER );
+    CASE_RETURN( TYPE_INTERNAL_EMBED         );
+    CASE_RETURN( TYPE_INTERNAL_OBJECT        );
+    CASE_RETURN( TYPE_INTERNAL_FRAME         );
+    CASE_RETURN( TYPE_INTERNAL_IFRAME        );
+    CASE_RETURN( TYPE_INTERNAL_AUDIO         );
+    CASE_RETURN( TYPE_INTERNAL_VIDEO         );
+    CASE_RETURN( TYPE_INTERNAL_TRACK         );
    default:
     return "<Unknown Type>";
   }
 }
 
 #undef CASE_RETURN
 
 /* Passes on parameters from its "caller"'s context. */
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7807,8 +7807,36 @@ nsContentUtils::GetWindowRoot(nsIDocumen
   if (aDoc) {
     nsPIDOMWindow* win = aDoc->GetWindow();
     if (win) {
       return win->GetTopWindowRoot();
     }
   }
   return nullptr;
 }
+
+/* static */
+nsContentPolicyType
+nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType)
+{
+  switch (aType) {
+  case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
+  case nsIContentPolicy::TYPE_INTERNAL_WORKER:
+  case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
+    return nsIContentPolicy::TYPE_SCRIPT;
+
+  case nsIContentPolicy::TYPE_INTERNAL_EMBED:
+  case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
+    return nsIContentPolicy::TYPE_OBJECT;
+
+  case nsIContentPolicy::TYPE_INTERNAL_FRAME:
+  case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
+    return nsIContentPolicy::TYPE_SUBDOCUMENT;
+
+  case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
+  case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
+  case nsIContentPolicy::TYPE_INTERNAL_TRACK:
+    return nsIContentPolicy::TYPE_MEDIA;
+
+  default:
+    return aType;
+  }
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -912,16 +912,21 @@ public:
   static bool IsInChromeDocshell(nsIDocument *aDocument);
 
   /**
    * Return the content policy service
    */
   static nsIContentPolicy *GetContentPolicy();
 
   /**
+   * Map internal content policy types to external ones.
+   */
+  static nsContentPolicyType InternalContentPolicyTypeToExternal(nsContentPolicyType aType);
+
+  /**
    * Quick helper to determine whether there are any mutation listeners
    * of a given type that apply to this content or any of its ancestors.
    * The method has the side effect to call document's MayDispatchMutationEvent
    * using aTargetForSubtreeModified as the parameter.
    *
    * @param aNode  The node to search for listeners
    * @param aType  The type of listener (NS_EVENT_BITS_MUTATION_*)
    * @param aTargetForSubtreeModified The node which is the target of the
--- a/dom/base/nsDataDocumentContentPolicy.cpp
+++ b/dom/base/nsDataDocumentContentPolicy.cpp
@@ -38,16 +38,19 @@ nsDataDocumentContentPolicy::ShouldLoad(
                                         nsIURI *aContentLocation,
                                         nsIURI *aRequestingLocation,
                                         nsISupports *aRequestingContext,
                                         const nsACString &aMimeGuess,
                                         nsISupports *aExtra,
                                         nsIPrincipal *aRequestPrincipal,
                                         int16_t *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   *aDecision = nsIContentPolicy::ACCEPT;
   // Look for the document.  In most cases, aRequestingContext is a node.
   nsCOMPtr<nsIDocument> doc;
   nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
   if (node) {
     doc = node->OwnerDoc();
   } else {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aRequestingContext);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -12458,16 +12458,17 @@ nsGlobalWindow::RunTimeoutHandler(nsTime
 
     const char* filename = nullptr;
     uint32_t lineNo = 0;
     handler->GetLocation(&filename, &lineNo);
 
     // New script entry point required, due to the "Create a script" sub-step of
     // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
     AutoEntryScript entryScript(this, reason, true, aScx->GetNativeContext());
+    entryScript.TakeOwnershipOfErrorReporting();
     JS::CompileOptions options(entryScript.cx());
     options.setFileAndLine(filename, lineNo)
            .setVersion(JSVERSION_DEFAULT);
     JS::Rooted<JSObject*> global(entryScript.cx(), FastGetGlobalJSObject());
     nsJSUtils::EvaluateString(entryScript.cx(), nsDependentString(script),
                               global, options);
   } else {
     // Hold strong ref to ourselves while we call the callback.
--- a/dom/base/nsIContentPolicy.idl
+++ b/dom/base/nsIContentPolicy.idl
@@ -15,17 +15,17 @@ interface nsIPrincipal;
  * Interface for content policy mechanism.  Implementations of this
  * interface can be used to control loading of various types of out-of-line
  * content, or processing of certain types of in-line content.
  *
  * WARNING: do not block the caller from shouldLoad or shouldProcess (e.g.,
  * by launching a dialog to prompt the user for something).
  */
 
-[scriptable,uuid(cb978019-0c5b-4067-abb6-c914461208c1)]
+[scriptable,uuid(b545899e-42bd-434c-8fec-a0af3448ea15)]
 interface nsIContentPolicy : nsIContentPolicyBase
 {
   /**
    * Should the resource at this location be loaded?
    * ShouldLoad will be called before loading the resource at aContentLocation
    * to determine whether to start the load at all.
    *
    * @param aContentType      the type of content being tested. This will be one
--- a/dom/base/nsIContentPolicyBase.idl
+++ b/dom/base/nsIContentPolicyBase.idl
@@ -19,17 +19,17 @@ typedef unsigned long nsContentPolicyTyp
  * Interface for content policy mechanism.  Implementations of this
  * interface can be used to control loading of various types of out-of-line
  * content, or processing of certain types of in-line content.
  *
  * WARNING: do not block the caller from shouldLoad or shouldProcess (e.g.,
  * by launching a dialog to prompt the user for something).
  */
 
-[scriptable,uuid(4f2655e8-6365-4583-8510-732bff2186c5)]
+[scriptable,uuid(11b8d725-7c2b-429e-b51f-8b5b542d5009)]
 interface nsIContentPolicyBase : nsISupports
 {
   /**
    * Indicates a unset or bogus policy type.
    */
   const nsContentPolicyType TYPE_INVALID = 0;
 
   /**
@@ -52,16 +52,20 @@ interface nsIContentPolicyBase : nsISupp
    * of the existing ones. In the bug you file, provide a more detailed
    * description of the new type of content you want Gecko to support, so that
    * the existing implementations of nsIContentPolicy can be properly modified
    * to deal with that new type of content.
    *
    * Implementations of nsIContentPolicy should treat this the same way they
    * treat unknown types, because existing users of TYPE_OTHER may be converted
    * to use new content types.
+   *
+   * Note that the TYPE_INTERNAL_* constants are never passed to content
+   * policy implementations.  They are mapped to other TYPE_* constants, and
+   * are only intended for internal usage inside Gecko.
    */
   const nsContentPolicyType TYPE_OTHER = 1;
 
   /**
    * Indicates an executable script (such as JavaScript).
    */
   const nsContentPolicyType TYPE_SCRIPT = 2;
 
@@ -172,16 +176,92 @@ interface nsIContentPolicyBase : nsISupp
    */
   const nsContentPolicyType TYPE_IMAGESET = 21;
 
   /**
    * Indicates a web manifest.
    */
   const nsContentPolicyType TYPE_WEB_MANIFEST = 22;
 
+  /**
+   * Indicates an internal constant for scripts loaded through script
+   * elements.
+   *
+   * This will be mapped to TYPE_SCRIPT before being passed to content policy
+   * implementations.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_SCRIPT = 23;
+
+  /**
+   * Indicates an internal constant for scripts loaded through a dedicated
+   * worker.
+   *
+   * This will be mapped to TYPE_SCRIPT before being passed to content policy
+   * implementations.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_WORKER = 24;
+
+  /**
+   * Indicates an internal constant for scripts loaded through a shared
+   * worker.
+   *
+   * This will be mapped to TYPE_SCRIPT before being passed to content policy
+   * implementations.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_SHARED_WORKER = 25;
+
+  /**
+   * Indicates an internal constant for content loaded from embed elements.
+   *
+   * This will be mapped to TYPE_OBJECT.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_EMBED = 26;
+
+  /**
+   * Indicates an internal constant for content loaded from object elements.
+   *
+   * This will be mapped to TYPE_OBJECT.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_OBJECT = 27;
+
+  /**
+   * Indicates an internal constant for content loaded from frame elements.
+   *
+   * This will be mapped to TYPE_SUBDOCUMENT.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_FRAME = 28;
+
+  /**
+   * Indicates an internal constant for content loaded from iframe elements.
+   *
+   * This will be mapped to TYPE_SUBDOCUMENT.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_IFRAME = 29;
+
+  /**
+   * Indicates an internal constant for content loaded from audio elements.
+   *
+   * This will be mapped to TYPE_MEDIA.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_AUDIO = 30;
+
+  /**
+   * Indicates an internal constant for content loaded from video elements.
+   *
+   * This will be mapped to TYPE_MEDIA.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_VIDEO = 31;
+
+  /**
+   * Indicates an internal constant for content loaded from track elements.
+   *
+   * This will be mapped to TYPE_MEDIA.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_TRACK = 32;
+
   /* When adding new content types, please update nsContentBlocker,
    * NS_CP_ContentTypeName, nsCSPContext, all nsIContentPolicy
    * implementations, and other things that are not listed here that are
    * related to nsIContentPolicy. */
 
   //////////////////////////////////////////////////////////////////////
 
   /**
--- a/dom/base/nsISimpleContentPolicy.idl
+++ b/dom/base/nsISimpleContentPolicy.idl
@@ -23,17 +23,17 @@ interface nsIDOMElement;
  * to block loads without using cross-process wrappers (CPOWs). Add-ons should
  * prefer this interface to nsIContentPolicy because it should be faster in
  * e10s. In the future, it may also be run asynchronously.
  *
  * WARNING: do not block the caller from shouldLoad or shouldProcess (e.g.,
  * by launching a dialog to prompt the user for something).
  */
 
-[scriptable,uuid(704b4b8e-2287-498a-9c0a-d1bde547a2d4)]
+[scriptable,uuid(b181c97c-9d67-4da1-95a0-e0a202e1807c)]
 interface nsISimpleContentPolicy : nsIContentPolicyBase
 {
   /**
    * Should the resource at this location be loaded?
    * ShouldLoad will be called before loading the resource at aContentLocation
    * to determine whether to start the load at all.
    *
    * @param aContentType      the type of content being tested. This will be one
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -93,51 +93,16 @@ nsJSUtils::GetCurrentlyRunningCodeInnerW
       if (win)
         innerWindowID = win->WindowID();
     }
   }
 
   return innerWindowID;
 }
 
-void
-nsJSUtils::ReportPendingException(JSContext *aContext)
-{
-  if (JS_IsExceptionPending(aContext)) {
-    bool saved = JS_SaveFrameChain(aContext);
-    {
-      // JS_SaveFrameChain set the compartment of aContext to null, so we need
-      // to enter a compartment.  The question is, which one? We don't want to
-      // enter the original compartment of aContext (or the compartment of the
-      // current exception on aContext, for that matter) because when we
-      // JS_ReportPendingException the JS engine can try to duck-type the
-      // exception and produce a JSErrorReport.  It will then pass that
-      // JSErrorReport to the error reporter on aContext, which might expose
-      // information from it to script via onerror handlers.  So it's very
-      // important that the duck typing happen in the same compartment as the
-      // onerror handler.  In practice, that's the compartment of the window (or
-      // otherwise default global) of aContext, so use that here.
-      nsIScriptContext* scx = GetScriptContextFromJSContext(aContext);
-      JS::Rooted<JSObject*> scope(aContext);
-      scope = scx ? scx->GetWindowProxy() : nullptr;
-      if (!scope) {
-        // The SafeJSContext has no default object associated with it.
-        MOZ_ASSERT(NS_IsMainThread());
-        MOZ_ASSERT(aContext == nsContentUtils::GetSafeJSContext());
-        scope = xpc::UnprivilegedJunkScope(); // Usage approved by bholley
-      }
-      JSAutoCompartment ac(aContext, scope);
-      JS_ReportPendingException(aContext);
-    }
-    if (saved) {
-      JS_RestoreFrameChain(aContext);
-    }
-  }
-}
-
 nsresult
 nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
                            JS::AutoObjectVector& aScopeChain,
                            JS::CompileOptions& aOptions,
                            const nsACString& aName,
                            uint32_t aArgCount,
                            const char** aArgArray,
                            const nsAString& aBody,
@@ -194,22 +159,21 @@ nsJSUtils::EvaluateString(JSContext* aCx
                           JS::CompileOptions& aCompileOptions,
                           const EvaluateOptions& aEvaluateOptions,
                           JS::MutableHandle<JS::Value> aRetValue,
                           void **aOffThreadToken)
 {
   PROFILER_LABEL("nsJSUtils", "EvaluateString",
     js::ProfileEntry::Category::JS);
 
+  MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
+             "Caller must own error reporting");
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
   MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
-  MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, !aCompileOptions.noScriptRval);
-  // Note that the above assert means that if aCompileOptions.noScriptRval then
-  // also aEvaluateOptions.reportUncaught.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
              aEvaluationGlobal);
   MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
 
   // Unfortunately, the JS engine actually compiles scripts with a return value
   // in a different, less efficient way.  Furthermore, it can't JIT them in many
@@ -220,23 +184,16 @@ nsJSUtils::EvaluateString(JSContext* aCx
   aRetValue.setUndefined();
 
   nsAutoMicroTask mt;
   nsresult rv = NS_OK;
 
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   NS_ENSURE_TRUE(ssm->ScriptAllowed(aEvaluationGlobal), NS_OK);
 
-  mozilla::Maybe<AutoDontReportUncaught> dontReport;
-  if (!aEvaluateOptions.reportUncaught) {
-    // We need to prevent AutoLastFrameCheck from reporting and clearing
-    // any pending exceptions.
-    dontReport.emplace(aCx);
-  }
-
   bool ok = true;
   // Scope the JSAutoCompartment so that we can later wrap the return value
   // into the caller's cx.
   {
     JSAutoCompartment ac(aCx, aEvaluationGlobal);
 
     // Now make sure to wrap the scope chain into the right compartment.
     JS::AutoObjectVector scopeChain(aCx);
@@ -270,34 +227,24 @@ nsJSUtils::EvaluateString(JSContext* aCx
       JS::Rooted<JS::Value> value(aCx, aRetValue);
       JSString* str = JS::ToString(aCx, value);
       ok = !!str;
       aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
     }
   }
 
   if (!ok) {
-    if (aEvaluateOptions.reportUncaught) {
-      ReportPendingException(aCx);
-      if (!aCompileOptions.noScriptRval) {
-        aRetValue.setUndefined();
-      }
-    } else {
-      rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE
-                                      : NS_ERROR_OUT_OF_MEMORY;
-      JS::Rooted<JS::Value> exn(aCx);
-      JS_GetPendingException(aCx, &exn);
-      MOZ_ASSERT(!aCompileOptions.noScriptRval); // we asserted this on entry
-      aRetValue.set(exn);
-      JS_ClearPendingException(aCx);
+    rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
+    if (!aCompileOptions.noScriptRval) {
+      aRetValue.setUndefined();
     }
   }
 
   // Wrap the return value into whatever compartment aCx was in.
-  if (!aCompileOptions.noScriptRval) {
+  if (ok && !aCompileOptions.noScriptRval) {
     if (!JS_WrapValue(aCx, aRetValue)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
   return rv;
 }
 
 nsresult
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -48,57 +48,45 @@ public:
    *
    * @param JSContext aContext
    *        The JSContext from which you want to find the inner window ID.
    *
    * @returns uint64_t the inner window ID.
    */
   static uint64_t GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext);
 
-  /**
-   * Report a pending exception on aContext, if any.  Note that this
-   * can be called when the context has a JS stack.  If that's the
-   * case, the stack will be set aside before reporting the exception.
-   */
-  static void ReportPendingException(JSContext *aContext);
-
   static nsresult CompileFunction(mozilla::dom::AutoJSAPI& jsapi,
                                   JS::AutoObjectVector& aScopeChain,
                                   JS::CompileOptions& aOptions,
                                   const nsACString& aName,
                                   uint32_t aArgCount,
                                   const char** aArgArray,
                                   const nsAString& aBody,
                                   JSObject** aFunctionObject);
 
   struct MOZ_STACK_CLASS EvaluateOptions {
     bool coerceToString;
-    bool reportUncaught;
     JS::AutoObjectVector scopeChain;
 
     explicit EvaluateOptions(JSContext* cx)
       : coerceToString(false)
-      , reportUncaught(true)
       , scopeChain(cx)
     {}
 
     EvaluateOptions& setCoerceToString(bool aCoerce) {
       coerceToString = aCoerce;
       return *this;
     }
-
-    EvaluateOptions& setReportUncaught(bool aReport) {
-      reportUncaught = aReport;
-      return *this;
-    }
   };
 
   // aEvaluationGlobal is the global to evaluate in.  The return value
   // will then be wrapped back into the compartment aCx is in when
-  // this function is called.
+  // this function is called.  For all the EvaluateString overloads,
+  // the JSContext must come from an AutoJSAPI that has had
+  // TakeOwnershipOfErrorReporting() called on it.
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aEvaluationGlobal,
                                  JS::CompileOptions &aCompileOptions,
                                  const EvaluateOptions& aEvaluateOptions,
                                  JS::MutableHandle<JS::Value> aRetValue);
 
   static nsresult EvaluateString(JSContext* aCx,
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -1115,16 +1115,17 @@ nsScriptLoader::EvaluateScript(nsScriptL
   if (version == JSVERSION_UNKNOWN) {
     return NS_OK;
   }
 
   // New script entry point required, due to the "Create a script" sub-step of
   // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block
   AutoEntryScript entryScript(globalObject, "<script> element", true,
                               context->GetNativeContext());
+  entryScript.TakeOwnershipOfErrorReporting();
   JS::Rooted<JSObject*> global(entryScript.cx(),
                                globalObject->GetGlobalJSObject());
 
   bool oldProcessingScriptTag = context->GetProcessingScriptTag();
   context->SetProcessingScriptTag(true);
   nsresult rv;
   {
     // Update our current script.
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -29,18 +29,16 @@
 #include "xpcprivate.h"
 #include "XrayWrapper.h"
 #include "nsPrintfCString.h"
 #include "prprf.h"
 
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMErrorBinding.h"
-#include "mozilla/dom/DOMException.h"
-#include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLSharedObjectElement.h"
 #include "mozilla/dom/HTMLEmbedElementBinding.h"
 #include "mozilla/dom/HTMLAppletElementBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
@@ -279,36 +277,26 @@ ErrorResult::ReportJSException(JSContext
 }
 
 void
 ErrorResult::ReportJSExceptionFromJSImplementation(JSContext* aCx)
 {
   MOZ_ASSERT(!mMightHaveUnreportedJSException,
              "Why didn't you tell us you planned to handle JS exceptions?");
 
-  dom::DOMException* domException;
-  nsresult rv =
-    UNWRAP_OBJECT(DOMException, &mJSException.toObject(), domException);
-  if (NS_SUCCEEDED(rv)) {
+  // Check for a DOMError, since we convert that into an Error in the content
+  // compartment.  We can probably remove that now; see bug 1174954.
+  dom::DOMError* domError;
+  nsresult rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
+  if (NS_FAILED(rv)) {
+    // Just report it.
     ReportJSException(aCx);
     return;
   }
 
-  dom::DOMError* domError;
-  rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
-  if (NS_FAILED(rv)) {
-    // Unwrapping really shouldn't fail here: if mExceptionHandling is set to
-    // eRethrowContentExceptions then the CallSetup destructor only stores an
-    // exception if it unwraps to DOMError or DOMException. If we reach this
-    // then either mExceptionHandling wasn't set to eRethrowContentExceptions
-    // and we shouldn't be calling ReportJSExceptionFromJSImplementation or
-    // something went really wrong.
-    NS_RUNTIMEABORT("We stored a non-DOMError exception!");
-  }
-
   nsString message;
   domError->GetMessage(message);
 
   JS_ReportError(aCx, "%hs", message.get());
   js::RemoveRawValueRoot(aCx, &mJSException);
 
   // We no longer have a useful exception but we do want to signal that an error
   // occured.
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -1,20 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/CallbackObject.h"
 #include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/DOMError.h"
-#include "mozilla/dom/DOMErrorBinding.h"
-#include "mozilla/dom/DOMException.h"
-#include "mozilla/dom/DOMExceptionBinding.h"
 #include "jsfriendapi.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIXPConnect.h"
 #include "nsIScriptContext.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "xpcprivate.h"
@@ -219,33 +215,25 @@ CallbackObject::CallSetup::ShouldRethrow
     if (callerPrincipal->SubsumesConsideringDomain(calleePrincipal)) {
       return true;
     }
   }
 
   MOZ_ASSERT(mCompartment);
 
   // Now we only want to throw an exception to the caller if the object that was
-  // thrown is a DOMError or DOMException object in the caller compartment
-  // (which we stored in mCompartment).
+  // thrown is in the caller compartment (which we stored in mCompartment).
 
   if (!aException.isObject()) {
     return false;
   }
 
   JS::Rooted<JSObject*> obj(mCx, &aException.toObject());
   obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
-  if (js::GetObjectCompartment(obj) != mCompartment) {
-    return false;
-  }
-
-  DOMError* domError;
-  DOMException* domException;
-  return NS_SUCCEEDED(UNWRAP_OBJECT(DOMError, obj, domError)) ||
-         NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException));
+  return js::GetObjectCompartment(obj) == mCompartment;
 }
 
 CallbackObject::CallSetup::~CallSetup()
 {
   // To get our nesting right we have to destroy our JSAutoCompartment first.
   // In particular, we want to do this before we try reporting any exceptions,
   // so we end up reporting them while in the compartment of our entry point,
   // not whatever cross-compartment wrappper mCallback might be.
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -137,19 +137,19 @@ void
 ThrowAndReport(nsPIDOMWindow* aWindow, nsresult aRv, const char* aMessage)
 {
   MOZ_ASSERT(aRv != NS_ERROR_UNCATCHABLE_EXCEPTION,
              "Doesn't make sense to report uncatchable exceptions!");
   AutoJSAPI jsapi;
   if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(aWindow))) {
     return;
   }
+  jsapi.TakeOwnershipOfErrorReporting();
 
   Throw(jsapi.cx(), aRv, aMessage);
-  (void) JS_ReportPendingException(jsapi.cx());
 }
 
 already_AddRefed<Exception>
 CreateException(JSContext* aCx, nsresult aRv, const char* aMessage)
 {
   // Do we use DOM exceptions for this error code?
   switch (NS_ERROR_GET_MODULE(aRv)) {
   case NS_ERROR_MODULE_DOM:
--- a/dom/bindings/test/TestInterfaceJS.js
+++ b/dom/bindings/test/TestInterfaceJS.js
@@ -68,16 +68,32 @@ TestInterfaceJS.prototype = {
     throw new this._win.DOMError("NotSupportedError", "We are a DOMError");
   },
 
   testThrowDOMException: function() {
     throw new this._win.DOMException("We are a DOMException",
                                      "NotSupportedError");
   },
 
+  testThrowTypeError: function() {
+    throw new this._win.TypeError("We are a TypeError");
+  },
+
+  testThrowCallbackError: function(callback) {
+    callback();
+  },
+
+  testThrowXraySelfHosted: function() {
+    this._win.Array.indexOf();
+  },
+
+  testThrowSelfHosted: function() {
+    Array.indexOf();
+  },
+
   testPromiseWithThrowingChromePromiseInit: function() {
     return new this._win.Promise(function() {
       noSuchMethodExistsYo1();
     })
   },
 
   testPromiseWithThrowingContentPromiseInit: function(func) {
       return new this._win.Promise(func);
--- a/dom/bindings/test/test_exception_options_from_jsimplemented.html
+++ b/dom/bindings/test/test_exception_options_from_jsimplemented.html
@@ -46,19 +46,96 @@ https://bugzilla.mozilla.org/show_bug.cg
          "Should have the right 'code'");
       is(e.stack,
          "doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:38:7\n",
          "Exception stack should still only show our code");
       is(e.filename,
          "http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
          "Should still have the right file name");
       is(e.lineNumber, 38, "Should still have the right line number");
-      todo_is(e.columnNumber, 7,
-              "No column number support for DOMException yet");
+      todo_isnot(e.columnNumber, 0,
+                 "No column number support for DOMException yet");
+    }
+
+    try {
+      t.testThrowTypeError();
+    } catch (e) {
+      ok(e instanceof TypeError, "Should have a TypeError here");
+      ok(!(e instanceof DOMException), "Should not have DOMException here (2)");
+      ok(!("code" in e), "Should not have a 'code' property (2)");
+      is(e.name, "TypeError", "Should be named TypeError");
+      is(e.message, "We are a TypeError",
+         "Should also have the right message (2)");
+      is(e.stack,
+         "doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:59:7\n",
+         "Exception stack for TypeError should only show our code");
+      is(e.fileName,
+         "http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
+         "Should still have the right file name for TypeError");
+      is(e.lineNumber, 59, "Should still have the right line number for TypeError");
+      is(e.columnNumber, 7, "Should have the right column number for TypeError");
     }
+
+    try {
+      t.testThrowCallbackError(function() { Array.indexOf() });
+    } catch (e) {
+      ok(e instanceof TypeError, "Should have a TypeError here (3)");
+      ok(!(e instanceof DOMException), "Should not have DOMException here (3)");
+      ok(!("code" in e), "Should not have a 'code' property (3)");
+      is(e.name, "TypeError", "Should be named TypeError (3)");
+      is(e.message, "missing argument 0 when calling function Array.indexOf",
+         "Should also have the right message (3)");
+      is(e.stack,
+         "doTest/<@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:45\n" +
+         "doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:7\n"
+  ,
+         "Exception stack for TypeError should only show our code (3)");
+      is(e.fileName,
+         "http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
+         "Should still have the right file name for TypeError (3)");
+      is(e.lineNumber, 78, "Should still have the right line number for TypeError (3)");
+      is(e.columnNumber, 45, "Should have the right column number for TypeError (3)");
+    }
+
+    try {
+      t.testThrowXraySelfHosted();
+    } catch (e) {
+      ok(!(e instanceof Error), "Should have an Exception here (4)");
+      ok(!(e instanceof DOMException), "Should not have DOMException here (4)");
+      ok(!("code" in e), "Should not have a 'code' property (4)");
+      is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (4)");
+      is(e.message, "", "Message should be sanitized (5)");
+      is(e.stack,
+         "doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:99:7\n",
+         "Exception stack for sanitized exception should only show our code (4)");
+      is(e.filename,
+         "http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
+         "Should still have the right file name for sanitized exception (4)");
+      is(e.lineNumber, 99, "Should still have the right line number for sanitized exception (4)");
+      todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (4)");
+    }
+
+    try {
+      t.testThrowSelfHosted();
+    } catch (e) {
+      ok(!(e instanceof Error), "Should have an Exception here (5)");
+      ok(!(e instanceof DOMException), "Should not have DOMException here (5)");
+      ok(!("code" in e), "Should not have a 'code' property (5)");
+      is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (5)");
+      is(e.message, "", "Message should be sanitized (5)");
+      is(e.stack,
+         "doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:117:7\n",
+         "Exception stack for sanitized exception should only show our code (5)");
+      is(e.filename,
+         "http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
+         "Should still have the right file name for sanitized exception (5)");
+      is(e.lineNumber, 117, "Should still have the right line number for sanitized exception (5)");
+      todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (5)");
+    }
+
     SimpleTest.finish();
   }
 
   SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]},
                             doTest);
   </script>
 </head>
 <body>
--- a/dom/cache/CacheTypes.ipdlh
+++ b/dom/cache/CacheTypes.ipdlh
@@ -7,17 +7,16 @@ include protocol PCachePushStream;
 include protocol PCacheStreamControl;
 include InputStreamParams;
 include ChannelInfo;
 
 using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
 using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
 using RequestMode from "mozilla/dom/cache/IPCUtils.h";
 using RequestCache from "mozilla/dom/cache/IPCUtils.h";
-using RequestContext from "mozilla/dom/cache/IPCUtils.h";
 using ResponseType from "mozilla/dom/cache/IPCUtils.h";
 using mozilla::void_t from "ipc/IPCMessageUtils.h";
 using struct nsID from "nsID.h";
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
@@ -58,17 +57,16 @@ struct CacheRequest
   nsString urlWithoutQuery;
   HeadersEntry[] headers;
   HeadersGuardEnum headersGuard;
   nsString referrer;
   RequestMode mode;
   RequestCredentials credentials;
   CacheReadStreamOrVoid body;
   uint32_t contentPolicyType;
-  RequestContext context;
   RequestCache requestCache;
 };
 
 union CacheRequestOrVoid
 {
   void_t;
   CacheRequest;
 };
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -24,21 +24,21 @@
 #include "mozilla/dom/ResponseBinding.h"
 #include "nsIContentPolicy.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 namespace db {
 
-const int32_t kMaxWipeSchemaVersion = 11;
+const int32_t kMaxWipeSchemaVersion = 13;
 
 namespace {
 
-const int32_t kLatestSchemaVersion = 11;
+const int32_t kLatestSchemaVersion = 13;
 const int32_t kMaxEntriesPerStatement = 255;
 
 const uint32_t kPageSize = 4 * 1024;
 
 // Grow the database in chunks to reduce fragmentation
 const uint32_t kGrowthSize = 32 * 1024;
 const uint32_t kGrowthPages = kGrowthSize / kPageSize;
 static_assert(kGrowthSize % kPageSize == 0,
@@ -72,50 +72,16 @@ static_assert(int(RequestMode::Same_orig
               int(RequestMode::Cors_with_forced_preflight) == 3 &&
               int(RequestMode::EndGuard_) == 4,
               "RequestMode values are as expected");
 static_assert(int(RequestCredentials::Omit) == 0 &&
               int(RequestCredentials::Same_origin) == 1 &&
               int(RequestCredentials::Include) == 2 &&
               int(RequestCredentials::EndGuard_) == 3,
               "RequestCredentials values are as expected");
-static_assert(int(RequestContext::Audio) == 0 &&
-              int(RequestContext::Beacon) == 1 &&
-              int(RequestContext::Cspreport) == 2 &&
-              int(RequestContext::Download) == 3 &&
-              int(RequestContext::Embed) == 4 &&
-              int(RequestContext::Eventsource) == 5 &&
-              int(RequestContext::Favicon) == 6 &&
-              int(RequestContext::Fetch) == 7 &&
-              int(RequestContext::Font) == 8 &&
-              int(RequestContext::Form) == 9 &&
-              int(RequestContext::Frame) == 10 &&
-              int(RequestContext::Hyperlink) == 11 &&
-              int(RequestContext::Iframe) == 12 &&
-              int(RequestContext::Image) == 13 &&
-              int(RequestContext::Imageset) == 14 &&
-              int(RequestContext::Import) == 15 &&
-              int(RequestContext::Internal) == 16 &&
-              int(RequestContext::Location) == 17 &&
-              int(RequestContext::Manifest) == 18 &&
-              int(RequestContext::Object) == 19 &&
-              int(RequestContext::Ping) == 20 &&
-              int(RequestContext::Plugin) == 21 &&
-              int(RequestContext::Prefetch) == 22 &&
-              int(RequestContext::Script) == 23 &&
-              int(RequestContext::Serviceworker) == 24 &&
-              int(RequestContext::Sharedworker) == 25 &&
-              int(RequestContext::Subresource) == 26 &&
-              int(RequestContext::Style) == 27 &&
-              int(RequestContext::Track) == 28 &&
-              int(RequestContext::Video) == 29 &&
-              int(RequestContext::Worker) == 30 &&
-              int(RequestContext::Xmlhttprequest) == 31 &&
-              int(RequestContext::Xslt) == 32,
-              "RequestContext values are as expected");
 static_assert(int(RequestCache::Default) == 0 &&
               int(RequestCache::No_store) == 1 &&
               int(RequestCache::Reload) == 2 &&
               int(RequestCache::No_cache) == 3 &&
               int(RequestCache::Force_cache) == 4 &&
               int(RequestCache::Only_if_cached) == 5 &&
               int(RequestCache::EndGuard_) == 6,
               "RequestCache values are as expected");
@@ -286,17 +252,16 @@ CreateSchema(mozIStorageConnection* aCon
         "request_method TEXT NOT NULL, "
         "request_url TEXT NOT NULL, "
         "request_url_no_query TEXT NOT NULL, "
         "request_referrer TEXT NOT NULL, "
         "request_headers_guard INTEGER NOT NULL, "
         "request_mode INTEGER NOT NULL, "
         "request_credentials INTEGER NOT NULL, "
         "request_contentpolicytype INTEGER NOT NULL, "
-        "request_context INTEGER NOT NULL, "
         "request_cache INTEGER NOT NULL, "
         "request_body_id TEXT NULL, "
         "response_type INTEGER NOT NULL, "
         "response_url TEXT NOT NULL, "
         "response_status INTEGER NOT NULL, "
         "response_status_text TEXT NOT NULL, "
         "response_headers_guard INTEGER NOT NULL, "
         "response_body_id TEXT NULL, "
@@ -1457,17 +1422,16 @@ InsertEntry(mozIStorageConnection* aConn
       "request_method, "
       "request_url, "
       "request_url_no_query, "
       "request_referrer, "
       "request_headers_guard, "
       "request_mode, "
       "request_credentials, "
       "request_contentpolicytype, "
-      "request_context, "
       "request_cache, "
       "request_body_id, "
       "response_type, "
       "response_url, "
       "response_status, "
       "response_status_text, "
       "response_headers_guard, "
       "response_body_id, "
@@ -1479,17 +1443,16 @@ InsertEntry(mozIStorageConnection* aConn
       ":request_method, "
       ":request_url, "
       ":request_url_no_query, "
       ":request_referrer, "
       ":request_headers_guard, "
       ":request_mode, "
       ":request_credentials, "
       ":request_contentpolicytype, "
-      ":request_context, "
       ":request_cache, "
       ":request_body_id, "
       ":response_type, "
       ":response_url, "
       ":response_status, "
       ":response_status_text, "
       ":response_headers_guard, "
       ":response_body_id, "
@@ -1528,20 +1491,16 @@ InsertEntry(mozIStorageConnection* aConn
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_credentials"),
     static_cast<int32_t>(aRequest.credentials()));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_contentpolicytype"),
     static_cast<int32_t>(aRequest.contentPolicyType()));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_context"),
-    static_cast<int32_t>(aRequest.context()));
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_cache"),
     static_cast<int32_t>(aRequest.requestCache()));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = BindId(state, NS_LITERAL_CSTRING("request_body_id"), aRequestBodyId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_type"),
@@ -1775,17 +1734,16 @@ ReadRequest(mozIStorageConnection* aConn
       "request_method, "
       "request_url, "
       "request_url_no_query, "
       "request_referrer, "
       "request_headers_guard, "
       "request_mode, "
       "request_credentials, "
       "request_contentpolicytype, "
-      "request_context, "
       "request_cache, "
       "request_body_id "
     "FROM entries "
     "WHERE id=:id;"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
@@ -1825,35 +1783,29 @@ ReadRequest(mozIStorageConnection* aConn
     static_cast<RequestCredentials>(credentials);
 
   int32_t requestContentPolicyType;
   rv = state->GetInt32(7, &requestContentPolicyType);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   aSavedRequestOut->mValue.contentPolicyType() =
     static_cast<nsContentPolicyType>(requestContentPolicyType);
 
-  int32_t requestContext;
-  rv = state->GetInt32(8, &requestContext);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-  aSavedRequestOut->mValue.context() =
-    static_cast<RequestContext>(requestContext);
-
   int32_t requestCache;
-  rv = state->GetInt32(9, &requestCache);
+  rv = state->GetInt32(8, &requestCache);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   aSavedRequestOut->mValue.requestCache() =
     static_cast<RequestCache>(requestCache);
 
   bool nullBody = false;
-  rv = state->GetIsNull(10, &nullBody);
+  rv = state->GetIsNull(9, &nullBody);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   aSavedRequestOut->mHasBodyId = !nullBody;
 
   if (aSavedRequestOut->mHasBodyId) {
-    rv = ExtractId(state, 10, &aSavedRequestOut->mBodyId);
+    rv = ExtractId(state, 9, &aSavedRequestOut->mBodyId);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   }
 
   rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT "
       "name, "
       "value "
     "FROM request_headers "
--- a/dom/cache/IPCUtils.h
+++ b/dom/cache/IPCUtils.h
@@ -34,21 +34,16 @@ namespace IPC {
                                     mozilla::dom::RequestCredentials::Omit,
                                     mozilla::dom::RequestCredentials::EndGuard_> {};
   template<>
   struct ParamTraits<mozilla::dom::RequestCache> :
     public ContiguousEnumSerializer<mozilla::dom::RequestCache,
                                     mozilla::dom::RequestCache::Default,
                                     mozilla::dom::RequestCache::EndGuard_> {};
   template<>
-  struct ParamTraits<mozilla::dom::RequestContext> :
-    public ContiguousEnumSerializer<mozilla::dom::RequestContext,
-                                    mozilla::dom::RequestContext::Audio,
-                                    mozilla::dom::RequestContext::EndGuard_> {};
-  template<>
   struct ParamTraits<mozilla::dom::ResponseType> :
     public ContiguousEnumSerializer<mozilla::dom::ResponseType,
                                     mozilla::dom::ResponseType::Basic,
                                     mozilla::dom::ResponseType::EndGuard_> {};
   template<>
   struct ParamTraits<mozilla::dom::cache::Namespace> :
     public ContiguousEnumSerializer<mozilla::dom::cache::Namespace,
                                     mozilla::dom::cache::DEFAULT_NAMESPACE,
--- a/dom/cache/TypeUtils.cpp
+++ b/dom/cache/TypeUtils.cpp
@@ -172,17 +172,16 @@ TypeUtils::ToCacheRequest(CacheRequest& 
 
   nsRefPtr<InternalHeaders> headers = aIn->Headers();
   MOZ_ASSERT(headers);
   ToHeadersEntryList(aOut.headers(), headers);
   aOut.headersGuard() = headers->Guard();
   aOut.mode() = aIn->Mode();
   aOut.credentials() = aIn->GetCredentialsMode();
   aOut.contentPolicyType() = aIn->ContentPolicyType();
-  aOut.context() = aIn->Context();
   aOut.requestCache() = aIn->GetCacheMode();
 
   if (aBodyAction == IgnoreBody) {
     aOut.body() = void_t();
     return;
   }
 
   // BodyUsed flag is checked and set previously in ToInternalRequest()
@@ -323,20 +322,16 @@ TypeUtils::ToInternalRequest(const Cache
   nsRefPtr<InternalRequest> internalRequest = new InternalRequest();
 
   internalRequest->SetMethod(aIn.method());
   internalRequest->SetURL(NS_ConvertUTF16toUTF8(aIn.url()));
   internalRequest->SetReferrer(aIn.referrer());
   internalRequest->SetMode(aIn.mode());
   internalRequest->SetCredentialsMode(aIn.credentials());
   internalRequest->SetContentPolicyType(aIn.contentPolicyType());
-  DebugOnly<RequestContext> contextAfterSetContentPolicyType = internalRequest->Context();
-  internalRequest->SetContext(aIn.context());
-  MOZ_ASSERT(contextAfterSetContentPolicyType.value == internalRequest->Context(),
-             "The RequestContext and nsContentPolicyType values should not get out of sync");
   internalRequest->SetCacheMode(aIn.requestCache());
 
   nsRefPtr<InternalHeaders> internalHeaders =
     ToInternalHeaders(aIn.headers(), aIn.headersGuard());
   ErrorResult result;
   internalRequest->Headers()->SetGuard(aIn.headersGuard(), result);
   MOZ_ASSERT(!result.Failed());
   internalRequest->Headers()->Fill(*internalHeaders, result);
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -889,16 +889,20 @@ WebGLContext::SetDimensions(int32_t sign
         GenerateWarning("Too many WebGL contexts created this run.");
         return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
     }
 
     // Get some prefs for some preferred/overriden things
     NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
     bool disabled = Preferences::GetBool("webgl.disabled", false);
+
+    // TODO: When we have software webgl support we should use that instead.
+    disabled |= gfxPlatform::InSafeMode();
+
     if (disabled) {
         GenerateWarning("WebGL creation is disabled, and so disallowed here.");
         return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
     bool failIfMajorPerformanceCaveat =
                     !gfxPrefs::WebGLDisableFailIfMajorPerformanceCaveat() &&
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -487,17 +487,26 @@ WebGLContext::GenerateWarning(const char
 
     mAlreadyGeneratedWarnings++;
 
     char buf[1024];
     PR_vsnprintf(buf, 1024, fmt, ap);
 
     // no need to print to stderr, as JS_ReportWarning takes care of this for us.
 
-    AutoJSContext cx;
+    if (!mCanvasElement) {
+        return;
+    }
+
+    AutoJSAPI api;
+    if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) {
+        return;
+    }
+
+    JSContext* cx = api.cx();
     JS_ReportWarning(cx, "WebGL: %s", buf);
     if (!ShouldGenerateWarnings()) {
         JS_ReportWarning(cx,
                          "WebGL: No further warnings will be reported for this"
                          " WebGL context. (already reported %d warnings)",
                          mAlreadyGeneratedWarnings);
     }
 }
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -34,17 +34,16 @@ InternalRequest::GetRequestConstructorCo
   // The "client" is not stored in our implementation. Fetch API users should
   // use the appropriate window/document/principal and other Gecko security
   // mechanisms as appropriate.
   copy->mSameOriginDataURL = true;
   copy->mPreserveContentCodings = true;
   // The default referrer is already about:client.
 
   copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH;
-  copy->mContext = RequestContext::Fetch;
   copy->mMode = mMode;
   copy->mCredentialsMode = mCredentialsMode;
   copy->mCacheMode = mCacheMode;
   copy->mCreatedByFetchEvent = mCreatedByFetchEvent;
   return copy.forget();
 }
 
 already_AddRefed<InternalRequest>
@@ -71,17 +70,16 @@ InternalRequest::Clone()
   return clone.forget();
 }
 
 InternalRequest::InternalRequest(const InternalRequest& aOther)
   : mMethod(aOther.mMethod)
   , mURL(aOther.mURL)
   , mHeaders(new InternalHeaders(*aOther.mHeaders))
   , mContentPolicyType(aOther.mContentPolicyType)
-  , mContext(aOther.mContext)
   , mReferrer(aOther.mReferrer)
   , mMode(aOther.mMode)
   , mCredentialsMode(aOther.mCredentialsMode)
   , mResponseTainting(aOther.mResponseTainting)
   , mCacheMode(aOther.mCacheMode)
   , mAuthenticationFlag(aOther.mAuthenticationFlag)
   , mForceOriginHeader(aOther.mForceOriginHeader)
   , mPreserveContentCodings(aOther.mPreserveContentCodings)
@@ -99,84 +97,91 @@ InternalRequest::InternalRequest(const I
 InternalRequest::~InternalRequest()
 {
 }
 
 void
 InternalRequest::SetContentPolicyType(nsContentPolicyType aContentPolicyType)
 {
   mContentPolicyType = aContentPolicyType;
+}
+
+/* static */
+RequestContext
+InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType)
+{
+  RequestContext context = RequestContext::Internal;
   switch (aContentPolicyType) {
   case nsIContentPolicy::TYPE_OTHER:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_SCRIPT:
-    mContext = RequestContext::Script;
+    context = RequestContext::Script;
     break;
   case nsIContentPolicy::TYPE_IMAGE:
-    mContext = RequestContext::Image;
+    context = RequestContext::Image;
     break;
   case nsIContentPolicy::TYPE_STYLESHEET:
-    mContext = RequestContext::Style;
+    context = RequestContext::Style;
     break;
   case nsIContentPolicy::TYPE_OBJECT:
-    mContext = RequestContext::Object;
+    context = RequestContext::Object;
     break;
   case nsIContentPolicy::TYPE_DOCUMENT:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_SUBDOCUMENT:
-    mContext = RequestContext::Iframe;
+    context = RequestContext::Iframe;
     break;
   case nsIContentPolicy::TYPE_REFRESH:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_XBL:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_PING:
-    mContext = RequestContext::Ping;
+    context = RequestContext::Ping;
     break;
   case nsIContentPolicy::TYPE_XMLHTTPREQUEST:
-    mContext = RequestContext::Xmlhttprequest;
+    context = RequestContext::Xmlhttprequest;
     break;
   case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST:
-    mContext = RequestContext::Plugin;
+    context = RequestContext::Plugin;
     break;
   case nsIContentPolicy::TYPE_DTD:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_FONT:
-    mContext = RequestContext::Font;
+    context = RequestContext::Font;
     break;
   case nsIContentPolicy::TYPE_MEDIA:
-    mContext = RequestContext::Audio;
+    context = RequestContext::Audio;
     break;
   case nsIContentPolicy::TYPE_WEBSOCKET:
-    mContext = RequestContext::Internal;
+    context = RequestContext::Internal;
     break;
   case nsIContentPolicy::TYPE_CSP_REPORT:
-    mContext = RequestContext::Cspreport;
+    context = RequestContext::Cspreport;
     break;
   case nsIContentPolicy::TYPE_XSLT:
-    mContext = RequestContext::Xslt;
+    context = RequestContext::Xslt;
     break;
   case nsIContentPolicy::TYPE_BEACON:
-    mContext = RequestContext::Beacon;
+    context = RequestContext::Beacon;
     break;
   case nsIContentPolicy::TYPE_FETCH:
-    mContext = RequestContext::Fetch;
+    context = RequestContext::Fetch;
     break;
   case nsIContentPolicy::TYPE_IMAGESET:
-    mContext = RequestContext::Imageset;
+    context = RequestContext::Imageset;
     break;
   case nsIContentPolicy::TYPE_WEB_MANIFEST:
-    mContext = RequestContext::Manifest;
+    context = RequestContext::Manifest;
     break;
   default:
     MOZ_ASSERT(false, "Unhandled nsContentPolicyType value");
-    mContext = RequestContext::Internal;
     break;
   }
+  return context;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -21,18 +21,17 @@
 #endif
 
 namespace mozilla {
 namespace dom {
 
 /*
  * The mapping of RequestContext and nsContentPolicyType is currently as the
  * following.  Note that this mapping is not perfect yet (see the TODO comments
- * below for examples), so for now we'll have to keep both an mContext and an
- * mContentPolicyType, because we cannot have a two way conversion.
+ * below for examples).
  *
  * RequestContext    | nsContentPolicyType
  * ------------------+--------------------
  * audio             | TYPE_MEDIA
  * beacon            | TYPE_BEACON
  * cspreport         | TYPE_CSP_REPORT
  * download          |
  * embed             | TYPE_OBJECT
@@ -50,17 +49,16 @@ namespace dom {
  * internal          | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER
  * location          |
  * manifest          | TYPE_WEB_MANIFEST
  * object            | TYPE_OBJECT
  * ping              | TYPE_PING
  * plugin            | TYPE_OBJECT_SUBREQUEST
  * prefetch          |
  * script            | TYPE_SCRIPT
- * serviceworker     |
  * sharedworker      |
  * subresource       | Not supported by Gecko
  * style             | TYPE_STYLESHEET
  * track             | TYPE_MEDIA
  * video             | TYPE_MEDIA
  * worker            |
  * xmlhttprequest    | TYPE_XMLHTTPREQUEST
  * xslt              | TYPE_XSLT
@@ -277,23 +275,17 @@ public:
   }
 
   void
   SetContentPolicyType(nsContentPolicyType aContentPolicyType);
 
   RequestContext
   Context() const
   {
-    return mContext;
-  }
-
-  void
-  SetContext(RequestContext aContext)
-  {
-    mContext = aContext;
+    return MapContentPolicyTypeToRequestContext(mContentPolicyType);
   }
 
   bool
   UnsafeRequest() const
   {
     return mUnsafeRequest;
   }
 
@@ -367,23 +359,25 @@ public:
   }
 
 private:
   // Does not copy mBodyStream.  Use fallible Clone() for complete copy.
   explicit InternalRequest(const InternalRequest& aOther);
 
   ~InternalRequest();
 
+  static RequestContext
+  MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType);
+
   nsCString mMethod;
   nsCString mURL;
   nsRefPtr<InternalHeaders> mHeaders;
   nsCOMPtr<nsIInputStream> mBodyStream;
 
   nsContentPolicyType mContentPolicyType;
-  RequestContext mContext;
 
   // Empty string: no-referrer
   // "about:client": client (default)
   // URL: an URL
   nsString mReferrer;
 
   RequestMode mMode;
   RequestCredentials mCredentialsMode;
--- a/dom/fetch/Request.h
+++ b/dom/fetch/Request.h
@@ -74,23 +74,16 @@ public:
   }
 
   RequestContext
   Context() const
   {
     return mRequest->Context();
   }
 
-  // [ChromeOnly]
-  void
-  SetContext(RequestContext aContext)
-  {
-    mRequest->SetContext(aContext);
-  }
-
   void
   SetContentPolicyType(nsContentPolicyType aContentPolicyType)
   {
     mRequest->SetContentPolicyType(aContentPolicyType);
   }
 
   void
   GetReferrer(nsAString& aReferrer) const
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -76,17 +76,17 @@ Directory::GetParentObject() const
 
 JSObject*
 Directory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return DirectoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
-Directory::GetName(nsString& aRetval) const
+Directory::GetName(nsAString& aRetval) const
 {
   aRetval.Truncate();
 
   if (mPath.IsEmpty()) {
     aRetval = mFileSystem->GetRootName();
     return;
   }
 
--- a/dom/filesystem/Directory.h
+++ b/dom/filesystem/Directory.h
@@ -54,17 +54,17 @@ public:
 
   nsPIDOMWindow*
   GetParentObject() const;
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void
-  GetName(nsString& aRetval) const;
+  GetName(nsAString& aRetval) const;
 
   already_AddRefed<Promise>
   CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
              ErrorResult& aRv);
 
   already_AddRefed<Promise>
   CreateDirectory(const nsAString& aPath, ErrorResult& aRv);
 
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -108,16 +108,17 @@
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLDocumentBinding.h"
 #include "nsCharsetSource.h"
 #include "nsIStringBundle.h"
 #include "nsDOMClassInfo.h"
 #include "nsFocusManager.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
+#include "nsLayoutStylesheetCache.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define NS_MAX_DOCUMENT_WRITE_DEPTH 20
 
 #include "prtime.h"
 
@@ -141,36 +142,16 @@ static bool ConvertToMidasInternalComman
                                             bool& boolValue);
 
 static bool ConvertToMidasInternalCommand(const nsAString & inCommandID,
                                             nsACString& outCommandID);
 
 // ==================================================================
 // =
 // ==================================================================
-static nsresult
-RemoveFromAgentSheets(nsCOMArray<nsIStyleSheet> &aAgentSheets, const nsAString& url)
-{
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (int32_t i = aAgentSheets.Count() - 1; i >= 0; --i) {
-    nsIStyleSheet* sheet = aAgentSheets[i];
-    nsIURI* sheetURI = sheet->GetSheetURI();
-
-    bool equals = false;
-    uri->Equals(sheetURI, &equals);
-    if (equals) {
-      aAgentSheets.RemoveObjectAt(i);
-    }
-  }
-
-  return NS_OK;
-}
 
 nsresult
 NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData)
 {
   nsRefPtr<nsHTMLDocument> doc = new nsHTMLDocument();
 
   nsresult rv = doc->Init();
 
@@ -2655,19 +2636,19 @@ nsHTMLDocument::TearingDownEditor(nsIEdi
 
     nsCOMPtr<nsIPresShell> presShell = GetShell();
     if (!presShell)
       return;
 
     nsCOMArray<nsIStyleSheet> agentSheets;
     presShell->GetAgentStyleSheets(agentSheets);
 
-    RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
+    agentSheets.RemoveObject(nsLayoutStylesheetCache::ContentEditableSheet());
     if (oldState == eDesignMode)
-      RemoveFromAgentSheets(agentSheets, NS_LITERAL_STRING("resource://gre/res/designmode.css"));
+      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
 
     presShell->SetAgentStyleSheets(agentSheets);
 
     presShell->ReconstructStyleData();
   }
 }
 
 nsresult
@@ -2795,51 +2776,44 @@ nsHTMLDocument::EditingStateChanged()
 
     // Before making this window editable, we need to modify UA style sheet
     // because new style may change whether focused element will be focusable
     // or not.
     nsCOMArray<nsIStyleSheet> agentSheets;
     rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri),
-                   NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsRefPtr<CSSStyleSheet> sheet;
-    rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
-    NS_ENSURE_TRUE(sheet, rv);
-
-    bool result = agentSheets.AppendObject(sheet);
-    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+    CSSStyleSheet* contentEditableSheet =
+      nsLayoutStylesheetCache::ContentEditableSheet();
+
+    bool result;
+
+    if (!agentSheets.Contains(contentEditableSheet)) {
+      bool result = agentSheets.AppendObject(contentEditableSheet);
+      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+    }
 
     // Should we update the editable state of all the nodes in the document? We
     // need to do this when the designMode value changes, as that overrides
     // specific states on the elements.
     if (designMode) {
       // designMode is being turned on (overrides contentEditable).
-      rv = NS_NewURI(getter_AddRefs(uri),
-                     NS_LITERAL_STRING("resource://gre/res/designmode.css"));
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
-      NS_ENSURE_TRUE(sheet, rv);
-
-      result = agentSheets.AppendObject(sheet);
-      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+      CSSStyleSheet* designModeSheet =
+        nsLayoutStylesheetCache::DesignModeSheet();
+      if (!agentSheets.Contains(designModeSheet)) {
+        result = agentSheets.AppendObject(designModeSheet);
+        NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+      }
 
       updateState = true;
       spellRecheckAll = oldState == eContentEditable;
     }
     else if (oldState == eDesignMode) {
       // designMode is being turned off (contentEditable is still on).
-      RemoveFromAgentSheets(agentSheets,
-        NS_LITERAL_STRING("resource://gre/res/designmode.css"));
-
+      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
       updateState = true;
     }
 
     rv = presShell->SetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     presShell->ReconstructStyleData();
 
--- a/dom/indexedDB/FileSnapshot.cpp
+++ b/dom/indexedDB/FileSnapshot.cpp
@@ -120,17 +120,17 @@ BlobImplSnapshot::CreateSlice(uint64_t a
   nsRefPtr<BlobImpl> impl =
     new BlobImplSnapshot(this, aStart, aLength, aContentType);
 
   return impl.forget();
 }
 
 void
 BlobImplSnapshot::GetMozFullPathInternal(nsAString& aFilename,
-                                         ErrorResult& aRv)
+                                         ErrorResult& aRv) const
 {
   AssertSanity();
   MOZ_ASSERT(mIsFile);
 
   aRv = mFile->GetPath(aFilename);
 }
 
 bool
--- a/dom/indexedDB/FileSnapshot.h
+++ b/dom/indexedDB/FileSnapshot.h
@@ -69,17 +69,17 @@ private:
   AssertSanity()
 #ifdef DEBUG
   ;
 #else
   { }
 #endif
 
   virtual void
-  GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) override;
+  GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) const override;
 
   virtual void
   GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv) override;
 
   virtual bool MayBeClonedToOtherThreads() const override
   {
     return false;
   }
index 2a3976fc25fb2271838db74e18d54473c6af3663..1a7d61a4f624cca3888fa5fa92f0c5f937abc741
GIT binary patch
literal 62944
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%0ApudJ)8@11yq$JGRjN$<T3q=Wmm@
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
--- a/dom/indexedDB/test/unit/test_defaultStorageUpgrade.js
+++ b/dom/indexedDB/test/unit/test_defaultStorageUpgrade.js
@@ -58,16 +58,28 @@ function testSteps()
     { url: "http://127.0.0.1", dbName: "dbO", dbVersion: 1 },
 
     // This one lives in storage/default/file++++
     { url: "file:///", dbName: "dbP", dbVersion: 1 },
 
     // This one lives in storage/default/file++++c++
     { url: "file:///c:/", dbName: "dbQ", dbVersion: 1 },
 
+    // This one lives in storage/default/file++++Users+joe+c+++index.html
+    { url: "file:///Users/joe/c++/index.html", dbName: "dbR", dbVersion: 1 },
+
+    // This one lives in storage/default/file++++Users+joe+c+++index.html
+    { url: "file:///Users/joe/c///index.html", dbName: "dbR", dbVersion: 1 },
+
+    // This one lives in storage/default/file++++++index.html
+    { url: "file:///+/index.html", dbName: "dbS", dbVersion: 1 },
+
+    // This one lives in storage/default/file++++++index.html
+    { url: "file://///index.html", dbName: "dbS", dbVersion: 1 },
+
     // This one lives in storage/temporary/http+++localhost
     { url: "http://localhost", dbName: "dbZ",
       dbOptions: { version: 1, storage: "temporary" } }
   ];
 
   let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
                          .getService(SpecialPowers.Ci.nsIIOService);
 
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -1913,17 +1913,17 @@ public:
   AsSlice() const;
 
   RemoteBlobImpl*
   BaseRemoteBlobImpl() const;
 
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual void
-  GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) override;
+  GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const override;
 
   virtual already_AddRefed<BlobImpl>
   CreateSlice(uint64_t aStart,
               uint64_t aLength,
               const nsAString& aContentType,
               ErrorResult& aRv) override;
 
   virtual void
@@ -2073,20 +2073,20 @@ public:
 
   virtual int64_t
   GetLastModified(ErrorResult& aRv) override;
 
   virtual void
   SetLastModified(int64_t aLastModified) override;
 
   virtual void
-  GetMozFullPath(nsAString& aName, ErrorResult& aRv) override;
+  GetMozFullPath(nsAString& aName, ErrorResult& aRv) const override;
 
   virtual void
-  GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) override;
+  GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const override;
 
   virtual uint64_t
   GetSize(ErrorResult& aRv) override;
 
   virtual void
   GetType(nsAString& aType) override;
 
   virtual uint64_t
@@ -2314,17 +2314,17 @@ NS_IMPL_ADDREF(BlobChild::RemoteBlobImpl
 NS_IMPL_RELEASE_WITH_DESTROY(BlobChild::RemoteBlobImpl, Destroy())
 NS_IMPL_QUERY_INTERFACE_INHERITED(BlobChild::RemoteBlobImpl,
                                   BlobImpl,
                                   nsIRemoteBlob)
 
 void
 BlobChild::
 RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFilePath,
-                                       ErrorResult& aRv)
+                                       ErrorResult& aRv) const
 {
   if (!EventTargetIsOnCurrentThread(mActorTarget)) {
     MOZ_CRASH("Not implemented!");
   }
 
   if (mSameProcessBlobImpl) {
     MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
 
@@ -2769,24 +2769,24 @@ void
 BlobParent::
 RemoteBlobImpl::SetLastModified(int64_t aLastModified)
 {
   MOZ_CRASH("SetLastModified of a remote blob is not allowed!");
 }
 
 void
 BlobParent::
-RemoteBlobImpl::GetMozFullPath(nsAString& aName, ErrorResult& aRv)
+RemoteBlobImpl::GetMozFullPath(nsAString& aName, ErrorResult& aRv) const
 {
   mBlobImpl->GetMozFullPath(aName, aRv);
 }
 
 void
 BlobParent::
-RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
+RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const
 {
   mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
 }
 
 uint64_t
 BlobParent::
 RemoteBlobImpl::GetSize(ErrorResult& aRv)
 {
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -418,16 +418,17 @@ TabChildBase::HandlePossibleViewportChan
       viewportInfo.SetDefaultZoom(newIntrinsicScale);
     }
 
     CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom();
     MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
                defaultZoom <= viewportInfo.GetMaxZoom());
     metrics.SetZoom(CSSToParentLayerScale2D(ConvertScaleForRoot(defaultZoom)));
 
+    metrics.SetPresShellId(presShellId);
     metrics.SetScrollId(viewId);
   }
 
   if (shell) {
     if (nsPresContext* context = shell->GetPresContext()) {
       metrics.SetDevPixelsPerCSSPixel(CSSToLayoutDeviceScale(
         (float)nsPresContext::AppUnitsPerCSSPixel() / context->AppUnitsPerDevPixel()));
     }
@@ -556,38 +557,32 @@ TabChildBase::UpdateFrameHandler(const F
       if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
         mLastRootMetrics = ProcessUpdateFrame(aFrameMetrics);
         return true;
       }
     }
   } else {
     // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
     // This requires special handling.
-    nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(
-                                      aFrameMetrics.GetScrollId());
-    if (content) {
-      FrameMetrics newSubFrameMetrics(aFrameMetrics);
-      APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
-      return true;
-    }
+    FrameMetrics newSubFrameMetrics(aFrameMetrics);
+    APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
+    return true;
   }
   return true;
 }
 
 FrameMetrics
 TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
 {
     if (!mGlobal || !mTabChildGlobal) {
         return aFrameMetrics;
     }
 
     FrameMetrics newMetrics = aFrameMetrics;
-    if (nsCOMPtr<nsIPresShell> presShell = GetPresShell()) {
-      APZCCallbackHelper::UpdateRootFrame(presShell, newMetrics);
-    }
+    APZCCallbackHelper::UpdateRootFrame(newMetrics);
 
     CSSSize cssCompositedSize = newMetrics.CalculateCompositedSizeInCssPixels();
     // The BrowserElementScrolling helper must know about these updated metrics
     // for other functions it performs, such as double tap handling.
     // Note, %f must not be used because it is locale specific!
     nsString data;
     data.AppendPrintf("{ \"x\" : %d", NS_lround(newMetrics.GetScrollOffset().x));
     data.AppendPrintf(", \"y\" : %d", NS_lround(newMetrics.GetScrollOffset().y));
--- a/dom/ipc/manifestMessages.js
+++ b/dom/ipc/manifestMessages.js
@@ -74,17 +74,17 @@ function fetchManifest() {
     }
     const reqInit = {
       mode: 'cors'
     };
     if (elem.crossOrigin === 'use-credentials') {
       reqInit.credentials = 'include';
     }
     const req = new content.Request(manifestURL, reqInit);
-    req.setContext('manifest');
+    req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
     const response = yield content.fetch(req);
     const manifest = yield processResponse(response, content);
     return manifest;
   });
 }
 
 function canLoadManifest(aElem) {
   const contentPolicy = Cc['@mozilla.org/layout/content-policy;1']
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -246,16 +246,20 @@ nsresult nsJSThunk::EvaluateScript(nsICh
     securityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
     if (NS_FAILED(rv))
         return rv;
 
     // New script entry point required, due to the "Create a script" step of
     // http://www.whatwg.org/specs/web-apps/current-work/#javascript-protocol
     AutoEntryScript entryScript(innerGlobal, "javascript: URI", true,
                                 scriptContext->GetNativeContext());
+    // We want to make sure we report any exceptions that happen before we
+    // return, since whatever happens inside our execution shouldn't affect any
+    // other scripts that might happen to be running.
+    entryScript.TakeOwnershipOfErrorReporting();
     JSContext* cx = entryScript.cx();
     JS::Rooted<JSObject*> globalJSObject(cx, innerGlobal->GetGlobalJSObject());
     NS_ENSURE_TRUE(globalJSObject, NS_ERROR_UNEXPECTED);
 
     //-- Don't execute unless the script principal subsumes the
     //   principal of the context.
     nsIPrincipal* objectPrincipal = nsContentUtils::ObjectPrincipal(globalJSObject);
 
@@ -273,30 +277,23 @@ nsresult nsJSThunk::EvaluateScript(nsICh
     JS::CompileOptions options(cx);
     options.setFileAndLine(mURL.get(), 1)
            .setVersion(JSVERSION_DEFAULT);
     nsJSUtils::EvaluateOptions evalOptions(cx);
     evalOptions.setCoerceToString(true);
     rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
                                    globalJSObject, options, evalOptions, &v);
 
-    // If there's an error on cx as a result of that call, report
-    // it now -- either we're just running under the event loop,
-    // so we shouldn't propagate JS exceptions out of here, or we
-    // can't be sure that our caller is JS (and if it's not we'll
-    // lose the error), or it might be JS that then proceeds to
-    // cause an error of its own (which will also make us lose
-    // this error).
-    ::JS_ReportPendingException(cx);
-
     if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
         return NS_ERROR_MALFORMED_URI;
     } else if (v.isUndefined()) {
         return NS_ERROR_DOM_RETVAL_UNDEFINED;
     } else {
+        MOZ_ASSERT(rv != NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW,
+                   "How did we get a non-undefined return value?");
         nsAutoJSString result;
         if (!result.init(cx, v)) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
 
         char *bytes;
         uint32_t bytesLen;
         NS_NAMED_LITERAL_CSTRING(isoCharset, "ISO-8859-1");
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -99,22 +99,23 @@ void InitPreferredSampleRate()
     // Query failed, use a sensible default.
     sPreferredSampleRate = 44100;
   }
 }
 
 cubeb* GetCubebContextUnlocked()
 {
   sMutex.AssertCurrentThreadOwns();
-  if (sCubebContext ||
-      cubeb_init(&sCubebContext, "CubebUtils") == CUBEB_OK) {
-    return sCubebContext;
+  if (!sCubebContext) {
+    MOZ_ASSERT(NS_IsMainThread());
+    if (cubeb_init(&sCubebContext, "CubebUtils") != CUBEB_OK) {
+      NS_WARNING("cubeb_init failed");
+    }
   }
-  NS_WARNING("cubeb_init failed");
-  return nullptr;
+  return sCubebContext;
 }
 
 uint32_t GetCubebLatency()
 {
   StaticMutexAutoLock lock(sMutex);
   return sCubebLatency;
 }
 
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -51,20 +51,16 @@
 #ifdef NECKO_PROTOCOL_rtsp
 #if ANDROID_VERSION >= 18
 #include "RtspMediaCodecDecoder.h"
 #include "RtspMediaCodecReader.h"
 #endif
 #include "RtspOmxDecoder.h"
 #include "RtspOmxReader.h"
 #endif
-#ifdef MOZ_WMF
-#include "WMFDecoder.h"
-#include "WMFReader.h"
-#endif
 #ifdef MOZ_DIRECTSHOW
 #include "DirectShowDecoder.h"
 #include "DirectShowReader.h"
 #endif
 #ifdef MOZ_APPLEMEDIA
 #include "AppleDecoder.h"
 #include "AppleMP3Reader.h"
 #endif
@@ -329,24 +325,16 @@ IsAndroidMediaType(const nsACString& aTy
 
   static const char* supportedTypes[] = {
     "audio/mpeg", "audio/mp4", "video/mp4", nullptr
   };
   return CodecListContains(supportedTypes, aType);
 }
 #endif
 
-#ifdef MOZ_WMF
-static bool
-IsWMFSupportedType(const nsACString& aType)
-{
-  return WMFDecoder::CanPlayType(aType, NS_LITERAL_STRING(""));
-}
-#endif
-
 #ifdef MOZ_DIRECTSHOW
 static bool
 IsDirectShowSupportedType(const nsACString& aType)
 {
   return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
 }
 #endif
 
@@ -476,33 +464,20 @@ DecoderTraits::CanHandleMediaType(const 
       codecList = gOMXWebMCodecs;
 #endif
     } else {
       codecList = gH264Codecs;
     }
   }
 #endif
 #ifdef MOZ_DIRECTSHOW
-  // Note: DirectShow should come before WMF, so that we prefer DirectShow's
-  // MP3 support over WMF's.
   if (DirectShowDecoder::GetSupportedCodecs(nsDependentCString(aMIMEType), &codecList)) {
     result = CANPLAY_MAYBE;
   }
 #endif
-#ifdef MOZ_WMF
-  if (!Preferences::GetBool("media.fragmented-mp4.exposed", false) &&
-      IsWMFSupportedType(nsDependentCString(aMIMEType))) {
-    if (!aHaveRequestedCodecs) {
-      return CANPLAY_MAYBE;
-    }
-    return WMFDecoder::CanPlayType(nsDependentCString(aMIMEType),
-                                   aRequestedCodecs)
-           ? CANPLAY_YES : CANPLAY_NO;
-  }
-#endif
 #ifdef MOZ_APPLEMEDIA
   if (IsAppleMediaSupportedType(nsDependentCString(aMIMEType), &codecList)) {
     result = CANPLAY_MAYBE;
   }
 #endif
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
@@ -632,22 +607,16 @@ InstantiateDecoder(const nsACString& aTy
 #ifdef MOZ_DIRECTSHOW
   // Note: DirectShow should come before WMF, so that we prefer DirectShow's
   // MP3 support over WMF's.
   if (IsDirectShowSupportedType(aType)) {
     decoder = new DirectShowDecoder();
     return decoder.forget();
   }
 #endif
-#ifdef MOZ_WMF
-  if (IsWMFSupportedType(aType)) {
-    decoder = new WMFDecoder();
-    return decoder.forget();
-  }
-#endif
 #ifdef MOZ_APPLEMEDIA
   if (IsAppleMediaSupportedType(aType)) {
     decoder = new AppleDecoder();
     return decoder.forget();
   }
 #endif
 
   NS_ENSURE_TRUE(decoder != nullptr, nullptr);
@@ -722,27 +691,20 @@ MediaDecoderReader* DecoderTraits::Creat
   } else
 #endif
 #ifdef MOZ_WEBM
   if (IsWebMType(aType)) {
     decoderReader = new WebMReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_DIRECTSHOW
-  // Note: DirectShowReader is preferred for MP3, but if it's disabled we
-  // fallback to the WMFReader.
   if (IsDirectShowSupportedType(aType)) {
     decoderReader = new DirectShowReader(aDecoder);
   } else
 #endif
-#ifdef MOZ_WMF
-  if (IsWMFSupportedType(aType)) {
-    decoderReader = new WMFReader(aDecoder);
-  } else
-#endif
 #ifdef MOZ_APPLEMEDIA
   if (IsAppleMediaSupportedType(aType)) {
     decoderReader = new AppleMP3Reader(aDecoder);
   } else
 #endif
   if (false) {} // dummy if to take care of the dangling else
 
   return decoderReader;
@@ -776,19 +738,16 @@ bool DecoderTraits::IsSupportedInVideoDo
 #endif
 #ifdef MOZ_ANDROID_OMX
     (MediaDecoder::IsAndroidMediaEnabled() && IsAndroidMediaType(aType)) ||
 #endif
 #ifdef MOZ_FMP4
     IsMP4SupportedType(aType) ||
 #endif
     IsMP3SupportedType(aType) ||
-#ifdef MOZ_WMF
-    IsWMFSupportedType(aType) ||
-#endif
 #ifdef MOZ_DIRECTSHOW
     IsDirectShowSupportedType(aType) ||
 #endif
 #ifdef MOZ_APPLEMEDIA
     IsAppleMediaSupportedType(aType) ||
 #endif
 #ifdef NECKO_PROTOCOL_rtsp
     IsRtspSupportedType(aType) ||
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaDecoder.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include <limits>
 #include "nsIObserver.h"
 #include "nsTArray.h"
+#include "CubebUtils.h"
 #include "VideoUtils.h"
 #include "MediaDecoderStateMachine.h"
 #include "ImageContainer.h"
 #include "MediaResource.h"
 #include "nsError.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIMemoryReporter.h"
@@ -23,20 +24,16 @@
 #include "MediaShutdownManager.h"
 #include "AudioChannelService.h"
 #include "mozilla/dom/AudioTrack.h"
 #include "mozilla/dom/AudioTrackList.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/VideoTrack.h"
 #include "mozilla/dom/VideoTrackList.h"
 
-#ifdef MOZ_WMF
-#include "WMFDecoder.h"
-#endif
-
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::media;
 
 // Default timeout msecs until try to enter dormant state by heuristic.
 static const int DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS = 60000;
 
 namespace mozilla {
@@ -399,16 +396,21 @@ MediaDecoder::MediaDecoder() :
 }
 
 bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mOwner = aOwner;
   mVideoFrameContainer = aOwner->GetVideoFrameContainer();
   MediaShutdownManager::Instance().Register(this);
+  // We don't use the cubeb context yet, but need to ensure it is created on
+  // the main thread.
+  if (!CubebUtils::GetCubebContext()) {
+    NS_WARNING("Audio backend initialization failed.");
+  }
   return true;
 }
 
 void MediaDecoder::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mShuttingDown)
@@ -1504,24 +1506,16 @@ MediaDecoder::IsOmxAsyncEnabled()
 #ifdef MOZ_ANDROID_OMX
 bool
 MediaDecoder::IsAndroidMediaEnabled()
 {
   return Preferences::GetBool("media.plugins.enabled");
 }
 #endif
 
-#ifdef MOZ_WMF
-bool
-MediaDecoder::IsWMFEnabled()
-{
-  return WMFDecoder::IsEnabled();
-}
-#endif
-
 #ifdef MOZ_APPLEMEDIA
 bool
 MediaDecoder::IsAppleMP3Enabled()
 {
   return Preferences::GetBool("media.apple.mp3.enabled");
 }
 #endif
 
--- a/dom/media/MediaTaskQueue.cpp
+++ b/dom/media/MediaTaskQueue.cpp
@@ -154,20 +154,21 @@ MediaTaskQueue::AwaitShutdownAndIdle()
     mQueueMonitor.Wait();
   }
   AwaitIdleLocked();
 }
 
 nsRefPtr<ShutdownPromise>
 MediaTaskQueue::BeginShutdown()
 {
-  // Make sure there are no tasks for this queue waiting in the caller's tail
-  // dispatcher.
-  MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
-                !AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
+  // Dispatch any tasks for this queue waiting in the caller's tail dispatcher,
+  // since this is the last opportunity to do so.
+  if (AbstractThread* currentThread = AbstractThread::GetCurrent()) {
+    currentThread->TailDispatcher().DispatchTasksFor(this);
+  }
 
   MonitorAutoLock mon(mQueueMonitor);
   mIsShutdown = true;
   nsRefPtr<ShutdownPromise> p = mShutdownPromise.Ensure(__func__);
   MaybeResolveShutdown();
   mon.NotifyAll();
   return p;
 }
--- a/dom/media/TaskDispatcher.h
+++ b/dom/media/TaskDispatcher.h
@@ -51,16 +51,17 @@ public:
                                   already_AddRefed<nsIRunnable> aRunnable) = 0;
 
   // Regular tasks are dispatched asynchronously, and run after state change
   // tasks.
   virtual void AddTask(AbstractThread* aThread,
                        already_AddRefed<nsIRunnable> aRunnable,
                        AbstractThread::DispatchFailureHandling aFailureHandling = AbstractThread::AssertDispatchSuccess) = 0;
 
+  virtual void DispatchTasksFor(AbstractThread* aThread) = 0;
   virtual bool HasTasksFor(AbstractThread* aThread) = 0;
   virtual void DrainDirectTasks() = 0;
 };
 
 /*
  * AutoTaskDispatcher is a stack-scoped TaskDispatcher implementation that fires
  * its queued tasks when it is popped off the stack.
  */
@@ -77,24 +78,17 @@ public:
     // this is only necessary in the case where this AutoTaskDispatcher can be
     // accessed by the direct tasks it dispatches (true for TailDispatchers, but
     // potentially not true for other hypothetical AutoTaskDispatchers). Feel
     // free to loosen this restriction to apply only to mIsTailDispatcher if a
     // use-case requires it.
     MOZ_ASSERT(mDirectTasks.empty());
 
     for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
-      UniquePtr<PerThreadTaskGroup> group(Move(mTaskGroups[i]));
-      nsRefPtr<AbstractThread> thread = group->mThread;
-
-      AbstractThread::DispatchFailureHandling failureHandling = group->mFailureHandling;
-      AbstractThread::DispatchReason reason = mIsTailDispatcher ? AbstractThread::TailDispatch
-                                                                : AbstractThread::NormalDispatch;
-      nsCOMPtr<nsIRunnable> r = new TaskGroupRunnable(Move(group));
-      thread->Dispatch(r.forget(), failureHandling, reason);
+      DispatchTaskGroup(Move(mTaskGroups[i]));
     }
   }
 
   void DrainDirectTasks() override
   {
     while (!mDirectTasks.empty()) {
       nsCOMPtr<nsIRunnable> r = mDirectTasks.front();
       mDirectTasks.pop();
@@ -127,16 +121,27 @@ public:
     }
   }
 
   bool HasTasksFor(AbstractThread* aThread) override
   {
     return !!GetTaskGroup(aThread) || (aThread == AbstractThread::GetCurrent() && !mDirectTasks.empty());
   }
 
+  void DispatchTasksFor(AbstractThread* aThread) override
+  {
+    for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
+      if (mTaskGroups[i]->mThread == aThread) {
+        DispatchTaskGroup(Move(mTaskGroups[i]));
+        mTaskGroups.RemoveElementAt(i);
+        return;
+      }
+    }
+  }
+
 private:
 
   struct PerThreadTaskGroup
   {
   public:
     explicit PerThreadTaskGroup(AbstractThread* aThread)
       : mThread(aThread), mFailureHandling(AbstractThread::DontAssertDispatchSuccess)
     {
@@ -210,16 +215,27 @@ private:
         return mTaskGroups[i].get();
       }
     }
 
     // Not found.
     return nullptr;
   }
 
+  void DispatchTaskGroup(UniquePtr<PerThreadTaskGroup> aGroup)
+  {
+    nsRefPtr<AbstractThread> thread = aGroup->mThread;
+
+    AbstractThread::DispatchFailureHandling failureHandling = aGroup->mFailureHandling;
+    AbstractThread::DispatchReason reason = mIsTailDispatcher ? AbstractThread::TailDispatch
+                                                              : AbstractThread::NormalDispatch;
+    nsCOMPtr<nsIRunnable> r = new TaskGroupRunnable(Move(aGroup));
+    thread->Dispatch(r.forget(), failureHandling, reason);
+  }
+
   // Direct tasks.
   std::queue<nsCOMPtr<nsIRunnable>> mDirectTasks;
 
   // Task groups, organized by thread.
   nsTArray<UniquePtr<PerThreadTaskGroup>> mTaskGroups;
 
   // True if this TaskDispatcher represents the tail dispatcher for the thread
   // upon which it runs.
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -49,19 +49,16 @@ if CONFIG['MOZ_GSTREAMER']:
     DIRS += ['gstreamer']
 
 if CONFIG['MOZ_DIRECTSHOW']:
     DIRS += ['directshow']
 
 if CONFIG['MOZ_ANDROID_OMX']:
     DIRS += ['android']
 
-if CONFIG['MOZ_WMF']:
-    DIRS += ['wmf']
-
 if CONFIG['MOZ_FMP4']:
     DIRS += ['fmp4']
 
 if CONFIG['MOZ_APPLEMEDIA']:
     DIRS += ['apple']
 
 if CONFIG['MOZ_WEBRTC']:
     DIRS += ['bridge']
rename from dom/media/wmf/DXVA2Manager.cpp
rename to dom/media/platforms/wmf/DXVA2Manager.cpp
rename from dom/media/wmf/DXVA2Manager.h
rename to dom/media/platforms/wmf/DXVA2Manager.h
rename from dom/media/wmf/WMF.h
rename to dom/media/platforms/wmf/WMF.h
--- a/dom/media/wmf/WMF.h
+++ b/dom/media/platforms/wmf/WMF.h
@@ -48,78 +48,34 @@ which makes Windows Media Foundation una
 #ifndef CLSID_CMSAACDecMFT
 extern "C" const CLSID CLSID_CMSAACDecMFT;
 #define WMF_MUST_DEFINE_AAC_MFT_CLSID
 #endif
 
 namespace mozilla {
 namespace wmf {
 
-// Loads/Unloads all the DLLs in which the WMF functions are located.
-// The DLLs must be loaded before any of the WMF functions below will work.
-// All the function definitions below are wrappers which locate the
-// corresponding WMF function in the appropriate DLL (hence why LoadDLL()
-// must be called first...).
-HRESULT LoadDLLs();
-HRESULT UnloadDLLs();
+// If successful, loads all required WMF DLLs and calls the WMF MFStartup()
+// function.
+HRESULT MFStartup();
+
+// Calls the WMF MFShutdown() function. Call this once for every time
+// wmf::MFStartup() succeeds. Note: does not unload the WMF DLLs loaded by
+// MFStartup(); leaves them in memory to save I/O at next MFStartup() call.
+HRESULT MFShutdown();
 
 // All functions below are wrappers around the corresponding WMF function,
 // and automatically locate and call the corresponding function in the WMF DLLs.
 
-HRESULT MFStartup();
-
-HRESULT MFShutdown();
-
-HRESULT MFCreateAsyncResult(IUnknown *aUunkObject,
-                            IMFAsyncCallback *aCallback,
-                            IUnknown *aUnkState,
-                            IMFAsyncResult **aOutAsyncResult);
-
-HRESULT MFInvokeCallback(IMFAsyncResult *aAsyncResult);
-
 HRESULT MFCreateMediaType(IMFMediaType **aOutMFType);
 
-HRESULT MFCreateSourceReaderFromByteStream(IMFByteStream *aByteStream,
-                                           IMFAttributes *aAttributes,
-                                           IMFSourceReader **aOutSourceReader);
-
-HRESULT PropVariantToUInt32(REFPROPVARIANT aPropvar, ULONG *aOutUL);
-
-HRESULT PropVariantToInt64(REFPROPVARIANT aPropVar, LONGLONG *aOutLL);
-
-HRESULT MFTGetInfo(CLSID aClsidMFT,
-                   LPWSTR *aOutName,
-                   MFT_REGISTER_TYPE_INFO **aOutInputTypes,
-                   UINT32 *aOutNumInputTypes,
-                   MFT_REGISTER_TYPE_INFO **aOutOutputTypes,
-                   UINT32 *aOutNumOutputTypes,
-                   IMFAttributes **aOutAttributes);
-
 HRESULT MFGetStrideForBitmapInfoHeader(DWORD aFormat,
                                        DWORD aWidth,
                                        LONG *aOutStride);
 
-// Note: We shouldn't use this in production code; it's really only
-// here so we can compare behaviour of the SourceReader using WMF's
-// byte stream and ours when debugging.
-HRESULT MFCreateSourceReaderFromURL(LPCWSTR aURL,
-                                    IMFAttributes *aAttributes,
-                                    IMFSourceReader **aSourceReader);
-
-HRESULT MFCreateAttributes(IMFAttributes **ppMFAttributes, UINT32 cInitialSize);
-
-HRESULT MFGetPluginControl(IMFPluginControl **aOutPluginControl);
-
-HRESULT MFTEnumEx(GUID guidCategory,
-                  UINT32 Flags,
-                  const MFT_REGISTER_TYPE_INFO *pInputType,
-                  const MFT_REGISTER_TYPE_INFO *pOutputType,
-                  IMFActivate ***pppMFTActivate,
-                  UINT32 *pcMFTActivate);
-
 HRESULT MFGetService(IUnknown *punkObject,
                      REFGUID guidService,
                      REFIID riid,
                      LPVOID *ppvObject);
 
 HRESULT DXVA2CreateDirect3DDeviceManager9(UINT *pResetToken,
                                           IDirect3DDeviceManager9 **ppDXVAManager);
 
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
@@ -284,29 +284,28 @@ WMFAudioMFTManager::Output(int64_t aStre
   nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[numSamples]);
 
   int16_t* pcm = (int16_t*)data;
   for (int32_t i = 0; i < numSamples; ++i) {
     audioData[i] = AudioSampleToFloat(pcm[i]);
   }
 
   buffer->Unlock();
-  int64_t timestamp;
-  hr = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, mAudioRate, &timestamp);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
+  CheckedInt64 timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, mAudioRate);
+  NS_ENSURE_TRUE(timestamp.isValid(), E_FAIL);
 
   mAudioFrameSum += numFrames;
 
-  int64_t duration;
-  hr = FramesToUsecs(numFrames, mAudioRate, &duration);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+  CheckedInt64 duration = FramesToUsecs(numFrames, mAudioRate);
+  NS_ENSURE_TRUE(duration.isValid(), E_FAIL);
 
   aOutData = new AudioData(aStreamOffset,
-                           timestamp,
-                           duration,
+                           timestamp.value(),
+                           duration.value(),
                            numFrames,
                            audioData.forget(),
                            mAudioChannels,
                            mAudioRate);
 
   #ifdef LOG_SAMPLE_DECODE
   LOG("Decoded audio sample! timestamp=%lld duration=%lld currentLength=%u",
       timestamp, duration, currentLength);
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -1,72 +1,70 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "WMF.h"
 #include "WMFDecoderModule.h"
-#include "WMFDecoder.h"
 #include "WMFVideoMFTManager.h"
 #include "WMFAudioMFTManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
 #include "WMFMediaDataDecoder.h"
 #include "nsIWindowsRegKey.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIGfxInfo.h"
 #include "GfxDriverInfo.h"
 #include "gfxWindowsPlatform.h"
 #include "MediaInfo.h"
 
 namespace mozilla {
 
-bool WMFDecoderModule::sIsWMFEnabled = false;
-bool WMFDecoderModule::sDXVAEnabled = false;
+static bool sIsWMFEnabled = false;
+static bool sDXVAEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
+  : mWMFInitialized(false)
 {
 }
 
 WMFDecoderModule::~WMFDecoderModule()
 {
-  DebugOnly<HRESULT> hr = wmf::MFShutdown();
-  NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
+  if (mWMFInitialized) {
+    DebugOnly<HRESULT> hr = wmf::MFShutdown();
+    NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
+  }
+}
+
+void
+WMFDecoderModule::DisableHardwareAcceleration()
+{
+  sDXVAEnabled = false;
 }
 
 /* static */
 void
 WMFDecoderModule::Init()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
   sIsWMFEnabled = Preferences::GetBool("media.windows-media-foundation.enabled", false);
-  if (!sIsWMFEnabled) {
-    return;
-  }
-  if (NS_FAILED(WMFDecoder::LoadDLLs())) {
-    sIsWMFEnabled = false;
-  }
   sDXVAEnabled = !gfxWindowsPlatform::GetPlatform()->IsWARP() &&
                  gfxPlatform::CanUseHardwareVideoDecoding();
 }
 
 nsresult
 WMFDecoderModule::Startup()
 {
-  if (!sIsWMFEnabled) {
-    return NS_ERROR_FAILURE;
+  if (sIsWMFEnabled) {
+    mWMFInitialized = SUCCEEDED(wmf::MFStartup());
   }
-  if (FAILED(wmf::MFStartup())) {
-    NS_WARNING("Failed to initialize Windows Media Foundation");
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
+  return mWMFInitialized ? NS_OK : NS_ERROR_FAILURE;
 }
 
 already_AddRefed<MediaDataDecoder>
 WMFDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
                                      layers::LayersBackend aLayersBackend,
                                      layers::ImageContainer* aImageContainer,
                                      FlushableMediaTaskQueue* aVideoTaskQueue,
                                      MediaDataDecoderCallback* aCallback)
--- a/dom/media/platforms/wmf/WMFDecoderModule.h
+++ b/dom/media/platforms/wmf/WMFDecoderModule.h
@@ -28,37 +28,31 @@ public:
 
   virtual already_AddRefed<MediaDataDecoder>
   CreateAudioDecoder(const AudioInfo& aConfig,
                      FlushableMediaTaskQueue* aAudioTaskQueue,
                      MediaDataDecoderCallback* aCallback) override;
 
   bool SupportsMimeType(const nsACString& aMimeType) override;
 
-  virtual void DisableHardwareAcceleration() override
-  {
-    sDXVAEnabled = false;
-  }
-
+  virtual void DisableHardwareAcceleration() override;
   virtual bool SupportsSharedDecoders(const VideoInfo& aConfig) const override;
 
   virtual ConversionRequired
   DecoderNeedsConversion(const TrackInfo& aConfig) const override;
 
   // Accessors that report whether we have the required MFTs available
   // on the system to play various codecs. Windows Vista doesn't have the
   // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
   // is not installed.
   static bool HasAAC();
   static bool HasH264();
 
   // Called on main thread.
   static void Init();
 private:
   bool ShouldUseDXVA(const VideoInfo& aConfig) const;
-
-  static bool sIsWMFEnabled;
-  static bool sDXVAEnabled;
+  bool mWMFInitialized;
 };
 
 } // namespace mozilla
 
 #endif
rename from dom/media/wmf/WMFUtils.cpp
rename to dom/media/platforms/wmf/WMFUtils.cpp
--- a/dom/media/wmf/WMFUtils.cpp
+++ b/dom/media/platforms/wmf/WMFUtils.cpp
@@ -10,248 +10,40 @@
 #include "mozilla/RefPtr.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/Logging.h"
 #include "nsThreadUtils.h"
 #include "nsWindowsHelpers.h"
 #include "mozilla/CheckedInt.h"
 #include "VideoUtils.h"
 #include <initguid.h>
+#include "nsTArray.h"
 
 #ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
 // Some SDK versions don't define the AAC decoder CLSID.
 // {32D186A7-218F-4C75-8876-DD77273A8999}
 DEFINE_GUID(CLSID_CMSAACDecMFT, 0x32D186A7, 0x218F, 0x4C75, 0x88, 0x76, 0xDD, 0x77, 0x27, 0x3A, 0x89, 0x99);
 #endif
 
 namespace mozilla {
 
-struct GuidToName {
-  GUID guid;
-  const char* name;
-};
-
-#define GUID_TO_NAME_ENTRY(g) { g, #g }
-#define INTERFACE_TO_NAME_ENTRY(i) {IID_##i, #i }
-
-GuidToName GuidToNameTable[] = {
-  GUID_TO_NAME_ENTRY(MF_MT_MAJOR_TYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_MAJOR_TYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_SUBTYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_ALL_SAMPLES_INDEPENDENT),
-  GUID_TO_NAME_ENTRY(MF_MT_FIXED_SIZE_SAMPLES),
-  GUID_TO_NAME_ENTRY(MF_MT_COMPRESSED),
-  GUID_TO_NAME_ENTRY(MF_MT_SAMPLE_SIZE),
-  GUID_TO_NAME_ENTRY(MF_MT_WRAPPED_TYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_AVG_BYTES_PER_SECOND),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_BLOCK_ALIGNMENT),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_BITS_PER_SAMPLE),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_SAMPLES_PER_BLOCK),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_FOLDDOWN_MATRIX),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_PEAKREF),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_PEAKTARGET),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_AVGREF),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_AVGTARGET),
-  GUID_TO_NAME_ENTRY(MF_MT_AUDIO_PREFER_WAVEFORMATEX),
-  GUID_TO_NAME_ENTRY(MF_MT_AAC_PAYLOAD_TYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION),
-  GUID_TO_NAME_ENTRY(MF_MT_FRAME_SIZE),
-  GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE),
-  GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE_RANGE_MAX),
-  GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE_RANGE_MIN),
-  GUID_TO_NAME_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
-  GUID_TO_NAME_ENTRY(MF_MT_DRM_FLAGS),
-  GUID_TO_NAME_ENTRY(MF_MT_PAD_CONTROL_FLAGS),
-  GUID_TO_NAME_ENTRY(MF_MT_SOURCE_CONTENT_HINT),
-  GUID_TO_NAME_ENTRY(MF_MT_VIDEO_CHROMA_SITING),
-  GUID_TO_NAME_ENTRY(MF_MT_INTERLACE_MODE),
-  GUID_TO_NAME_ENTRY(MF_MT_TRANSFER_FUNCTION),
-  GUID_TO_NAME_ENTRY(MF_MT_VIDEO_PRIMARIES),
-  GUID_TO_NAME_ENTRY(MF_MT_CUSTOM_VIDEO_PRIMARIES),
-  GUID_TO_NAME_ENTRY(MF_MT_YUV_MATRIX),
-  GUID_TO_NAME_ENTRY(MF_MT_VIDEO_LIGHTING),
-  GUID_TO_NAME_ENTRY(MF_MT_VIDEO_NOMINAL_RANGE),
-  GUID_TO_NAME_ENTRY(MF_MT_GEOMETRIC_APERTURE),
-  GUID_TO_NAME_ENTRY(MF_MT_MINIMUM_DISPLAY_APERTURE),
-  GUID_TO_NAME_ENTRY(MF_MT_PAN_SCAN_APERTURE),
-  GUID_TO_NAME_ENTRY(MF_MT_PAN_SCAN_ENABLED),
-  GUID_TO_NAME_ENTRY(MF_MT_AVG_BITRATE),
-  GUID_TO_NAME_ENTRY(MF_MT_AVG_BIT_ERROR_RATE),
-  GUID_TO_NAME_ENTRY(MF_MT_MAX_KEYFRAME_SPACING),
-  GUID_TO_NAME_ENTRY(MF_MT_DEFAULT_STRIDE),
-  GUID_TO_NAME_ENTRY(MF_MT_PALETTE),
-  GUID_TO_NAME_ENTRY(MF_MT_USER_DATA),
-  GUID_TO_NAME_ENTRY(MF_MT_AM_FORMAT_TYPE),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG_START_TIME_CODE),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG2_PROFILE),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG2_LEVEL),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG2_FLAGS),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG_SEQUENCE_HEADER),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_SRC_PACK_0),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_CTRL_PACK_0),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_SRC_PACK_1),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_CTRL_PACK_1),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_VAUX_SRC_PACK),
-  GUID_TO_NAME_ENTRY(MF_MT_DV_VAUX_CTRL_PACK),
-  GUID_TO_NAME_ENTRY(MF_MT_ARBITRARY_HEADER),
-  GUID_TO_NAME_ENTRY(MF_MT_ARBITRARY_FORMAT),
-  GUID_TO_NAME_ENTRY(MF_MT_IMAGE_LOSS_TOLERANT),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG4_SAMPLE_DESCRIPTION),
-  GUID_TO_NAME_ENTRY(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY),
-  GUID_TO_NAME_ENTRY(MF_MT_ORIGINAL_4CC),
-  GUID_TO_NAME_ENTRY(MF_MT_ORIGINAL_WAVE_FORMAT_TAG),
-
-  GUID_TO_NAME_ENTRY(MFMediaType_Audio),
-  GUID_TO_NAME_ENTRY(MFMediaType_Video),
-  GUID_TO_NAME_ENTRY(MFMediaType_Protected),
-  GUID_TO_NAME_ENTRY(MFMediaType_SAMI),
-  GUID_TO_NAME_ENTRY(MFMediaType_Script),
-  GUID_TO_NAME_ENTRY(MFMediaType_Image),
-  GUID_TO_NAME_ENTRY(MFMediaType_HTML),
-  GUID_TO_NAME_ENTRY(MFMediaType_Binary),
-  GUID_TO_NAME_ENTRY(MFMediaType_FileTransfer),
-
-  GUID_TO_NAME_ENTRY(MFVideoFormat_AI44),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_ARGB32),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_AYUV),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_DV25),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_DV50),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_DVH1),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_DVSD),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_DVSL),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_H264),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_I420),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_IYUV),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_M4S2),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MJPG),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MP43),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MP4S),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MP4V),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MPG1),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MSS1),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_MSS2),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_NV11),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_NV12),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_P010),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_P016),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_P210),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_P216),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_RGB24),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_RGB32),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_RGB555),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_RGB565),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_RGB8),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_UYVY),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_v210),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_v410),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_WMV1),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_WMV2),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_WMV3),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_WVC1),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y210),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y216),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y410),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y416),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y41P),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_Y41T),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_YUY2),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_YV12),
-  GUID_TO_NAME_ENTRY(MFVideoFormat_YVYU),
-
-  GUID_TO_NAME_ENTRY(MFAudioFormat_PCM),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_Float),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_DTS),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_Dolby_AC3_SPDIF),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_DRM),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudioV8),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudioV9),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudio_Lossless),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_WMASPDIF),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_MSP1),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_MP3),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_MPEG),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_AAC),
-  GUID_TO_NAME_ENTRY(MFAudioFormat_ADTS),
-
-  // Interfaces which may be implemented by WMFByteStream.
-  INTERFACE_TO_NAME_ENTRY(IUnknown),
-  INTERFACE_TO_NAME_ENTRY(IMFByteStream),
-  INTERFACE_TO_NAME_ENTRY(IMFMediaSource),
-  INTERFACE_TO_NAME_ENTRY(IMFAttributes),
-  INTERFACE_TO_NAME_ENTRY(IMFByteStreamBuffering),
-};
-
-nsCString GetGUIDName(const GUID& guid)
-{
-  const unsigned numTypes = ArrayLength(GuidToNameTable);
-  for (unsigned i = 0; i < numTypes; i++) {
-    if (guid == GuidToNameTable[i].guid) {
-      return nsDependentCString(GuidToNameTable[i].name);
-    }
-  }
-
-  WCHAR* name = nullptr;
-  HRESULT hr = StringFromCLSID(guid , &name);
-  if (FAILED(hr)) {
-    return nsDependentCString("GuidUnknown");
-  }
-  nsCString name_u8(NS_ConvertUTF16toUTF8(nsDependentString((char16_t*)(name))));
-  CoTaskMemFree(name);
-  return name_u8;
-}
-
-bool
-SourceReaderHasStream(IMFSourceReader* aReader, const DWORD aIndex)
-{
-  RefPtr<IMFMediaType> nativeType;
-  HRESULT hr = aReader->GetNativeMediaType(aIndex, 0, byRef(nativeType));
-  return FAILED(hr) ? false : true;
-}
-
-HRESULT
-DoGetInterface(IUnknown* aUnknown, void** aInterface)
-{
-  if (!aInterface)
-    return E_POINTER;
-  *aInterface = aUnknown;
-  aUnknown->AddRef();
-  return S_OK;
-}
-
 HRESULT
 HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames)
 {
   MOZ_ASSERT(aOutFrames);
   const int64_t HNS_PER_S = USECS_PER_S * 10;
   CheckedInt<int64_t> i = aHNs;
   i *= aRate;
   i /= HNS_PER_S;
   NS_ENSURE_TRUE(i.isValid(), E_FAIL);
   *aOutFrames = i.value();
   return S_OK;
 }
 
 HRESULT
-FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs)
-{
-  MOZ_ASSERT(aOutUsecs);
-  CheckedInt<int64_t> i = aSamples;
-  i *= USECS_PER_S;
-  i /= aRate;
-  NS_ENSURE_TRUE(i.isValid(), E_FAIL);
-  *aOutUsecs = i.value();
-  return S_OK;
-}
-
-HRESULT
 GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride)
 {
   // Try to get the default stride from the media type.
   HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, aOutStride);
   if (SUCCEEDED(hr)) {
     return S_OK;
   }
 
@@ -349,151 +141,55 @@ GetPictureRegion(IMFMediaType* aMediaTyp
   hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   aOutPictureRegion = nsIntRect(0, 0, width, height);
   return S_OK;
 }
 
 namespace wmf {
 
-static bool
-IsSupportedDecoder(const GUID& aDecoderGUID)
-{
-  return aDecoderGUID == CLSID_CMSH264DecoderMFT ||
-         aDecoderGUID == CLSID_CMSAACDecMFT ||
-         aDecoderGUID == CLSID_CMP3DecMediaObject;
-}
-
-static HRESULT
-DisableBlockedDecoders(IMFPluginControl* aPluginControl,
-                       const GUID& aCategory)
-{
-  HRESULT hr = S_OK;
-
-  UINT32 numMFTs = 0;
-  IMFActivate **ppActivate = nullptr;
-  hr = wmf::MFTEnumEx(aCategory,
-                      MFT_ENUM_FLAG_ALL,
-                      nullptr, // Input type, nullptr -> match all.
-                      nullptr, // Output type, nullptr -> match all.
-                      &ppActivate,
-                      &numMFTs);
-
-  if (SUCCEEDED(hr) && numMFTs == 0) {
-    hr = MF_E_TOPO_CODEC_NOT_FOUND;
-  }
-
-  for (UINT32 i = 0; i < numMFTs; i++) {
-    // Note: We must release all IMFActivate objects in the list, hence
-    // we're putting individual IMFActivate objects in into a smart ptr.
-    RefPtr<IMFActivate> activate = ppActivate[i];
-    GUID guid = GUID_NULL;
-    hr = activate->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guid);
-    if (FAILED(hr)) {
-      NS_WARNING("FAILED to get IMFActivate clsid");
-      continue;
-    }
-    if (!IsSupportedDecoder(guid)) {
-      hr = aPluginControl->SetDisabled(MF_Plugin_Type_MFT, guid, TRUE);
-      NS_ASSERTION(SUCCEEDED(hr), "Failed to disable plugin!");
-    }
-  }
-  CoTaskMemFree(ppActivate);
-
-  return hr;
-}
-
-static HRESULT
-DisableBlockedDecoders()
-{
-  RefPtr<IMFPluginControl> pluginControl;
-  HRESULT hr = wmf::MFGetPluginControl(byRef(pluginControl));
-  if (SUCCEEDED(hr) && pluginControl) {
-    hr = DisableBlockedDecoders(pluginControl,
-                                MFT_CATEGORY_VIDEO_DECODER);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-    hr = DisableBlockedDecoders(pluginControl,
-                                MFT_CATEGORY_AUDIO_DECODER);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-  }
-
-  return S_OK;
-}
-
-static bool sDLLsLoaded = false;
-static bool sFailedToLoadDlls = false;
-
-struct WMFModule {
-  const wchar_t* name;
-  HMODULE handle;
-};
-
-static WMFModule sDLLs[] = {
-  { L"mfplat.dll", nullptr },
-  { L"mfreadwrite.dll", nullptr },
-  { L"propsys.dll", nullptr },
-  { L"mf.dll", nullptr },
-  { L"dxva2.dll", nullptr }
+static const wchar_t* sDLLs[] = {
+  L"mfplat.dll",
+  L"mf.dll",
+  L"dxva2.dll",
+  L"evr.dll",
 };
 
 HRESULT
 LoadDLLs()
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
+  static bool sDLLsLoaded = false;
+  static bool sFailedToLoadDlls = false;
 
   if (sDLLsLoaded) {
     return S_OK;
   }
   if (sFailedToLoadDlls) {
     return E_FAIL;
   }
 
-  // Try to load all the required DLLs.
-  const uint32_t dllLength = ArrayLength(sDLLs);
-  for (uint32_t i = 0; i < dllLength; i++) {
-    sDLLs[i].handle = LoadLibrarySystem32(sDLLs[i].name);
-    if (!sDLLs[i].handle) {
+  // Try to load all the required DLLs. If we fail to load any dll,
+  // unload the dlls we succeeded in loading.
+  nsTArray<const wchar_t*> loadedDlls;
+  for (const wchar_t* dll : sDLLs) {
+    if (!LoadLibrarySystem32(dll)) {
+      NS_WARNING("Failed to load WMF DLLs");
+      for (const wchar_t* loadedDll : loadedDlls) {
+        FreeLibrary(GetModuleHandleW(loadedDll));
+      }
       sFailedToLoadDlls = true;
-      NS_WARNING("Failed to load WMF DLLs");
-      UnloadDLLs();
       return E_FAIL;
     }
+    loadedDlls.AppendElement(dll);
   }
-
-  // Enumerate all the decoders on the system, and disable the ones except
-  // those which we expect to use, the MP3, AAC and H.264 decoders.
-  if (FAILED(DisableBlockedDecoders())) {
-    sFailedToLoadDlls = true;
-    NS_WARNING("Failed to disable non whitelisted WMF decoders");
-    UnloadDLLs();
-    return E_FAIL;
-  }
-
   sDLLsLoaded = true;
 
   return S_OK;
 }
 
-HRESULT
-UnloadDLLs()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  const uint32_t length = ArrayLength(sDLLs);
-  for (uint32_t i = 0; i < length; i++) {
-    if (sDLLs[i].handle) {
-      FreeLibrary(sDLLs[i].handle);
-      sDLLs[i].handle = nullptr;
-    }
-    sDLLsLoaded = false;
-  }
-  return S_OK;
-}
-
 #define ENSURE_FUNCTION_PTR_HELPER(FunctionType, FunctionName, DLL) \
   static FunctionType FunctionName##Ptr = nullptr; \
   if (!FunctionName##Ptr) { \
     FunctionName##Ptr = (FunctionType) GetProcAddress(GetModuleHandleW(L ## #DLL), #FunctionName); \
     if (!FunctionName##Ptr) { \
       NS_WARNING("Failed to get GetProcAddress of " #FunctionName " from " #DLL); \
       return E_FAIL; \
     } \
@@ -506,16 +202,19 @@ UnloadDLLs()
   ENSURE_FUNCTION_PTR_HELPER(FunctionName##Ptr_t, FunctionName, DLL) \
 
 #define DECL_FUNCTION_PTR(FunctionName, ...) \
   typedef HRESULT (STDMETHODCALLTYPE * FunctionName##Ptr_t)(__VA_ARGS__)
 
 HRESULT
 MFStartup()
 {
+  HRESULT hr = LoadDLLs();
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
   const int MF_VISTA_VERSION = (0x0001 << 16 | MF_API_VERSION);
   const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
 
   // decltype is unusable for functions having default parameters
   DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
   ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
   if (!IsWin7OrLater())
     return MFStartupPtr(MF_VISTA_VERSION, MFSTARTUP_FULL);
@@ -526,128 +225,32 @@ MFStartup()
 HRESULT
 MFShutdown()
 {
   ENSURE_FUNCTION_PTR(MFShutdown, Mfplat.dll)
   return (MFShutdownPtr)();
 }
 
 HRESULT
-MFCreateAsyncResult(IUnknown *aUnkObject,
-                    IMFAsyncCallback *aCallback,
-                    IUnknown *aUnkState,
-                    IMFAsyncResult **aOutAsyncResult)
-{
-  ENSURE_FUNCTION_PTR(MFCreateAsyncResult, Mfplat.dll)
-  return (MFCreateAsyncResultPtr)(aUnkObject, aCallback, aUnkState, aOutAsyncResult);
-}
-
-HRESULT
-MFInvokeCallback(IMFAsyncResult *aAsyncResult)
-{
-  ENSURE_FUNCTION_PTR(MFInvokeCallback, Mfplat.dll);
-  return (MFInvokeCallbackPtr)(aAsyncResult);
-}
-
-HRESULT
 MFCreateMediaType(IMFMediaType **aOutMFType)
 {
   ENSURE_FUNCTION_PTR(MFCreateMediaType, Mfplat.dll)
   return (MFCreateMediaTypePtr)(aOutMFType);
 }
 
-HRESULT
-MFCreateSourceReaderFromByteStream(IMFByteStream *aByteStream,
-                                   IMFAttributes *aAttributes,
-                                   IMFSourceReader **aOutSourceReader)
-{
-  ENSURE_FUNCTION_PTR(MFCreateSourceReaderFromByteStream, Mfreadwrite.dll)
-  return (MFCreateSourceReaderFromByteStreamPtr)(aByteStream,
-                                                 aAttributes,
-                                                 aOutSourceReader);
-}
-
-HRESULT
-PropVariantToUInt32(REFPROPVARIANT aPropvar, ULONG *aOutUL)
-{
-  // decltype is unusable for overloaded functions
-  DECL_FUNCTION_PTR(PropVariantToUInt32, REFPROPVARIANT, ULONG *);
-  ENSURE_FUNCTION_PTR_(PropVariantToUInt32, Propsys.dll)
-  return (PropVariantToUInt32Ptr)(aPropvar, aOutUL);
-}
-
-HRESULT PropVariantToInt64(REFPROPVARIANT aPropVar, LONGLONG *aOutLL)
-{
-  ENSURE_FUNCTION_PTR(PropVariantToInt64, Propsys.dll)
-  return (PropVariantToInt64Ptr)(aPropVar, aOutLL);
-}
-
-HRESULT
-MFTGetInfo(CLSID aClsidMFT,
-           LPWSTR *aOutName,
-           MFT_REGISTER_TYPE_INFO **aOutInputTypes,
-           UINT32 *aOutNumInputTypes,
-           MFT_REGISTER_TYPE_INFO **aOutOutputTypes,
-           UINT32 *aOutNumOutputTypes,
-           IMFAttributes **aOutAttributes)
-{
-  ENSURE_FUNCTION_PTR(MFTGetInfo, Mfplat.dll)
-  return (MFTGetInfoPtr)(aClsidMFT,
-                         aOutName,
-                         aOutInputTypes,
-                         aOutNumInputTypes,
-                         aOutOutputTypes,
-                         aOutNumOutputTypes,
-                         aOutAttributes);
-}
 
 HRESULT
 MFGetStrideForBitmapInfoHeader(DWORD aFormat,
                                DWORD aWidth,
                                LONG *aOutStride)
 {
-  ENSURE_FUNCTION_PTR(MFGetStrideForBitmapInfoHeader, Mfplat.dll)
+  ENSURE_FUNCTION_PTR(MFGetStrideForBitmapInfoHeader, evr.dll)
   return (MFGetStrideForBitmapInfoHeaderPtr)(aFormat, aWidth, aOutStride);
 }
 
-HRESULT
-MFCreateSourceReaderFromURL(LPCWSTR aURL,
-                            IMFAttributes *aAttributes,
-                            IMFSourceReader **aSourceReader)
-{
-  ENSURE_FUNCTION_PTR(MFCreateSourceReaderFromURL, Mfreadwrite.dll)
-  return (MFCreateSourceReaderFromURLPtr)(aURL, aAttributes, aSourceReader);
-}
-
-HRESULT
-MFCreateAttributes(IMFAttributes **ppMFAttributes, UINT32 cInitialSize)
-{
-  ENSURE_FUNCTION_PTR(MFCreateAttributes, mfplat.dll)
-  return (MFCreateAttributesPtr)(ppMFAttributes, cInitialSize);
-}
-
-HRESULT
-MFGetPluginControl(IMFPluginControl **aOutPluginControl)
-{
-  ENSURE_FUNCTION_PTR(MFGetPluginControl, mfplat.dll)
-  return (MFGetPluginControlPtr)(aOutPluginControl);
-}
-
-HRESULT
-MFTEnumEx(GUID guidCategory,
-          UINT32 Flags,
-          const MFT_REGISTER_TYPE_INFO *pInputType,
-          const MFT_REGISTER_TYPE_INFO *pOutputType,
-          IMFActivate ***pppMFTActivate,
-          UINT32 *pcMFTActivate)
-{
-  ENSURE_FUNCTION_PTR(MFTEnumEx, mfplat.dll)
-  return (MFTEnumExPtr)(guidCategory, Flags, pInputType, pOutputType, pppMFTActivate, pcMFTActivate);
-}
-
 HRESULT MFGetService(IUnknown *punkObject,
                      REFGUID guidService,
                      REFIID riid,
                      LPVOID *ppvObject)
 {
   ENSURE_FUNCTION_PTR(MFGetService, mf.dll)
   return (MFGetServicePtr)(punkObject, guidService, riid, ppvObject);
 }
rename from dom/media/wmf/WMFUtils.h
rename to dom/media/platforms/wmf/WMFUtils.h
--- a/dom/media/wmf/WMFUtils.h
+++ b/dom/media/platforms/wmf/WMFUtils.h
@@ -11,76 +11,36 @@
 #include "nsString.h"
 #include "nsRect.h"
 #include "VideoUtils.h"
 
 // Various utilities shared by WMF backend files.
 
 namespace mozilla {
 
-nsCString
-GetGUIDName(const GUID& guid);
-
-// Returns true if the reader has a stream with the specified index.
-// Index can be a specific index, or one of:
-//   MF_SOURCE_READER_FIRST_VIDEO_STREAM
-//   MF_SOURCE_READER_FIRST_AUDIO_STREAM
-bool
-SourceReaderHasStream(IMFSourceReader* aReader, const DWORD aIndex);
-
-// Auto manages the lifecycle of a PROPVARIANT.
-class AutoPropVar {
-public:
-  AutoPropVar() {
-    PropVariantInit(&mVar);
-  }
-  ~AutoPropVar() {
-    PropVariantClear(&mVar);
-  }
-  operator PROPVARIANT&() {
-    return mVar;
-  }
-  PROPVARIANT* operator->() {
-    return &mVar;
-  }
-  PROPVARIANT* operator&() {
-    return &mVar;
-  }
-private:
-  PROPVARIANT mVar;
-};
-
 // Converts from microseconds to hundreds of nanoseconds.
 // We use microseconds for our timestamps, whereas WMF uses
 // hundreds of nanoseconds.
 inline int64_t
 UsecsToHNs(int64_t aUsecs) {
   return aUsecs * 10;
 }
 
 // Converts from hundreds of nanoseconds to microseconds.
 // We use microseconds for our timestamps, whereas WMF uses
 // hundreds of nanoseconds.
 inline int64_t
 HNsToUsecs(int64_t hNanoSecs) {
   return hNanoSecs / 10;
 }
 
-// Assigns aUnknown to *aInterface, and AddRef's it.
-// Helper for MSCOM QueryInterface implementations.
-HRESULT
-DoGetInterface(IUnknown* aUnknown, void** aInterface);
-
 HRESULT
 HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames);
 
 HRESULT
-FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs);
-
-HRESULT
 GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride);
 
 int32_t
 MFOffsetToInt32(const MFOffset& aOffset);
 
 // Gets the sub-region of the video frame that should be displayed.
 // See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
 HRESULT
--- a/dom/media/platforms/wmf/moz.build
+++ b/dom/media/platforms/wmf/moz.build
@@ -1,26 +1,39 @@
 # -*- 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/.
 
 EXPORTS += [
+    'DXVA2Manager.h',
     'MFTDecoder.h',
+    'WMF.h',
     'WMFAudioMFTManager.h',
     'WMFDecoderModule.h',
     'WMFMediaDataDecoder.h',
+    'WMFUtils.h',
     'WMFVideoMFTManager.h',
 ]
 UNIFIED_SOURCES += [
+    'DXVA2Manager.cpp',
     'MFTDecoder.cpp',
     'WMFAudioMFTManager.cpp',
     'WMFDecoderModule.cpp',
     'WMFMediaDataDecoder.cpp',
     'WMFVideoMFTManager.cpp',
 ]
 
+SOURCES += [
+    'WMFUtils.cpp',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FINAL_LIBRARY = 'xul'
 
+if CONFIG['OS_ARCH'] == 'WINNT':
+    DEFINES['NOMINMAX'] = True
+
 FAIL_ON_WARNINGS = True
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -105,16 +105,21 @@ AudioContext::AudioContext(nsPIDOMWindow
   // bound to the window.
   mDestination = new AudioDestinationNode(this, aIsOffline, aChannel,
                                           aNumberOfChannels, aLength, aSampleRate);
   // We skip calling SetIsOnlyNodeForContext and the creation of the
   // audioChannelAgent during mDestination's constructor, because we can only
   // call them after mDestination has been set up.
   mDestination->CreateAudioChannelAgent();
   mDestination->SetIsOnlyNodeForContext(true);
+  // We don't use the cubeb context yet, but need to ensure it is created on
+  // the main thread.
+  if (!aIsOffline && !CubebUtils::GetCubebContext()) {
+    NS_WARNING("Audio backend initialization failed.");
+  }
 }
 
 AudioContext::~AudioContext()
 {
   nsPIDOMWindow* window = GetOwner();
   if (window) {
     window->RemoveAudioContext(this);
   }
deleted file mode 100644
--- a/dom/media/wmf/WMFByteStream.cpp
+++ /dev/null
@@ -1,680 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "WMF.h"
-
-#include <unknwn.h>
-#include <ole2.h>
-
-#include "WMFByteStream.h"
-#include "WMFSourceReaderCallback.h"
-#include "WMFUtils.h"
-#include "MediaResource.h"
-#include "nsISeekableStream.h"
-#include "mozilla/RefPtr.h"
-#include "nsIThreadPool.h"
-#include "nsXPCOMCIDInternal.h"
-#include "nsComponentManagerUtils.h"
-#include "mozilla/DebugOnly.h"
-#include "SharedThreadPool.h"
-#include <algorithm>
-#include <cassert>
-
-namespace mozilla {
-
-PRLogModuleInfo* gWMFByteStreamLog = nullptr;
-#define WMF_BS_LOG(...) MOZ_LOG(gWMFByteStreamLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-WMFByteStream::WMFByteStream(MediaResource* aResource,
-                             WMFSourceReaderCallback* aSourceReaderCallback)
-  : mSourceReaderCallback(aSourceReaderCallback),
-    mResource(aResource),
-    mReentrantMonitor("WMFByteStream.Data"),
-    mOffset(0),
-    mIsShutdown(false)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-  NS_ASSERTION(mSourceReaderCallback, "Must have a source reader callback.");
-
-  if (!gWMFByteStreamLog) {
-    gWMFByteStreamLog = PR_NewLogModule("WMFByteStream");
-  }
-  WMF_BS_LOG("[%p] WMFByteStream CTOR", this);
-  MOZ_COUNT_CTOR(WMFByteStream);
-}
-
-WMFByteStream::~WMFByteStream()
-{
-  MOZ_COUNT_DTOR(WMFByteStream);
-  WMF_BS_LOG("[%p] WMFByteStream DTOR", this);
-}
-
-nsresult
-WMFByteStream::Init()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-
-  mThreadPool = SharedThreadPool::Get(NS_LITERAL_CSTRING("WMFByteStream IO"), 4);
-  NS_ENSURE_TRUE(mThreadPool, NS_ERROR_FAILURE);
-
-  NS_ConvertUTF8toUTF16 contentTypeUTF16(mResource->GetContentType());
-  if (!contentTypeUTF16.IsEmpty()) {
-    HRESULT hr = wmf::MFCreateAttributes(byRef(mAttributes), 1);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
-    hr = mAttributes->SetString(MF_BYTESTREAM_CONTENT_TYPE,
-                                contentTypeUTF16.get());
-    NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
-    WMF_BS_LOG("[%p] WMFByteStream has Content-Type=%s", this, mResource->GetContentType().get());
-  }
-  return NS_OK;
-}
-
-nsresult
-WMFByteStream::Shutdown()
-{
-  {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    mIsShutdown = true;
-  }
-  mSourceReaderCallback->Cancel();
-  return NS_OK;
-}
-
-// IUnknown Methods
-STDMETHODIMP
-WMFByteStream::QueryInterface(REFIID aIId, void **aInterface)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::QueryInterface %s", this, GetGUIDName(aIId).get());
-
-  if (aIId == IID_IMFByteStream) {
-    return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface);
-  }
-  if (aIId == IID_IUnknown) {
-    return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface);
-  }
-  if (aIId == IID_IMFAttributes) {
-    return DoGetInterface(static_cast<IMFAttributes*>(this), aInterface);
-  }
-
-  *aInterface = nullptr;
-  return E_NOINTERFACE;
-}
-
-NS_IMPL_ADDREF(WMFByteStream)
-NS_IMPL_RELEASE(WMFByteStream)
-
-
-// Stores data regarding an async read opreation.
-class ReadRequest final : public IUnknown {
-  ~ReadRequest() {}
-
-public:
-  ReadRequest(int64_t aOffset, BYTE* aBuffer, ULONG aLength)
-    : mOffset(aOffset),
-      mBuffer(aBuffer),
-      mBufferLength(aLength),
-      mBytesRead(0)
-  {}
-
-  // IUnknown Methods
-  STDMETHODIMP QueryInterface(REFIID aRIID, LPVOID *aOutObject);
-  STDMETHODIMP_(ULONG) AddRef();
-  STDMETHODIMP_(ULONG) Release();
-
-  int64_t mOffset;
-  BYTE* mBuffer;
-  ULONG mBufferLength;
-  ULONG mBytesRead;
-
-  // IUnknown ref counting.
-  ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-};
-
-NS_IMPL_ADDREF(ReadRequest)
-NS_IMPL_RELEASE(ReadRequest)
-
-// IUnknown Methods
-STDMETHODIMP
-ReadRequest::QueryInterface(REFIID aIId, void **aInterface)
-{
-  WMF_BS_LOG("ReadRequest::QueryInterface %s", GetGUIDName(aIId).get());
-
-  if (aIId == IID_IUnknown) {
-    return DoGetInterface(static_cast<IUnknown*>(this), aInterface);
-  }
-
-  *aInterface = nullptr;
-  return E_NOINTERFACE;
-}
-
-class ProcessReadRequestEvent final : public nsRunnable {
-public:
-  ProcessReadRequestEvent(WMFByteStream* aStream,
-                          IMFAsyncResult* aResult,
-                          ReadRequest* aRequestState)
-    : mStream(aStream),
-      mResult(aResult),
-      mRequestState(aRequestState) {}
-
-  NS_IMETHOD Run() {
-    mStream->ProcessReadRequest(mResult, mRequestState);
-    return NS_OK;
-  }
-private:
-  RefPtr<WMFByteStream> mStream;
-  RefPtr<IMFAsyncResult> mResult;
-  RefPtr<ReadRequest> mRequestState;
-};
-
-// IMFByteStream Methods
-STDMETHODIMP
-WMFByteStream::BeginRead(BYTE *aBuffer,
-                         ULONG aLength,
-                         IMFAsyncCallback *aCallback,
-                         IUnknown *aCallerState)
-{
-  NS_ENSURE_TRUE(aBuffer, E_POINTER);
-  NS_ENSURE_TRUE(aCallback, E_POINTER);
-
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  WMF_BS_LOG("[%p] WMFByteStream::BeginRead() mOffset=%lld tell=%lld length=%lu mIsShutdown=%d",
-             this, mOffset, mResource->Tell(), aLength, mIsShutdown);
-
-  if (mIsShutdown || mOffset < 0) {
-    return E_INVALIDARG;
-  }
-
-  // Create an object to store our state.
-  RefPtr<ReadRequest> requestState = new ReadRequest(mOffset, aBuffer, aLength);
-
-  // Create an IMFAsyncResult, this is passed back to the caller as a token to
-  // retrieve the number of bytes read.
-  RefPtr<IMFAsyncResult> callersResult;
-  HRESULT hr = wmf::MFCreateAsyncResult(requestState,
-                                        aCallback,
-                                        aCallerState,
-                                        byRef(callersResult));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Dispatch an event to perform the read in the thread pool.
-  nsCOMPtr<nsIRunnable> r = new ProcessReadRequestEvent(this,
-                                                        callersResult,
-                                                        requestState);
-  nsresult rv = mThreadPool->Dispatch(r, NS_DISPATCH_NORMAL);
-
-  if (mResource->GetLength() > -1) {
-    mOffset = std::min<int64_t>(mOffset + aLength, mResource->GetLength());
-  } else {
-    mOffset += aLength;
-  }
-
-  return NS_SUCCEEDED(rv) ? S_OK : E_FAIL;
-}
-
-nsresult
-WMFByteStream::Read(ReadRequest* aRequestState)
-{
-  // Read in a loop to ensure we fill the buffer, when possible.
-  ULONG totalBytesRead = 0;
-  nsresult rv = NS_OK;
-  while (totalBytesRead < aRequestState->mBufferLength) {
-    BYTE* buffer = aRequestState->mBuffer + totalBytesRead;
-    ULONG bytesRead = 0;
-    ULONG length = aRequestState->mBufferLength - totalBytesRead;
-    rv = mResource->ReadAt(aRequestState->mOffset + totalBytesRead,
-                           reinterpret_cast<char*>(buffer),
-                           length,
-                           reinterpret_cast<uint32_t*>(&bytesRead));
-    NS_ENSURE_SUCCESS(rv, rv);
-    totalBytesRead += bytesRead;
-    if (bytesRead == 0) {
-      break;
-    }
-  }
-  aRequestState->mBytesRead = totalBytesRead;
-  return NS_OK;
-}
-
-// Note: This is called on one of the thread pool's threads.
-void
-WMFByteStream::ProcessReadRequest(IMFAsyncResult* aResult,
-                                  ReadRequest* aRequestState)
-{
-  if (mResource->GetLength() > -1 &&
-      aRequestState->mOffset > mResource->GetLength()) {
-    aResult->SetStatus(S_OK);
-    wmf::MFInvokeCallback(aResult);
-    WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read offset greater than length, soft-failing read", this);
-    return;
-  }
-
-  nsresult rv = Read(aRequestState);
-  if (NS_FAILED(rv)) {
-    Shutdown();
-    aResult->SetStatus(E_ABORT);
-  } else {
-    aResult->SetStatus(S_OK);
-  }
-
-  WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read %d at %lld finished rv=%x",
-             this, aRequestState->mBytesRead, aRequestState->mOffset, rv);
-
-  // Let caller know read is complete.
-  DebugOnly<HRESULT> hr = wmf::MFInvokeCallback(aResult);
-  NS_ASSERTION(SUCCEEDED(hr), "Failed to invoke callback!");
-}
-
-STDMETHODIMP
-WMFByteStream::BeginWrite(const BYTE *, ULONG ,
-                          IMFAsyncCallback *,
-                          IUnknown *)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::BeginWrite()", this);
-  return E_NOTIMPL;
-}
-
-STDMETHODIMP
-WMFByteStream::Close()
-{
-  WMF_BS_LOG("[%p] WMFByteStream::Close()", this);
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead)
-{
-  NS_ENSURE_TRUE(aResult, E_POINTER);
-  NS_ENSURE_TRUE(aBytesRead, E_POINTER);
-
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-  // Extract our state object.
-  RefPtr<IUnknown> unknown;
-  HRESULT hr = aResult->GetObject(byRef(unknown));
-  if (FAILED(hr) || !unknown) {
-    return E_INVALIDARG;
-  }
-  ReadRequest* requestState =
-    static_cast<ReadRequest*>(unknown.get());
-
-  // Report result.
-  *aBytesRead = requestState->mBytesRead;
-
-  WMF_BS_LOG("[%p] WMFByteStream::EndRead() offset=%lld *aBytesRead=%u mOffset=%lld status=0x%x hr=0x%x eof=%d",
-             this, requestState->mOffset, *aBytesRead, mOffset, aResult->GetStatus(), hr, IsEOS());
-
-  return aResult->GetStatus();
-}
-
-STDMETHODIMP
-WMFByteStream::EndWrite(IMFAsyncResult *, ULONG *)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::EndWrite()", this);
-  return E_NOTIMPL;
-}
-
-STDMETHODIMP
-WMFByteStream::Flush()
-{
-  WMF_BS_LOG("[%p] WMFByteStream::Flush()", this);
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::GetCapabilities(DWORD *aCapabilities)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::GetCapabilities()", this);
-  NS_ENSURE_TRUE(aCapabilities, E_POINTER);
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  bool seekable = mResource->IsTransportSeekable();
-  bool cached = mResource->IsDataCachedToEndOfResource(0);
-  *aCapabilities = MFBYTESTREAM_IS_READABLE |
-                   MFBYTESTREAM_IS_SEEKABLE |
-                   (!cached ? MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED : 0) |
-                   (!seekable ? MFBYTESTREAM_HAS_SLOW_SEEK : 0);
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::GetCurrentPosition(QWORD *aPosition)
-{
-  NS_ENSURE_TRUE(aPosition, E_POINTER);
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  // Note: Returning the length of stream as position when read
-  // cursor is < 0 seems to be the behaviour expected by WMF, but
-  // also note it doesn't seem to expect that the position is an
-  // unsigned value since if you seek to > length and read WMF
-  // expects the read to succeed after reading 0 bytes, but if you
-  // seek to < 0 and read, the read is expected to fails... So
-  // go figure...
-  *aPosition = mOffset < 0 ? mResource->GetLength() : mOffset;
-  WMF_BS_LOG("[%p] WMFByteStream::GetCurrentPosition() %lld", this, mOffset);
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::GetLength(QWORD *aLength)
-{
-  NS_ENSURE_TRUE(aLength, E_POINTER);
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  *aLength = mResource->GetLength();
-  WMF_BS_LOG("[%p] WMFByteStream::GetLength() %lld", this, *aLength);
-  return S_OK;
-}
-
-bool
-WMFByteStream::IsEOS()
-{
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  return mResource->GetLength() > -1 &&
-         (mOffset < 0 ||
-          mOffset >= mResource->GetLength());
-}
-
-STDMETHODIMP
-WMFByteStream::IsEndOfStream(BOOL *aEndOfStream)
-{
-  NS_ENSURE_TRUE(aEndOfStream, E_POINTER);
-  *aEndOfStream = IsEOS();
-  WMF_BS_LOG("[%p] WMFByteStream::IsEndOfStream() %d", this, *aEndOfStream);
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::Read(BYTE* aBuffer, ULONG aBufferLength, ULONG* aOutBytesRead)
-{
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  nsRefPtr<ReadRequest> request = new ReadRequest(mOffset, aBuffer, aBufferLength);
-  if (NS_FAILED(Read(request))) {
-    WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld failed!", this, mOffset);
-    return E_FAIL;
-  }
-  if (aOutBytesRead) {
-    *aOutBytesRead = request->mBytesRead;
-  }
-  WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld length=%u bytesRead=%u",
-             this, mOffset, aBufferLength, request->mBytesRead);
-  mOffset += request->mBytesRead;
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin,
-                    LONGLONG aSeekOffset,
-                    DWORD aSeekFlags,
-                    QWORD *aCurrentPosition)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::Seek(%d, %lld)", this, aSeekOrigin, aSeekOffset);
-
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-  int64_t offset = mOffset;
-  if (aSeekOrigin == msoBegin) {
-    offset = aSeekOffset;
-  } else {
-    offset += aSeekOffset;
-  }
-  int64_t length = mResource->GetLength();
-  if (length > -1) {
-    mOffset = std::min<int64_t>(offset, length);
-  } else {
-    mOffset = offset;
-  }
-  if (aCurrentPosition) {
-    *aCurrentPosition = mOffset;
-  }
-
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::SetCurrentPosition(QWORD aPosition)
-{
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  WMF_BS_LOG("[%p] WMFByteStream::SetCurrentPosition(%lld)",
-             this, aPosition);
-
-  int64_t length = mResource->GetLength();
-  if (length > -1) {
-    mOffset = std::min<int64_t>(aPosition, length);
-  } else {
-    mOffset = aPosition;
-  }
-
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFByteStream::SetLength(QWORD)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::SetLength()", this);
-  return E_NOTIMPL;
-}
-
-STDMETHODIMP
-WMFByteStream::Write(const BYTE *, ULONG, ULONG *)
-{
-  WMF_BS_LOG("[%p] WMFByteStream::Write()", this);
-  return E_NOTIMPL;
-}
-
-// IMFAttributes methods
-STDMETHODIMP
-WMFByteStream::GetItem(REFGUID guidKey, PROPVARIANT* pValue)
-{
-    MOZ_ASSERT(mAttributes);
-    return mAttributes->GetItem(guidKey, pValue);
-}
-
-STDMETHODIMP
-WMFByteStream::GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType)
-{
-    assert(mAttributes);
-    return mAttributes->GetItemType(guidKey, pType);
-}
-
-STDMETHODIMP
-WMFByteStream::CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult)
-{
-    assert(mAttributes);
-    return mAttributes->CompareItem(guidKey, Value, pbResult);
-}
-
-STDMETHODIMP
-WMFByteStream::Compare(IMFAttributes* pTheirs,
-                       MF_ATTRIBUTES_MATCH_TYPE MatchType,
-                       BOOL* pbResult)
-{
-    assert(mAttributes);
-    return mAttributes->Compare(pTheirs, MatchType, pbResult);
-}
-
-STDMETHODIMP
-WMFByteStream::GetUINT32(REFGUID guidKey, UINT32* punValue)
-{
-    assert(mAttributes);
-    return mAttributes->GetUINT32(guidKey, punValue);
-}
-
-STDMETHODIMP
-WMFByteStream::GetUINT64(REFGUID guidKey, UINT64* punValue)
-{
-    assert(mAttributes);
-    return mAttributes->GetUINT64(guidKey, punValue);
-}
-
-STDMETHODIMP
-WMFByteStream::GetDouble(REFGUID guidKey, double* pfValue)
-{
-    assert(mAttributes);
-    return mAttributes->GetDouble(guidKey, pfValue);
-}
-
-STDMETHODIMP
-WMFByteStream::GetGUID(REFGUID guidKey, GUID* pguidValue)
-{
-    assert(mAttributes);
-    return mAttributes->GetGUID(guidKey, pguidValue);
-}
-
-STDMETHODIMP
-WMFByteStream::GetStringLength(REFGUID guidKey, UINT32* pcchLength)
-{
-    assert(mAttributes);
-    return mAttributes->GetStringLength(guidKey, pcchLength);
-}
-
-STDMETHODIMP
-WMFByteStream::GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength)
-{
-    assert(mAttributes);
-    return mAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
-}
-
-STDMETHODIMP
-WMFByteStream::GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength)
-{
-    assert(mAttributes);
-    return mAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
-}
-
-STDMETHODIMP
-WMFByteStream::GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize)
-{
-    assert(mAttributes);
-    return mAttributes->GetBlobSize(guidKey, pcbBlobSize);
-}
-
-STDMETHODIMP
-WMFByteStream::GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize)
-{
-    assert(mAttributes);
-    return mAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
-}
-
-STDMETHODIMP
-WMFByteStream::GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize)
-{
-    assert(mAttributes);
-    return mAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
-}
-
-STDMETHODIMP
-WMFByteStream::GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv)
-{
-    assert(mAttributes);
-    return mAttributes->GetUnknown(guidKey, riid, ppv);
-}
-
-STDMETHODIMP
-WMFByteStream::SetItem(REFGUID guidKey, REFPROPVARIANT Value)
-{
-    assert(mAttributes);
-    return mAttributes->SetItem(guidKey, Value);
-}
-
-STDMETHODIMP
-WMFByteStream::DeleteItem(REFGUID guidKey)
-{
-    assert(mAttributes);
-    return mAttributes->DeleteItem(guidKey);
-}
-
-STDMETHODIMP
-WMFByteStream::DeleteAllItems()
-{
-    assert(mAttributes);
-    return mAttributes->DeleteAllItems();
-}
-
-STDMETHODIMP
-WMFByteStream::SetUINT32(REFGUID guidKey, UINT32 unValue)
-{
-    assert(mAttributes);
-    return mAttributes->SetUINT32(guidKey, unValue);
-}
-
-STDMETHODIMP
-WMFByteStream::SetUINT64(REFGUID guidKey,UINT64 unValue)
-{
-    assert(mAttributes);
-    return mAttributes->SetUINT64(guidKey, unValue);
-}
-
-STDMETHODIMP
-WMFByteStream::SetDouble(REFGUID guidKey, double fValue)
-{
-    assert(mAttributes);
-    return mAttributes->SetDouble(guidKey, fValue);
-}
-
-STDMETHODIMP
-WMFByteStream::SetGUID(REFGUID guidKey, REFGUID guidValue)
-{
-    assert(mAttributes);
-    return mAttributes->SetGUID(guidKey, guidValue);
-}
-
-STDMETHODIMP
-WMFByteStream::SetString(REFGUID guidKey, LPCWSTR wszValue)
-{
-    assert(mAttributes);
-    return mAttributes->SetString(guidKey, wszValue);
-}
-
-STDMETHODIMP
-WMFByteStream::SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize)
-{
-    assert(mAttributes);
-    return mAttributes->SetBlob(guidKey, pBuf, cbBufSize);
-}
-
-STDMETHODIMP
-WMFByteStream::SetUnknown(REFGUID guidKey, IUnknown* pUnknown)
-{
-    assert(mAttributes);
-    return mAttributes->SetUnknown(guidKey, pUnknown);
-}
-
-STDMETHODIMP
-WMFByteStream::LockStore()
-{
-    assert(mAttributes);
-    return mAttributes->LockStore();
-}
-
-STDMETHODIMP
-WMFByteStream::UnlockStore()
-{
-    assert(mAttributes);
-    return mAttributes->UnlockStore();
-}
-
-STDMETHODIMP
-WMFByteStream::GetCount(UINT32* pcItems)
-{
-    assert(mAttributes);
-    return mAttributes->GetCount(pcItems);
-}
-
-STDMETHODIMP
-WMFByteStream::GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue)
-{
-    assert(mAttributes);
-    return mAttributes->GetItemByIndex(unIndex, pguidKey, pValue);
-}
-
-STDMETHODIMP
-WMFByteStream::CopyAllItems(IMFAttributes* pDest)
-{
-    assert(mAttributes);
-    return mAttributes->CopyAllItems(pDest);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/wmf/WMFByteStream.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 !defined(WMFByteStream_h_)
-#define WMFByteStream_h_
-
-#include "WMF.h"
-
-#include "nsISupportsImpl.h"
-#include "nsCOMPtr.h"
-#include "mozilla/ReentrantMonitor.h"
-#include "mozilla/Attributes.h"
-#include "nsAutoPtr.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class MediaResource;
-class ReadRequest;
-class WMFSourceReaderCallback;
-class SharedThreadPool;
-
-// Wraps a MediaResource around an IMFByteStream interface, so that it can
-// be used by the IMFSourceReader. Each WMFByteStream creates a WMF Work Queue
-// on which blocking I/O is performed. The SourceReader requests reads
-// asynchronously using {Begin,End}Read(), and more rarely synchronously
-// using Read().
-//
-// Note: This implementation attempts to be bug-compatible with Windows Media
-//       Foundation's implementation of IMFByteStream. The behaviour of WMF's
-//       IMFByteStream was determined by creating it and testing the edge cases.
-//       For details see the test code at:
-//       https://github.com/cpearce/IMFByteStreamBehaviour/
-class WMFByteStream final : public IMFByteStream
-                          , public IMFAttributes
-{
-  ~WMFByteStream();
-
-public:
-  WMFByteStream(MediaResource* aResource, WMFSourceReaderCallback* aCallback);
-
-  nsresult Init();
-  nsresult Shutdown();
-
-  // IUnknown Methods.
-  STDMETHODIMP QueryInterface(REFIID aIId, LPVOID *aInterface);
-  STDMETHODIMP_(ULONG) AddRef();
-  STDMETHODIMP_(ULONG) Release();
-
-  // IMFByteStream Methods.
-  STDMETHODIMP BeginRead(BYTE *aBuffer,
-                         ULONG aLength,
-                         IMFAsyncCallback *aCallback,
-                         IUnknown *aCallerState);
-  STDMETHODIMP BeginWrite(const BYTE *, ULONG ,
-                          IMFAsyncCallback *,
-                          IUnknown *);
-  STDMETHODIMP Close();
-  STDMETHODIMP EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead);
-  STDMETHODIMP EndWrite(IMFAsyncResult *, ULONG *);
-  STDMETHODIMP Flush();
-  STDMETHODIMP GetCapabilities(DWORD *aCapabilities);
-  STDMETHODIMP GetCurrentPosition(QWORD *aPosition);
-  STDMETHODIMP GetLength(QWORD *pqwLength);
-  STDMETHODIMP IsEndOfStream(BOOL *aIsEndOfStream);
-  STDMETHODIMP Read(BYTE *, ULONG, ULONG *);
-  STDMETHODIMP Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin,
-                    LONGLONG aSeekOffset,
-                    DWORD aSeekFlags,
-                    QWORD *aCurrentPosition);
-  STDMETHODIMP SetCurrentPosition(QWORD aPosition);
-  STDMETHODIMP SetLength(QWORD);
-  STDMETHODIMP Write(const BYTE *, ULONG, ULONG *);
-
-  // IMFAttributes methods
-  STDMETHODIMP GetItem(REFGUID guidKey, PROPVARIANT* pValue);
-  STDMETHODIMP GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType);
-  STDMETHODIMP CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult);
-  STDMETHODIMP Compare(IMFAttributes* pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL* pbResult);
-  STDMETHODIMP GetUINT32(REFGUID guidKey, UINT32* punValue);
-  STDMETHODIMP GetUINT64(REFGUID guidKey, UINT64* punValue);
-  STDMETHODIMP GetDouble(REFGUID guidKey, double* pfValue);
-  STDMETHODIMP GetGUID(REFGUID guidKey, GUID* pguidValue);
-  STDMETHODIMP GetStringLength(REFGUID guidKey, UINT32* pcchLength);
-  STDMETHODIMP GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength);
-  STDMETHODIMP GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength);
-  STDMETHODIMP GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize);
-  STDMETHODIMP GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize);
-  STDMETHODIMP GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize);
-  STDMETHODIMP GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv);
-  STDMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value);
-  STDMETHODIMP DeleteItem(REFGUID guidKey);
-  STDMETHODIMP DeleteAllItems();
-  STDMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue);
-  STDMETHODIMP SetUINT64(REFGUID guidKey,UINT64 unValue);
-  STDMETHODIMP SetDouble(REFGUID guidKey, double fValue);
-  STDMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue);
-  STDMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue);
-  STDMETHODIMP SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize);
-  STDMETHODIMP SetUnknown(REFGUID guidKey, IUnknown* pUnknown);
-  STDMETHODIMP LockStore();
-  STDMETHODIMP UnlockStore();
-  STDMETHODIMP GetCount(UINT32* pcItems);
-  STDMETHODIMP GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue);
-  STDMETHODIMP CopyAllItems(IMFAttributes* pDest);
-
-  // We perform an async read operation in this callback implementation.
-  // Processes an async read request, storing the result in aResult, and
-  // notifying the caller when the read operation is complete.
-  void ProcessReadRequest(IMFAsyncResult* aResult,
-                          ReadRequest* aRequestState);
-
-private:
-
-  // Locks the MediaResource and performs the read. The other read methods
-  // call this function.
-  nsresult Read(ReadRequest* aRequestState);
-
-  // Returns true if the current position of the stream is at end of stream.
-  bool IsEOS();
-
-  // Reference to the thread pool in which we perform the reads asynchronously.
-  // Note this is pool is shared amongst all active WMFByteStreams.
-  RefPtr<SharedThreadPool> mThreadPool;
-
-  // Reference to the source reader's callback. We use this reference to
-  // notify threads waiting on a ReadSample() callback to stop waiting
-  // if the stream is closed, which happens when the media element is
-  // shutdown.
-  RefPtr<WMFSourceReaderCallback> mSourceReaderCallback;
-
-  // Resource we're wrapping.
-  nsRefPtr<MediaResource> mResource;
-
-  // Protects mOffset, which is accessed by the SourceReaders thread(s), and
-  // on the work queue thread.
-  ReentrantMonitor mReentrantMonitor;
-
-  // Current offset of the logical read cursor. We maintain this separately
-  // from the media resource's offset since a partially complete read (in Invoke())
-  // would leave the resource's offset at a value unexpected by the caller,
-  // since the read hadn't yet completed.
-  int64_t mOffset;
-
-  // We implement IMFAttributes by forwarding all calls to an instance of the
-  // standard IMFAttributes class, which we store a reference to here.
-  RefPtr<IMFAttributes> mAttributes;
-
-  // True if the resource has been shutdown, either because the WMFReader is
-  // shutting down, or because the underlying MediaResource has closed.
-  bool mIsShutdown;
-
-  // IUnknown ref counting.
-  ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-};
-
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/media/wmf/WMFDecoder.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "WMF.h"
-#include "WMFDecoder.h"
-#include "WMFReader.h"
-#include "WMFUtils.h"
-#include "MediaDecoderStateMachine.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/WindowsVersion.h"
-#include "nsCharSeparatedTokenizer.h"
-
-#ifdef MOZ_DIRECTSHOW
-#include "DirectShowDecoder.h"
-#endif
-
-namespace mozilla {
-
-MediaDecoderStateMachine* WMFDecoder::CreateStateMachine()
-{
-  return new MediaDecoderStateMachine(this, new WMFReader(this));
-}
-
-/* static */
-bool
-WMFDecoder::IsMP3Supported()
-{
-  MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
-  if (!MediaDecoder::IsWMFEnabled()) {
-    return false;
-  }
-  // MP3 works fine in WMF on Windows Vista and Windows 8.
-  if (!IsWin7OrLater()) {
-    return true;
-  }
-  // MP3 support is disabled if we're on Windows 7 and no service packs are
-  // installed, since it's crashy. Win7 with service packs is not so crashy,
-  // so we enable it there. Note we prefer DirectShow for MP3 playback, but
-  // we still support MP3 in MP4 via WMF, or MP3 in WMF if DirectShow is
-  // disabled.
-  return IsWin7SP1OrLater();
-}
-
-static bool
-IsSupportedH264Codec(const nsAString& aCodec)
-{
-  // According to the WMF documentation:
-  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
-  // "The Media Foundation H.264 video decoder is a Media Foundation Transform
-  // that supports decoding of Baseline, Main, and High profiles, up to level
-  // 5.1.". We also report that we can play Extended profile, as there are
-  // bitstreams that are Extended compliant that are also Baseline compliant.
-
-  int16_t profile = 0, level = 0;
-  if (!ExtractH264CodecDetails(aCodec, profile, level)) {
-    return false;
-  }
-
-  return level >= H264_LEVEL_1 &&
-         level <= H264_LEVEL_5_1 &&
-         (profile == H264_PROFILE_BASE ||
-          profile == H264_PROFILE_MAIN ||
-          profile == H264_PROFILE_EXTENDED ||
-          profile == H264_PROFILE_HIGH);
-}
-
-bool
-WMFDecoder::CanPlayType(const nsACString& aType,
-                        const nsAString& aCodecs)
-{
-  if (!MediaDecoder::IsWMFEnabled() ||
-      NS_FAILED(LoadDLLs())) {
-    return false;
-  }
-
-  // Assume that if LoadDLLs() didn't fail, we can playback the types that
-  // we know should be supported by Windows Media Foundation.
-  if ((aType.EqualsASCII("audio/mpeg") || aType.EqualsASCII("audio/mp3")) &&
-      IsMP3Supported()) {
-    // Note: We block MP3 playback on Window 7 SP0 since it seems to crash
-    // in some circumstances.
-    return !aCodecs.Length() || aCodecs.EqualsASCII("mp3");
-  }
-
-  // AAC-LC or MP3 in M4A.
-  if (aType.EqualsASCII("audio/mp4") || aType.EqualsASCII("audio/x-m4a")) {
-    return !aCodecs.Length() ||
-           aCodecs.EqualsASCII("mp4a.40.2") ||
-           aCodecs.EqualsASCII("mp3");
-  }
-
-  if (!aType.EqualsASCII("video/mp4")) {
-    return false;
-  }
-
-  // H.264 + AAC in MP4. Verify that all the codecs specifed are ones that
-  // we expect that we can play.
-  nsCharSeparatedTokenizer tokenizer(aCodecs, ',');
-  bool expectMoreTokens = false;
-  while (tokenizer.hasMoreTokens()) {
-    const nsSubstring& token = tokenizer.nextToken();
-    expectMoreTokens = tokenizer.separatorAfterCurrentToken();
-    if (token.EqualsASCII("mp4a.40.2") || // AAC-LC
-        token.EqualsASCII("mp3") ||
-        IsSupportedH264Codec(token)) {
-      continue;
-    }
-    return false;
-  }
-  if (expectMoreTokens) {
-    // Last codec name was empty
-    return false;
-  }
-  return true;
-}
-
-nsresult
-WMFDecoder::LoadDLLs()
-{
-  return SUCCEEDED(wmf::LoadDLLs()) ? NS_OK : NS_ERROR_FAILURE;
-}
-
-void
-WMFDecoder::UnloadDLLs()
-{
-  wmf::UnloadDLLs();
-}
-
-/* static */
-bool
-WMFDecoder::IsEnabled()
-{
-  // We only use WMF on Windows Vista and up
-  return IsVistaOrLater() &&
-         Preferences::GetBool("media.windows-media-foundation.enabled");
-}
-
-} // namespace mozilla
-
deleted file mode 100644
--- a/dom/media/wmf/WMFDecoder.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 !defined(WMFDecoder_h_)
-#define WMFDecoder_h_
-
-#include "MediaDecoder.h"
-
-namespace mozilla {
-
-// Decoder that uses Windows Media Foundation to playback H.264/AAC in MP4
-// and M4A files, and MP3 files if the DirectShow backend is disabled.
-// Playback is strictly limited to only those codecs.
-class WMFDecoder : public MediaDecoder
-{
-public:
-
-  virtual MediaDecoder* Clone() {
-    if (!IsWMFEnabled()) {
-      return nullptr;
-    }
-    return new WMFDecoder();
-  }
-
-  virtual MediaDecoderStateMachine* CreateStateMachine();
-
-  // Loads the DLLs required by Windows Media Foundation. If this returns
-  // failure, you can assume that WMF is not available on the user's system.
-  static nsresult LoadDLLs();
-  static void UnloadDLLs();
-
-  // Returns true if the WMF backend is preffed on, and we're running on a
-  // version of Windows which is likely to support WMF.
-  static bool IsEnabled();
-
-  // Returns true if MP3 decoding is enabled on this system. We block
-  // MP3 playback on Windows 7 SP0, since it's crashy on that platform.
-  static bool IsMP3Supported();
-
-  // Returns the HTMLMediaElement.canPlayType() result for the mime type
-  // and codecs parameter. aCodecs can be empty.
-  static bool CanPlayType(const nsACString& aType,
-                          const nsAString& aCodecs);
-
-};
-
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/media/wmf/WMFReader.cpp
+++ /dev/null
@@ -1,929 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "WMFReader.h"
-#include "WMFDecoder.h"
-#include "WMFUtils.h"
-#include "WMFByteStream.h"
-#include "WMFSourceReaderCallback.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/Preferences.h"
-#include "DXVA2Manager.h"
-#include "ImageContainer.h"
-#include "Layers.h"
-#include "mozilla/layers/LayersTypes.h"
-#include "gfxWindowsPlatform.h"
-
-#ifndef MOZ_SAMPLE_TYPE_FLOAT32
-#error We expect 32bit float audio samples on desktop for the Windows Media Foundation media backend.
-#endif
-
-#include "MediaDecoder.h"
-#include "VideoUtils.h"
-#include "gfx2DGlue.h"
-
-using namespace mozilla::gfx;
-using namespace mozilla::media;
-using mozilla::layers::Image;
-using mozilla::layers::LayerManager;
-using mozilla::layers::LayersBackend;
-
-namespace mozilla {
-
-extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(...) MOZ_LOG(gMediaDecoderLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-// Uncomment to enable verbose per-sample logging.
-//#define LOG_SAMPLE_DECODE 1
-
-WMFReader::WMFReader(AbstractMediaDecoder* aDecoder)
-  : MediaDecoderReader(aDecoder),
-    mSourceReader(nullptr),
-    mAudioChannels(0),
-    mAudioBytesPerSample(0),
-    mAudioRate(0),
-    mVideoWidth(0),
-    mVideoHeight(0),
-    mVideoStride(0),
-    mAudioFrameOffset(0),
-    mAudioFrameSum(0),
-    mMustRecaptureAudioPosition(true),
-    mHasAudio(false),
-    mHasVideo(false),
-    mUseHwAccel(false),
-    mIsMP3Enabled(WMFDecoder::IsMP3Supported()),
-    mCOMInitialized(false)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-  MOZ_COUNT_CTOR(WMFReader);
-}
-
-WMFReader::~WMFReader()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-
-  // Note: We must shutdown the byte stream before calling MFShutdown, else we
-  // get assertion failures when unlocking the byte stream's work queue.
-  if (mByteStream) {
-    DebugOnly<nsresult> rv = mByteStream->Shutdown();
-    NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to shutdown WMFByteStream");
-  }
-  DebugOnly<HRESULT> hr = wmf::MFShutdown();
-  NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
-  MOZ_COUNT_DTOR(WMFReader);
-}
-
-bool
-WMFReader::InitializeDXVA()
-{
-  if (gfxWindowsPlatform::GetPlatform()->IsWARP() ||
-      !gfxPlatform::CanUseHardwareVideoDecoding()) {
-    return false;
-  }
-
-  MOZ_ASSERT(mDecoder->GetImageContainer());
-
-  // Extract the layer manager backend type so that we can determine
-  // whether it's worthwhile using DXVA. If we're not running with a D3D
-  // layer manager then the readback of decoded video frames from GPU to
-  // CPU memory grinds painting to a halt, and makes playback performance
-  // *worse*.
-  MediaDecoderOwner* owner = mDecoder->GetOwner();
-  NS_ENSURE_TRUE(owner, false);
-
-  dom::HTMLMediaElement* element = owner->GetMediaElement();
-  NS_ENSURE_TRUE(element, false);
-
-  nsRefPtr<LayerManager> layerManager =
-    nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
-  NS_ENSURE_TRUE(layerManager, false);
-
-  LayersBackend backend = layerManager->GetCompositorBackendType();
-  if (backend != LayersBackend::LAYERS_D3D9 &&
-      backend != LayersBackend::LAYERS_D3D11) {
-    return false;
-  }
-
-  mDXVA2Manager = DXVA2Manager::CreateD3D9DXVA();
-
-  return mDXVA2Manager != nullptr;
-}
-
-nsresult
-WMFReader::Init(MediaDecoderReader* aCloneDonor)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-
-  nsresult rv = WMFDecoder::LoadDLLs();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (FAILED(wmf::MFStartup())) {
-    NS_WARNING("Failed to initialize Windows Media Foundation");
-    return NS_ERROR_FAILURE;
-  }
-
-  mSourceReaderCallback = new WMFSourceReaderCallback();
-
-  // Must be created on main thread.
-  mByteStream = new WMFByteStream(mDecoder->GetResource(), mSourceReaderCallback);
-  rv = mByteStream->Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (mDecoder->GetImageContainer() != nullptr &&
-      IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
-    mUseHwAccel = InitializeDXVA();
-  } else {
-    mUseHwAccel = false;
-  }
-
-  return NS_OK;
-}
-
-bool
-WMFReader::HasAudio()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  return mHasAudio;
-}
-
-bool
-WMFReader::HasVideo()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  return mHasVideo;
-}
-
-static HRESULT
-ConfigureSourceReaderStream(IMFSourceReader *aReader,
-                            const DWORD aStreamIndex,
-                            const GUID& aOutputSubType,
-                            const GUID* aAllowedInSubTypes,
-                            const uint32_t aNumAllowedInSubTypes)
-{
-  NS_ENSURE_TRUE(aReader, E_POINTER);
-  NS_ENSURE_TRUE(aAllowedInSubTypes, E_POINTER);
-
-  RefPtr<IMFMediaType> nativeType;
-  RefPtr<IMFMediaType> type;
-  HRESULT hr;
-
-  // Find the native format of the stream.
-  hr = aReader->GetNativeMediaType(aStreamIndex, 0, byRef(nativeType));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Get the native output subtype of the stream. This denotes the uncompressed
-  // type.
-  GUID subType;
-  hr = nativeType->GetGUID(MF_MT_SUBTYPE, &subType);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Ensure the input type of the media is in the allowed formats list.
-  bool isSubTypeAllowed = false;
-  for (uint32_t i = 0; i < aNumAllowedInSubTypes; i++) {
-    if (aAllowedInSubTypes[i] == subType) {
-      isSubTypeAllowed = true;
-      break;
-    }
-  }
-  if (!isSubTypeAllowed) {
-    nsCString name = GetGUIDName(subType);
-    DECODER_LOG("ConfigureSourceReaderStream subType=%s is not allowed to be decoded", name.get());
-    return E_FAIL;
-  }
-
-  // Find the major type.
-  GUID majorType;
-  hr = nativeType->GetGUID(MF_MT_MAJOR_TYPE, &majorType);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Define the output type.
-  hr = wmf::MFCreateMediaType(byRef(type));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  hr = type->SetGUID(MF_MT_MAJOR_TYPE, majorType);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  hr = type->SetGUID(MF_MT_SUBTYPE, aOutputSubType);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Set the uncompressed format. This can fail if the decoder can't produce
-  // that type.
-  return aReader->SetCurrentMediaType(aStreamIndex, nullptr, type);
-}
-
-// Returns the duration of the resource, in microseconds.
-HRESULT
-GetSourceReaderDuration(IMFSourceReader *aReader,
-                        int64_t& aOutDuration)
-{
-  AutoPropVar var;
-  HRESULT hr = aReader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE,
-                                                 MF_PD_DURATION,
-                                                 &var);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // WMF stores duration in hundred nanosecond units.
-  int64_t duration_hns = 0;
-  hr = wmf::PropVariantToInt64(var, &duration_hns);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  aOutDuration = HNsToUsecs(duration_hns);
-
-  return S_OK;
-}
-
-HRESULT
-GetSourceReaderCanSeek(IMFSourceReader* aReader, bool& aOutCanSeek)
-{
-  NS_ENSURE_TRUE(aReader, E_FAIL);
-
-  HRESULT hr;
-  AutoPropVar var;
-  hr = aReader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE,
-                                         MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS,
-                                         &var);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  ULONG flags = 0;
-  hr = wmf::PropVariantToUInt32(var, &flags);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  aOutCanSeek = ((flags & MFMEDIASOURCE_CAN_SEEK) == MFMEDIASOURCE_CAN_SEEK);
-
-  return S_OK;
-}
-
-HRESULT
-WMFReader::ConfigureVideoFrameGeometry(IMFMediaType* aMediaType)
-{
-  NS_ENSURE_TRUE(aMediaType != nullptr, E_POINTER);
-  HRESULT hr;
-
-  // Verify that the video subtype is what we expect it to be.
-  // When using hardware acceleration/DXVA2 the video format should
-  // be NV12, which is DXVA2's preferred format. For software decoding
-  // we use YV12, as that's easier for us to stick into our rendering
-  // pipeline than NV12. NV12 has interleaved UV samples, whereas YV12
-  // is a planar format.
-  GUID videoFormat;
-  hr = aMediaType->GetGUID(MF_MT_SUBTYPE, &videoFormat);
-  NS_ENSURE_TRUE(videoFormat == MFVideoFormat_NV12 || !mUseHwAccel, E_FAIL);
-  NS_ENSURE_TRUE(videoFormat == MFVideoFormat_YV12 || mUseHwAccel, E_FAIL);
-
-  nsIntRect pictureRegion;
-  hr = GetPictureRegion(aMediaType, pictureRegion);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  UINT32 width = 0, height = 0;
-  hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  uint32_t aspectNum = 0, aspectDenom = 0;
-  hr = MFGetAttributeRatio(aMediaType,
-                           MF_MT_PIXEL_ASPECT_RATIO,
-                           &aspectNum,
-                           &aspectDenom);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Calculate and validate the picture region and frame dimensions after
-  // scaling by the pixel aspect ratio.
-  nsIntSize frameSize = nsIntSize(width, height);
-  nsIntSize displaySize = nsIntSize(pictureRegion.width, pictureRegion.height);
-  ScaleDisplayByAspectRatio(displaySize, float(aspectNum) / float(aspectDenom));
-  if (!IsValidVideoRegion(frameSize, pictureRegion, displaySize)) {
-    // Video track's frame sizes will overflow. Ignore the video track.
-    return E_FAIL;
-  }
-
-  // Success! Save state.
-  mInfo.mVideo.mDisplay = displaySize;
-  GetDefaultStride(aMediaType, &mVideoStride);
-  mVideoWidth = width;
-  mVideoHeight = height;
-  mPictureRegion = pictureRegion;
-
-  DECODER_LOG("WMFReader frame geometry frame=(%u,%u) stride=%u picture=(%d, %d, %d, %d) display=(%d,%d) PAR=%d:%d",
-              width, height,
-              mVideoStride,
-              mPictureRegion.x, mPictureRegion.y, mPictureRegion.width, mPictureRegion.height,
-              displaySize.width, displaySize.height,
-              aspectNum, aspectDenom);
-
-  return S_OK;
-}
-
-HRESULT
-WMFReader::ConfigureVideoDecoder()
-{
-  NS_ASSERTION(mSourceReader, "Must have a SourceReader before configuring decoders!");
-
-  // Determine if we have video.
-  if (!mSourceReader ||
-      !SourceReaderHasStream(mSourceReader, MF_SOURCE_READER_FIRST_VIDEO_STREAM)) {
-    // No stream, no error.
-    return S_OK;
-  }
-
-  if (!mDecoder->GetImageContainer()) {
-    // We can't display the video, so don't bother to decode; disable the stream.
-    return mSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_VIDEO_STREAM, FALSE);
-  }
-
-  static const GUID MP4VideoTypes[] = {
-    MFVideoFormat_H264
-  };
-  HRESULT hr = ConfigureSourceReaderStream(mSourceReader,
-                                           MF_SOURCE_READER_FIRST_VIDEO_STREAM,
-                                           mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12,
-                                           MP4VideoTypes,
-                                           ArrayLength(MP4VideoTypes));
-  if (FAILED(hr)) {
-    DECODER_LOG("Failed to configured video output");
-    return hr;
-  }
-
-  RefPtr<IMFMediaType> mediaType;
-  hr = mSourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
-                                          byRef(mediaType));
-  if (FAILED(hr)) {
-    NS_WARNING("Failed to get configured video media type");
-    return hr;
-  }
-
-  if (FAILED(ConfigureVideoFrameGeometry(mediaType))) {
-    NS_WARNING("Failed configured video frame dimensions");
-    return hr;
-  }
-
-  DECODER_LOG("Successfully configured video stream");
-
-  mHasVideo = true;
-
-  return S_OK;
-}
-
-void
-WMFReader::GetSupportedAudioCodecs(const GUID** aCodecs, uint32_t* aNumCodecs)
-{
-  MOZ_ASSERT(aCodecs);
-  MOZ_ASSERT(aNumCodecs);
-
-  if (mIsMP3Enabled) {
-    GUID aacOrMp3 = MFMPEG4Format_Base;
-    aacOrMp3.Data1 = 0x6D703461;// FOURCC('m','p','4','a');
-    static const GUID codecs[] = {
-      MFAudioFormat_AAC,
-      MFAudioFormat_MP3,
-      aacOrMp3
-    };
-    *aCodecs = codecs;
-    *aNumCodecs = ArrayLength(codecs);
-  } else {
-    static const GUID codecs[] = {
-      MFAudioFormat_AAC
-    };
-    *aCodecs = codecs;
-    *aNumCodecs = ArrayLength(codecs);
-  }
-}
-
-HRESULT
-WMFReader::ConfigureAudioDecoder()
-{
-  NS_ASSERTION(mSourceReader, "Must have a SourceReader before configuring decoders!");
-
-  if (!mSourceReader ||
-      !SourceReaderHasStream(mSourceReader, MF_SOURCE_READER_FIRST_AUDIO_STREAM)) {
-    // No stream, no error.
-    return S_OK;
-  }
-
-  const GUID* codecs;
-  uint32_t numCodecs = 0;
-  GetSupportedAudioCodecs(&codecs, &numCodecs);
-
-  HRESULT hr = ConfigureSourceReaderStream(mSourceReader,
-                                           MF_SOURCE_READER_FIRST_AUDIO_STREAM,
-                                           MFAudioFormat_Float,
-                                           codecs,
-                                           numCodecs);
-  if (FAILED(hr)) {
-    NS_WARNING("Failed to configure WMF Audio decoder for PCM output");
-    return hr;
-  }
-
-  RefPtr<IMFMediaType> mediaType;
-  hr = mSourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM,
-                                          byRef(mediaType));
-  if (FAILED(hr)) {
-    NS_WARNING("Failed to get configured audio media type");
-    return hr;
-  }
-
-  mAudioRate = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0);
-  mAudioChannels = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_NUM_CHANNELS, 0);
-  mAudioBytesPerSample = MFGetAttributeUINT32(mediaType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16) / 8;
-
-  mInfo.mAudio.mChannels = mAudioChannels;
-  mInfo.mAudio.mRate = mAudioRate;
-  mHasAudio = true;
-
-  DECODER_LOG("Successfully configured audio stream. rate=%u channels=%u bitsPerSample=%u",
-              mAudioRate, mAudioChannels, mAudioBytesPerSample);
-
-  return S_OK;
-}
-
-HRESULT
-WMFReader::CreateSourceReader()
-{
-  HRESULT hr;
-
-  RefPtr<IMFAttributes> attr;
-  hr = wmf::MFCreateAttributes(byRef(attr), 1);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  hr = attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, mSourceReaderCallback);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  if (mUseHwAccel) {
-    hr = attr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER,
-                          mDXVA2Manager->GetDXVADeviceManager());
-    if (FAILED(hr)) {
-      DECODER_LOG("Failed to set DXVA2 D3D Device manager on source reader attributes");
-      mUseHwAccel = false;
-    }
-  }
-
-  hr = wmf::MFCreateSourceReaderFromByteStream(mByteStream, attr, byRef(mSourceReader));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  hr = ConfigureVideoDecoder();
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  hr = ConfigureAudioDecoder();
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  if (mUseHwAccel && mInfo.HasVideo()) {
-    RefPtr<IMFTransform> videoDecoder;
-    hr = mSourceReader->GetServiceForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
-                                            GUID_NULL,
-                                            IID_IMFTransform,
-                                            (void**)(IMFTransform**)(byRef(videoDecoder)));
-
-    if (SUCCEEDED(hr)) {
-      ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
-      hr = videoDecoder->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,
-                                        manager);
-      if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
-        // Ignore MF_E_TRANSFORM_TYPE_NOT_SET. Vista returns this here
-        // on some, perhaps all, video cards. This may be because activating
-        // DXVA changes the available output types. It seems to be safe to
-        // ignore this error.
-        hr = S_OK;
-      }
-    }
-    if (FAILED(hr)) {
-      DECODER_LOG("Failed to set DXVA2 D3D Device manager on decoder hr=0x%x", hr);
-      mUseHwAccel = false;
-    }
-  }
-  return hr;
-}
-
-nsresult
-WMFReader::ReadMetadata(MediaInfo* aInfo,
-                        MetadataTags** aTags)
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  DECODER_LOG("WMFReader::ReadMetadata()");
-  HRESULT hr;
-
-  const bool triedToInitDXVA = mUseHwAccel;
-  if (FAILED(CreateSourceReader())) {
-    mSourceReader = nullptr;
-    if (triedToInitDXVA && !mUseHwAccel) {
-      // We tried to initialize DXVA and failed. Try again to create the
-      // IMFSourceReader but this time we won't use DXVA. Note that we
-      // must recreate the IMFSourceReader from scratch, as on some systems
-      // (AMD Radeon 3000) we cannot successfully reconfigure an existing
-      // reader to not use DXVA after we've failed to configure DXVA.
-      // See bug 987127.
-      if (FAILED(CreateSourceReader())) {
-        mSourceReader = nullptr;
-      }
-    }
-  }
-
-  if (!mSourceReader) {
-    NS_WARNING("Failed to create IMFSourceReader");
-    return NS_ERROR_FAILURE;
-  }
-
-  if (mInfo.HasVideo()) {
-    DECODER_LOG("Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
-  }
-
-  // Abort if both video and audio failed to initialize.
-  NS_ENSURE_TRUE(mInfo.HasValidMedia(), NS_ERROR_FAILURE);
-
-  // Get the duration, and report it to the decoder if we have it.
-  int64_t duration = 0;
-  hr = GetSourceReaderDuration(mSourceReader, duration);
-  if (SUCCEEDED(hr)) {
-    mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
-  }
-
-  *aInfo = mInfo;
-  *aTags = nullptr;
-  // aTags can be retrieved using techniques like used here:
-  // http://blogs.msdn.com/b/mf/archive/2010/01/12/mfmediapropdump.aspx
-
-  return NS_OK;
-}
-
-bool
-WMFReader::IsMediaSeekable()
-{
-  // Get the duration
-  int64_t duration = 0;
-  HRESULT hr = GetSourceReaderDuration(mSourceReader, duration);
-  // We can seek if we get a duration *and* the reader reports that it's
-  // seekable.
-  bool canSeek = false;
-  if (FAILED(hr) || FAILED(GetSourceReaderCanSeek(mSourceReader, canSeek)) ||
-      !canSeek) {
-    return false;
-  }
-  return true;
-}
-
-bool
-WMFReader::DecodeAudioData()
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  HRESULT hr;
-  hr = mSourceReader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM,
-                                 0, // control flags
-                                 0, // read stream index
-                                 nullptr,
-                                 nullptr,
-                                 nullptr);
-
-  if (FAILED(hr)) {
-    DECODER_LOG("WMFReader::DecodeAudioData() ReadSample failed with hr=0x%x", hr);
-    // End the stream.
-    return false;
-  }
-
-  DWORD flags = 0;
-  LONGLONG timestampHns = 0;
-  RefPtr<IMFSample> sample;
-  hr = mSourceReaderCallback->Wait(&flags, &timestampHns, byRef(sample));
-  if (FAILED(hr) ||
-      (flags & MF_SOURCE_READERF_ERROR) ||
-      (flags & MF_SOURCE_READERF_ENDOFSTREAM) ||
-      (flags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)) {
-    DECODER_LOG("WMFReader::DecodeAudioData() ReadSample failed with hr=0x%x flags=0x%x",
-                hr, flags);
-    // End the stream.
-    return false;
-  }
-
-  if (!sample) {
-    // Not enough data? Try again...
-    return true;
-  }
-
-  RefPtr<IMFMediaBuffer> buffer;
-  hr = sample->ConvertToContiguousBuffer(byRef(buffer));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), false);
-
-  BYTE* data = nullptr; // Note: *data will be owned by the IMFMediaBuffer, we don't need to free it.
-  DWORD maxLength = 0, currentLength = 0;
-  hr = buffer->Lock(&data, &maxLength, &currentLength);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), false);
-
-  uint32_t numFrames = currentLength / mAudioBytesPerSample / mAudioChannels;
-  NS_ASSERTION(sizeof(AudioDataValue) == mAudioBytesPerSample, "Size calculation is wrong");
-  nsAutoArrayPtr<AudioDataValue> pcmSamples(new AudioDataValue[numFrames * mAudioChannels]);
-  memcpy(pcmSamples.get(), data, currentLength);
-  buffer->Unlock();
-
-  // We calculate the timestamp and the duration based on the number of audio
-  // frames we've already played. We don't trust the timestamp stored on the
-  // IMFSample, as sometimes it's wrong, possibly due to buggy encoders?
-
-  // If this sample block comes after a discontinuity (i.e. a gap or seek)
-  // reset the frame counters, and capture the timestamp. Future timestamps
-  // will be offset from this block's timestamp.
-  UINT32 discontinuity = false;
-  sample->GetUINT32(MFSampleExtension_Discontinuity, &discontinuity);
-  if (mMustRecaptureAudioPosition || discontinuity) {
-    mAudioFrameSum = 0;
-    hr = HNsToFrames(timestampHns, mAudioRate, &mAudioFrameOffset);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), false);
-    mMustRecaptureAudioPosition = false;
-  }
-
-  int64_t timestamp;
-  hr = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, mAudioRate, &timestamp);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), false);
-
-  mAudioFrameSum += numFrames;
-
-  int64_t duration;
-  hr = FramesToUsecs(numFrames, mAudioRate, &duration);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), false);
-
-  mAudioQueue.Push(new AudioData(mDecoder->GetResource()->Tell(),
-                                 timestamp,
-                                 duration,
-                                 numFrames,
-                                 pcmSamples.forget(),
-                                 mAudioChannels,
-                                 mAudioRate));
-
-  #ifdef LOG_SAMPLE_DECODE
-  DECODER_LOG("Decoded audio sample! timestamp=%lld duration=%lld currentLength=%u",
-              timestamp, duration, currentLength);
-  #endif
-
-  return true;
-}
-
-HRESULT
-WMFReader::CreateBasicVideoFrame(IMFSample* aSample,
-                                 int64_t aTimestampUsecs,
-                                 int64_t aDurationUsecs,
-                                 int64_t aOffsetBytes,
-                                 VideoData** aOutVideoData)
-{
-  NS_ENSURE_TRUE(aSample, E_POINTER);
-  NS_ENSURE_TRUE(aOutVideoData, E_POINTER);
-
-  *aOutVideoData = nullptr;
-
-  HRESULT hr;
-  RefPtr<IMFMediaBuffer> buffer;
-
-  // Must convert to contiguous buffer to use IMD2DBuffer interface.
-  hr = aSample->ConvertToContiguousBuffer(byRef(buffer));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
-  // Try and use the IMF2DBuffer interface if available, otherwise fallback
-  // to the IMFMediaBuffer interface. Apparently IMF2DBuffer is more efficient,
-  // but only some systems (Windows 8?) support it.
-  BYTE* data = nullptr;
-  LONG stride = 0;
-  RefPtr<IMF2DBuffer> twoDBuffer;
-  hr = buffer->QueryInterface(static_cast<IMF2DBuffer**>(byRef(twoDBuffer)));
-  if (SUCCEEDED(hr)) {
-    hr = twoDBuffer->Lock2D(&data, &stride);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-  } else {
-    hr = buffer->Lock(&data, nullptr, nullptr);
-    NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-    stride = mVideoStride;
-  }
-
-  // YV12, planar format: [YYYY....][VVVV....][UUUU....]
-  // i.e., Y, then V, then U.
-  VideoData::YCbCrBuffer b;
-
-  // Y (Y') plane
-  b.mPlanes[0].mData = data;
-  b.mPlanes[0].mStride = stride;
-  b.mPlanes[0].mHeight = mVideoHeight;
-  b.mPlanes[0].mWidth = mVideoWidth;
-  b.mPlanes[0].mOffset = 0;
-  b.mPlanes[0].mSkip = 0;
-
-  // The V and U planes are stored 16-row-aligned, so we need to add padding
-  // to the row heights to ensure the Y'CbCr planes are referenced properly.
-  uint32_t padding = 0;
-  if (mVideoHeight % 16 != 0) {
-    padding = 16 - (mVideoHeight % 16);
-  }
-  uint32_t y_size = stride * (mVideoHeight + padding);
-  uint32_t v_size = stride * (mVideoHeight + padding) / 4;
-  uint32_t halfStride = (stride + 1) / 2;
-  uint32_t halfHeight = (mVideoHeight + 1) / 2;
-  uint32_t halfWidth = (mVideoWidth + 1) / 2;
-
-  // U plane (Cb)
-  b.mPlanes[1].mData = data + y_size + v_size;
-  b.mPlanes[1].mStride = halfStride;
-  b.mPlanes[1].mHeight = halfHeight;
-  b.mPlanes[1].mWidth = halfWidth;
-  b.mPlanes[1].mOffset = 0;
-  b.mPlanes[1].mSkip = 0;
-
-  // V plane (Cr)
-  b.mPlanes[2].mData = data + y_size;
-  b.mPlanes[2].mStride = halfStride;
-  b.mPlanes[2].mHeight = halfHeight;
-  b.mPlanes[2].mWidth = halfWidth;
-  b.mPlanes[2].mOffset = 0;
-  b.mPlanes[2].mSkip = 0;
-
-  nsRefPtr<VideoData> v = VideoData::Create(mInfo.mVideo,
-                                            mDecoder->GetImageContainer(),
-                                            aOffsetBytes,
-                                            aTimestampUsecs,
-                                            aDurationUsecs,
-                                            b,
-                                            false,
-                                            -1,
-                                            mPictureRegion);
-  if (twoDBuffer) {
-    twoDBuffer->Unlock2D();
-  } else {
-    buffer->Unlock();
-  }
-
-  v.forget(aOutVideoData);
-  return S_OK;
-}
-
-HRESULT
-WMFReader::CreateD3DVideoFrame(IMFSample* aSample,
-                               int64_t aTimestampUsecs,
-                               int64_t aDurationUsecs,
-                               int64_t aOffsetBytes,
-                               VideoData** aOutVideoData)
-{
-  NS_ENSURE_TRUE(aSample, E_POINTER);
-  NS_ENSURE_TRUE(aOutVideoData, E_POINTER);
-  NS_ENSURE_TRUE(mDXVA2Manager, E_ABORT);
-  NS_ENSURE_TRUE(mUseHwAccel, E_ABORT);
-
-  *aOutVideoData = nullptr;
-  HRESULT hr;
-
-  nsRefPtr<Image> image;
-  hr = mDXVA2Manager->CopyToImage(aSample,
-                                  mPictureRegion,
-                                  mDecoder->GetImageContainer(),
-                                  getter_AddRefs(image));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-  NS_ENSURE_TRUE(image, E_FAIL);
-
-  nsRefPtr<VideoData> v = VideoData::CreateFromImage(mInfo.mVideo,
-                                                     mDecoder->GetImageContainer(),
-                                                     aOffsetBytes,
-                                                     aTimestampUsecs,
-                                                     aDurationUsecs,
-                                                     image.forget(),
-                                                     false,
-                                                     -1,
-                                                     mPictureRegion);
-
-  NS_ENSURE_TRUE(v, E_FAIL);
-  v.forget(aOutVideoData);
-
-  return S_OK;
-}
-
-bool
-WMFReader::DecodeVideoFrame(bool &aKeyframeSkip,
-                            int64_t aTimeThreshold)
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  // Record number of frames decoded and parsed. Automatically update the
-  // stats counters using the AutoNotifyDecoded stack-based class.
-  AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
-
-  HRESULT hr;
-
-  hr = mSourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
-                                 0, // control flags
-                                 0, // read stream index
-                                 nullptr,
-                                 nullptr,
-                                 nullptr);
-  if (FAILED(hr)) {
-    DECODER_LOG("WMFReader::DecodeVideoData() ReadSample failed with hr=0x%x", hr);
-    return false;
-  }
-
-  DWORD flags = 0;
-  LONGLONG timestampHns = 0;
-  RefPtr<IMFSample> sample;
-  hr = mSourceReaderCallback->Wait(&flags, &timestampHns, byRef(sample));
-
-  if (flags & MF_SOURCE_READERF_ERROR) {
-    NS_WARNING("WMFReader: Catastrophic failure reading video sample");
-    // Future ReadSample() calls will fail, so give up and report end of stream.
-    return false;
-  }
-
-  if (FAILED(hr)) {
-    // Unknown failure, ask caller to try again?
-    return true;
-  }
-
-  if (!sample) {
-    if ((flags & MF_SOURCE_READERF_ENDOFSTREAM)) {
-      DECODER_LOG("WMFReader; Null sample after video decode, at end of stream");
-      return false;
-    }
-    DECODER_LOG("WMFReader; Null sample after video decode. Maybe insufficient data...");
-    return true;
-  }
-
-  if ((flags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)) {
-    DECODER_LOG("WMFReader: Video media type changed!");
-    RefPtr<IMFMediaType> mediaType;
-    hr = mSourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
-                                            byRef(mediaType));
-    if (FAILED(hr) ||
-        FAILED(ConfigureVideoFrameGeometry(mediaType))) {
-      NS_WARNING("Failed to reconfigure video media type");
-      return false;
-    }
-  }
-
-  int64_t timestamp = HNsToUsecs(timestampHns);
-  if (timestamp < aTimeThreshold) {
-    return true;
-  }
-  int64_t offset = mDecoder->GetResource()->Tell();
-  int64_t duration = GetSampleDuration(sample);
-
-  VideoData* v = nullptr;
-  if (mUseHwAccel) {
-    hr = CreateD3DVideoFrame(sample, timestamp, duration, offset, &v);
-  } else {
-    hr = CreateBasicVideoFrame(sample, timestamp, duration, offset, &v);
-  }
-  NS_ENSURE_TRUE(SUCCEEDED(hr) && v, false);
-
-  a.mParsed++;
-  a.mDecoded++;
-  mVideoQueue.Push(v);
-
-  #ifdef LOG_SAMPLE_DECODE
-  DECODER_LOG("Decoded video sample timestamp=%lld duration=%lld stride=%d height=%u flags=%u",
-              timestamp, duration, mVideoStride, mVideoHeight, flags);
-  #endif
-
-  if ((flags & MF_SOURCE_READERF_ENDOFSTREAM)) {
-    // End of stream.
-    DECODER_LOG("End of video stream");
-    return false;
-  }
-
-  return true;
-}
-
-nsRefPtr<MediaDecoderReader::SeekPromise>
-WMFReader::Seek(int64_t aTargetUs, int64_t aEndTime)
-{
-  nsresult res = SeekInternal(aTargetUs);
-  if (NS_FAILED(res)) {
-    return SeekPromise::CreateAndReject(res, __func__);
-  } else {
-    return SeekPromise::CreateAndResolve(aTargetUs, __func__);
-  }
-}
-
-nsresult
-WMFReader::SeekInternal(int64_t aTargetUs)
-{
-  DECODER_LOG("WMFReader::Seek() %lld", aTargetUs);
-
-  MOZ_ASSERT(OnTaskQueue());
-#ifdef DEBUG
-  bool canSeek = false;
-  GetSourceReaderCanSeek(mSourceReader, canSeek);
-  NS_ASSERTION(canSeek, "WMFReader::Seek() should only be called if we can seek!");
-#endif
-
-  nsresult rv = ResetDecode();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Mark that we must recapture the audio frame count from the next sample.
-  // WMF doesn't set a discontinuity marker when we seek to time 0, so we
-  // must remember to recapture the audio frame offset and reset the frame
-  // sum on the next audio packet we decode.
-  mMustRecaptureAudioPosition = true;
-
-  AutoPropVar var;
-  HRESULT hr = InitPropVariantFromInt64(UsecsToHNs(aTargetUs), &var);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
-  hr = mSourceReader->SetCurrentPosition(GUID_NULL, var);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
-  return NS_OK;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/wmf/WMFReader.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 !defined(WMFReader_h_)
-#define WMFReader_h_
-
-#include "WMF.h"
-#include "MediaDecoderReader.h"
-#include "nsAutoPtr.h"
-#include "mozilla/RefPtr.h"
-#include "nsRect.h"
-
-namespace mozilla {
-
-class WMFByteStream;
-class WMFSourceReaderCallback;
-class DXVA2Manager;
-
-// Decoder backend for reading H.264/AAC in MP4/M4A, and MP3 files using
-// Windows Media Foundation.
-class WMFReader : public MediaDecoderReader
-{
-public:
-  WMFReader(AbstractMediaDecoder* aDecoder);
-
-  virtual ~WMFReader();
-
-  nsresult Init(MediaDecoderReader* aCloneDonor) override;
-
-  bool DecodeAudioData() override;
-  bool DecodeVideoFrame(bool &aKeyframeSkip,
-                        int64_t aTimeThreshold) override;
-
-  bool HasAudio() override;
-  bool HasVideo() override;
-
-  nsresult ReadMetadata(MediaInfo* aInfo,
-                        MetadataTags** aTags) override;
-
-  nsRefPtr<SeekPromise>
-  Seek(int64_t aTime, int64_t aEndTime) override;
-
-  bool IsMediaSeekable() override;
-  
-private:
-
-  HRESULT CreateSourceReader();
-  HRESULT ConfigureAudioDecoder();
-  HRESULT ConfigureVideoDecoder();
-  HRESULT ConfigureVideoFrameGeometry(IMFMediaType* aMediaType);
-  void GetSupportedAudioCodecs(const GUID** aCodecs, uint32_t* aNumCodecs);
-
-  HRESULT CreateBasicVideoFrame(IMFSample* aSample,
-                                int64_t aTimestampUsecs,
-                                int64_t aDurationUsecs,
-                                int64_t aOffsetBytes,
-                                VideoData** aOutVideoData);
-
-  HRESULT CreateD3DVideoFrame(IMFSample* aSample,
-                              int64_t aTimestampUsecs,
-                              int64_t aDurationUsecs,
-                              int64_t aOffsetBytes,
-                              VideoData** aOutVideoData);
-
-  // Attempt to initialize DXVA. Returns true on success.
-  bool InitializeDXVA();  
-
-  nsresult SeekInternal(int64_t aTime);
-
-  RefPtr<IMFSourceReader> mSourceReader;
-  RefPtr<WMFByteStream> mByteStream;
-  RefPtr<WMFSourceReaderCallback> mSourceReaderCallback;
-  nsAutoPtr<DXVA2Manager> mDXVA2Manager;
-
-  // Region inside the video frame that makes up the picture. Pixels outside
-  // of this region should not be rendered.
-  nsIntRect mPictureRegion;
-
-  uint32_t mAudioChannels;
-  uint32_t mAudioBytesPerSample;
-  uint32_t mAudioRate;
-
-  uint32_t mVideoWidth;
-  uint32_t mVideoHeight;
-  uint32_t mVideoStride;
-
-  // The offset, in audio frames, at which playback started since the
-  // last discontinuity.
-  int64_t mAudioFrameOffset;
-  // The number of audio frames that we've played since the last
-  // discontinuity.
-  int64_t mAudioFrameSum;
-  // True if we need to re-initialize mAudioFrameOffset and mAudioFrameSum
-  // from the next audio packet we decode. This happens after a seek, since
-  // WMF doesn't mark a stream as having a discontinuity after a seek(0).
-  bool mMustRecaptureAudioPosition;
-
-  bool mHasAudio;
-  bool mHasVideo;
-  bool mUseHwAccel;
-
-  // We can't call WMFDecoder::IsMP3Supported() on non-main threads, since it
-  // checks a pref, so we cache its value in mIsMP3Enabled and use that on
-  // the decode thread.
-  const bool mIsMP3Enabled;
-
-  bool mCOMInitialized;
-};
-
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/media/wmf/WMFSourceReaderCallback.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "WMFSourceReaderCallback.h"
-#include "WMFUtils.h"
-
-namespace mozilla {
-
-static PRLogModuleInfo* gWMFSourceReaderCallbackLog = nullptr;
-#define WMF_CB_LOG(...) MOZ_LOG(gWMFSourceReaderCallbackLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-// IUnknown Methods
-STDMETHODIMP
-WMFSourceReaderCallback::QueryInterface(REFIID aIId, void **aInterface)
-{
-  WMF_CB_LOG("WMFSourceReaderCallback::QueryInterface %s", GetGUIDName(aIId).get());
-
-  if (aIId == IID_IMFSourceReaderCallback) {
-    return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
-  }
-  if (aIId == IID_IUnknown) {
-    return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
-  }
-
-  *aInterface = nullptr;
-  return E_NOINTERFACE;
-}
-
-NS_IMPL_ADDREF(WMFSourceReaderCallback)
-NS_IMPL_RELEASE(WMFSourceReaderCallback)
-
-WMFSourceReaderCallback::WMFSourceReaderCallback()
-  : mMonitor("WMFSourceReaderCallback")
-  , mResultStatus(S_OK)
-  , mStreamFlags(0)
-  , mTimestamp(0)
-  , mSample(nullptr)
-  , mReadFinished(false)
-{
-  if (!gWMFSourceReaderCallbackLog) {
-    gWMFSourceReaderCallbackLog = PR_NewLogModule("WMFSourceReaderCallback");
-  }
-}
-
-HRESULT
-WMFSourceReaderCallback::NotifyReadComplete(HRESULT aReadStatus,
-                                            DWORD aStreamIndex,
-                                            DWORD aStreamFlags,
-                                            LONGLONG aTimestamp,
-                                            IMFSample *aSample)
-{
-  // Note: aSample can be nullptr on success if more data is required!
-  ReentrantMonitorAutoEnter mon(mMonitor);
-
-  if (mSample) {
-    // The WMFReader should have called Wait() to retrieve the last
-    // sample returned by the last ReadSample() call, but if we're
-    // aborting the read before Wait() is called the sample ref
-    // can be non-null.
-    mSample->Release();
-    mSample = nullptr;
-  }
-
-  if (SUCCEEDED(aReadStatus)) {
-    if (aSample) {
-      mTimestamp = aTimestamp;
-      mSample = aSample;
-      mSample->AddRef();
-    }
-  }
-
-  mResultStatus = aReadStatus;
-  mStreamFlags = aStreamFlags;
-
-  // Set the sentinal value and notify the monitor, so that threads waiting
-  // in Wait() are awoken.
-  mReadFinished = true;
-  mon.NotifyAll();
-
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFSourceReaderCallback::OnReadSample(HRESULT aReadStatus,
-                                      DWORD aStreamIndex,
-                                      DWORD aStreamFlags,
-                                      LONGLONG aTimestamp,
-                                      IMFSample *aSample)
-{
-  WMF_CB_LOG("WMFSourceReaderCallback::OnReadSample() hr=0x%x flags=0x%x time=%lld sample=%p",
-             aReadStatus, aStreamFlags, aTimestamp, aSample);
-  return NotifyReadComplete(aReadStatus,
-                            aStreamIndex,
-                            aStreamFlags,
-                            aTimestamp,
-                            aSample);
-}
-
-HRESULT
-WMFSourceReaderCallback::Cancel()
-{
-  WMF_CB_LOG("WMFSourceReaderCallback::Cancel()");
-  return NotifyReadComplete(E_ABORT,
-                            0,
-                            0,
-                            0,
-                            nullptr);
-}
-
-STDMETHODIMP
-WMFSourceReaderCallback::OnEvent(DWORD, IMFMediaEvent *)
-{
-  return S_OK;
-}
-
-STDMETHODIMP
-WMFSourceReaderCallback::OnFlush(DWORD)
-{
-  return S_OK;
-}
-
-HRESULT
-WMFSourceReaderCallback::Wait(DWORD* aStreamFlags,
-                              LONGLONG* aTimeStamp,
-                              IMFSample** aSample)
-{
-  ReentrantMonitorAutoEnter mon(mMonitor);
-  WMF_CB_LOG("WMFSourceReaderCallback::Wait() starting wait");
-  while (!mReadFinished) {
-    mon.Wait();
-  }
-  mReadFinished = false;
-  WMF_CB_LOG("WMFSourceReaderCallback::Wait() done waiting");
-
-  *aStreamFlags = mStreamFlags;
-  *aTimeStamp = mTimestamp;
-  *aSample = mSample;
-  HRESULT hr = mResultStatus;
-
-  mSample = nullptr;
-  mTimestamp = 0;
-  mStreamFlags = 0;
-  mResultStatus = S_OK;
-
-  return hr;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/wmf/WMFSourceReaderCallback.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 !defined(WMFSourceReaderCallback_h_)
-#define WMFSourceReaderCallback_h_
-
-#include "WMF.h"
-#include "mozilla/ReentrantMonitor.h"
-#include "mozilla/RefPtr.h"
-#include "nsISupportsImpl.h"
-
-namespace mozilla {
-
-// A listener which we pass into the IMFSourceReader upon creation which is
-// notified when an asynchronous call to IMFSourceReader::ReadSample()
-// completes. This allows us to abort ReadSample() operations when the
-// WMFByteStream's underlying MediaResource is closed. This ensures that
-// the decode threads don't get stuck in a synchronous ReadSample() call
-// when the MediaResource is unexpectedly shutdown.
-class WMFSourceReaderCallback final : public IMFSourceReaderCallback
-{
-  ~WMFSourceReaderCallback() {}
-
-public:
-  WMFSourceReaderCallback();
-
-  // IUnknown Methods.
-  STDMETHODIMP QueryInterface(REFIID aIId, LPVOID *aInterface);
-  STDMETHODIMP_(ULONG) AddRef();
-  STDMETHODIMP_(ULONG) Release();
-
-  // IMFSourceReaderCallback methods
-  STDMETHODIMP OnReadSample(HRESULT hrStatus,
-                            DWORD dwStreamIndex,
-                            DWORD dwStreamFlags,
-                            LONGLONG llTimestamp,
-                            IMFSample *pSample);
-  STDMETHODIMP OnEvent(DWORD, IMFMediaEvent *);
-  STDMETHODIMP OnFlush(DWORD);
-
-  // Causes the calling thread to block waiting for the
-  // IMFSourceReader::ReadSample() result callback to occur, or for the
-  // WMFByteStream to be closed.
-  HRESULT Wait(DWORD* aStreamFlags,
-               LONGLONG* aTimeStamp,
-               IMFSample** aSample);
-
-  // Cancels Wait() calls.
-  HRESULT Cancel();
-
-private:
-
-  // Sets state to record the result of a read, and awake threads
-  // waiting in Wait().
-  HRESULT NotifyReadComplete(HRESULT aReadStatus,
-                             DWORD aStreamIndex,
-                             DWORD aStreamFlags,
-                             LONGLONG aTimestamp,
-                             IMFSample *aSample);
-
-  // Synchronizes all member data in this class, and Wait() blocks on
-  // and NotifyReadComplete() notifies this monitor.
-  ReentrantMonitor mMonitor;
-
-  // Read result data.
-  HRESULT mResultStatus;
-  DWORD mStreamFlags;
-  LONGLONG mTimestamp;
-  IMFSample* mSample;
-
-  // Sentinal. Set to true when a read result is returned. Wait() won't exit
-  // until this is set to true.
-  bool mReadFinished;
-
-  // IUnknown ref counting.
-  ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-
-};
-
-} // namespace mozilla
-
-#endif // WMFSourceReaderCallback_h_
deleted file mode 100644
--- a/dom/media/wmf/moz.build
+++ /dev/null
@@ -1,36 +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/.
-
-EXPORTS += [
-    'DXVA2Manager.h',
-    'WMF.h',
-    'WMFDecoder.h',
-    'WMFReader.h',
-    'WMFUtils.h',
-]
-
-UNIFIED_SOURCES += [
-    'DXVA2Manager.cpp',
-    'WMFByteStream.cpp',
-    'WMFDecoder.cpp',
-    'WMFReader.cpp',
-    'WMFSourceReaderCallback.cpp',
-]
-
-SOURCES += [
-    'WMFUtils.cpp',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FAIL_ON_WARNINGS = True
-
-FINAL_LIBRARY = 'xul'
-
-if CONFIG['OS_ARCH'] == 'WINNT':
-    DEFINES['NOMINMAX'] = True
-
-CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1494,16 +1494,17 @@ bool
   NS_ENSURE_TRUE(doc, false);
 
   nsGlobalWindow* win = static_cast<nsGlobalWindow*>(doc->GetInnerWindow());
   if (NS_WARN_IF(!win || !win->FastGetGlobalJSObject())) {
     return false;
   }
 
   dom::AutoEntryScript aes(win, "NPAPI NPN_evaluate");
+  aes.TakeOwnershipOfErrorReporting();
   JSContext* cx = aes.cx();
 
   JS::Rooted<JSObject*> obj(cx, nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj));
 
   if (!obj) {
     return false;
   }
 
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -798,18 +798,21 @@ this.PushService = {
    * Exceptions thrown in _onRegisterSuccess are caught by the promise obtained
    * from _service.request, causing the promise to be rejected instead.
    */
   _onRegisterSuccess: function(aRecord) {
     debug("_onRegisterSuccess()");
 
     return this._db.put(aRecord)
       .then(_ => aRecord, error => {
-        // Unable to save.
-        this._sendRequest("unregister", aRecord);
+        // Unable to save. Destroy the subscription in the background.
+        this._sendRequest("unregister", aRecord).catch(err => {
+          debug("_onRegisterSuccess: Error unregistering stale subscription" +
+            err);
+        });
         throw error;
       });
   },
 
   /**
    * Exceptions thrown in _onRegisterError are caught by the promise obtained
    * from _service.request, causing the promise to be rejected instead.
    */
@@ -874,17 +877,17 @@ this.PushService = {
    * retry the unregister when it fails due to timeout (websocket) or any other
    * reason at which point the server will say it does not know of this
    * unregistration.  We'll have to make the registration/unregistration phases
    * have retries and attempts to resend messages from the server, and have the
    * client acknowledge. On a server, data is cheap, reliable notification is
    * not.
    */
   _unregister: function(aPageRecord) {
-    debug("unregisterWithServer()");
+    debug("_unregister()");
 
     if (!aPageRecord.scope) {
       return Promise.reject({state: 0, error: "NotFoundError"});
     }
 
     return this._checkActivated()
       .then(_ => this._db.getByScope(aPageRecord.scope))
       .then(record => {
--- a/dom/push/PushServiceWebSocket.jsm
+++ b/dom/push/PushServiceWebSocket.jsm
@@ -946,34 +946,32 @@ this.PushServiceWebSocket = {
                                       .createInstance(Ci.nsITimer);
       }
       this._requestTimeoutTimer.init(this,
                                      this._requestTimeout,
                                      Ci.nsITimer.TYPE_REPEATING_SLACK);
     }
 
     if (action == "register") {
-      record.channelID = this._generateID();
-    }
-    var data = {channelID: record.channelID,
-                messageType: action};
+      let data = {channelID: this._generateID(),
+                  messageType: action};
 
-    var p = new Promise((resolve, reject) => {
-      this._pendingRequests[data.channelID] = {record: record,
-                                               resolve: resolve,
-                                               reject: reject,
-                                               ctime: Date.now()
-                                              };
-      this._queueRequest(data);
-    });
-    if (action == "unregister") {
-      return Promise.resolve();
-    } else {
-      return p;
+      return new Promise((resolve, reject) => {
+        this._pendingRequests[data.channelID] = {record: record,
+                                                 resolve: resolve,
+                                                 reject: reject,
+                                                 ctime: Date.now()
+                                                };
+        this._queueRequest(data);
+      });
     }
+
+    this._queueRequest({channelID: record.channelID,
+                        messageType: action});
+    return Promise.resolve();
   },
 
   _queueStart: Promise.resolve(),
   _notifyRequestQueue: null,
   _queue: null,
   _enqueue: function(op, errop) {
     debug("enqueue");
     if (!this._queue) {
@@ -981,23 +979,21 @@ this.PushServiceWebSocket = {
     }
     this._queue = this._queue
                     .then(op)
                     .catch(_ => {});
   },
 
   _send(data) {
     if (this._currentState == STATE_READY) {
-      if (data.messageType == "ack") {
+      if (data.messageType != "register" ||
+        typeof this._pendingRequests[data.channelID] == "object") {
+
+        // check if request has not been cancelled
         this._wsSendMessage(data);
-      } else {
-        // check if request has not been canelled
-        if (typeof this._pendingRequests[data.channelID] == "object") {
-          this._wsSendMessage(data);
-        }
       }
     }
   },
 
   _queueRequest(data) {
     if (this._currentState != STATE_READY) {
       if (!this._notifyRequestQueue) {
         this._enqueue(_ => {
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -664,19 +664,18 @@ class MOZ_STACK_CLASS OriginParser final
     eExpectingAppIdOrSchema,
     eExpectingInMozBrowser,
     eExpectingSchema,
     eExpectingEmptyToken1,
     eExpectingEmptyToken2,
     eExpectingEmptyToken3,
     eExpectingHost,
     eExpectingPort,
-    eExpectingDriveLetterOrPathnameComponent,
+    eExpectingEmptyTokenOrDriveLetterOrPathnameComponent,
     eExpectingEmptyTokenOrPathnameComponent,
-    eExpectingPathnameComponent,
     eComplete,
     eHandledTrailingSeparator
   };
 
   const nsCString mOrigin;
   Tokenizer mTokenizer;
 
   uint32_t mAppId;
@@ -4991,24 +4990,24 @@ OriginParser::HandleSchema(const nsDepen
 
   mError = true;
 }
 
 void
 OriginParser::HandlePathnameComponent(const nsDependentCSubstring& aToken)
 {
   MOZ_ASSERT(!aToken.IsEmpty());
-  MOZ_ASSERT(mState == eExpectingDriveLetterOrPathnameComponent ||
-             mState == eExpectingEmptyTokenOrPathnameComponent ||
-             mState == eExpectingPathnameComponent);
+  MOZ_ASSERT(mState == eExpectingEmptyTokenOrDriveLetterOrPathnameComponent ||
+             mState == eExpectingEmptyTokenOrPathnameComponent);
   MOZ_ASSERT(mSchemaType == eFile);
 
   mPathnameComponents.AppendElement(aToken);
 
-  mState = mTokenizer.hasMoreTokens() ? eExpectingPathnameComponent : eComplete;
+  mState = mTokenizer.hasMoreTokens() ? eExpectingEmptyTokenOrPathnameComponent
+                                      : eComplete;
 }
 
 void
 OriginParser::HandleToken(const nsDependentCSubstring& aToken)
 {
   switch (mState) {
     case eExpectingAppIdOrSchema: {
       if (aToken.IsEmpty()) {
@@ -5110,19 +5109,19 @@ OriginParser::HandleToken(const nsDepend
 
       if (!aToken.IsEmpty()) {
         QM_WARNING("Expected the third empty token!");
 
         mError = true;
         return;
       }
 
-      mState =
-        mTokenizer.hasMoreTokens() ? eExpectingDriveLetterOrPathnameComponent
-                                   : eComplete;
+      mState = mTokenizer.hasMoreTokens()
+                 ? eExpectingEmptyTokenOrDriveLetterOrPathnameComponent
+                 : eComplete;
 
       return;
     }
 
     case eExpectingHost: {
       if (aToken.IsEmpty()) {
         QM_WARNING("Expected a host (not an empty string)!");
 
@@ -5161,24 +5160,26 @@ OriginParser::HandleToken(const nsDepend
         return;
       }
 
       mState = eComplete;
 
       return;
     }
 
-    case eExpectingDriveLetterOrPathnameComponent: {
+    case eExpectingEmptyTokenOrDriveLetterOrPathnameComponent: {
       MOZ_ASSERT(mSchemaType == eFile);
 
       if (aToken.IsEmpty()) {
-        QM_WARNING("Expected a drive letter or pathname component "
-                   "(not an empty string)!");
-
-        mError = true;
+        mPathnameComponents.AppendElement(EmptyCString());
+
+        mState =
+          mTokenizer.hasMoreTokens() ? eExpectingEmptyTokenOrPathnameComponent
+                                     : eComplete;
+
         return;
       }
 
       if (aToken.Length() == 1 && NS_IsAsciiAlpha(aToken.First())) {
         mMaybeDriveLetter = true;
 
         mPathnameComponents.AppendElement(aToken);
 
@@ -5192,38 +5193,32 @@ OriginParser::HandleToken(const nsDepend
       HandlePathnameComponent(aToken);
 
       return;
     }
 
     case eExpectingEmptyTokenOrPathnameComponent: {
       MOZ_ASSERT(mSchemaType == eFile);
 
-      if (mMaybeDriveLetter && aToken.IsEmpty()) {
-        MOZ_ASSERT(mPathnameComponents.Length() == 1);
-
-        nsCString& pathnameComponent = mPathnameComponents[0];
-        pathnameComponent.Append(':');
-
-        mState = mTokenizer.hasMoreTokens() ? eExpectingPathnameComponent
-                                            : eComplete;
-
-        return;
-      }
-
-      HandlePathnameComponent(aToken);
-
-      return;
-    }
-
-    case eExpectingPathnameComponent: {
       if (aToken.IsEmpty()) {
-        QM_WARNING("Expected a pathname component (not an empty string)!");
-
-        mError = true;
+        if (mMaybeDriveLetter) {
+          MOZ_ASSERT(mPathnameComponents.Length() == 1);
+
+          nsCString& pathnameComponent = mPathnameComponents[0];
+          pathnameComponent.Append(':');
+
+          mMaybeDriveLetter = false;
+        } else {
+          mPathnameComponents.AppendElement(EmptyCString());
+        }
+
+        mState =
+          mTokenizer.hasMoreTokens() ? eExpectingEmptyTokenOrPathnameComponent
+                                     : eComplete;
+
         return;
       }
 
       HandlePathnameComponent(aToken);
 
       return;
     }
 
--- a/dom/security/nsCSPService.cpp
+++ b/dom/security/nsCSPService.cpp
@@ -100,16 +100,19 @@ CSPService::ShouldLoad(uint32_t aContent
                        nsIURI *aContentLocation,
                        nsIURI *aRequestOrigin,
                        nsISupports *aRequestContext,
                        const nsACString &aMimeTypeGuess,
                        nsISupports *aExtra,
                        nsIPrincipal *aRequestPrincipal,
                        int16_t *aDecision)
 {
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   if (!aContentLocation) {
     return NS_ERROR_FAILURE;
   }
 
   if (MOZ_LOG_TEST(gCspPRLog, LogLevel::Debug)) {
     nsAutoCString location;
     aContentLocation->GetSpec(location);
     MOZ_LOG(gCspPRLog, LogLevel::Debug,
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -334,16 +334,19 @@ nsMixedContentBlocker::ShouldLoad(bool a
                                   nsIPrincipal* aRequestPrincipal,
                                   int16_t* aDecision)
 {
   // Asserting that we are on the main thread here and hence do not have to lock
   // and unlock sBlockMixedScript and sBlockMixedDisplay before reading/writing
   // to them.
   MOZ_ASSERT(NS_IsMainThread());
 
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+             "We should only see external content policy types here.");
+
   // Assume active (high risk) content and blocked by default
   MixedContentTypes classification = eMixedScript;
   // Make decision to block/reject by default
   *aDecision = REJECT_REQUEST;
 
 
   // Notes on non-obvious decisions:
   //
--- a/dom/svg/SVGDocument.cpp
+++ b/dom/svg/SVGDocument.cpp
@@ -99,16 +99,18 @@ void
 SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
 {
   if (mHasLoadedNonSVGUserAgentStyleSheets) {
     return;
   }
 
   mHasLoadedNonSVGUserAgentStyleSheets = true;
 
+  BeginUpdate(UPDATE_STYLE);
+
   if (IsBeingUsedAsImage()) {
     // nsDocumentViewer::CreateStyleSet skipped loading all user-agent/user
     // style sheets in this case, but we'll need B2G/Fennec's
     // content.css. We could load all the sheets registered with the
     // nsIStyleSheetService (and maybe we should) but most likely it isn't
     // desirable or necessary for foreignObject in SVG-as-an-image. Instead we
     // only load the "agent-style-sheets" that nsStyleSheetService::Init()
     // pulls in from the category manager. That keeps memory use of
@@ -160,17 +162,25 @@ SVGDocument::EnsureNonSVGUserAgentStyleS
   CSSStyleSheet* sheet = nsLayoutStylesheetCache::NumberControlSheet();
   if (sheet) {
     // number-control.css can be behind a pref
     EnsureOnDemandBuiltInUASheet(sheet);
   }
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::CounterStylesSheet());
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
+  if (nsLayoutUtils::ShouldUseNoFramesSheet(this)) {
+    EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::NoFramesSheet());
+  }
+  if (nsLayoutUtils::ShouldUseNoScriptSheet(this)) {
+    EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::NoScriptSheet());
+  }
   EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
+
+  EndUpdate(UPDATE_STYLE);
 }
 
 JSObject*
 SVGDocument::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return SVGDocumentBinding::Wrap(aCx, this, aGivenProto);
 }
 
--- a/dom/tests/moz.build
+++ b/dom/tests/moz.build
@@ -37,17 +37,17 @@ MOCHITEST_CHROME_MANIFESTS += [
     'mochitest/chrome/chrome.ini',
     'mochitest/general/chrome.ini',
     'mochitest/localstorage/chrome.ini',
     'mochitest/sessionstorage/chrome.ini',
     'mochitest/webapps/chrome.ini',
     'mochitest/whatwg/chrome.ini',
 ]
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk2':
+if CONFIG['MOZ_WIDGET_TOOLKIT'] not in ('gtk2', 'gtk3'):
     # Bug 788164.
     MOCHITEST_MANIFESTS += [
         'mochitest/pointerlock/mochitest.ini',
     ]
 
 if CONFIG['MOZ_GAMEPAD']:
     MOCHITEST_MANIFESTS += [
         'mochitest/gamepad/mochitest.ini',
--- a/dom/webidl/Request.webidl
+++ b/dom/webidl/Request.webidl
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * https://fetch.spec.whatwg.org/#request-class
  */
 
 typedef (Request or USVString) RequestInfo;
+typedef unsigned long nsContentPolicyType;
 
 [Constructor(RequestInfo input, optional RequestInit init),
  Exposed=(Window,Worker)]
 interface Request {
   readonly attribute ByteString method;
   readonly attribute USVString url;
   [SameObject] readonly attribute Headers headers;
 
@@ -22,35 +23,35 @@ interface Request {
   readonly attribute RequestCredentials credentials;
   readonly attribute RequestCache cache;
 
   [Throws,
    NewObject] Request clone();
 
   // Bug 1124638 - Allow chrome callers to set the context.
   [ChromeOnly]
-  void setContext(RequestContext context);
+  void setContentPolicyType(nsContentPolicyType context);
 };
 Request implements Body;
 
 dictionary RequestInit {
   ByteString method;
   HeadersInit headers;
   BodyInit body;
   RequestMode mode;
   RequestCredentials credentials;
   RequestCache cache;
 };
 
 enum RequestContext {
   "audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon", "fetch",
   "font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import",
   "internal", "location", "manifest", "object", "ping", "plugin", "prefetch", "script",
-  "serviceworker", "sharedworker", "subresource", "style", "track", "video", "worker",
-  "xmlhttprequest", "xslt"
+  "sharedworker", "subresource", "style", "track", "video", "worker", "xmlhttprequest",
+  "xslt"
 };
 
 // cors-with-forced-preflight is internal to the Fetch spec, but adding it here
 // allows us to use the various conversion conveniences offered by the WebIDL
 // codegen. The Request constructor has explicit checks to prevent it being
 // passed as a valid value, while Request.mode never returns it. Since enums
 // are only exposed as strings to client JS, this has the same effect as not
 // exposing it at all.
--- a/dom/webidl/TestInterfaceJS.webidl
+++ b/dom/webidl/TestInterfaceJS.webidl
@@ -51,16 +51,28 @@ interface TestInterfaceJS {
 
   // Tests for exception-throwing behavior
   [Throws]
   void testThrowDOMError();
 
   [Throws]
   void testThrowDOMException();
 
+  [Throws]
+  void testThrowTypeError();
+
+  [Throws]
+  void testThrowCallbackError(Function callback);
+
+  [Throws]
+  void testThrowXraySelfHosted();
+
+  [Throws]
+  void testThrowSelfHosted();
+
   // Tests for promise-rejection behavior
   Promise<void> testPromiseWithThrowingChromePromiseInit();
   Promise<void> testPromiseWithThrowingContentPromiseInit(PromiseInit func);
   Promise<void> testPromiseWithDOMExceptionThrowingPromiseInit();
   Promise<void> testPromiseWithThrowingChromeThenFunction();
   Promise<void> testPromiseWithThrowingContentThenFunction(AnyCallback func);
   Promise<void> testPromiseWithDOMExceptionThrowingThenFunction();
   Promise<void> testPromiseWithThrowingChromeThenable();
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -401,16 +401,17 @@ nsXBLProtoImplField::InstallField(JS::Ha
   nsIGlobalObject* globalObject = xpc::WindowGlobalOrNull(aBoundNode);
   if (!globalObject) {
     return NS_OK;
   }
 
   // We are going to run script via EvaluateString, so we need a script entry
   // point, but as this is XBL related it does not appear in the HTML spec.
   AutoEntryScript entryScript(globalObject, "XBL <field> initialization", true);
+  entryScript.TakeOwnershipOfErrorReporting();
   JSContext* cx = entryScript.cx();
 
   NS_ASSERTION(!::JS_IsExceptionPending(cx),
                "Shouldn't get here when an exception is pending!");
 
   JSAddonId* addonId = MapURIToAddonID(aBindingDocURI);
 
   Element* boundElement = nullptr;
@@ -436,16 +437,22 @@ nsXBLProtoImplField::InstallField(JS::Ha
   }
   rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
                                                        mFieldTextLength),
                                  scopeObject, options, evalOptions, &result);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW) {
+    // Report the exception now, before we try using the JSContext for
+    // the JS_DefineUCProperty call.
+    entryScript.ReportException();
+  }
+
   // Now, enter the node's compartment, wrap the eval result, and define it on
   // the bound node.
   JSAutoCompartment ac2(cx, aBoundNode);
   nsDependentString name(mName);
   if (!JS_WrapValue(cx, &result) ||
       !::JS_DefineUCProperty(cx, aBoundNode,
                              reinterpret_cast<const char16_t*>(mName),
                              name.Length(), result, mJSAttributes)) {
--- a/extensions/permissions/nsContentBlocker.cpp
+++ b/extensions/permissions/nsContentBlocker.cpp
@@ -17,17 +17,18 @@
 
 // Possible behavior pref values
 // Those map to the nsIPermissionManager values where possible
 #define BEHAVIOR_ACCEPT nsIPermissionManager::ALLOW_ACTION
 #define BEHAVIOR_REJECT nsIPermissionManager::DENY_ACTION
 #define BEHAVIOR_NOFOREIGN 3
 
 // From nsIContentPolicy
-static const char *kTypeString[] = {"other",
+static const char *kTypeString[] = {
+                                    "other",
                                     "script",
                                     "image",
                                     "stylesheet",
                                     "object",
                                     "document",
                                     "subdocument",
                                     "refresh",
                                     "xbl",
@@ -38,17 +39,28 @@ static const char *kTypeString[] = {"oth
                                     "font",
                                     "media",
                                     "websocket",
                                     "csp_report",
                                     "xslt",
                                     "beacon",
                                     "fetch",
                                     "imageset",
-                                    "manifest"};
+                                    "manifest",
+                                    "", // TYPE_INTERNAL_SCRIPT
+                                    "", // TYPE_INTERNAL_WORKER
+                                    "", // TYPE_INTERNAL_SHARED_WORKER
+                                    "", // TYPE_INTERNAL_EMBED
+                                    "", // TYPE_INTERNAL_OBJECT
+                                    "", // TYPE_INTERNAL_FRAME
+                                    "", // TYPE_INTERNAL_IFRAME
+                                    "", // TYPE_INTERNAL_AUDIO
+                                    "", // TYPE_INTERNAL_VIDEO
+                                    ""  // TYPE_INTERNAL_TRACK
+};
 
 #define NUMBER_OF_TYPES MOZ_ARRAY_LENGTH(kTypeString)
 uint8_t nsContentBlocker::mBehaviorPref[NUMBER_OF_TYPES];
 
 NS_IMPL_ISUPPORTS(nsContentBlocker, 
                   nsIContentPolicy,
                   nsIObserver,
                   nsISupportsWeakReference)
@@ -114,17 +126,18 @@ void
 nsContentBlocker::PrefChanged(nsIPrefBranch *aPrefBranch,
                               const char    *aPref)
 {
   int32_t val;
 
 #define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
 
   for(uint32_t i = 0; i < NUMBER_OF_TYPES; ++i) {
-    if (PREF_CHANGED(kTypeString[i]) &&
+    if (*kTypeString[i] &&
+        PREF_CHANGED(kTypeString[i]) &&
         NS_SUCCEEDED(aPrefBranch->GetIntPref(kTypeString[i], &val)))
       mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
   }
 
 }
 
 // nsIContentPolicy Implementation
 NS_IMETHODIMP 
@@ -232,16 +245,23 @@ nsContentBlocker::ShouldProcess(uint32_t
 nsresult
 nsContentBlocker::TestPermission(nsIURI *aCurrentURI,
                                  nsIURI *aFirstURI,
                                  int32_t aContentType,
                                  bool *aPermission,
                                  bool *aFromPrefs)
 {
   *aFromPrefs = false;
+
+  if (!*kTypeString[aContentType - 1]) {
+    // Disallow internal content policy types, they should not be used here.
+    *aPermission = false;
+    return NS_OK;
+  }
+
   // This default will also get used if there is an unknown value in the
   // permission list, or if the permission manager returns unknown values.
   *aPermission = true;
 
   // check the permission list first; if we find an entry, it overrides
   // default prefs.
   // Don't forget the aContentType ranges from 1..8, while the
   // array is indexed 0..7
--- a/gfx/2d/DataSurfaceHelpers.cpp
+++ b/gfx/2d/DataSurfaceHelpers.cpp
@@ -92,17 +92,17 @@ CopyBGRXSurfaceDataToPackedBGRArray(uint
                                     IntSize aSrcSize, int32_t aSrcStride)
 {
   int packedStride = aSrcSize.width * 3;
 
   uint8_t* srcPx = aSrc;
   uint8_t* dstPx = aDst;
 
   for (int row = 0; row < aSrcSize.height; ++row) {
-    for (int col = 0; col < aSrcSize.height; ++col) {
+    for (int col = 0; col < aSrcSize.width; ++col) {
       dstPx[0] = srcPx[0];
       dstPx[1] = srcPx[1];
       dstPx[2] = srcPx[2];
       // srcPx[3] (unused or alpha component) dropped on floor
       srcPx += 4;
       dstPx += 3;
     }
     srcPx = aSrc += aSrcStride;
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -108,23 +108,23 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
        aTarget->GetBackendType() == BackendType::DIRECT2D1_1) &&
       aOperator == CompositionOp::OP_SOURCE) {
     aOperator = CompositionOp::OP_OVER;
     if (snapshot->GetFormat() == SurfaceFormat::B8G8R8A8) {
       aTarget->ClearRect(ToRect(fillRect));
     }
   }
 
-  if (aOperator == CompositionOp::OP_SOURCE) {
-    // OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here.
-    // We also can't do a ClearRect+FillRect since we need the drawing to happen
-    // as an atomic operation (to prevent flickering).
-    aTarget->PushClipRect(gfx::Rect(fillRect.x, fillRect.y,
-                                    fillRect.width, fillRect.height));
-  }
+  // OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here.
+  // We also can't do a ClearRect+FillRect since we need the drawing to happen
+  // as an atomic operation (to prevent flickering).
+  // We also need this clip in the case where we have a mask, since the mask surface
+  // might cover more than fillRect, but we only want to touch the pixels inside
+  // fillRect.
+  aTarget->PushClipRect(gfx::ToRect(fillRect));
 
   if (aMask) {
     Matrix oldTransform = aTarget->GetTransform();
 
     // Transform from user -> buffer space.
     Matrix transform =
       Matrix::Translation(quadrantTranslation.x, quadrantTranslation.y);
 
@@ -150,19 +150,17 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
     DrawSurfaceOptions options;
 #endif
     aTarget->DrawSurface(snapshot, ToRect(fillRect),
                          GetSourceRectangle(aXSide, aYSide),
                          options,
                          DrawOptions(aOpacity, aOperator));
   }
 
-  if (aOperator == CompositionOp::OP_SOURCE) {
-    aTarget->PopClip();
-  }
+  aTarget->PopClip();
 }
 
 void
 RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
                                       float aOpacity,
                                       gfx::CompositionOp aOperator,
                                       gfx::SourceSurface* aMask,
                                       const gfx::Matrix* aMaskTransform) const
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -158,28 +158,45 @@ SetDisplayPortMargins(nsIPresShell* aPre
   nsLayoutUtils::SetDisplayPortMargins(aContent, aPresShell, margins, 0);
   CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
   nsRect base(0, 0,
               baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
               baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
   nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
 }
 
-void
-APZCCallbackHelper::UpdateRootFrame(nsIPresShell* aPresShell,
-                                    FrameMetrics& aMetrics)
+static already_AddRefed<nsIPresShell>
+GetPresShell(const nsIContent* aContent)
 {
-  // Precondition checks
-  MOZ_ASSERT(aPresShell);
-  MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
+  nsCOMPtr<nsIPresShell> result;
+  if (nsIDocument* doc = aContent->GetComposedDoc()) {
+    result = doc->GetShell();
+  }
+  return result.forget();
+}
+
+void
+APZCCallbackHelper::UpdateRootFrame(FrameMetrics& aMetrics)
+{
   if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
     return;
   }
+  nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
+  if (!content) {
+    return;
+  }
 
-  float presShellResolution = nsLayoutUtils::GetResolution(aPresShell);
+  nsCOMPtr<nsIPresShell> shell = GetPresShell(content);
+  if (!shell || aMetrics.GetPresShellId() != shell->GetPresShellId()) {
+    return;
+  }
+
+  MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
+
+  float presShellResolution = nsLayoutUtils::GetResolution(shell);
 
   // If the pres shell resolution has changed on the content side side
   // the time this repaint request was fired, consider this request out of date
   // and drop it; setting a zoom based on the out-of-date resolution can have
   // the effect of getting us stuck with the stale resolution.
   if (presShellResolution != aMetrics.GetPresShellResolution()) {
     return;
   }
@@ -189,55 +206,49 @@ APZCCallbackHelper::UpdateRootFrame(nsIP
   // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent
   // overscroll). Note that if the content here was zoomed to 2x, the document would
   // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum
   // scroll range would be 900. Therefore this calculation depends on the zoom applied
   // to the content relative to the container.
   // Note that this needs to happen before scrolling the frame (in UpdateFrameCommon),
   // otherwise the scroll position may get clamped incorrectly.
   CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels();
-  nsLayoutUtils::SetScrollPositionClampingScrollPortSize(aPresShell, scrollPort);
+  nsLayoutUtils::SetScrollPositionClampingScrollPortSize(shell, scrollPort);
 
   // The pres shell resolution is updated by the the async zoom since the
   // last paint.
   presShellResolution = aMetrics.GetPresShellResolution()
                       * aMetrics.GetAsyncZoom().scale;
-  nsLayoutUtils::SetResolutionAndScaleTo(aPresShell, presShellResolution);
+  nsLayoutUtils::SetResolutionAndScaleTo(shell, presShellResolution);
 
   // Do this as late as possible since scrolling can flush layout. It also
   // adjusts the display port margins, so do it before we set those.
-  nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
   ScrollFrame(content, aMetrics);
 
-  SetDisplayPortMargins(aPresShell, content, aMetrics);
-}
-
-static already_AddRefed<nsIPresShell>
-GetPresShell(const nsIContent* aContent)
-{
-  nsCOMPtr<nsIPresShell> result;
-  if (nsIDocument* doc = aContent->GetComposedDoc()) {
-    result = doc->GetShell();
-  }
-  return result.forget();
+  SetDisplayPortMargins(shell, content, aMetrics);
 }
 
 void
-APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
-                                   FrameMetrics& aMetrics)
+APZCCallbackHelper::UpdateSubFrame(FrameMetrics& aMetrics)
 {
-  // Precondition checks
-  MOZ_ASSERT(aContent);
+  if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
+    return;
+  }
+  nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
+  if (!content) {
+    return;
+  }
+
   MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
 
   // We don't currently support zooming for subframes, so nothing extra
   // needs to be done beyond the tasks common to this and UpdateRootFrame.
-  ScrollFrame(aContent, aMetrics);
-  if (nsCOMPtr<nsIPresShell> shell = GetPresShell(aContent)) {
-    SetDisplayPortMargins(shell, aContent, aMetrics);
+  ScrollFrame(content, aMetrics);
+  if (nsCOMPtr<nsIPresShell> shell = GetPresShell(content)) {
+    SetDisplayPortMargins(shell, content, aMetrics);
   }
 }
 
 bool
 APZCCallbackHelper::GetOrCreateScrollIdentifiers(nsIContent* aContent,
                                                  uint32_t* aPresShellIdOut,
                                                  FrameMetrics::ViewID* aViewIdOut)
 {
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -36,33 +36,31 @@ protected:
    to hold code that can be shared across the different platform implementations.
  */
 class APZCCallbackHelper
 {
     typedef mozilla::layers::FrameMetrics FrameMetrics;
     typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
 
 public:
-    /* Applies the scroll and zoom parameters from the given FrameMetrics object to
-       the root frame corresponding to the given pres shell. If tiled thebes
+    /* Applies the scroll and zoom parameters from the given FrameMetrics object
+       to the root frame for the given metrics' scrollId. If tiled thebes layers
+       are enabled, this will align the displayport to tile boundaries. Setting
+       the scroll position can cause some small adjustments to be made to the
+       actual scroll position. aMetrics' display port and scroll position will
+       be updated with any modifications made. */
+    static void UpdateRootFrame(FrameMetrics& aMetrics);
+
+    /* Applies the scroll parameters from the given FrameMetrics object to the
+       subframe corresponding to given metrics' scrollId. If tiled thebes
        layers are enabled, this will align the displayport to tile boundaries.
        Setting the scroll position can cause some small adjustments to be made
        to the actual scroll position. aMetrics' display port and scroll position
        will be updated with any modifications made. */
-    static void UpdateRootFrame(nsIPresShell* aPresShell,
-                                FrameMetrics& aMetrics);
-
-    /* Applies the scroll parameters from the given FrameMetrics object to the subframe
-       corresponding to the given content object. If tiled thebes
-       layers are enabled, this will align the displayport to tile boundaries.
-       Setting the scroll position can cause some small adjustments to be made
-       to the actual scroll position. aMetrics' display port and scroll position
-       will be updated with any modifications made. */
-    static void UpdateSubFrame(nsIContent* aContent,
-                               FrameMetrics& aMetrics);
+    static void UpdateSubFrame(FrameMetrics& aMetrics);
 
     /* Get the presShellId and view ID for the given content element.
      * If the view ID does not exist, one is created.
      * The pres shell ID should generally already exist; if it doesn't for some
      * reason, false is returned. */
     static bool GetOrCreateScrollIdentifiers(nsIContent* aContent,
                                              uint32_t* aPresShellIdOut,
                                              FrameMetrics::ViewID* aViewIdOut);
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -66,24 +66,21 @@ ChromeProcessController::InitializeRoot(
   }
 }
 
 void
 ChromeProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (aFrameMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
-    return;
-  }
-
-  nsCOMPtr<nsIContent> targetContent = nsLayoutUtils::FindContentFor(aFrameMetrics.GetScrollId());
-  if (targetContent) {
-    FrameMetrics metrics = aFrameMetrics;
-    APZCCallbackHelper::UpdateSubFrame(targetContent, metrics);
+  FrameMetrics metrics = aFrameMetrics;
+  if (metrics.IsRootContent()) {
+    APZCCallbackHelper::UpdateRootFrame(metrics);
+  } else {
+    APZCCallbackHelper::UpdateSubFrame(metrics);
   }
 }
 
 void
 ChromeProcessController::PostDelayedTask(Task* aTask, int aDelayMs)
 {
   MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
 }
--- a/gfx/tests/gtest/TestRect.cpp
+++ b/gfx/tests/gtest/TestRect.cpp
@@ -1,12 +1,13 @@
 /* -*- 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/. */
+#include <limits>
 
 #include "gtest/gtest.h"
 
 #include "nsRect.h"
 #include "gfxRect.h"
 #ifdef XP_WIN
 #include <windows.h>
 #endif
@@ -366,21 +367,19 @@ TestUnion()
   EXPECT_TRUE(dest.IsFinite()) << "[5b] Should be finite";
 
   return true;
 }
 
 static bool
 TestFiniteGfx()
 {
-  // Doesn't appear that __builtin_inf() and __builtin_nan() are available on
-  // all compilers, so go the old fashioned way for inf and nan.
-  float posInf = 1.0/0.0;
-  float negInf = -1.0/0.0;
-  float justNaN = 0.0/0.0;
+  float posInf = std::numeric_limits<float>::infinity();
+  float negInf = -std::numeric_limits<float>::infinity();
+  float justNaN = std::numeric_limits<float>::quiet_NaN();
 
   gfxFloat values[4] = {5.0, 10.0, 15.0, 20.0};
 
   // Try the "non-finite" values for x, y, width, height, one at a time
   for (int i=0; i<4; i+=1) {
     values[i] = posInf;
     gfxRect rectPosInf(values[0], values[1], values[2], values[3]);
     EXPECT_FALSE(rectPosInf.IsFinite()) << "For +inf (" << values[0] << "," << values[1] << "," << values[2] << "," << values[3] << ")";
--- a/gfx/tests/gtest/moz.build
+++ b/gfx/tests/gtest/moz.build
@@ -10,41 +10,36 @@ UNIFIED_SOURCES += [
     #'gfxWordCacheTest.cpp',
     'TestAsyncPanZoomController.cpp',
     'TestBufferRotation.cpp',
     'TestColorNames.cpp',
     'TestCompositor.cpp',
     'TestGfxPrefs.cpp',
     'TestGfxWidgets.cpp',
     'TestLayers.cpp',
+    'TestMoz2D.cpp',
+    'TestRect.cpp',
     'TestRegion.cpp',
     'TestSkipChars.cpp',
     # Hangs on linux in ApplyGdkScreenFontOptions
     #'gfxFontSelectionTest.cpp',
     'TestTextures.cpp',
     # Test works but it doesn't assert anything
     #'gfxTextRunPerfTest.cpp',
     'TestTiledLayerBuffer.cpp',
     'TestVsync.cpp',
 ]
 
-# Because of gkmedia on windows we won't find these
-# symbols in xul.dll.
-if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
-    UNIFIED_SOURCES += [ '/gfx/2d/unittest/%s' % p for p in [
-        'TestBase.cpp',
-        'TestBugs.cpp',
-        'TestCairo.cpp',
-        'TestPoint.cpp',
-        'TestScaling.cpp',
-    ]]
-    UNIFIED_SOURCES += [
-        'TestMoz2D.cpp',
-        'TestRect.cpp',
-    ]
+UNIFIED_SOURCES += [ '/gfx/2d/unittest/%s' % p for p in [
+    'TestBase.cpp',
+    'TestBugs.cpp',
+    'TestCairo.cpp',
+    'TestPoint.cpp',
+    'TestScaling.cpp',
+]]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/gfx/2d',
     '/gfx/2d/unittest',
     '/gfx/layers',
 ]
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -437,27 +437,32 @@ gfxWindowsPlatform::gfxWindowsPlatform()
     RegisterStrongMemoryReporter(new D3D9TextureReporter());
     RegisterStrongMemoryReporter(new D3D9SurfaceImageReporter());
     RegisterStrongMemoryReporter(new D3D9SharedTextureReporter());
 }
 
 gfxWindowsPlatform::~gfxWindowsPlatform()
 {
     mDeviceManager = nullptr;
+    mD3D11Device = nullptr;
+    mD3D11ContentDevice = nullptr;
+    mD3D11ImageBridgeDevice = nullptr;
 
     // not calling FT_Done_FreeType because cairo may still hold references to
     // these FT_Faces.  See bug 458169.
 #ifdef CAIRO_HAS_D2D_SURFACE
     if (mD2DDevice) {
         cairo_release_device(mD2DDevice);
     }
 #endif
 
     mozilla::gfx::Factory::D2DCleanup();
 
+    mAdapter = nullptr;
+
     /* 
      * Uninitialize COM 
      */ 
     CoUninitialize();
 }
 
 double
 gfxWindowsPlatform::GetDPIScale()
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -2506,58 +2506,85 @@ BacktrackingAllocator::trySplitAcrossHot
         return splitAt(bundle, splitPositions);
     }
 
     LiveBundle* hotBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
     if (!hotBundle)
         return false;
     LiveBundle* preBundle = nullptr;
     LiveBundle* postBundle = nullptr;
+    LiveBundle* coldBundle = nullptr;
+
+    if (testbed) {
+        coldBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
+        if (!coldBundle)
+            return false;
+    }
 
     // Accumulate the ranges of hot and cold code in the bundle. Note that
     // we are only comparing with the single hot range found, so the cold code
     // may contain separate hot ranges.
     for (LiveRange::BundleLinkIterator iter = bundle->rangesBegin(); iter; iter++) {
         LiveRange* range = LiveRange::get(*iter);
         LiveRange::Range hot, coldPre, coldPost;
         range->intersect(hotRange, &coldPre, &hot, &coldPost);
 
         if (!hot.empty()) {
             if (!hotBundle->addRangeAndDistributeUses(alloc(), range, hot.from, hot.to))
                 return false;
         }
 
         if (!coldPre.empty()) {
-            if (!preBundle) {
-                preBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
-                if (!preBundle)
+            if (testbed) {
+                if (!coldBundle->addRangeAndDistributeUses(alloc(), range, coldPre.from, coldPre.to))
+                    return false;
+            } else {
+                if (!preBundle) {
+                    preBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
+                    if (!preBundle)
+                        return false;
+                }
+                if (!preBundle->addRangeAndDistributeUses(alloc(), range, coldPre.from, coldPre.to))
                     return false;
             }
-            if (!preBundle->addRangeAndDistributeUses(alloc(), range, coldPre.from, coldPre.to))
-                return false;
         }
 
         if (!coldPost.empty()) {
-            if (!postBundle)
-                postBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
-            if (!postBundle->addRangeAndDistributeUses(alloc(), range, coldPost.from, coldPost.to))
-                return false;
+            if (testbed) {
+                if (!coldBundle->addRangeAndDistributeUses(alloc(), range, coldPost.from, coldPost.to))
+                    return false;
+            } else {
+                if (!postBundle) {
+                    postBundle = LiveBundle::New(alloc(), bundle->spillSet(), bundle->spillParent());
+                    if (!postBundle)
+                        return false;
+                }
+                if (!postBundle->addRangeAndDistributeUses(alloc(), range, coldPost.from, coldPost.to))
+                    return false;
+            }
         }
     }
 
-    MOZ_ASSERT(preBundle || postBundle);
     MOZ_ASSERT(hotBundle->numRanges() != 0);
 
     LiveBundleVector newBundles;
     if (!newBundles.append(hotBundle))
         return false;
-    if (preBundle && !newBundles.append(preBundle))
-        return false;
-    if (postBundle && !newBundles.append(postBundle))
-        return false;
+
+    if (testbed) {
+        MOZ_ASSERT(coldBundle->numRanges() != 0);
+        if (!newBundles.append(coldBundle))
+            return false;
+    } else {
+        MOZ_ASSERT(preBundle || postBundle);
+        if (preBundle && !newBundles.append(preBundle))
+            return false;
+        if (postBundle && !newBundles.append(postBundle))
+            return false;
+    }
 
     *success = true;
     return splitAndRequeueBundles(bundle, newBundles);
 }
 
 bool
 BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveBundle* bundle, LiveBundle* conflict,
                                                     bool* success)
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -541,16 +541,19 @@ class VirtualRegister
 // where to split.
 typedef js::Vector<CodePosition, 4, SystemAllocPolicy> SplitPositionVector;
 
 class BacktrackingAllocator : protected RegisterAllocator
 {
     friend class C1Spewer;
     friend class JSONSpewer;
 
+    // This flag is set when testing new allocator modifications.
+    bool testbed;
+
     BitSet* liveIn;
     FixedList<VirtualRegister> vregs;
 
     // Ranges where all registers must be spilled due to call instructions.
     LiveBundle* callRanges;
 
     // Allocation state.
     StackSlotAllocator stackSlotAllocator;
@@ -601,18 +604,19 @@ class BacktrackingAllocator : protected 
         {}
     };
     typedef InlineForwardList<SpillSlot> SpillSlotList;
 
     // All allocated slots of each width.
     SpillSlotList normalSlots, doubleSlots, quadSlots;
 
   public:
-    BacktrackingAllocator(MIRGenerator* mir, LIRGenerator* lir, LIRGraph& graph)
+    BacktrackingAllocator(MIRGenerator* mir, LIRGenerator* lir, LIRGraph& graph, bool testbed)
       : RegisterAllocator(mir, lir, graph),
+        testbed(testbed),
         liveIn(nullptr),
         callRanges(nullptr)
     { }
 
     bool go();
 
   private:
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1648,24 +1648,28 @@ GenerateLIR(MIRGenerator* mir)
             return nullptr;
     }
 
     AllocationIntegrityState integrity(*lir);
 
     {
         AutoTraceLog log(logger, TraceLogger_RegisterAllocation);
 
-        switch (mir->optimizationInfo().registerAllocator()) {
-          case RegisterAllocator_Backtracking: {
+        IonRegisterAllocator allocator = mir->optimizationInfo().registerAllocator();
+
+        switch (allocator) {
+          case RegisterAllocator_Backtracking:
+          case RegisterAllocator_Testbed: {
 #ifdef DEBUG
             if (!integrity.record())
                 return nullptr;
 #endif
 
-            BacktrackingAllocator regalloc(mir, &lirgen, *lir);
+            BacktrackingAllocator regalloc(mir, &lirgen, *lir,
+                                           allocator == RegisterAllocator_Testbed);
             if (!regalloc.go())
                 return nullptr;
 
 #ifdef DEBUG
             if (!integrity.check(false))
                 return nullptr;
 #endif
 
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -18,24 +18,27 @@ namespace jit {
 // Longer scripts can only be compiled off thread, as these compilations
 // can be expensive and stall the main thread for too long.
 static const uint32_t MAX_MAIN_THREAD_SCRIPT_SIZE = 2 * 1000;
 static const uint32_t MAX_MAIN_THREAD_LOCALS_AND_ARGS = 256;
 
 // Possible register allocators which may be used.
 enum IonRegisterAllocator {
     RegisterAllocator_Backtracking,
+    RegisterAllocator_Testbed,
     RegisterAllocator_Stupid
 };
 
 static inline mozilla::Maybe<IonRegisterAllocator>
 LookupRegisterAllocator(const char* name)
 {
     if (!strcmp(name, "backtracking"))
         return mozilla::Some(RegisterAllocator_Backtracking);
+    if (!strcmp(name, "testbed"))
+        return mozilla::Some(RegisterAllocator_Testbed);
     if (!strcmp(name, "stupid"))
         return mozilla::Some(RegisterAllocator_Stupid);
     return mozilla::Nothing();
 }
 
 struct JitOptions
 {
     bool checkGraphConsistency;
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -228,17 +228,17 @@ ReportError(JSContext* cx, const char* m
     if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) {
         if (ErrorToException(cx, message, reportp, callback, userRef))
             return;
 
         /*
          * The AutoJSAPI error reporter only allows warnings to be reported so
          * just ignore this error rather than try to report it.
          */
-        if (cx->options().autoJSAPIOwnsErrorReporting())
+        if (cx->options().autoJSAPIOwnsErrorReporting() && !JSREPORT_IS_WARNING(reportp->flags))
             return;
     }
 
     /*
      * Call the error reporter only if an exception wasn't raised.
      */
     if (message)
         CallErrorReporter(cx, message, reportp);
@@ -248,19 +248,19 @@ ReportError(JSContext* cx, const char* m
  * The given JSErrorReport object have been zeroed and must not outlive
  * cx->fp() (otherwise owned fields may become invalid).
  */
 static void
 PopulateReportBlame(JSContext* cx, JSErrorReport* report)
 {
     /*
      * Walk stack until we find a frame that is associated with a non-builtin
-     * rather than a builtin frame.
+     * rather than a builtin frame and which we're allowed to know about.
      */
-    NonBuiltinFrameIter iter(cx);
+    NonBuiltinFrameIter iter(cx, cx->compartment()->principals());
     if (iter.done())
         return;
 
     report->filename = iter.scriptFilename();
     report->lineno = iter.computeLine(&report->column);
     // XXX: Make the column 1-based as in other browsers, instead of 0-based
     // which is how SpiderMonkey stores it internally. This will be
     // unnecessary once bug 1144340 is fixed.
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -331,18 +331,18 @@ Error(JSContext* cx, unsigned argc, Valu
     /* Compute the error message, if any. */
     RootedString message(cx, nullptr);
     if (args.hasDefined(0)) {
         message = ToString<CanGC>(cx, args[0]);
         if (!message)
             return false;
     }
 
-    /* Find the scripted caller. */
-    NonBuiltinFrameIter iter(cx);
+    /* Find the scripted caller, but only ones we're allowed to know about. */
+    NonBuiltinFrameIter iter(cx, cx->compartment()->principals());
 
     /* Set the 'fileName' property. */
     RootedString fileName(cx);
     if (args.length() > 1) {
         fileName = ToString<CanGC>(cx, args[1]);
     } else {
         fileName = cx->runtime()->emptyString;
         if (!iter.done()) {
@@ -862,17 +862,17 @@ bool
 ErrorReport::populateUncaughtExceptionReportVA(JSContext* cx, va_list ap)
 {
     new (&ownedReport) JSErrorReport();
     ownedReport.flags = JSREPORT_ERROR;
     ownedReport.errorNumber = JSMSG_UNCAUGHT_EXCEPTION;
     // XXXbz this assumes the stack we have right now is still
     // related to our exception object.  It would be better if we
     // could accept a passed-in stack of some sort instead.
-    NonBuiltinFrameIter iter(cx);
+    NonBuiltinFrameIter iter(cx, cx->compartment()->principals());
     if (!iter.done()) {
         ownedReport.filename = iter.scriptFilename();
         ownedReport.lineno = iter.computeLine(&ownedReport.column);
         // XXX: Make the column 1-based as in other browsers, instead of 0-based
         // which is how SpiderMonkey stores it internally. This will be
         // unnecessary once bug 1144340 is fixed.
         ++ownedReport.column;
         ownedReport.isMuted = iter.mutedErrors();
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6287,16 +6287,17 @@ main(int argc, char** argv, char** envp)
         || !op.addStringOption('\0', "ion-limit-script-size", "on/off",
                                "Don't compile very large scripts (default: on, off to disable)")
         || !op.addIntOption('\0', "ion-warmup-threshold", "COUNT",
                             "Wait for COUNT calls or iterations before compiling "
                             "(default: 1000)", -1)
         || !op.addStringOption('\0', "ion-regalloc", "[mode]",
                                "Specify Ion register allocation:\n"
                                "  backtracking: Priority based backtracking register allocation (default)\n"
+                               "  testbed: Backtracking allocator with experimental features\n"
                                "  stupid: Simple block local register allocation")
         || !op.addBoolOption('\0', "ion-eager", "Always ion-compile methods (implies --baseline-eager)")
         || !op.addStringOption('\0', "ion-offthread-compile", "on/off",
                                "Compile scripts off thread (default: on)")
         || !op.addStringOption('\0', "ion-parallel-compile", "on/off",
                                "--ion-parallel compile is deprecated. Use --ion-offthread-compile.")
         || !op.addBoolOption('\0', "baseline", "Enable baseline compiler (default)")
         || !op.addBoolOption('\0', "no-baseline", "Disable baseline compiler")
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1898,16 +1898,23 @@ class NonBuiltinFrameIter : public Frame
                         FrameIter::SavedOption savedOption,
                         FrameIter::DebuggerEvalOption debuggerEvalOption,
                         JSPrincipals* principals)
       : FrameIter(cx, contextOption, savedOption, debuggerEvalOption, principals)
     {
         settle();
     }
 
+    NonBuiltinFrameIter(JSContext* cx, JSPrincipals* principals)
+        : FrameIter(cx, FrameIter::ALL_CONTEXTS, FrameIter::GO_THROUGH_SAVED,
+                    FrameIter::FOLLOW_DEBUGGER_EVAL_PREV_LINK, principals)
+    {
+        settle();
+    }
+
     explicit NonBuiltinFrameIter(const FrameIter::Data& data)
       : FrameIter(data)
     {}
 
     NonBuiltinFrameIter& operator++() {
         FrameIter::operator++();
         settle();
         return *this;
--- a/js/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/xpconnect/loader/XPCOMUtils.jsm
@@ -226,36 +226,58 @@ this.XPCOMUtils = {
   {
     this.defineLazyGetter(aObject, aName, function XPCU_serviceLambda() {
       return Cc[aContract].getService(Ci[aInterfaceName]);
     });
   },
 
   /**
    * Defines a getter on a specified object for a module.  The module will not
-   * be imported until first use.
+   * be imported until first use. The getter allows to execute setup and
+   * teardown code (e.g.  to register/unregister to services) and accepts
+   * a proxy object which acts on behalf of the module until it is imported.
    *
    * @param aObject
    *        The object to define the lazy getter on.
    * @param aName
    *        The name of the getter to define on aObject for the module.
    * @param aResource
    *        The URL used to obtain the module.
    * @param aSymbol
    *        The name of the symbol exported by the module.
    *        This parameter is optional and defaults to aName.
+   * @param aPreLambda
+   *        A function that is executed when the proxy is set up.
+   *        This will only ever be called once.
+   * @param aPostLambda
+   *        A function that is executed when the module has been imported to
+   *        run optional teardown procedures on the proxy object.
+   *        This will only ever be called once.
+   * @param aProxy
+   *        An object which acts on behalf of the module to be imported until
+   *        the module has been imported.
    */
-  defineLazyModuleGetter: function XPCU_defineLazyModuleGetter(aObject, aName,
-                                                               aResource,
-                                                               aSymbol)
+  defineLazyModuleGetter: function XPCU_defineLazyModuleGetter(
+                                   aObject, aName, aResource, aSymbol,
+                                   aPreLambda, aPostLambda, aProxy)
   {
+    let proxy = aProxy || {};
+
+    if (typeof(aPreLambda) === "function") {
+      aPreLambda.apply(proxy);
+    }
+
     this.defineLazyGetter(aObject, aName, function XPCU_moduleLambda() {
       var temp = {};
       try {
         Cu.import(aResource, temp);
+
+        if (typeof(aPostLambda) === "function") {
+          aPostLambda.apply(proxy);
+        }
       } catch (ex) {
         Cu.reportError("Failed to load module " + aResource + ".");
         throw ex;
       }
       return temp[aSymbol || aName];
     });
   },
 
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -574,19 +574,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       function testProperty(name, criterion, goodReplacement, faultyReplacement) {
         ok(criterion(e[name]), name + " property is correct: " + e[name]);
         e.wrappedJSObject[name] = goodReplacement;
         is(e[name], goodReplacement, name + " property ok after replacement: " + goodReplacement);
         e.wrappedJSObject[name] = faultyReplacement;
         is(e[name], undefined, name + " property censored after suspicious replacement");
       }
       testProperty('message', x => x == 'some message', 'some other message', 42);
-      testProperty('fileName', x => /xul/.test(x), 'otherFilename.html', new iwin.Object());
-      testProperty('columnNumber', x => x > 5 && x < 100, 99, 99.5);
-      testProperty('lineNumber', x => x > 100 && x < 10000, 50, 'foo');
+      testProperty('fileName', x => x == '', 'otherFilename.html', new iwin.Object());
+      testProperty('columnNumber', x => x == 1, 99, 99.5);
+      testProperty('lineNumber', x => x == 0, 50, 'foo');
 
       // Note - an Exception newed via Xrays is going to have an empty stack given the
       // current semantics and implementation. This tests the current behavior, but that
       // may change in bug 1036527 or similar.
       //
       // Furthermore, xrays should always return an error's original stack, and
       // not overwrite it.
       var stack = e.stack;
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -826,17 +826,17 @@ AccessibleCaretManager::AdjustDragBounda
   // bound) of its Y-coordinate is the logical position of the first caret.
   // Likewise, when dragging the first caret, the horizontal boundary (upper
   // bound) of its Y-coordinate is the logical position of the second caret.
   nsPoint adjustedPoint = aPoint;
 
   if (GetCaretMode() == CaretMode::Selection) {
     if (mActiveCaret == mFirstCaret.get()) {
       nscoord dragDownBoundaryY = mSecondCaret->LogicalPosition().y;
-      if (adjustedPoint.y > dragDownBoundaryY) {
+      if (dragDownBoundaryY > 0 && adjustedPoint.y > dragDownBoundaryY) {
         adjustedPoint.y = dragDownBoundaryY;
       }
     } else {
       nscoord dragUpBoundaryY = mFirstCaret->LogicalPosition().y;
       if (adjustedPoint.y < dragUpBoundaryY) {
         adjustedPoint.y = dragUpBoundaryY;
       }
     }
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -46,16 +46,63 @@ using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 class PaintedDisplayItemLayerUserData;
 
 static nsTHashtable<nsPtrHashKey<FrameLayerBuilder::DisplayItemData>>* sAliveDisplayItemDatas;
 
+static const nsIntSize kRegionTileSize(128, 128);
+
+/**
+ * An alternative to nsIntRegion that keeps the region simple by snapping all
+ * accumulated rects outwards to tiles. It keeps track of the bounds of the
+ * true unsimplified region so that the result still has the bounds you'd
+ * expect.
+ * This approach doesn't guarantee a maximum number of rectangles in the
+ * region, but it has the advantage that region simplification doesn't merge
+ * rectangles that are very far apart; the simplification impact is local.
+ * This representation also has the property of being canonical: the result
+ * is independent of the order in which the rectangles are added.
+ */
+struct nsIntRegionSimplifiedToTiles
+{
+  nsIntRegionSimplifiedToTiles(const nsIntPoint& aTileOrigin,
+                               const nsIntSize& aTileSize)
+    : mTileOrigin(aTileOrigin)
+    , mTileSize(aTileSize)
+  {}
+
+  nsIntRegion Get() const { return mRegion.Intersect(mBounds); }
+
+  void Accumulate(const nsIntRect& aRect)
+  {
+    mBounds = mBounds.Union(aRect);
+    nsIntRect rect = aRect - mTileOrigin;
+    rect.InflateToMultiple(mTileSize);
+    mRegion.OrWith(rect + mTileOrigin);
+  }
+
+  bool IsEmpty() const { return mBounds.IsEmpty(); }
+  void SetEmpty()
+  { mRegion.SetEmpty(); mBounds.SetEmpty(); }
+  nsIntRegion Intersect(const nsIntRegion& aRegion) const
+  { return Get().Intersect(aRegion); }
+  bool Intersects(const nsIntRect& aRect) const
+  { return mRegion.Intersects(mBounds.Intersect(aRect)); }
+  nsIntRect GetBounds() const { return mBounds; }
+
+private:
+  nsIntRegion mRegion;
+  nsIntRect mBounds;
+  nsIntPoint mTileOrigin;
+  nsIntSize mTileSize;
+};
+
 FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
                                                     Layer* aLayer, nsIFrame* aFrame)
 
   : mParent(aParent)
   , mLayer(aLayer)
   , mDisplayItemKey(aKey)
   , mItem(nullptr)
   , mUsed(true)
@@ -281,31 +328,36 @@ struct AssignedDisplayItem
  * We use a stack here because as much as possible we want to
  * assign display items to existing PaintedLayers, and to the lowest
  * PaintedLayer in z-order. This reduces the number of layers and
  * makes it more likely a display item will be rendered to an opaque
  * layer, giving us the best chance of getting subpixel AA.
  */
 class PaintedLayerData {
 public:
-  PaintedLayerData() :
-    mAnimatedGeometryRoot(nullptr),
+  PaintedLayerData(const nsIFrame* aAnimatedGeometryRoot,
+                   const nsPoint& aTopLeft,
+                   const nsIntPoint& aSnappedOffset) :
+    mVisibleRegion(aSnappedOffset, kRegionTileSize),
+    mAnimatedGeometryRoot(aAnimatedGeometryRoot),
+    mAnimatedGeometryRootOffset(aTopLeft),
     mFixedPosFrameForLayerData(nullptr),
     mReferenceFrame(nullptr),
     mLayer(nullptr),
     mIsSolidColorInVisibleRegion(false),
     mFontSmoothingBackgroundColor(NS_RGBA(0,0,0,0)),
     mSingleItemFixedToViewport(false),
     mNeedComponentAlpha(false),
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
     mImage(nullptr),
     mCommonClipCount(-1),
-    mNewChildLayersIndex(-1)
+    mNewChildLayersIndex(-1),
+    mVisibleAboveRegion(aSnappedOffset, kRegionTileSize)
   {}
 
 #ifdef MOZ_DUMP_PAINTING
   /**
    * Keep track of important decisions for debugging.
    */
   nsCString mLog;
 
@@ -372,17 +424,17 @@ public:
   bool VisibleRegionIntersects(const nsIntRegion& aRegion) const
   { return !mVisibleRegion.Intersect(aRegion).IsEmpty(); }
 
   /**
    * The region of visible content in the layer, relative to the
    * container layer (which is at the snapped top-left of the display
    * list reference frame).
    */
-  nsIntRegion  mVisibleRegion;
+  nsIntRegionSimplifiedToTiles mVisibleRegion;
   /**
    * The region of visible content in the layer that is opaque.
    * Same coordinate system as mVisibleRegion.
    */
   nsIntRegion  mOpaqueRegion;
   /**
    * The definitely-hit region for this PaintedLayer.
    */
@@ -513,17 +565,17 @@ public:
    * The union of all the bounds of the display items in this layer.
    */
   nsIntRect mBounds;
   /**
    * The region of visible content above the layer and below the
    * next PaintedLayerData currently in the stack, if any.
    * This is a conservative approximation: it contains the true region.
    */
-  nsIntRegion mVisibleAboveRegion;
+  nsIntRegionSimplifiedToTiles mVisibleAboveRegion;
   /**
    * All the display items that have been assigned to this painted layer.
    * These items get added by Accumulate().
    */
   nsTArray<AssignedDisplayItem> mAssignedDisplayItems;
 
 };
 
@@ -590,17 +642,18 @@ class PaintedLayerDataTree;
  * stack, in z-order, and the clip rects of the child nodes are allowed to
  * intersect with the visible region or visible above region of their parent
  * node's PaintedLayerDatas.
  */
 class PaintedLayerDataNode {
 public:
   PaintedLayerDataNode(PaintedLayerDataTree& aTree,
                        PaintedLayerDataNode* aParent,
-                       const nsIFrame* aAnimatedGeometryRoot);
+                       const nsIFrame* aAnimatedGeometryRoot,
+                       const nsIntPoint& aSnappedOffset);
   ~PaintedLayerDataNode();
 
   const nsIFrame* AnimatedGeometryRoot() const { return mAnimatedGeometryRoot; }
 
   /**
    * Whether this node's contents can potentially intersect aRect.
    * aRect is in our tree's ContainerState's coordinate space.
    */
@@ -688,16 +741,17 @@ protected:
    * Pass off opaque background color searching to our parent node, if we have
    * one.
    */
   nscolor FindOpaqueBackgroundColorInParentNode() const;
 
   PaintedLayerDataTree& mTree;
   PaintedLayerDataNode* mParent;
   const nsIFrame* mAnimatedGeometryRoot;
+  const nsIntPoint mSnappedAnimatedGeometryRootOffset;
 
   /**
    * Our contents: a PaintedLayerData stack and our child nodes.
    */
   nsTArray<PaintedLayerData> mPaintedLayerDataStack;
 
   /**
    * UniquePtr is used here in the sense of "unique ownership", i.e. there is
@@ -713,17 +767,17 @@ protected:
 
   /**
    * The region that's covered between our "background" and the bottom of
    * mPaintedLayerDataStack. This is used to indicate whether we can pull
    * a background color from our parent node. If mVisibleAboveBackgroundRegion
    * should be considered infinite, mAllDrawingAboveBackground will be true and
    * the value of mVisibleAboveBackgroundRegion will be meaningless.
    */
-  nsIntRegion mVisibleAboveBackgroundRegion;
+  nsIntRegionSimplifiedToTiles mVisibleAboveBackgroundRegion;
 
   /**
    * Our clip, if we have any. If not, that means we can move anywhere, and
    * mHasClip will be false and mClipRect will be meaningless.
    */
   nsIntRect mClipRect;
   bool mHasClip;
 
@@ -983,19 +1037,30 @@ public:
   {
     if (aSnap && mSnappingEnabled) {
       return ScaleRegionToNearestPixels(aRegion);
     }
     return aRegion.ScaleToOutsidePixels(mParameters.mXScale, mParameters.mYScale,
                                         mAppUnitsPerDevPixel);
   }
 
+  nsIntPoint SnapPointToPixels(const nsPoint& aPoint) const
+  {
+    return aPoint.ScaleToNearestPixels(mParameters.mXScale, mParameters.mYScale,
+                                       mAppUnitsPerDevPixel);
+  }
+
   nsIFrame* GetContainerFrame() const { return mContainerFrame; }
   nsDisplayListBuilder* Builder() const { return mBuilder; }
 
+  nsIntPoint GetSnappedOffsetToContainerReferenceFrame(const nsIFrame* aFrame)
+  {
+    return SnapPointToPixels(aFrame->GetOffsetToCrossDoc(mContainerReferenceFrame));
+  }
+
   /**
    * Sets aOuterVisibleRegion as aLayer's visible region. aOuterVisibleRegion
    * is in the coordinate space of the container reference frame.
    * aLayerContentsVisibleRect, if non-null, is in the layer's own
    * coordinate system.
    */
   void SetOuterVisibleRegionForLayer(Layer* aLayer,
                                      const nsIntRegion& aOuterVisibleRegion,
@@ -2493,38 +2558,41 @@ PaintedLayerData::GetContainerForImageLa
     return nullptr;
   }
 
   return mImage->GetContainer(mLayer->Manager(), aBuilder);
 }
 
 PaintedLayerDataNode::PaintedLayerDataNode(PaintedLayerDataTree& aTree,
                                            PaintedLayerDataNode* aParent,
-                                           const nsIFrame* aAnimatedGeometryRoot)
+                                           const nsIFrame* aAnimatedGeometryRoot,
+                                           const nsIntPoint& aSnappedOffset)
   : mTree(aTree)
   , mParent(aParent)
   , mAnimatedGeometryRoot(aAnimatedGeometryRoot)
+  , mVisibleAboveBackgroundRegion(aSnappedOffset, kRegionTileSize)
   , mAllDrawingAboveBackground(false)
 {
   MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(mTree.Builder()->RootReferenceFrame(), mAnimatedGeometryRoot));
   mHasClip = mTree.IsClippedWithRespectToParentAnimatedGeometryRoot(mAnimatedGeometryRoot, &mClipRect);
 }
 
 PaintedLayerDataNode::~PaintedLayerDataNode()
 {
   MOZ_ASSERT(mPaintedLayerDataStack.IsEmpty());
   MOZ_ASSERT(mChildren.IsEmpty());
 }
 
 PaintedLayerDataNode*
 PaintedLayerDataNode::AddChildNodeFor(const nsIFrame* aAnimatedGeometryRoot)
 {
   MOZ_ASSERT(mTree.GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot) == mAnimatedGeometryRoot);
+  nsIntPoint snappedOffset = mTree.ContState().GetSnappedOffsetToContainerReferenceFrame(aAnimatedGeometryRoot);
   UniquePtr<PaintedLayerDataNode> child =
-    MakeUnique<PaintedLayerDataNode>(mTree, this, aAnimatedGeometryRoot);
+    MakeUnique<PaintedLayerDataNode>(mTree, this, aAnimatedGeometryRoot, snappedOffset);
   mChildren.AppendElement(Move(child));
   return mChildren.LastElement().get();
 }
 
 template<typename NewPaintedLayerCallbackType>
 PaintedLayerData*
 PaintedLayerDataNode::FindPaintedLayerFor(const nsIntRect& aVisibleRect,
                                           NewPaintedLayerCallbackType aNewPaintedLayerCallback)
@@ -2590,21 +2658,20 @@ PaintedLayerDataNode::Finish(bool aParen
     }
   }
   mTree.NodeWasFinished(mAnimatedGeometryRoot);
 }
 
 void
 PaintedLayerDataNode::AddToVisibleAboveRegion(const nsIntRect& aRect)
 {
-  nsIntRegion& visibleAboveRegion = mPaintedLayerDataStack.IsEmpty()
+  nsIntRegionSimplifiedToTiles& visibleAboveRegion = mPaintedLayerDataStack.IsEmpty()
     ? mVisibleAboveBackgroundRegion
     : mPaintedLayerDataStack.LastElement().mVisibleAboveRegion;
-  visibleAboveRegion.Or(visibleAboveRegion, aRect);
-  visibleAboveRegion.SimplifyOutward(8);
+  visibleAboveRegion.Accumulate(aRect);
 }
 
 void
 PaintedLayerDataNode::SetAllDrawingAbove()
 {
   PopAllPaintedLayerData();
   mAllDrawingAboveBackground = true;
   mVisibleAboveBackgroundRegion.SetEmpty();
@@ -2612,17 +2679,17 @@ PaintedLayerDataNode::SetAllDrawingAbove
 
 void
 PaintedLayerDataNode::PopPaintedLayerData()
 {
   MOZ_ASSERT(!mPaintedLayerDataStack.IsEmpty());
   size_t lastIndex = mPaintedLayerDataStack.Length() - 1;
   PaintedLayerData& data = mPaintedLayerDataStack[lastIndex];
   mTree.ContState().FinishPaintedLayerData(data, [this, &data, lastIndex]() {
-    return this->FindOpaqueBackgroundColor(data.mVisibleRegion, lastIndex);
+    return this->FindOpaqueBackgroundColor(data.mVisibleRegion.Get(), lastIndex);
   });
   mPaintedLayerDataStack.RemoveElementAt(lastIndex);
 }
 
 void
 PaintedLayerDataNode::PopAllPaintedLayerData()
 {
   while (!mPaintedLayerDataStack.IsEmpty()) {
@@ -2769,17 +2836,18 @@ PaintedLayerDataTree::EnsureNodeFor(cons
   if (node) {
     return node;
   }
 
   const nsIFrame* parentAnimatedGeometryRoot = GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot);
   if (!parentAnimatedGeometryRoot) {
     MOZ_ASSERT(!mRoot);
     MOZ_ASSERT(aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
-    mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot);
+    nsIntPoint snappedOffset = ContState().GetSnappedOffsetToContainerReferenceFrame(aAnimatedGeometryRoot);
+    mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot, snappedOffset);
     node = mRoot.get();
   } else {
     PaintedLayerDataNode* parentNode = EnsureNodeFor(parentAnimatedGeometryRoot);
     MOZ_ASSERT(parentNode);
     node = parentNode->AddChildNodeFor(aAnimatedGeometryRoot);
   }
   MOZ_ASSERT(node);
   mNodes.Put(aAnimatedGeometryRoot, node);
@@ -3040,22 +3108,22 @@ void ContainerState::FinishPaintedLayerD
   if (!layer) {
     // We couldn't optimize to an image layer or a color layer above.
     layer = data->mLayer;
     layer->SetClipRect(Nothing());
     FLB_LOG_PAINTED_LAYER_DECISION(data, "  Selected painted layer=%p\n", layer.get());
   }
 
   if (mLayerBuilder->IsBuildingRetainedLayers()) {
-    newLayerEntry->mVisibleRegion = data->mVisibleRegion;
+    newLayerEntry->mVisibleRegion = data->mVisibleRegion.Get();
     newLayerEntry->mOpaqueRegion = data->mOpaqueRegion;
     newLayerEntry->mHideAllLayersBelow = data->mHideAllLayersBelow;
     newLayerEntry->mOpaqueForAnimatedGeometryRootParent = data->mOpaqueForAnimatedGeometryRootParent;
   } else {
-    SetOuterVisibleRegionForLayer(layer, data->mVisibleRegion);
+    SetOuterVisibleRegionForLayer(layer, data->mVisibleRegion.Get());
   }
 
   nsIntRect layerBounds = data->mBounds;
   layerBounds.MoveBy(-GetTranslationForPaintedLayer(data->mLayer));
   layer->SetLayerBounds(layerBounds);
 
 #ifdef MOZ_DUMP_PAINTING
   if (!data->mLog.IsEmpty()) {
@@ -3063,17 +3131,17 @@ void ContainerState::FinishPaintedLayerD
       containingPld->mLayer->AddExtraDumpInfo(nsCString(data->mLog));
     } else {
       layer->AddExtraDumpInfo(nsCString(data->mLog));
     }
   }
 #endif
 
   nsIntRegion transparentRegion;
-  transparentRegion.Sub(data->mVisibleRegion, data->mOpaqueRegion);
+  transparentRegion.Sub(data->mVisibleRegion.Get(), data->mOpaqueRegion);
   bool isOpaque = transparentRegion.IsEmpty();
   // For translucent PaintedLayers, try to find an opaque background
   // color that covers the entire area beneath it so we can pull that
   // color into this layer to make it opaque.
   if (layer == data->mLayer) {
     nscolor backgroundColor = NS_RGBA(0,0,0,0);
     if (!isOpaque) {
       backgroundColor = aFindOpaqueBackgroundColor();
@@ -3103,24 +3171,24 @@ void ContainerState::FinishPaintedLayerD
     userData->mForcedBackgroundColor = backgroundColor;
 
     userData->mFontSmoothingBackgroundColor = data->mFontSmoothingBackgroundColor;
 
     // use a mask layer for rounded rect clipping.
     // data->mCommonClipCount may be -1 if we haven't put any actual
     // drawable items in this layer (i.e. it's only catching events).
     int32_t commonClipCount = std::max(0, data->mCommonClipCount);
-    SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion, commonClipCount);
+    SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion.Get(), commonClipCount);
     // copy commonClipCount to the entry
     FrameLayerBuilder::PaintedLayerItemsEntry* entry = mLayerBuilder->
       GetPaintedLayerItemsEntry(static_cast<PaintedLayer*>(layer.get()));
     entry->mCommonClipCount = commonClipCount;
   } else {
     // mask layer for image and color layers
-    SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion);
+    SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion.Get());
   }
 
   uint32_t flags = 0;
   nsIWidget* widget = mContainerReferenceFrame->PresContext()->GetRootWidget();
   // See bug 941095. Not quite ready to disable this.
   bool hidpi = false && widget && widget->GetDefaultScale().scale >= 2;
   if (hidpi) {
     flags |= Layer::CONTENT_DISABLE_SUBPIXEL_AA;
@@ -3246,33 +3314,33 @@ PaintedLayerData::Accumulate(ContainerSt
   }
 
   bool clipMatches = mItemClip == aClip;
   mItemClip = aClip;
 
   mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState));
 
   if (!mIsSolidColorInVisibleRegion && mOpaqueRegion.Contains(aVisibleRect) &&
-      mVisibleRegion.Contains(aVisibleRect) && !mImage) {
+      mVisibleRegion.Get().Contains(aVisibleRect) && !mImage) {
     // A very common case! Most pages have a PaintedLayer with the page
     // background (opaque) visible and most or all of the page content over the
     // top of that background.
     // The rest of this method won't do anything. mVisibleRegion and mOpaqueRegion
     // don't need updating. mVisibleRegion contains aVisibleRect already,
     // mOpaqueRegion contains aVisibleRect and therefore whatever the opaque
     // region of the item is. mVisibleRegion must contain mOpaqueRegion
     // and therefore aVisibleRect.
     return;
   }
 
   /* Mark as available for conversion to image layer if this is a nsDisplayImage and
    * it's the only thing visible in this layer.
    */
-  if (nsIntRegion(aVisibleRect).Contains(mVisibleRegion) &&
-      aClippedOpaqueRegion.Contains(mVisibleRegion) &&
+  if (nsIntRegion(aVisibleRect).Contains(mVisibleRegion.Get()) &&
+      aClippedOpaqueRegion.Contains(mVisibleRegion.Get()) &&
       aItem->SupportsOptimizingToImage()) {
     mImage = static_cast<nsDisplayImageContainer*>(aItem);
     FLB_LOG_PAINTED_LAYER_DECISION(this, "  Tracking image: nsDisplayImageContainer covers the layer\n");
   } else if (mImage) {
     FLB_LOG_PAINTED_LAYER_DECISION(this, "  No longer tracking image\n");
     mImage = nullptr;
   }
 
@@ -3304,31 +3372,30 @@ PaintedLayerData::Accumulate(ContainerSt
       }
     }
     if (isUniform) {
       if (isFirstVisibleItem) {
         // This color is all we have
         mSolidColor = uniformColor;
         mIsSolidColorInVisibleRegion = true;
       } else if (mIsSolidColorInVisibleRegion &&
-                 mVisibleRegion.IsEqual(nsIntRegion(aVisibleRect)) &&
+                 mVisibleRegion.Get().IsEqual(nsIntRegion(aVisibleRect)) &&
                  clipMatches) {
         // we can just blend the colors together
         mSolidColor = NS_ComposeColors(mSolidColor, uniformColor);
       } else {
         FLB_LOG_PAINTED_LAYER_DECISION(this, "  Layer not a solid color: Can't blend colors togethers\n");
         mIsSolidColorInVisibleRegion = false;
       }
     } else {
       FLB_LOG_PAINTED_LAYER_DECISION(this, "  Layer is not a solid color: Display item is not uniform over the visible bound\n");
       mIsSolidColorInVisibleRegion = false;
     }
 
-    mVisibleRegion.Or(mVisibleRegion, aVisibleRect);
-    mVisibleRegion.SimplifyOutward(4);
+    mVisibleRegion.Accumulate(aVisibleRect);
   }
 
   if (!aClippedOpaqueRegion.IsEmpty()) {
     nsIntRegionRectIterator iter(aClippedOpaqueRegion);
     for (const nsIntRect* r = iter.Next(); r; r = iter.Next()) {
       // We don't use SimplifyInward here since it's not defined exactly
       // what it will discard. For our purposes the most important case
       // is a large opaque background at the bottom of z-order (e.g.,
@@ -3364,19 +3431,17 @@ PaintedLayerData::Accumulate(ContainerSt
 
 PaintedLayerData
 ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
                                     const nsIntRect& aVisibleRect,
                                     const nsIFrame* aAnimatedGeometryRoot,
                                     const nsPoint& aTopLeft,
                                     bool aShouldFixToViewport)
 {
-  PaintedLayerData data;
-  data.mAnimatedGeometryRoot = aAnimatedGeometryRoot;
-  data.mAnimatedGeometryRootOffset = aTopLeft;
+  PaintedLayerData data(aAnimatedGeometryRoot, aTopLeft, SnapPointToPixels(aTopLeft));
   data.mFixedPosFrameForLayerData =
     FindFixedPosFrameForLayerData(aAnimatedGeometryRoot, aShouldFixToViewport);
   data.mReferenceFrame = aItem->ReferenceFrame();
   data.mSingleItemFixedToViewport = aShouldFixToViewport;
 
   data.mNewChildLayersIndex = mNewChildLayers.Length();
   NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
   newLayerEntry->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
new file mode 100644
--- /dev/null
+++ b/layout/base/LayoutLogging.cpp
@@ -0,0 +1,35 @@
+/* -*- 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/. */
+
+// Chromium headers must come before Mozilla headers.
+#include "base/process_util.h"
+
+#include "LayoutLogging.h"
+
+PRLogModuleInfo* GetLayoutLog()
+{
+  static PRLogModuleInfo* log = nullptr;
+  if (!log) {
+    log = PR_NewLogModule("layout");
+  }
+
+  return log;
+}
+
+namespace mozilla {
+namespace detail {
+
+void LayoutLogWarning(const char* aStr, const char* aExpr,
+                      const char* aFile, int32_t aLine)
+{
+  MOZ_LOG(GetLayoutLog(),
+          mozilla::LogLevel::Warning,
+          ("[%d] WARNING: %s: '%s', file %s, line %d",
+           base::GetCurrentProcId(),
+           aStr, aExpr, aFile, aLine));
+}
+
+} // namespace detail
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/base/LayoutLogging.h
@@ -0,0 +1,45 @@
+/* -*- 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 LayoutLogging_h
+#define LayoutLogging_h
+
+#include "mozilla/Logging.h"
+
+/**
+ * Retrieves the log module to use for layout logging.
+ */
+PRLogModuleInfo* GetLayoutLog();
+
+/**
+ * Use the layout log to warn if a given condition is false.
+ *
+ * This is only enabled in debug builds and the logging is only displayed if
+ * the environmental variable NSPR_LOG_MODULES includes "layout:2" (or higher). 
+ */
+#ifdef DEBUG
+#define LAYOUT_WARN_IF_FALSE(_cond, _msg)                                  \
+  PR_BEGIN_MACRO                                                           \
+    if (MOZ_LOG_TEST(GetLayoutLog(), mozilla::LogLevel::Warning) &&        \
+        !(_cond)) {                                                        \
+      mozilla::detail::LayoutLogWarning(_msg, #_cond, __FILE__, __LINE__); \
+    }                                                                      \
+  PR_END_MACRO
+#else
+#define LAYOUT_WARN_IF_FALSE(_cond, _msg) \
+  PR_BEGIN_MACRO                          \
+  PR_END_MACRO
+#endif
+
+namespace mozilla {
+namespace detail {
+
+void LayoutLogWarning(const char* aStr, const char* aExpr,
+                      const char* aFile, int32_t aLine);
+
+} // namespace detail
+} // namespace mozilla
+
+#endif // LayoutLogging_h
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -54,16 +54,17 @@ XPIDL_MODULE = 'layout_base'
 EXPORTS += [
     'ActiveLayerTracker.h',
     'CaretAssociationHint.h',
     'DisplayItemClip.h',
     'DisplayListClipState.h',
     'FrameLayerBuilder.h',
     'FramePropertyTable.h',
     'LayerState.h',
+    'LayoutLogging.h',
     'nsArenaMemoryStats.h',
     'nsBidi.h',
     'nsBidiPresUtils.h',
     'nsCaret.h',
     'nsChangeHint.h',
     'nsCompatibility.h',
     'nsCSSFrameConstructor.h',
     'nsDisplayItemTypes.h',
@@ -104,16 +105,17 @@ UNIFIED_SOURCES += [
     'AccessibleCaretLogger.cpp',
     'AccessibleCaretManager.cpp',
     'ActiveLayerTracker.cpp',
     'DisplayItemClip.cpp',
     'DisplayListClipState.cpp',
     'FrameLayerBuilder.cpp',
     'FramePropertyTable.cpp',
     'GeometryUtils.cpp',
+    'LayoutLogging.cpp',
     'MaskLayerImageCache.cpp',
     'nsBidi.cpp',
     'nsBidiPresUtils.cpp',
     'nsCaret.cpp',
     'nsCounterManager.cpp',
     'nsCSSColorUtils.cpp',
     'nsCSSFrameConstructor.cpp',
     'nsCSSRendering.cpp',
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2329,16 +2329,30 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
 
     sheet = nsLayoutStylesheetCache::CounterStylesSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
 
+    if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
+      sheet = nsLayoutStylesheetCache::NoScriptSheet();
+      if (sheet) {
+        styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+      }
+    }
+
+    if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
+      sheet = nsLayoutStylesheetCache::NoFramesSheet();
+      if (sheet) {
+        styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+      }
+    }
+
     sheet = nsLayoutStylesheetCache::HTMLSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
 
     styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
                                 nsLayoutStylesheetCache::UASheet());
   } else {
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -134,20 +134,20 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mPointerLock;
   bool mRetargetToElement;
   bool mPreventDrag;
   mozilla::StaticRefPtr<nsIContent> mContent;
 } CapturingContentInfo;
 
-// a7ef8bb3-d628-4965-80f3-a326e089fb7f
+// 7f0ae6b1-5fa1-4ba7-885e-a93e17d72cd2
 #define NS_IPRESSHELL_IID \
-{ 0xa7ef8bb3, 0xd628, 0x4965, \
-  { 0x80, 0xf3, 0xa3, 0x26, 0xe0, 0x89, 0xfb, 0x7f } }
+{ 0x7f0ae6b1, 0x5fa1, 0x4ba7, \
+  { 0x88, 0x5e, 0xa9, 0x3e, 0x17, 0xd7, 0x2c, 0xd2 } }
 
 // debug VerifyReflow flags
 #define VERIFY_REFLOW_ON                    0x01
 #define VERIFY_REFLOW_NOISY                 0x02
 #define VERIFY_REFLOW_ALL                   0x04
 #define VERIFY_REFLOW_DUMP_COMMANDS         0x08
 #define VERIFY_REFLOW_NOISY_RC              0x10
 #define VERIFY_REFLOW_REALLY_NOISY_RC       0x20
@@ -350,25 +350,21 @@ public:
   virtual void ReconstructStyleDataExternal();
   void ReconstructStyleDataInternal();
 #ifdef MOZILLA_INTERNAL_API
   void ReconstructStyleData() { ReconstructStyleDataInternal(); }
 #else
   void ReconstructStyleData() { ReconstructStyleDataExternal(); }
 #endif
 
-  /** Setup all style rules required to implement preferences
-   * - used for background/text/link colors and link underlining
-   *    may be extended for any prefs that are implemented via style rules
-   * - aForceReflow argument is used to force a full reframe to make the rules show
-   *   (only used when the current page needs to reflect changed pref rules)
-   *
-   * - initially created for bugs 31816, 20760, 22963
+  /**
+   * Update the style set somehow to take into account changed prefs which
+   * affect document styling.
    */
-  virtual nsresult SetPreferenceStyleRules(bool aForceReflow) = 0;
+  virtual void UpdatePreferenceStyles() = 0;
 
   /**
    * FrameSelection will return the Frame based selection API.
    * You cannot go back and forth anymore with QI between nsIDOM sel and
    * nsIFrame sel.
    */
   already_AddRefed<nsFrameSelection> FrameSelection();
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -7511,21 +7511,36 @@ nsLayoutUtils::FontSizeInflationEnabled(
 /* static */ nsRect
 nsLayoutUtils::GetBoxShadowRectForFrame(nsIFrame* aFrame, 
                                         const nsSize& aFrameSize)
 {
   nsCSSShadowArray* boxShadows = aFrame->StyleBorder()->mBoxShadow;
   if (!boxShadows) {
     return nsRect();
   }
+
+  bool nativeTheme;
+  const nsStyleDisplay* styleDisplay = aFrame->StyleDisplay();
+  nsITheme::Transparency transparency;
+  if (aFrame->IsThemed(styleDisplay, &transparency)) {
+    // For opaque (rectangular) theme widgets we can take the generic
+    // border-box path with border-radius disabled.
+    nativeTheme = transparency != nsITheme::eOpaque;
+  } else {
+    nativeTheme = false;
+  }
+
+  nsRect frameRect = nativeTheme ?
+    aFrame->GetVisualOverflowRectRelativeToSelf() :
+    nsRect(nsPoint(0, 0), aFrameSize);
   
   nsRect shadows;
   int32_t A2D = aFrame->PresContext()->AppUnitsPerDevPixel();
   for (uint32_t i = 0; i < boxShadows->Length(); ++i) {
-    nsRect tmpRect(nsPoint(0, 0), aFrameSize);
+    nsRect tmpRect = frameRect;
     nsCSSShadowItem* shadow = boxShadows->ShadowAt(i);
 
     // inset shadows are never painted outside the frame
     if (shadow->mInset)
       continue;
 
     tmpRect.MoveBy(nsPoint(shadow->mXOffset, shadow->mYOffset));
     tmpRect.Inflate(shadow->mSpread);
@@ -8429,8 +8444,30 @@ nsLayoutUtils::TransformToAncestorAndCom
   Matrix matrix2D;
   bool isPrecise = (matrix.Is2D(&matrix2D)
     && !matrix2D.HasNonAxisAlignedTransform());
   nsRect transformed = TransformFrameRectToAncestor(
     aFrame, aBounds, aAncestorFrame);
   nsRegion* dest = isPrecise ? aPreciseTargetDest : aImpreciseTargetDest;
   dest->OrWith(transformed);
 }
+
+/* static */ bool
+nsLayoutUtils::ShouldUseNoScriptSheet(nsIDocument* aDocument)
+{
+  // also handle the case where print is done from print preview
+  // see bug #342439 for more details
+  if (aDocument->IsStaticDocument()) {
+    aDocument = aDocument->GetOriginalDocument();
+  }
+  return aDocument->IsScriptEnabled();
+}
+
+/* static */ bool
+nsLayoutUtils::ShouldUseNoFramesSheet(nsIDocument* aDocument)
+{
+  bool allowSubframes = true;
+  nsIDocShell* docShell = aDocument->GetDocShell();
+  if (docShell) {
+    docShell->GetAllowSubframes(&allowSubframes);
+  }
+  return !allowSubframes;
+}
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2667,16 +2667,19 @@ public:
   static nsMargin ScrollbarAreaToExcludeFromCompositionBoundsFor(nsIFrame* aScrollFrame);
 
   /**
    * Looks in the layer subtree rooted at aLayer for a metrics with scroll id
    * aScrollId. Returns true if such is found.
    */
   static bool ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId);
 
+  static bool ShouldUseNoScriptSheet(nsIDocument* aDocument);
+  static bool ShouldUseNoFramesSheet(nsIDocument* aDocument);
+
 private:
   static uint32_t sFontSizeInflationEmPerLine;
   static uint32_t sFontSizeInflationMinTwips;
   static uint32_t sFontSizeInflationLineThreshold;
   static int32_t  sFontSizeInflationMappingIntercept;
   static uint32_t sFontSizeInflationMaxRatio;
   static bool sFontSizeInflationForceEnabled;
   static bool sFontSizeInflationDisabledInMasterProcess;
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -62,16 +62,17 @@
 #include "nsIDOMChromeWindow.h"
 #include "nsFrameLoader.h"
 #include "mozilla/dom/FontFaceSet.h"
 #include "nsContentUtils.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/Preferences.h"
 #include "gfxTextRun.h"
 #include "nsFontFaceUtils.h"
+#include "nsLayoutStylesheetCache.h"
 
 #if defined(MOZ_WIDGET_GTK)
 #include "gfxPlatformGtk.h" // xxx - for UseFcFontList
 #endif
 
 
 // Needed for Start/Stop of Image Animation
 #include "imgIContainer.h"
@@ -924,16 +925,22 @@ nsPresContext::PreferenceChanged(const c
     mPrefChangePendingNeedsReflow = true;
   }
   // we use a zero-delay timer to coalesce multiple pref updates
   if (!mPrefChangedTimer)
   {
     mPrefChangedTimer = do_CreateInstance("@mozilla.org/timer;1");
     if (!mPrefChangedTimer)
       return;
+    // We will end up calling InvalidatePreferenceSheets one from each pres
+    // context, but all it's doing is clearing its cached sheet pointers,
+    // so it won't be wastefully recreating the sheet multiple times.
+    // The first pres context that has its mPrefChangedTimer called will
+    // be the one to cause the reconstruction of the pref style sheet.
+    nsLayoutStylesheetCache::InvalidatePreferenceSheets();
     mPrefChangedTimer->InitWithFuncCallback(nsPresContext::PrefChangedUpdateTimerCallback, (void*)this, 0, nsITimer::TYPE_ONE_SHOT);
   }
   if (prefName.EqualsLiteral("nglayout.debug.paint_flashing") ||
       prefName.EqualsLiteral("nglayout.debug.paint_flashing_chrome")) {
     mPaintFlashingInitialized = false;
     return;
   }
 }
@@ -948,17 +955,17 @@ nsPresContext::UpdateAfterPreferencesCha
     return;
   }
 
   // Initialize our state from the user preferences
   GetUserPreferences();
 
   // update the presShell: tell it to set the preference style rules up
   if (mShell) {
-    mShell->SetPreferenceStyleRules(true);
+    mShell->UpdatePreferenceStyles();
   }
 
   InvalidatePaintedLayers();
   mDeviceContext->FlushFontCache();
 
   nsChangeHint hint = nsChangeHint(0);
 
   if (mPrefChangePendingNeedsReflow) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -174,16 +174,17 @@
 #include "ChildIterator.h"
 #include "RestyleManager.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDragSession.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/gfx/2D.h"
 #include "nsSubDocumentFrame.h"
 #include "nsQueryObject.h"
+#include "nsLayoutStylesheetCache.h"
 
 #ifdef ANDROID
 #include "nsIDocShellTreeOwner.h"
 #endif
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
 using namespace mozilla::tasktracer;
@@ -202,20 +203,16 @@ using namespace mozilla::layout;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
 nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerCaptureInfo>* nsIPresShell::gPointerCaptureList;
 nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerInfo>* nsIPresShell::gActivePointersIds;
 
-// convert a color value to a string, in the CSS format #RRGGBB
-// *  - initially created for bugs 31816, 20760, 22963
-static void ColorToString(nscolor aColor, nsAutoString &aString);
-
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
   nsRefPtr<nsRange> mRange;
   nsDisplayListBuilder mBuilder;
   nsDisplayList mList;
 
   // offset of builder's reference frame to the root frame
   nsPoint mRootOffset;
@@ -888,19 +885,18 @@ PresShell::Init(nsIDocument* aDocument,
   aStyleSet->Init(aPresContext);
   mStyleSet = aStyleSet;
 
   // Notify our prescontext that it now has a compatibility mode.  Note that
   // this MUST happen after we set up our style set but before we create any
   // frames.
   mPresContext->CompatibilityModeChanged();
 
-  // setup the preference style rules (no forced reflow), and do it
-  // before creating any frames.
-  SetPreferenceStyleRules(false);
+  // Add the preference style sheet.
+  UpdatePreferenceStyles();
 
   if (TouchCaretPrefEnabled() && !AccessibleCaretEnabled()) {
     // Create touch caret handle
     mTouchCaret = new TouchCaret(this);
     mTouchCaret->Init();
   }
 
   if (SelectionCaretPrefEnabled() && !AccessibleCaretEnabled()) {
@@ -1183,17 +1179,17 @@ PresShell::Destroy()
   }
 
   if (mAccessibleCaretEventHub) {
     mAccessibleCaretEventHub->Terminate();
     mAccessibleCaretEventHub = nullptr;
   }
 
   // release our pref style sheet, if we have one still
-  ClearPreferenceStyleRules();
+  RemovePreferenceStyles();
 
   mIsDestroying = true;
 
   // We can't release all the event content in
   // mCurrentEventContentStack here since there might be code on the
   // stack that will release the event content too. Double release
   // bad!
 
@@ -1318,358 +1314,70 @@ nsIPresShell::SetAuthorStyleDisabled(boo
 }
 
 bool
 nsIPresShell::GetAuthorStyleDisabled() const
 {
   return mStyleSet->GetAuthorStyleDisabled();
 }
 
-nsresult
-PresShell::SetPreferenceStyleRules(bool aForceReflow)
+void
+PresShell::UpdatePreferenceStyles()
 {
   if (!mDocument) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
-  nsPIDOMWindow *window = mDocument->GetWindow();
+    return;
+  }
 
   // If the document doesn't have a window there's no need to notify
   // its presshell about changes to preferences since the document is
   // in a state where it doesn't matter any more (see
   // nsDocumentViewer::Close()).
-
-  if (!window) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
-  NS_PRECONDITION(mPresContext, "presContext cannot be null");
-  if (mPresContext) {
-    // first, make sure this is not a chrome shell
-    if (nsContentUtils::IsInChromeDocshell(mDocument)) {
-      return NS_OK;
-    }
-
-#ifdef DEBUG_attinasi
-    printf("Setting Preference Style Rules:\n");
-#endif
-    // if here, we need to create rules for the prefs
-    // - this includes the background-color, the text-color,
-    //   the link color, the visited link color and the link-underlining
-
-    // first clear any exising rules
-    nsresult result = ClearPreferenceStyleRules();
-
-    // now the link rules (must come after the color rules, or links will not be correct color!)
-    // XXX - when there is both an override and agent pref stylesheet this won't matter,
-    //       as the color rules will be overrides and the links rules will be agent
-    if (NS_SUCCEEDED(result)) {
-      result = SetPrefLinkRules();
-    }
-    if (NS_SUCCEEDED(result)) {
-      result = SetPrefFocusRules();
-    }
-    if (NS_SUCCEEDED(result)) {
-      result = SetPrefNoScriptRule();
-    }
-    if (NS_SUCCEEDED(result)) {
-      result = SetPrefNoFramesRule();
-    }
-#ifdef DEBUG_attinasi
-    printf( "Preference Style Rules set: error=%ld\n", (long)result);
-#endif
-
-    // Note that this method never needs to force any calculation; the caller
-    // will recalculate style if needed
-
-    return result;
-  }
-
-  return NS_ERROR_NULL_POINTER;
-}
-
-nsresult PresShell::ClearPreferenceStyleRules(void)
-{
-  nsresult result = NS_OK;
+  if (!mDocument->GetWindow()) {
+    return;
+  }
+
+  // Documents in chrome shells do not have any preference style rules applied.
+  if (nsContentUtils::IsInChromeDocshell(mDocument)) {
+    return;
+  }
+
+  // We need to pass in mPresContext so that if the nsLayoutStylesheetCache
+  // needs to recreate the pref style sheet, it has somewhere to get the
+  // pref styling information from.  All pres contexts for
+  // IsChromeOriginImage() == false will have the same pref styling information,
+  // and similarly for IsChromeOriginImage() == true, so it doesn't really
+  // matter which pres context we pass in when it does need to be recreated.
+  // (See nsPresContext::GetDocumentColorPreferences for how whether we
+  // are a chrome origin image affects some pref styling information.)
+  nsRefPtr<CSSStyleSheet> newPrefSheet =
+    mPresContext->IsChromeOriginImage() ?
+      nsLayoutStylesheetCache::ChromePreferenceSheet(mPresContext) :
+      nsLayoutStylesheetCache::ContentPreferenceSheet(mPresContext);
+
+  if (mPrefStyleSheet == newPrefSheet) {
+    return;
+  }
+
+  mStyleSet->BeginUpdate();
+
+  RemovePreferenceStyles();
+
+  mStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, newPrefSheet);
+  mPrefStyleSheet = newPrefSheet;
+
+  mStyleSet->EndUpdate();
+}
+
+void
+PresShell::RemovePreferenceStyles()
+{
   if (mPrefStyleSheet) {
-    NS_ASSERTION(mStyleSet, "null styleset entirely unexpected!");
-    if (mStyleSet) {
-      // remove the sheet from the styleset:
-      // - note that we have to check for success by comparing the count before and after...
-#ifdef DEBUG
-      int32_t numBefore = mStyleSet->SheetCount(nsStyleSet::eUserSheet);
-      NS_ASSERTION(numBefore > 0, "no user stylesheets in styleset, but we have one!");
-#endif
-      mStyleSet->RemoveStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
-
-#ifdef DEBUG_attinasi
-      NS_ASSERTION((numBefore - 1) == mStyleSet->GetNumberOfUserStyleSheets(),
-                   "Pref stylesheet was not removed");
-      printf("PrefStyleSheet removed\n");
-#endif
-      // clear the sheet pointer: it is strictly historical now
-      mPrefStyleSheet = nullptr;
-    }
-  }
-  return result;
-}
-
-nsresult
-PresShell::CreatePreferenceStyleSheet()
-{
-  NS_ASSERTION(!mPrefStyleSheet, "prefStyleSheet already exists");
-  mPrefStyleSheet = new CSSStyleSheet(CORS_NONE, mozilla::net::RP_Default);
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
-  if (NS_FAILED(rv)) {
-    mPrefStyleSheet = nullptr;
-    return rv;
-  }
-  NS_ASSERTION(uri, "null but no error");
-  mPrefStyleSheet->SetURIs(uri, uri, uri);
-  mPrefStyleSheet->SetComplete();
-  uint32_t index;
-  rv =
-    mPrefStyleSheet->InsertRuleInternal(NS_LITERAL_STRING("@namespace svg url(http://www.w3.org/2000/svg);"),
-                                        0, &index);
-  if (NS_FAILED(rv)) {
-    mPrefStyleSheet = nullptr;
-    return rv;
-  }
-  rv =
-    mPrefStyleSheet->InsertRuleInternal(NS_LITERAL_STRING("@namespace url(http://www.w3.org/1999/xhtml);"),
-                                        0, &index);
-  if (NS_FAILED(rv)) {
+    mStyleSet->RemoveStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
     mPrefStyleSheet = nullptr;
-    return rv;
-  }
-
-  mStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
-  return NS_OK;
-}
-
-// XXX We want these after the @namespace rules.  Does order matter
-// for these rules, or can we call StyleRule::StyleRuleCount()
-// and just "append"?
-static uint32_t sInsertPrefSheetRulesAt = 2;
-
-nsresult
-PresShell::SetPrefNoScriptRule()
-{
-  nsresult rv = NS_OK;
-
-  // also handle the case where print is done from print preview
-  // see bug #342439 for more details
-  nsIDocument* doc = mDocument;
-  if (doc->IsStaticDocument()) {
-    doc = doc->GetOriginalDocument();
-  }
-
-  bool scriptEnabled = doc->IsScriptEnabled();
-  if (scriptEnabled) {
-    if (!mPrefStyleSheet) {
-      rv = CreatePreferenceStyleSheet();
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    uint32_t index = 0;
-    mPrefStyleSheet->
-      InsertRuleInternal(NS_LITERAL_STRING("noscript{display:none!important}"),
-                         sInsertPrefSheetRulesAt, &index);
-  }
-
-  return rv;
-}
-
-nsresult PresShell::SetPrefNoFramesRule(void)
-{
-  NS_ASSERTION(mPresContext,"null prescontext not allowed");
-  if (!mPresContext) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = NS_OK;
-
-  if (!mPrefStyleSheet) {
-    rv = CreatePreferenceStyleSheet();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
-
-  bool allowSubframes = true;
-  nsCOMPtr<nsIDocShell> docShell(mPresContext->GetDocShell());
-  if (docShell) {
-    docShell->GetAllowSubframes(&allowSubframes);
-  }
-  if (!allowSubframes) {
-    uint32_t index = 0;
-    rv = mPrefStyleSheet->
-      InsertRuleInternal(NS_LITERAL_STRING("noframes{display:block}"),
-                         sInsertPrefSheetRulesAt, &index);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = mPrefStyleSheet->
-      InsertRuleInternal(NS_LITERAL_STRING("frame, frameset, iframe {display:none!important}"),
-                         sInsertPrefSheetRulesAt, &index);
-  }
-  return rv;
-}
-
-nsresult PresShell::SetPrefLinkRules(void)
-{
-  NS_ASSERTION(mPresContext,"null prescontext not allowed");
-  if (!mPresContext) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = NS_OK;
-
-  if (!mPrefStyleSheet) {
-    rv = CreatePreferenceStyleSheet();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
-
-  // support default link colors:
-  //   this means the link colors need to be overridable,
-  //   which they are if we put them in the agent stylesheet,
-  //   though if using an override sheet this will cause authors grief still
-  //   In the agent stylesheet, they are !important when we are ignoring document colors
-
-  nscolor linkColor(mPresContext->DefaultLinkColor());
-  nscolor activeColor(mPresContext->DefaultActiveLinkColor());
-  nscolor visitedColor(mPresContext->DefaultVisitedLinkColor());
-
-  NS_NAMED_LITERAL_STRING(ruleClose, "}");
-  uint32_t index = 0;
-  nsAutoString strColor;
-
-  // insert a rule to color links: '*|*:link {color: #RRGGBB [!important];}'
-  ColorToString(linkColor, strColor);
-  rv = mPrefStyleSheet->
-    InsertRuleInternal(NS_LITERAL_STRING("*|*:link{color:") +
-                       strColor + ruleClose,
-                       sInsertPrefSheetRulesAt, &index);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // - visited links: '*|*:visited {color: #RRGGBB [!important];}'
-  ColorToString(visitedColor, strColor);
-  rv = mPrefStyleSheet->
-    InsertRuleInternal(NS_LITERAL_STRING("*|*:visited{color:") +
-                       strColor + ruleClose,
-                       sInsertPrefSheetRulesAt, &index);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // - active links: '*|*:-moz-any-link:active {color: #RRGGBB [!important];}'
-  ColorToString(activeColor, strColor);
-  rv = mPrefStyleSheet->
-    InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link:active{color:") +
-                       strColor + ruleClose,
-                       sInsertPrefSheetRulesAt, &index);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool underlineLinks =
-    mPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks);
-
-  if (underlineLinks) {
-    // create a rule to make underlining happen
-    //  '*|*:-moz-any-link {text-decoration:[underline|none];}'
-    // no need for important, we want these to be overridable
-    // NOTE: these must go in the agent stylesheet or they cannot be
-    //       overridden by authors
-    rv = mPrefStyleSheet->
-      InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link:not(svg|a){text-decoration:underline}"),
-                         sInsertPrefSheetRulesAt, &index);
-  } else {
-    rv = mPrefStyleSheet->
-      InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link{text-decoration:none}"),
-                         sInsertPrefSheetRulesAt, &index);
-  }
-
-  return rv;
-}
-
-nsresult PresShell::SetPrefFocusRules(void)
-{
-  NS_ASSERTION(mPresContext,"null prescontext not allowed");
-  nsresult result = NS_OK;
-
-  if (!mPresContext)
-    result = NS_ERROR_FAILURE;
-
-  if (NS_SUCCEEDED(result) && !mPrefStyleSheet)
-    result = CreatePreferenceStyleSheet();
-
-  if (NS_SUCCEEDED(result)) {
-    NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
-
-    if (mPresContext->GetUseFocusColors()) {
-      nscolor focusBackground(mPresContext->FocusBackgroundColor());
-      nscolor focusText(mPresContext->FocusTextColor());
-
-      // insert a rule to make focus the preferred color
-      uint32_t index = 0;
-      nsAutoString strRule, strColor;
-
-      ///////////////////////////////////////////////////////////////
-      // - focus: '*:focus
-      ColorToString(focusText,strColor);
-      strRule.AppendLiteral("*:focus,*:focus>font {color: ");
-      strRule.Append(strColor);
-      strRule.AppendLiteral(" !important; background-color: ");
-      ColorToString(focusBackground,strColor);
-      strRule.Append(strColor);
-      strRule.AppendLiteral(" !important; } ");
-      // insert the rules
-      result = mPrefStyleSheet->
-        InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
-    }
-    uint8_t focusRingWidth = mPresContext->FocusRingWidth();
-    bool focusRingOnAnything = mPresContext->GetFocusRingOnAnything();
-    uint8_t focusRingStyle = mPresContext->GetFocusRingStyle();
-
-    if ((NS_SUCCEEDED(result) && focusRingWidth != 1 && focusRingWidth <= 4 ) || focusRingOnAnything) {
-      uint32_t index = 0;
-      nsAutoString strRule;
-      if (!focusRingOnAnything)
-        strRule.AppendLiteral("*|*:link:focus, *|*:visited");    // If we only want focus rings on the normal things like links
-      strRule.AppendLiteral(":focus {outline: ");     // For example 3px dotted WindowText (maximum 4)
-      strRule.AppendInt(focusRingWidth);
-      if (focusRingStyle == 0) // solid
-        strRule.AppendLiteral("px solid -moz-mac-focusring !important; -moz-outline-radius: 3px; outline-offset: 1px; } ");
-      else // dotted
-        strRule.AppendLiteral("px dotted WindowText !important; } ");
-      // insert the rules
-      result = mPrefStyleSheet->
-        InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
-      NS_ENSURE_SUCCESS(result, result);
-      if (focusRingWidth != 1) {
-        // If the focus ring width is different from the default, fix buttons with rings
-        strRule.AssignLiteral("button::-moz-focus-inner, input[type=\"reset\"]::-moz-focus-inner,");
-        strRule.AppendLiteral("input[type=\"button\"]::-moz-focus-inner, ");
-        strRule.AppendLiteral("input[type=\"submit\"]::-moz-focus-inner { padding: 1px 2px 1px 2px; border: ");
-        strRule.AppendInt(focusRingWidth);
-        if (focusRingStyle == 0) // solid
-          strRule.AppendLiteral("px solid transparent !important; } ");
-        else
-          strRule.AppendLiteral("px dotted transparent !important; } ");
-        result = mPrefStyleSheet->
-          InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
-        NS_ENSURE_SUCCESS(result, result);
-
-        strRule.AssignLiteral("button:focus::-moz-focus-inner, input[type=\"reset\"]:focus::-moz-focus-inner,");
-        strRule.AppendLiteral("input[type=\"button\"]:focus::-moz-focus-inner, input[type=\"submit\"]:focus::-moz-focus-inner {");
-        strRule.AppendLiteral("border-color: ButtonText !important; }");
-        result = mPrefStyleSheet->
-          InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
-      }
-    }
-  }
-  return result;
+  }
 }
 
 void
 PresShell::AddUserSheet(nsISupports* aSheet)
 {
   // Make sure this does what nsDocumentViewer::CreateStyleSet does wrt
   // ordering. We want this new sheet to come after all the existing stylesheet
   // service sheets, but before other user sheets; see nsIStyleSheetService.idl
@@ -10742,26 +10450,16 @@ void ReflowCountMgr::DisplayDiffsInTotal
   }
   PL_HashTableEnumerateEntries(mCounts, DoDisplayDiffTotals, (void *)mCycledOnce);
 
   mCycledOnce = true;
 }
 
 #endif // MOZ_REFLOW_PERF
 
-// make a color string like #RRGGBB
-void ColorToString(nscolor aColor, nsAutoString &aString)
-{
-  char buf[8];
-
-  PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x",
-              NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor));
-  CopyASCIItoUTF16(buf, aString);
-}
-
 nsIFrame* nsIPresShell::GetAbsoluteContainingBlock(nsIFrame *aFrame)
 {
   return FrameConstructor()->GetAbsoluteContainingBlock(aFrame,
       nsCSSFrameConstructor::ABS_POS);
 }
 
 #ifdef ACCESSIBILITY
 bool
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -83,17 +83,17 @@ public:
   static bool BeforeAfterKeyboardEventEnabled();
 
   void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
             nsViewManager* aViewManager, nsStyleSet* aStyleSet,
             nsCompatibility aCompatMode);
   virtual void Destroy() override;
   virtual void MakeZombie() override;
 
-  virtual nsresult SetPreferenceStyleRules(bool aForceReflow) override;
+  virtual void UpdatePreferenceStyles() override;
 
   NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection) override;
   virtual mozilla::dom::Selection* GetCurrentSelection(SelectionType aType) override;
 
   NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
   NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
   NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion,
                                      int16_t aFlags) override;
@@ -509,26 +509,17 @@ protected:
   nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
   bool VerifyIncrementalReflow();
   bool mInVerifyReflow;
   void ShowEventTargetDebug();
 #endif
 
   void RecordStyleSheetChange(nsIStyleSheet* aStyleSheet);
 
-    /**
-    * methods that manage rules that are used to implement the associated preferences
-    *  - initially created for bugs 31816, 20760, 22963
-    */
-  nsresult ClearPreferenceStyleRules(void);
-  nsresult CreatePreferenceStyleSheet(void);
-  nsresult SetPrefLinkRules(void);
-  nsresult SetPrefFocusRules(void);
-  nsresult SetPrefNoScriptRule();
-  nsresult SetPrefNoFramesRule(void);
+  void RemovePreferenceStyles();
 
   // methods for painting a range to an offscreen buffer
 
   // given a display list, clip the items within the list to
   // the range
   nsRect ClipListToRange(nsDisplayListBuilder *aBuilder,
                          nsDisplayList* aList,
                          nsRange* aRange);
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -89,20 +89,16 @@
 #ifdef MOZ_WEBSPEECH
 #include "nsSynthVoiceRegistry.h"
 #endif
 
 #ifdef MOZ_ANDROID_OMX
 #include "AndroidMediaPluginHost.h"
 #endif
 
-#ifdef MOZ_WMF
-#include "WMFDecoder.h"
-#endif
-
 #ifdef MOZ_GSTREAMER
 #include "GStreamerFormatHelper.h"
 #endif
 
 #ifdef MOZ_FFMPEG
 #include "FFmpegRuntimeLinker.h"
 #endif
 
@@ -400,20 +396,16 @@ nsLayoutStatics::Shutdown()
 #ifdef MOZ_FFMPEG
   FFmpegRuntimeLinker::Unlink();
 #endif
 
   CubebUtils::ShutdownLibrary();
   AsyncLatencyLogger::ShutdownLogger();
   WebAudioUtils::Shutdown();
 
-#ifdef MOZ_WMF
-  WMFDecoder::UnloadDLLs();
-#endif
-
 #ifdef MOZ_WIDGET_GONK
   nsVolumeService::Shutdown();
   SpeakerManagerService::Shutdown();
 #endif
 
 #ifdef MOZ_WEBSPEECH
   nsSynthVoiceRegistry::Shutdown();
 #endif
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -3,23 +3,23 @@
 /* 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/. */
 
 /* state used in reflow of block frames */
 
 #include "nsBlockReflowState.h"
 
-#include "mozilla/DebugOnly.h"
-
+#include "LayoutLogging.h"
 #include "nsBlockFrame.h"
 #include "nsLineLayout.h"
 #include "nsPresContext.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
 
 #ifdef DEBUG
 #include "nsBlockDebugFlags.h"
 #endif
 
 using namespace mozilla;
@@ -107,20 +107,20 @@ nsBlockReflowState::nsBlockReflowState(c
     mFloatManager->GetTranslation(mFloatManagerI, mFloatManagerB);
     mFloatManager->PushState(&mFloatManagerStateBefore); // never popped
   }
 
   mReflowStatus = NS_FRAME_COMPLETE;
 
   mNextInFlow = static_cast<nsBlockFrame*>(mBlock->GetNextInFlow());
 
-  NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedISize(),
-                   "have unconstrained width; this should only result from "
-                   "very large sizes, not attempts at intrinsic width "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedISize(),
+                       "have unconstrained width; this should only result "
+                       "from very large sizes, not attempts at intrinsic "
+                       "width calculation");
   mContentArea.ISize(wm) = aReflowState.ComputedISize();
 
   // Compute content area height. Unlike the width, if we have a
   // specified style height we ignore it since extra content is
   // managed by the "overflow" property. When we don't have a
   // specified style height then we may end up limiting our height if
   // the availableHeight is constrained (this situation occurs when we
   // are paginated).
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 /* struct containing the input to nsIFrame::Reflow */
 
 #include "nsHTMLReflowState.h"
 
+#include "LayoutLogging.h"
 #include "nsStyleConsts.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsFrame.h"
 #include "nsIContent.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsFontMetrics.h"
@@ -352,20 +353,20 @@ nsHTMLReflowState::Init(nsPresContext*  
       if (parent->GetWritingMode().IsOrthogonalTo(mWritingMode) &&
           parent->mOrthogonalLimit != NS_UNCONSTRAINEDSIZE) {
         AvailableISize() = parent->mOrthogonalLimit;
         break;
       }
     }
   }
 
-  NS_WARN_IF_FALSE(AvailableISize() != NS_UNCONSTRAINEDSIZE,
-                   "have unconstrained inline-size; this should only result from "
-                   "very large sizes, not attempts at intrinsic inline-size "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(AvailableISize() != NS_UNCONSTRAINEDSIZE,
+                       "have unconstrained inline-size; this should only "
+                       "result from very large sizes, not attempts at "
+                       "intrinsic inline-size calculation");
 
   mStylePosition = frame->StylePosition();
   mStyleDisplay = frame->StyleDisplay();
   mStyleVisibility = frame->StyleVisibility();
   mStyleBorder = frame->StyleBorder();
   mStyleMargin = frame->StyleMargin();
   mStylePadding = frame->StylePadding();
   mStyleText = frame->StyleText();
@@ -441,23 +442,23 @@ nsHTMLReflowState::Init(nsPresContext*  
 
   if (AvailableBSize() != NS_UNCONSTRAINEDSIZE && parentReflowState &&
       parentReflowState->GetWritingMode().IsOrthogonalTo(mWritingMode)) {
     // Orthogonal frames are always reflowed with unconstrained block-size,
     // to avoid incomplete reflow across an orthogonal boundary.
     AvailableBSize() = NS_UNCONSTRAINEDSIZE;
   }
 
-  NS_WARN_IF_FALSE((mFrameType == NS_CSS_FRAME_TYPE_INLINE &&
-                    !frame->IsFrameOfType(nsIFrame::eReplaced)) ||
-                   type == nsGkAtoms::textFrame ||
-                   ComputedISize() != NS_UNCONSTRAINEDSIZE,
-                   "have unconstrained inline-size; this should only result from "
-                   "very large sizes, not attempts at intrinsic inline-size "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE((mFrameType == NS_CSS_FRAME_TYPE_INLINE &&
+                        !frame->IsFrameOfType(nsIFrame::eReplaced)) ||
+                       type == nsGkAtoms::textFrame ||
+                       ComputedISize() != NS_UNCONSTRAINEDSIZE,
+                       "have unconstrained inline-size; this should only "
+                       "result from very large sizes, not attempts at "
+                       "intrinsic inline-size calculation");
 }
 
 void nsHTMLReflowState::InitCBReflowState()
 {
   if (!parentReflowState) {
     mCBReflowState = nullptr;
     return;
   }
@@ -2448,21 +2449,21 @@ nsHTMLReflowState::CalculateBlockSideMar
   nscoord availISizeCBWM = AvailableSize(cbWM).ISize(cbWM);
   nscoord computedISizeCBWM = ComputedSize(cbWM).ISize(cbWM);
   if (computedISizeCBWM == NS_UNCONSTRAINEDSIZE) {
     // For orthogonal flows, where we found a parent orthogonal-limit
     // for AvailableISize() in Init(), we'll use the same here as well.
     computedISizeCBWM = availISizeCBWM;
   }
 
-  NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != computedISizeCBWM &&
-                   NS_UNCONSTRAINEDSIZE != availISizeCBWM,
-                   "have unconstrained inline-size; this should only result from "
-                   "very large sizes, not attempts at intrinsic inline-size "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != computedISizeCBWM &&
+                       NS_UNCONSTRAINEDSIZE != availISizeCBWM,
+                       "have unconstrained inline-size; this should only "
+                       "result from very large sizes, not attempts at "
+                       "intrinsic inline-size calculation");
 
   LogicalMargin margin =
     ComputedLogicalMargin().ConvertTo(cbWM, mWritingMode);
   LogicalMargin borderPadding =
     ComputedLogicalBorderPadding().ConvertTo(cbWM, mWritingMode);
   nscoord sum = margin.IStartEnd(cbWM) +
     borderPadding.IStartEnd(cbWM) + computedISizeCBWM;
   if (sum == availISizeCBWM) {
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -5,16 +5,17 @@
 
 /* state and methods used while laying out a single line of a block frame */
 
 // This has to be defined before nsLineLayout.h is included, because
 // nsLineLayout.h has a #include for plarena.h, which needs this defined:
 #define PL_ARENA_CONST_ALIGN_MASK (sizeof(void*)-1)
 #include "nsLineLayout.h"
 
+#include "LayoutLogging.h"
 #include "SVGTextFrame.h"
 #include "nsBlockFrame.h"
 #include "nsFontMetrics.h"
 #include "nsStyleConsts.h"
 #include "nsContainerFrame.h"
 #include "nsFloatManager.h"
 #include "nsStyleContext.h"
 #include "nsPresContext.h"
@@ -149,20 +150,20 @@ void
 nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord,
                               nscoord aISize, nscoord aBSize,
                               bool aImpactedByFloats,
                               bool aIsTopOfPage,
                               WritingMode aWritingMode,
                               const nsSize& aContainerSize)
 {
   NS_ASSERTION(nullptr == mRootSpan, "bad linelayout user");
-  NS_WARN_IF_FALSE(aISize != NS_UNCONSTRAINEDSIZE,
-                   "have unconstrained width; this should only result from "
-                   "very large sizes, not attempts at intrinsic width "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(aISize != NS_UNCONSTRAINEDSIZE,
+                       "have unconstrained width; this should only result from "
+                       "very large sizes, not attempts at intrinsic width "
+                       "calculation");
 #ifdef DEBUG
   if ((aISize != NS_UNCONSTRAINEDSIZE) && CRAZY_SIZE(aISize)) {
     nsFrame::ListTag(stdout, mBlockReflowState->frame);
     printf(": Init: bad caller: width WAS %d(0x%x)\n",
            aISize, aISize);
   }
   if ((aBSize != NS_UNCONSTRAINEDSIZE) && CRAZY_SIZE(aBSize)) {
     nsFrame::ListTag(stdout, mBlockReflowState->frame);
@@ -873,20 +874,20 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
 
   // Figure out whether we're talking about a textframe here
   nsIAtom* frameType = aFrame->GetType();
   bool isText = frameType == nsGkAtoms::textFrame;
   
   // Inline-ish and text-ish things don't compute their width;
   // everything else does.  We need to give them an available width that
   // reflects the space left on the line.
-  NS_WARN_IF_FALSE(psd->mIEnd != NS_UNCONSTRAINEDSIZE,
-                   "have unconstrained width; this should only result from "
-                   "very large sizes, not attempts at intrinsic width "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(psd->mIEnd != NS_UNCONSTRAINEDSIZE,
+                      "have unconstrained width; this should only result from "
+                      "very large sizes, not attempts at intrinsic width "
+                      "calculation");
   nscoord availableSpaceOnLine = psd->mIEnd - psd->mICoord;
 
   // Setup reflow state for reflowing the frame
   Maybe<nsHTMLReflowState> reflowStateHolder;
   if (!isText) {
     // Compute the available size for the frame. This available width
     // includes room for the side margins.
     // For now, set the available block-size to unconstrained always.
@@ -3047,20 +3048,20 @@ nsLineLayout::TextAlignLine(nsLineBox* a
                             bool aIsLastLine)
 {
   /**
    * NOTE: aIsLastLine ain't necessarily so: it is correctly set by caller
    * only in cases where the last line needs special handling.
    */
   PerSpanData* psd = mRootSpan;
   WritingMode lineWM = psd->mWritingMode;
-  NS_WARN_IF_FALSE(psd->mIEnd != NS_UNCONSTRAINEDSIZE,
-                   "have unconstrained width; this should only result from "
-                   "very large sizes, not attempts at intrinsic width "
-                   "calculation");
+  LAYOUT_WARN_IF_FALSE(psd->mIEnd != NS_UNCONSTRAINEDSIZE,
+                       "have unconstrained width; this should only result from "
+                       "very large sizes, not attempts at intrinsic width "
+                       "calculation");
   nscoord availISize = psd->mIEnd - psd->mIStart;
   nscoord remainingISize = availISize - aLine->ISize();
 #ifdef NOISY_INLINEDIR_ALIGN
   nsFrame::ListTag(stdout, mBlockReflowState->frame);
   printf(": availISize=%d lineBounds.IStart=%d lineISize=%d delta=%d\n",
          availISize, aLine->IStart(), aLine->ISize(), remainingISize);
 #endif
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1169331-1-ref.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8">
+<title>Rotated buffer with mask</title>
+
+<style>
+
+body {
+  margin: 0;
+}
+
+.outer {
+  padding: 50px;
+}
+
+.scrollbox {
+  width: 200px;
+  height: 200px;
+  overflow: auto;
+}
+
+.scrolled {
+  box-sizing: border-box;
+  border: 1px solid transparent;
+  height: 200px;
+}
+
+</style>
+
+<div class="outer">
+
+  <div class="scrollbox">
+    <div class="scrolled" style="background-color: blue;"></div>
+    <div class="scrolled" style="background-color: lime;"></div>
+  </div>
+
+</div>
+
+<script>
+
+var scrollbox = document.querySelector(".scrollbox");
+
+scrollbox.scrollTop = 199;
+
+</script>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1169331-1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html lang="en" class="reftest-wait">
+<meta charset="utf-8">
+<title>Rotated buffer with mask</title>
+
+<style>
+
+body {
+  margin: 0;
+}
+
+.outer {
+  overflow: hidden;
+  border-radius: 10px;
+  padding: 50px;
+}
+
+.scrollbox {
+  width: 200px;
+  height: 200px;
+  overflow: auto;
+}
+
+.scrolled {
+  box-sizing: border-box;
+  border: 1px solid transparent;
+  height: 200px;
+}
+
+</style>
+
+<div class="outer">
+
+  <div class="scrollbox">
+    <div class="scrolled" style="background-color: blue;"></div>
+    <div class="scrolled" style="background-color: lime;"></div>
+  </div>
+
+</div>
+
+<script>
+
+var scrollbox = document.querySelector(".scrollbox");
+
+scrollbox.scrollTop = 1;
+scrollbox.scrollTop = 0;
+
+window.addEventListener("MozReftestInvalidate", function (e) {
+  scrollbox.scrollTop = 199;
+  document.documentElement.removeAttribute("class");
+});
+
+</script>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1174332-1-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8">
+<title>Testcase for filters on canvas</title>
+
+<style>
+
+#checkbox {
+  filter: url(#filter);
+}
+
+</style>
+
+<svg style="display: block; height: 0;">
+
+  <defs>
+    <filter id="filter" color-interpolation-filters="sRGB" x="-100%" y="-100%" width="300%" height="300%">
+      <feMorphology operator="dilate" radius="5" in="SourceAlpha" result="mask"/>
+      <feFlood flood-color="blue"/>
+      <feComposite operator="in" in2="mask"/>
+      <feMerge>
+        <feMergeNode/>
+        <feMergeNode in="SourceGraphic"/>
+      </feMerge>
+    </filter>
+  </defs>
+
+</svg>
+
+<input type="checkbox" id="checkbox">
+
+<script>
+
+document.getElementById("checkbox").focus();
+
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1174332-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8">
+<title>Testcase for filters on canvas</title>
+
+<style>
+
+#checkbox {
+  box-shadow: 0 0 0 5px blue;
+}
+
+</style>
+
+<input type="checkbox" id="checkbox">
+
+<script>
+
+document.getElementById("checkbox").focus();
+
+</script>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -420,17 +420,17 @@ skip-if((B2G&&browserIsRemote)||Mulet) =
 == 322436-1.html 322436-1-ref.html
 == 322461-1.xml 322461-1-ref.html
 == 323656-1.html 323656-1-ref.html
 == 323656-2.html 323656-2-ref.html
 == 323656-3.html 323656-3-ref.html
 == 323656-4.html 323656-4-ref.html
 == 323656-5.svg 323656-5-ref.svg
 == 323656-6.html 323656-6-ref.html
-fuzzy-if(Android,2,140) == 325292-1.html 325292-1-ref.html
+fuzzy-if(Android,5,283) == 325292-1.html 325292-1-ref.html
 == 325486-1.html 325486-1-ref.html
 == 328111-1.html 328111-1-ref.html
 random == 328829-1.xhtml 328829-1-ref.xhtml # bug 369046 (intermittent)
 == 328829-2.xhtml 328829-2-ref.xhtml
 == 329359-1.html 329359-1-ref.html
 == 331809-1.html 331809-1-ref.html # bug 580499 is blacked out
 == 332360.html 332360-ref.html
 == 332360-ltr.html 332360-ltr-ref.html
@@ -690,17 +690,17 @@ skip-if(B2G||Mulet) == 378937-1.html 378
 == 379316-1.html 379316-1-ref.html
 skip-if(B2G||Mulet) fails-if(Android) random-if(cocoaWidget) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,170) fuzzy-if(gtkWidget,1,191) == 379316-2.html 379316-2-ref.html # bug 379786 # Initial mulet triage: parity with B2G/B2G Desktop
 == 379328-1.html 379328-1-ref.html
 == 379349-1a.xhtml 379349-1-ref.xhtml
 == 379349-1b.xhtml 379349-1-ref.xhtml
 == 379349-1c.xhtml 379349-1-ref.xhtml
 == 379349-2a.xhtml 379349-2-ref.xhtml
 == 379349-2b.xhtml 379349-2-ref.xhtml
-skip-if(B2G||Mulet) fuzzy-if(Android,2,140) == 379349-3a.xhtml 379349-3-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet) fuzzy-if(Android,5,283) == 379349-3a.xhtml 379349-3-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fuzzy-if(Android,2,140) == 379349-3b.xhtml 379349-3-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop
 == 379361-1.html 379361-1-ref.html
 == 379361-2.html 379361-2-ref.html
 == 379361-3.html 379361-3-ref.html
 == 379461-1.xhtml 379461-1.html
 == 379461-2.xhtml 379461-2.html
 skip-if(B2G||Mulet) == 379461-3-container-xhtml.html 379461-3-container-html.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fails-if(Android) != 379461-3-container-xhtml.html 379461-3-container-blank.html # there is a scrollbar # Initial mulet triage: parity with B2G/B2G Desktop
@@ -812,17 +812,17 @@ skip-if((B2G&&browserIsRemote)||Mulet) =
 == 395107-3.html 395107-3-ref.html
 == 395107-4.html 395107-4-ref.html
 == 395107-5.html 395107-5-ref.html
 == 395130-1.html 395130-1-ref.html
 == 395130-2.html 395130-2-ref.html
 skip-if((B2G&&browserIsRemote)||Mulet) == 395331-1.xml 395331-1-ref.xml # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
 == 395390-1.html 395390-1-ref.html
 == 396286-1.html about:blank  # crash test
-fuzzy-if(Android,2,140) == 397428-1.html 397428-1-ref.html
+fuzzy-if(Android,5,283) == 397428-1.html 397428-1-ref.html
 == 397844-1.xhtml 397844-1-ref.xhtml
 == 398092-1.html 398092-1-ref.html
 == 398101-1.html 398101-1-ref.html
 == 398144-1.html 398144-1-ref.html
 == 398682-1.html 398682-1-ref.html
 == 398797-1a.html 398797-1-ref.html
 == 398797-1b.html 398797-1-ref.html
 == 398797-1c.html 398797-1-ref.html
@@ -1399,30 +1399,30 @@ skip-if(B2G||Mulet) == 502447-1.html 502
 == 502942-1.html 502942-1-ref.html
 == 503364-1a.html 503364-1-ref.html
 == 503364-1b.html 503364-1-ref.html
 # Reftest for bug 503531 marked as failing; should be re-enabled when
 # bug 607548 gets resolved.
 needs-focus fails == 503531-1.html 503531-1-ref.html
 == 504032-1.html 504032-1-ref.html
 == 505743-1.html about:blank
-skip-if(B2G||Mulet) fuzzy-if(Android,5,2800) == 506481-1.html 506481-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet) fuzzy-if(Android,5,2806) == 506481-1.html 506481-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == 507187-1.html 507187-1-ref.html
 == 507487-1.html 507487-1-ref.html
 == 507487-2.xhtml 507487-2-ref.xhtml
 == 507762-1.html 507762-1-ref.html
 == 507762-2.html 507762-2-ref.html
 == 507762-3.html 507762-1-ref.html
 == 507762-4.html 507762-2-ref.html
 skip-if(B2G||Mulet) random-if(cocoaWidget) == 508816-1.xul 508816-1-ref.xul # Bug 631982 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) == 508816-2.html 508816-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) == 508908-1.xul 508908-1-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
 == 508919-1.xhtml 508919-1-ref.xhtml
 == 509155-1.xhtml 509155-1-ref.xhtml
-skip-if(B2G||Mulet) fuzzy-if(Android,5,1656) == 512410.html 512410-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet) fuzzy-if(Android,5,2555) == 512410.html 512410-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == 512631-1.html 512631-1-ref.html
 == 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) != 513318-2.xul 513318-2-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 == 514917-1.html 514917-1-ref.html
@@ -1653,19 +1653,19 @@ fuzzy-if(Android&&AndroidVersion>=15,8,3
 == 630835-1.html about:blank
 == 631352-1.html 631352-1-ref.html
 skip-if(!haveTestPlugin) skip-if(B2G||Mulet) fails-if(Android) fuzzy-if(winWidget&&!layersGPUAccelerated,102,535)  == 632423-1.html 632423-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(Android||B2G||Mulet) random-if(winWidget) == 632781-verybig.html 632781-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == 632781-normalsize.html 632781-ref.html
 fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,559) == 633344-1.html 633344-1-ref.html # bug 1103623
 == 634232-1.html 634232-1-ref.html
 fails-if(Android&&AndroidVersion<17&&AndroidVersion!=10) == 635302-1.html 635302-1-ref.html
-fuzzy(1,68) skip-if(B2G||Mulet) fails-if(Android) == 635373-1.html 635373-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
-skip-if(B2G||Mulet) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,61) == 635373-2.html 635373-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
-skip-if(B2G||Mulet) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,60) == 635373-3.html 635373-3-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+fuzzy(1,68) skip-if(B2G||Mulet) == 635373-1.html 635373-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet) random-if(d2d) fuzzy-if(winWidget&&!d2d,1,61) == 635373-2.html 635373-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet) random-if(d2d) fuzzy-if(winWidget&&!d2d,1,60) == 635373-3.html 635373-3-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 HTTP(..) == 635639-1.html 635639-1-ref.html
 HTTP(..) == 635639-2.html 635639-2-ref.html
 random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed!
 fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-1.html 637852-1-ref.html
 fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-2.html 637852-2-ref.html
 fuzzy-if(Android&&AndroidVersion>=15,8,500) == 637852-3.html 637852-3-ref.html
 skip-if(B2G||Mulet) == 641770-1.html 641770-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == 641856-1.html 641856-1-ref.html
@@ -1920,8 +1920,10 @@ skip-if(!asyncPanZoom) fuzzy-if(B2G,23,1
 skip-if(!asyncPanZoom) == 1133905-4-vh-rtl.html 1133905-ref-vh-rtl.html
 skip-if(!asyncPanZoom) fuzzy-if(B2G,102,577) == 1133905-5-vh-rtl.html 1133905-ref-vh-rtl.html
 skip-if(!asyncPanZoom) fuzzy-if(B2G,101,887) == 1133905-6-vh-rtl.html 1133905-ref-vh-rtl.html
 skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul
 == 1151145-1.html 1151145-1-ref.html
 == 1151306-1.html 1151306-1-ref.html
 == 1153845-1.html 1153845-1-ref.html
 == 1156129-1.html 1156129-1-ref.html
+== 1169331-1.html 1169331-1-ref.html
+fuzzy(1,74) == 1174332-1.html 1174332-1-ref.html
--- a/layout/reftests/css-blending/reftest.list
+++ b/layout/reftests/css-blending/reftest.list
@@ -79,14 +79,14 @@ pref(layout.css.background-blend-mode.en
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-origin-border-box.html background-blending-background-origin-ref.html
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-origin-content-box.html background-blending-background-origin-ref.html
 
 # Test plan 5.3.11 background-blend-mode for an element with background-attachement
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed.html background-blending-background-attachement-fixed-ref.html
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html
 
 pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html
-pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
+fuzzy-if(Android,4,768) pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
 
 pref(layout.css.background-blend-mode.enabled,true) == background-blending-moz-element.html background-blending-moz-element-ref.html
 
 # Test plan 4.4.2 element with isolation:isolate creates an isolated group for blended children
 pref(layout.css.isolation.enabled,true) == blend-isolation.html blend-isolation-ref.html
--- a/layout/reftests/css-break/reftest.list
+++ b/layout/reftests/css-break/reftest.list
@@ -1,9 +1,9 @@
 default-preferences pref(layout.css.box-decoration-break.enabled,true)
 
 == box-decoration-break-1.html box-decoration-break-1-ref.html
 fuzzy(1,20) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
-fuzzy(16,460) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html
+fuzzy(16,460) fuzzy-if(Android,10,3667) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html
 random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html
 == box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html
 == box-decoration-break-block-margin.html box-decoration-break-block-margin-ref.html
-== box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html
+fuzzy-if(Android,8,6627) == box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html
--- a/layout/reftests/css-display/reftest.list
+++ b/layout/reftests/css-display/reftest.list
@@ -1,26 +1,26 @@
 # Tests for CSS Display spec features.
 # http://dev.w3.org/csswg/css-display
 
-pref(layout.css.display-contents.enabled,true) == display-contents-acid.html display-contents-acid-ref.html
-pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-1.html display-contents-acid-ref.html
-pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-2.html display-contents-acid-ref.html
-pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-3.html display-contents-acid-ref.html
+fuzzy-if(Android,8,604) pref(layout.css.display-contents.enabled,true) == display-contents-acid.html display-contents-acid-ref.html
+fuzzy-if(Android,8,604) pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-1.html display-contents-acid-ref.html
+fuzzy-if(Android,8,604) pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-2.html display-contents-acid-ref.html
+fuzzy-if(Android,8,604) pref(layout.css.display-contents.enabled,true) == display-contents-acid-dyn-3.html display-contents-acid-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-generated-content.html display-contents-generated-content-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-generated-content-2.html display-contents-generated-content-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-style-inheritance-1.html display-contents-style-inheritance-1-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-style-inheritance-1-stylechange.html display-contents-style-inheritance-1-ref.html
 pref(layout.css.display-contents.enabled,true) fuzzy-if(winWidget,12,100) == display-contents-style-inheritance-1-dom-mutations.html display-contents-style-inheritance-1-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-tables.xhtml display-contents-tables-ref.xhtml
 pref(layout.css.display-contents.enabled,true) == display-contents-tables-2.xhtml display-contents-tables-ref.xhtml
 pref(layout.css.display-contents.enabled,true) == display-contents-tables-3.xhtml display-contents-tables-3-ref.xhtml
 pref(layout.css.display-contents.enabled,true) == display-contents-visibility-hidden.html display-contents-visibility-hidden-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-visibility-hidden-2.html display-contents-visibility-hidden-ref.html
 pref(layout.css.display-contents.enabled,true) == display-contents-495385-2d.html display-contents-495385-2d-ref.html
-skip-if(B2G||Mulet) pref(layout.css.display-contents.enabled,true) == display-contents-xbl.xhtml display-contents-xbl-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
-pref(layout.css.display-contents.enabled,true) pref(dom.webcomponents.enabled,true) == display-contents-shadow-dom-1.html display-contents-shadow-dom-1-ref.html
+skip-if(B2G||Mulet) fuzzy-if(Android,7,3935) pref(layout.css.display-contents.enabled,true) == display-contents-xbl.xhtml display-contents-xbl-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+fuzzy-if(Android,7,1186) pref(layout.css.display-contents.enabled,true) pref(dom.webcomponents.enabled,true) == display-contents-shadow-dom-1.html display-contents-shadow-dom-1-ref.html
 skip-if(B2G||Mulet) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-2.xul display-contents-xbl-2-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-3.xul display-contents-xbl-3-ref.xul # bug 1089223 # Initial mulet triage: parity with B2G/B2G Desktop
 skip pref(layout.css.display-contents.enabled,true) == display-contents-xbl-4.xul display-contents-xbl-4-ref.xul # fails (not just asserts) due to bug 1089223
-asserts(0-1) pref(layout.css.display-contents.enabled,true) == display-contents-fieldset.html display-contents-fieldset-ref.html # bug 1089223
+asserts(0-1) fuzzy-if(Android,8,3216) pref(layout.css.display-contents.enabled,true) == display-contents-fieldset.html display-contents-fieldset-ref.html # bug 1089223
 skip-if(B2G||Mulet) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-5.xul display-contents-xbl-3-ref.xul # bug 1089223 # Initial mulet triage: parity with B2G/B2G Desktop
 pref(layout.css.display-contents.enabled,true) == display-contents-list-item-child.html display-contents-list-item-child-ref.html
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -47,56 +47,56 @@ fails-if(d2d) == linear-repeat-1g.html l
 == linear-stops-1f.html linear-stops-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1a.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1b.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,2,26777) == linear-vertical-1c.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,2,26777) == linear-vertical-1d.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1e.html linear-vertical-1-ref.html
 == linear-vertical-subpixel-1.html linear-vertical-subpixel-1-ref.html
 == linear-viewport.html linear-viewport-ref.html
-fails-if(OSX==1010) == linear-zero-length-1a.html linear-zero-length-1-ref.html
-fails-if(OSX==1010) == linear-zero-length-1b.html linear-zero-length-1-ref.html
+fails-if(OSX==1010) fuzzy-if(Android,4,248) == linear-zero-length-1a.html linear-zero-length-1-ref.html
+fails-if(OSX==1010) fuzzy-if(Android,4,248) == linear-zero-length-1b.html linear-zero-length-1-ref.html
 fails-if(OSX==1010) == linear-zero-length-1c.html linear-zero-length-1-ref.html
 == nostops.html about:blank
 == onestop.html about:blank
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1a.html radial-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1b.html radial-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1c.html radial-1-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2a.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2b.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2c.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2d.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2e.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2f.html radial-2-ref.html
 == radial-position-1a.html radial-position-1-ref.html
 fuzzy-if(cocoaWidget,1,28) fuzzy-if(winWidget,1,18) == radial-position-1b.html radial-position-1-ref.html
-fuzzy-if(cocoaWidget,4,22317) == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html
-fuzzy(1,238) fuzzy-if(cocoaWidget,3,460) fuzzy-if(cocoaWidget,4,22608) fuzzy-if(/^Windows\x20NT\x206\./.test(http.oscpu)&&d2d,1,336) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html
-fuzzy-if(azureQuartz,2,41171) == radial-shape-closest-corner-1c.html radial-shape-closest-corner-1-ref.html
+fuzzy-if(cocoaWidget,4,22317) fuzzy-if(Android,8,771) == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html
+fuzzy(1,238) fuzzy-if(cocoaWidget,4,22608) fuzzy-if(/^Windows\x20NT\x206\./.test(http.oscpu)&&d2d,1,336) fuzzy-if(Android,8,787) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html
+fuzzy-if(azureQuartz,2,41171) fuzzy-if(Android,8,771) == radial-shape-closest-corner-1c.html radial-shape-closest-corner-1-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1c.html radial-shape-closest-side-1-ref.html
-== radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
-fails-if(gtkWidget&&/x86_64-/.test(xulRuntime.XPCOMABI)) fuzzy(1,1569) fuzzy-if(cocoaWidget,2,41281) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html
-== radial-shape-farthest-corner-1c.html radial-shape-farthest-corner-1-ref.html
+fuzzy-if(Android,8,771) == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
+fails-if(gtkWidget&&/x86_64-/.test(xulRuntime.XPCOMABI)) fuzzy(1,1569) fuzzy-if(cocoaWidget,2,41281) fuzzy-if(Android,8,1091) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html
+fuzzy-if(Android,8,771) == radial-shape-farthest-corner-1c.html radial-shape-farthest-corner-1-ref.html
 fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html
 fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html
 fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1c.html radial-shape-farthest-side-1-ref.html
 == radial-size-1a.html radial-size-1-ref.html
 == radial-size-1b.html radial-size-1-ref.html
-== radial-zero-length-1a.html radial-zero-length-1-ref.html
-== radial-zero-length-1b.html radial-zero-length-1-ref.html
-== radial-zero-length-1c.html radial-zero-length-1-ref.html
-== radial-zero-length-1d.html radial-zero-length-1-ref.html
-== radial-zero-length-1e.html radial-zero-length-1-ref.html
-== radial-zero-length-1f.html radial-zero-length-1-ref.html
-== radial-zero-length-1g.html radial-zero-length-1-ref.html
-== radial-zero-length-1h.html radial-zero-length-1-ref.html
-== radial-zero-length-1i.html radial-zero-length-1-ref.html
-== radial-zero-length-1j.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1a.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1b.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1c.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1d.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1e.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1f.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1g.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1h.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1i.html radial-zero-length-1-ref.html
+fuzzy-if(Android,4,248) == radial-zero-length-1j.html radial-zero-length-1-ref.html
 == radial-premul.html radial-premul-ref.html
 == repeated-final-stop-1.html repeated-final-stop-1-ref.html
 == repeating-linear-1a.html repeating-linear-1-ref.html
 == repeating-linear-1b.html repeating-linear-1-ref.html
 == repeating-linear-2a.html repeating-linear-2-ref.html
 fuzzy-if(d2d,127,2612) == repeating-radial-1a.html repeating-radial-1-ref.html
 == repeating-radial-1b.html repeating-radial-1-ref.html
 fuzzy-if(d2d,127,2612) == repeating-radial-1c.html repeating-radial-1-ref.html
--- a/layout/reftests/text-overflow/reftest.list
+++ b/layout/reftests/text-overflow/reftest.list
@@ -1,15 +1,15 @@
 skip-if(B2G||Mulet) == ellipsis-font-fallback.html ellipsis-font-fallback-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == line-clipping.html line-clipping-ref.html
 fuzzy-if