Browse Source

Some more serviceworkers backports

Ian Neal 5 months ago
parent
commit
cc8adfdf2b
32 changed files with 9304 additions and 134 deletions
  1. 28 0
      comm-release/patches/1433388-60a1.patch
  2. 1 0
      comm-release/patches/series
  3. 2308 0
      mozilla-release/patches/1425458-0-60a1.patch
  4. 417 0
      mozilla-release/patches/1425458-1-60a1.patch
  5. 1575 0
      mozilla-release/patches/1425458-2-60a1.patch
  6. 793 0
      mozilla-release/patches/1425458-3-60a1.patch
  7. 50 0
      mozilla-release/patches/1425458-4-60a1.patch
  8. 51 0
      mozilla-release/patches/1425458-5-60a1.patch
  9. 72 0
      mozilla-release/patches/1425458-6-60a1.patch
  10. 197 0
      mozilla-release/patches/1425458-7no8or9-60a1.patch
  11. 2314 0
      mozilla-release/patches/1429014-59a1.patch
  12. 140 0
      mozilla-release/patches/1431847-1-60a1.patch
  13. 257 0
      mozilla-release/patches/1431847-2-60a1.patch
  14. 110 0
      mozilla-release/patches/1431847-3-60a1.patch
  15. 48 0
      mozilla-release/patches/1431847-4-60a1.patch
  16. 236 0
      mozilla-release/patches/1431847-5-60a1.patch
  17. 40 0
      mozilla-release/patches/1433044-1no2-60a1.patch
  18. 6 6
      mozilla-release/patches/1434686-4-60a1.patch
  19. 128 0
      mozilla-release/patches/1437080-2-fix-60a1.patch
  20. 28 0
      mozilla-release/patches/1437897-1no2-61a1.patch
  21. 119 0
      mozilla-release/patches/1439879-60a1.patch
  22. 5 3
      mozilla-release/patches/1443429-3-66a1.patch
  23. 8 8
      mozilla-release/patches/1465580-62a1.patch
  24. 267 72
      mozilla-release/patches/1465585-3-std-62a1.patch
  25. 19 12
      mozilla-release/patches/1467852-62a1.patch
  26. 34 0
      mozilla-release/patches/1485197-63a1.patch
  27. 3 3
      mozilla-release/patches/1515021-66a1.patch
  28. 3 3
      mozilla-release/patches/1519319-2-66a1.patch
  29. 2 2
      mozilla-release/patches/1542878-68a1.patch
  30. 22 22
      mozilla-release/patches/1750902-916.patch
  31. 4 3
      mozilla-release/patches/833098-1-62a1.patch
  32. 19 0
      mozilla-release/patches/series

+ 28 - 0
comm-release/patches/1433388-60a1.patch

@@ -0,0 +1,28 @@
+# HG changeset patch
+# User Jorg K <jorgk@jorgk.com>
+# Date 1516959845 -3600
+# Node ID ed0e5a9bf28a0d75b1c0618833bd9e319b6136f8
+# Parent  1cf1a10ead69a48b7a1407f908503aabbf52bfa0
+Bug 1433388 - Port 1425458 to mailnews: Add aPerformanceStorage argument to NS_NewChannel() call. rs=bustage-fix
+
+diff --git a/mailnews/compose/src/nsURLFetcher.cpp b/mailnews/compose/src/nsURLFetcher.cpp
+--- a/mailnews/compose/src/nsURLFetcher.cpp
++++ b/mailnews/compose/src/nsURLFetcher.cpp
+@@ -317,16 +317,17 @@ nsURLFetcher::FireURLRequest(nsIURI *aUR
+   NS_ENSURE_TRUE(pURILoader, NS_ERROR_FAILURE);
+ 
+   nsCOMPtr<nsIChannel> channel;
+   rv = NS_NewChannel(getter_AddRefs(channel),
+                      aURL,
+                      nsContentUtils::GetSystemPrincipal(),
+                      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                      nsIContentPolicy::TYPE_OTHER,
++                     nullptr, // aPerformanceStorage
+                      nullptr, // aLoadGroup
+                      this); // aCallbacks
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   return pURILoader->OpenURI(channel, false, this);
+ }
+ 
+ nsresult

+ 1 - 0
comm-release/patches/series

@@ -2156,3 +2156,4 @@ TOP-1872623-cancelbookmark-25319.patch
 9999999-about-seamonkey-25319.patch
 1437393-fontsasync-25319.patch
 1896174-checkbox-25319.patch
+1433388-60a1.patch

+ 2308 - 0
mozilla-release/patches/1425458-0-60a1.patch

@@ -0,0 +1,2308 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810651 -3600
+# Node ID 3758a68f961f153f82b643e6bf2727d5c5c63d67
+# Parent  e595551c9ea31e5036cc990781f85aeee4ca439f
+Bug 1425458 - Resource timing entries Workers - part 0 - NS_NewChannel, r=smaug
+* * *
+Bug 1425458 - Resource timing entries Workers - part 10 - Correct parameters in NS_NewChannel in nsDataObj.cpp, r=me
+
+diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
+--- a/docshell/base/nsDocShell.cpp
++++ b/docshell/base/nsDocShell.cpp
+@@ -10657,16 +10657,17 @@ nsDocShell::DoURILoad(nsIURI* aURI,
+   // can be exposed on the service worker FetchEvent.
+   rv = loadInfo->SetIsDocshellReload(mLoadType & LOAD_CMD_RELOAD);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   if (!isSrcdoc) {
+     rv = NS_NewChannelInternal(getter_AddRefs(channel),
+                                aURI,
+                                loadInfo,
++                               nullptr,   // PerformanceStorage
+                                nullptr,   // loadGroup
+                                static_cast<nsIInterfaceRequestor*>(this),
+                                loadFlags);
+ 
+     if (NS_FAILED(rv)) {
+       if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
+         // This is a uri with a protocol scheme we don't know how
+         // to handle.  Embedders might still be interested in
+diff --git a/docshell/base/nsPingListener.cpp b/docshell/base/nsPingListener.cpp
+--- a/docshell/base/nsPingListener.cpp
++++ b/docshell/base/nsPingListener.cpp
+@@ -104,16 +104,17 @@ SendPing(void* aClosure, nsIContent* aCo
+   nsCOMPtr<nsIChannel> chan;
+   NS_NewChannel(getter_AddRefs(chan),
+                 aURI,
+                 doc,
+                 info->requireSameHost
+                   ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED
+                   : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                 nsIContentPolicy::TYPE_PING,
++                nullptr,   // PerformanceStorage
+                 nullptr, // aLoadGroup
+                 nullptr, // aCallbacks
+                 nsIRequest::LOAD_NORMAL, // aLoadFlags,
+                 aIOService);
+ 
+   if (!chan) {
+     return;
+   }
+diff --git a/dom/base/EventSource.cpp b/dom/base/EventSource.cpp
+--- a/dom/base/EventSource.cpp
++++ b/dom/base/EventSource.cpp
+@@ -1034,26 +1034,28 @@ EventSourceImpl::InitChannelAndRequestEv
+   // If we have the document, use it
+   if (doc) {
+     nsCOMPtr<nsILoadGroup> loadGroup = doc->GetDocumentLoadGroup();
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        mSrc,
+                        doc,
+                        securityFlags,
+                        nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
++                       nullptr,          // aPerformanceStorage
+                        loadGroup,
+                        nullptr,          // aCallbacks
+                        loadFlags);       // aLoadFlags
+   } else {
+     // otherwise use the principal
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        mSrc,
+                        mPrincipal,
+                        securityFlags,
+                        nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
++                       nullptr,          // aPerformanceStorage
+                        nullptr,          // loadGroup
+                        nullptr,          // aCallbacks
+                        loadFlags);       // aLoadFlags
+   }
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   mHttpChannel = do_QueryInterface(channel);
+diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
+--- a/dom/base/Navigator.cpp
++++ b/dom/base/Navigator.cpp
+@@ -1117,16 +1117,17 @@ Navigator::SendBeaconInternal(const nsAS
+   securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
+ 
+   nsCOMPtr<nsIChannel> channel;
+   rv = NS_NewChannel(getter_AddRefs(channel),
+                      uri,
+                      doc,
+                      securityFlags,
+                      nsIContentPolicy::TYPE_BEACON,
++                     nullptr, // aPerformanceStorage
+                      nullptr, // aLoadGroup
+                      nullptr, // aCallbacks
+                      loadFlags);
+ 
+   if (NS_FAILED(rv)) {
+     aRv.Throw(rv);
+     return false;
+   }
+diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
+--- a/dom/base/nsDocument.cpp
++++ b/dom/base/nsDocument.cpp
+@@ -1162,16 +1162,17 @@ nsExternalResourceMap::PendingLoad::Star
+ 
+   nsresult rv = NS_OK;
+   nsCOMPtr<nsIChannel> channel;
+   rv = NS_NewChannel(getter_AddRefs(channel),
+                      aURI,
+                      aRequestingNode,
+                      nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
+                      nsIContentPolicy::TYPE_OTHER,
++                     nullptr, // aPerformanceStorage
+                      loadGroup);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   mURI = aURI;
+ 
+   return channel->AsyncOpen2(this);
+ }
+ 
+diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
+--- a/dom/base/nsObjectLoadingContent.cpp
++++ b/dom/base/nsObjectLoadingContent.cpp
+@@ -1814,16 +1814,17 @@ nsObjectLoadingContent::OpenChannel()
+ 
+   nsContentPolicyType contentPolicyType = GetContentPolicyType();
+ 
+   rv = NS_NewChannel(getter_AddRefs(chan),
+                      mURI,
+                      thisContent,
+                      securityFlags,
+                      contentPolicyType,
++                     nullptr, // aPerformanceStorage
+                      group, // aLoadGroup
+                      shim,  // aCallbacks
+                      nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
+                      nsIChannel::LOAD_CLASSIFY_URI |
+                      nsIChannel::LOAD_BYPASS_SERVICE_WORKER |
+                      nsIRequest::LOAD_HTML_OBJECT_DATA);
+   NS_ENSURE_SUCCESS(rv, rv);
+   if (inherit) {
+diff --git a/dom/base/nsSyncLoadService.cpp b/dom/base/nsSyncLoadService.cpp
+--- a/dom/base/nsSyncLoadService.cpp
++++ b/dom/base/nsSyncLoadService.cpp
+@@ -316,16 +316,17 @@ nsSyncLoadService::LoadDocument(nsIURI *
+                                 nsIDOMDocument** aResult)
+ {
+     nsCOMPtr<nsIChannel> channel;
+     nsresult rv = NS_NewChannel(getter_AddRefs(channel),
+                                 aURI,
+                                 aLoaderPrincipal,
+                                 aSecurityFlags,
+                                 aContentPolicyType,
++                                nullptr, // PerformanceStorage
+                                 aLoadGroup);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     if (!aForceToXML) {
+         channel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
+     }
+ 
+     bool isChrome = false, isResource = false;
+diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
+--- a/dom/fetch/Fetch.cpp
++++ b/dom/fetch/Fetch.cpp
+@@ -420,17 +420,19 @@ public:
+       MOZ_ASSERT(workerPrivate);
+       nsCOMPtr<nsIPrincipal> principal = workerPrivate->GetPrincipal();
+       MOZ_ASSERT(principal);
+       nsCOMPtr<nsILoadGroup> loadGroup = workerPrivate->GetLoadGroup();
+       MOZ_ASSERT(loadGroup);
+       // We don't track if a worker is spawned from a tracking script for now,
+       // so pass false as the last argument to FetchDriver().
+       fetch = new FetchDriver(mRequest, principal, loadGroup,
+-                              workerPrivate->MainThreadEventTarget(), false);
++                              workerPrivate->MainThreadEventTarget(),
++                              workerPrivate->GetPerformanceStorage(),
++                              false);
+       nsAutoCString spec;
+       if (proxy->GetWorkerPrivate()->GetBaseURI()) {
+         proxy->GetWorkerPrivate()->GetBaseURI()->GetAsciiSpec(spec);
+       }
+       fetch->SetWorkerScript(spec);
+ 
+       fetch->SetClientInfo(mClientInfo);
+       fetch->SetController(mController);
+@@ -522,17 +524,19 @@ FetchRequest(nsIGlobalObject* aGlobal, c
+         return nullptr;
+       }
+     }
+ 
+     RefPtr<MainThreadFetchResolver> resolver =
+       new MainThreadFetchResolver(p, observer, signal, request->MozErrors());
+     RefPtr<FetchDriver> fetch =
+       new FetchDriver(r, principal, loadGroup,
+-                      aGlobal->EventTargetFor(TaskCategory::Other), isTrackingFetch);
++                      aGlobal->EventTargetFor(TaskCategory::Other),
++                      nullptr, // PerformanceStorage
++                      isTrackingFetch);
+     fetch->SetDocument(doc);
+     resolver->SetLoadGroup(loadGroup);
+     aRv = fetch->Fetch(signal, resolver);
+     if (NS_WARN_IF(aRv.Failed())) {
+       return nullptr;
+     }
+   } else {
+     WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
+diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
+--- a/dom/fetch/FetchDriver.cpp
++++ b/dom/fetch/FetchDriver.cpp
+@@ -26,16 +26,17 @@
+ #include "nsNetUtil.h"
+ #include "nsPrintfCString.h"
+ #include "nsProxyRelease.h"
+ #include "nsStreamUtils.h"
+ #include "nsStringStream.h"
+ #include "nsHttpChannel.h"
+ 
+ #include "mozilla/dom/File.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozilla/dom/workers/Workers.h"
+ #include "mozilla/EventStateManager.h"
+ #include "mozilla/ipc/PBackgroundSharedTypes.h"
+ #include "mozilla/Unused.h"
+ 
+ #include "Fetch.h"
+ #include "FetchUtil.h"
+ #include "InternalRequest.h"
+@@ -320,23 +321,27 @@ AlternativeDataStreamListener::CheckList
+ //-----------------------------------------------------------------------------
+ // FetchDriver
+ //-----------------------------------------------------------------------------
+ 
+ NS_IMPL_ISUPPORTS(FetchDriver,
+                   nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
+                   nsIThreadRetargetableStreamListener)
+ 
+-FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
+-                         nsILoadGroup* aLoadGroup, nsIEventTarget* aMainThreadEventTarget,
++FetchDriver::FetchDriver(InternalRequest* aRequest,
++                         nsIPrincipal* aPrincipal,
++                         nsILoadGroup* aLoadGroup,
++                         nsIEventTarget* aMainThreadEventTarget,
++                         PerformanceStorage* aPerformanceStorage,
+                          bool aIsTrackingFetch)
+   : mPrincipal(aPrincipal)
+   , mLoadGroup(aLoadGroup)
+   , mRequest(aRequest)
+   , mMainThreadEventTarget(aMainThreadEventTarget)
++  , mPerformanceStorage(aPerformanceStorage)
+   , mNeedToObserveOnDataAvailable(false)
+   , mIsTrackingFetch(aIsTrackingFetch)
+ #ifdef DEBUG
+   , mResponseAvailableCalled(false)
+   , mFetchCalled(false)
+ #endif
+ {
+   AssertIsOnMainThread();
+@@ -508,38 +513,41 @@ FetchDriver::HttpFetch(const nsACString&
+     bypassFlag | nsIChannel::LOAD_CLASSIFY_URI;
+   if (mDocument) {
+     MOZ_ASSERT(mDocument->NodePrincipal() == mPrincipal);
+     rv = NS_NewChannel(getter_AddRefs(chan),
+                        uri,
+                        mDocument,
+                        secFlags,
+                        mRequest->ContentPolicyType(),
++                       nullptr, /* aPerformanceStorage */
+                        mLoadGroup,
+                        nullptr, /* aCallbacks */
+                        loadFlags,
+                        ios);
+   } else if (mClientInfo.isSome()) {
+     rv = NS_NewChannel(getter_AddRefs(chan),
+                        uri,
+                        mPrincipal,
+                        mClientInfo.ref(),
+                        mController,
+                        secFlags,
+                        mRequest->ContentPolicyType(),
++                       mPerformanceStorage,
+                        mLoadGroup,
+                        nullptr, /* aCallbacks */
+                        loadFlags,
+                        ios);
+   } else {
+     rv = NS_NewChannel(getter_AddRefs(chan),
+                        uri,
+                        mPrincipal,
+                        secFlags,
+                        mRequest->ContentPolicyType(),
++                       mPerformanceStorage,
+                        mLoadGroup,
+                        nullptr, /* aCallbacks */
+                        loadFlags,
+                        ios);
+   }
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   // Insert ourselves into the notification callbacks chain so we can set
+diff --git a/dom/fetch/FetchDriver.h b/dom/fetch/FetchDriver.h
+--- a/dom/fetch/FetchDriver.h
++++ b/dom/fetch/FetchDriver.h
+@@ -27,16 +27,17 @@ class nsIOutputStream;
+ class nsILoadGroup;
+ class nsIPrincipal;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class InternalRequest;
+ class InternalResponse;
++class PerformanceStorage;
+ 
+ /**
+  * Provides callbacks to be called when response is available or on error.
+  * Implemenations usually resolve or reject the promise returned from fetch().
+  * The callbacks can be called synchronously or asynchronously from FetchDriver::Fetch.
+  */
+ class FetchDriverObserver
+ {
+@@ -104,16 +105,17 @@ public:
+   NS_DECL_NSICHANNELEVENTSINK
+   NS_DECL_NSIINTERFACEREQUESTOR
+   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+ 
+   FetchDriver(InternalRequest* aRequest,
+               nsIPrincipal* aPrincipal,
+               nsILoadGroup* aLoadGroup,
+               nsIEventTarget* aMainThreadEventTarget,
++              PerformanceStorage* aPerformanceStorage,
+               bool aIsTrackingFetch);
+ 
+   nsresult Fetch(AbortSignal* aSignal,
+                  FetchDriverObserver* aObserver);
+ 
+   void
+   SetDocument(nsIDocument* aDocument);
+ 
+@@ -142,16 +144,20 @@ private:
+   nsCOMPtr<nsIOutputStream> mPipeOutputStream;
+   RefPtr<FetchDriverObserver> mObserver;
+   nsCOMPtr<nsIDocument> mDocument;
+   Maybe<ClientInfo> mClientInfo;
+   Maybe<ServiceWorkerDescriptor> mController;
+   nsCOMPtr<nsIChannel> mChannel;
+   nsAutoPtr<SRICheckDataVerifier> mSRIDataVerifier;
+   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
++
++  // This is set only when Fetch is used in workers.
++  RefPtr<PerformanceStorage> mPerformanceStorage;
++
+   SRIMetadata mSRIMetadata;
+   nsCString mWorkerScript;
+ 
+   // This is written once in OnStartRequest on the main thread and then
+   // written/read in OnDataAvailable() on any thread.  Necko guarantees
+   // that these do not overlap.
+   bool mNeedToObserveOnDataAvailable;
+ 
+diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
+--- a/dom/html/HTMLMediaElement.cpp
++++ b/dom/html/HTMLMediaElement.cpp
+@@ -1217,16 +1217,17 @@ public:
+     nsCOMPtr<nsIChannel> channel;
+     nsresult rv =
+       NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
+                                            aElement->mLoadingSrc,
+                                            static_cast<Element*>(aElement),
+                                            triggeringPrincipal,
+                                            securityFlags,
+                                            contentPolicyType,
++                                           nullptr,   // aPerformanceStorage
+                                            loadGroup,
+                                            nullptr,   // aCallbacks
+                                            nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
+                                            nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
+                                            nsIChannel::LOAD_CLASSIFY_URI |
+                                            nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
+ 
+     if (NS_FAILED(rv)) {
+diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
+--- a/dom/html/HTMLTrackElement.cpp
++++ b/dom/html/HTMLTrackElement.cpp
+@@ -322,16 +322,17 @@ HTMLTrackElement::LoadResource()
+ 
+   nsCOMPtr<nsIChannel> channel;
+   nsCOMPtr<nsILoadGroup> loadGroup = OwnerDoc()->GetDocumentLoadGroup();
+   rv = NS_NewChannel(getter_AddRefs(channel),
+                      uri,
+                      static_cast<Element*>(this),
+                      secFlags,
+                      nsIContentPolicy::TYPE_INTERNAL_TRACK,
++                     nullptr, // PerformanceStorage
+                      loadGroup,
+                      nullptr,   // aCallbacks
+                      nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI);
+ 
+   NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
+ 
+   mListener = new WebVTTListener(this);
+   rv = mListener->LoadResource();
+diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
+--- a/dom/html/nsHTMLDocument.cpp
++++ b/dom/html/nsHTMLDocument.cpp
+@@ -1598,16 +1598,17 @@ nsHTMLDocument::Open(JSContext* cx,
+   // So we reset the document and then reinitialize it.
+   nsCOMPtr<nsIChannel> channel;
+   nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
+   aError = NS_NewChannel(getter_AddRefs(channel),
+                          uri,
+                          callerDoc,
+                          nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                          nsIContentPolicy::TYPE_OTHER,
++                         nullptr, // PerformanceStorage
+                          group);
+ 
+   if (aError.Failed()) {
+     return nullptr;
+   }
+ 
+   if (callerChannel) {
+     nsLoadFlags callerLoadFlags;
+diff --git a/dom/media/ChannelMediaResource.cpp b/dom/media/ChannelMediaResource.cpp
+--- a/dom/media/ChannelMediaResource.cpp
++++ b/dom/media/ChannelMediaResource.cpp
+@@ -721,16 +721,17 @@ ChannelMediaResource::RecreateChannel()
+                                              getter_AddRefs(triggeringPrincipal));
+ 
+   nsresult rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(mChannel),
+                                                      mURI,
+                                                      element,
+                                                      triggeringPrincipal,
+                                                      securityFlags,
+                                                      contentPolicyType,
++                                                     nullptr, // aPerformanceStorage
+                                                      loadGroup,
+                                                      nullptr,  // aCallbacks
+                                                      loadFlags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   if (setAttrs) {
+     nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
+     if (loadInfo) {
+diff --git a/dom/performance/PerformanceStorage.h b/dom/performance/PerformanceStorage.h
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/PerformanceStorage.h
+@@ -0,0 +1,34 @@
++/* -*- 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/. */
++
++#ifndef mozilla_dom_PerformanceStorage_h
++#define mozilla_dom_PerformanceStorage_h
++
++#include "nsISupportsImpl.h"
++
++class nsIHttpChannel;
++class nsITimedChannel;
++
++namespace mozilla {
++namespace dom {
++
++class PerformanceStorage
++{
++public:
++  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
++
++  virtual void AddEntry(nsIHttpChannel* aChannel,
++                        nsITimedChannel* aTimedChannel) = 0;
++
++
++protected:
++  virtual ~PerformanceStorage() {}
++};
++
++} // namespace dom
++} // namespace mozilla
++
++#endif // mozilla_dom_PerformanceStorage_h
+diff --git a/dom/performance/moz.build b/dom/performance/moz.build
+--- a/dom/performance/moz.build
++++ b/dom/performance/moz.build
+@@ -13,16 +13,17 @@ EXPORTS.mozilla.dom += [
+     'PerformanceMark.h',
+     'PerformanceMeasure.h',
+     'PerformanceNavigation.h',
+     'PerformanceNavigationTiming.h',
+     'PerformanceObserver.h',
+     'PerformanceObserverEntryList.h',
+     'PerformanceResourceTiming.h',
+     'PerformanceService.h',
++    'PerformanceStorage.h',
+     'PerformanceTiming.h',
+ ]
+ 
+ UNIFIED_SOURCES += [
+     'Performance.cpp',
+     'PerformanceEntry.cpp',
+     'PerformanceMainThread.cpp',
+     'PerformanceMark.cpp',
+diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
+--- a/dom/script/ScriptLoader.cpp
++++ b/dom/script/ScriptLoader.cpp
+@@ -1047,16 +1047,17 @@ ScriptLoader::StartLoad(ScriptLoadReques
+   nsCOMPtr<nsIChannel> channel;
+   nsresult rv = NS_NewChannelWithTriggeringPrincipal(
+       getter_AddRefs(channel),
+       aRequest->mURI,
+       context,
+       aRequest->mTriggeringPrincipal,
+       securityFlags,
+       contentPolicyType,
++      nullptr, // aPerformanceStorage
+       loadGroup,
+       prompter,
+       nsIRequest::LOAD_NORMAL |
+       nsIChannel::LOAD_CLASSIFY_URI);
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   // To avoid decoding issues, the build-id is part of the JSBytecodeMimeType
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -1068,26 +1068,28 @@ nsCSPContext::SendReports(
+     // try to create a new channel for every report-uri
+     nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI;
+     if (doc) {
+       rv = NS_NewChannel(getter_AddRefs(reportChannel),
+                          reportURI,
+                          doc,
+                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                          nsIContentPolicy::TYPE_CSP_REPORT,
++                         nullptr, // aPerformanceStorage
+                          nullptr, // aLoadGroup
+                          nullptr, // aCallbacks
+                          loadFlags);
+     }
+     else {
+       rv = NS_NewChannel(getter_AddRefs(reportChannel),
+                          reportURI,
+                          mLoadingPrincipal,
+                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                          nsIContentPolicy::TYPE_CSP_REPORT,
++                         nullptr, // PerformanceStorage
+                          nullptr, // aLoadGroup
+                          nullptr, // aCallbacks
+                          loadFlags);
+     }
+ 
+     if (NS_FAILED(rv)) {
+       CSPCONTEXTLOG(("Could not create new channel for report URI %s",
+                      reportURICstring.get()));
+diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
++++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+@@ -1359,16 +1359,17 @@ nsresult nsWebBrowserPersist::SaveURIInt
+ 
+     // Open a channel to the URI
+     nsCOMPtr<nsIChannel> inputChannel;
+     rv = NS_NewChannel(getter_AddRefs(inputChannel),
+                        aURI,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,  // aPerformanceStorage
+                        nullptr,  // aLoadGroup
+                        static_cast<nsIInterfaceRequestor*>(this),
+                        loadFlags);
+ 
+     nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(inputChannel);
+     if (pbChannel)
+     {
+         pbChannel->SetPrivate(aIsPrivate);
+diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
+--- a/dom/workers/ScriptLoader.cpp
++++ b/dom/workers/ScriptLoader.cpp
+@@ -52,16 +52,17 @@
+ #include "mozilla/dom/cache/CacheStorage.h"
+ #include "mozilla/dom/ChannelInfo.h"
+ #include "mozilla/dom/ClientChannelHelper.h"
+ #include "mozilla/dom/ClientInfo.h"
+ #include "mozilla/dom/Exceptions.h"
+ #include "mozilla/dom/InternalResponse.h"
+ #include "mozilla/dom/nsCSPService.h"
+ #include "mozilla/dom/nsCSPUtils.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozilla/dom/Promise.h"
+ #include "mozilla/dom/PromiseNativeHandler.h"
+ #include "mozilla/dom/Response.h"
+ #include "mozilla/dom/ScriptLoader.h"
+ #include "mozilla/dom/ScriptSettings.h"
+ #include "mozilla/dom/SRILogHelper.h"
+ #include "mozilla/UniquePtr.h"
+ #include "Principal.h"
+@@ -105,16 +106,17 @@ GetBaseURI(bool aIsMainScript, WorkerPri
+ 
+   return baseURI;
+ }
+ 
+ nsresult
+ ChannelFromScriptURL(nsIPrincipal* principal,
+                      nsIURI* baseURI,
+                      nsIDocument* parentDoc,
++                     WorkerPrivate* aWorkerPrivate,
+                      nsILoadGroup* loadGroup,
+                      nsIIOService* ios,
+                      nsIScriptSecurityManager* secMan,
+                      const nsAString& aScriptURL,
+                      const Maybe<ClientInfo>& aClientInfo,
+                      const Maybe<ServiceWorkerDescriptor>& aController,
+                      bool aIsMainScript,
+                      WorkerScriptType aWorkerScriptType,
+@@ -185,44 +187,52 @@ ChannelFromScriptURL(nsIPrincipal* princ
+   // that we want to use. So make sure to avoid using 'parentDoc' in that
+   // situation.
+   if (parentDoc && parentDoc->NodePrincipal() == principal) {
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        uri,
+                        parentDoc,
+                        secFlags,
+                        contentPolicyType,
++                       nullptr, // aPerformanceStorage
+                        loadGroup,
+                        nullptr, // aCallbacks
+                        aLoadFlags,
+                        ios);
+   } else {
+     // We must have a loadGroup with a load context for the principal to
+     // traverse the channel correctly.
+     MOZ_ASSERT(loadGroup);
+     MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(loadGroup, principal));
+ 
++    RefPtr<PerformanceStorage> performanceStorage;
++    if (aWorkerPrivate && !aIsMainScript) {
++      performanceStorage = aWorkerPrivate->GetPerformanceStorage();
++    }
++
+     if (aClientInfo.isSome()) {
+       rv = NS_NewChannel(getter_AddRefs(channel),
+                          uri,
+                          principal,
+                          aClientInfo.ref(),
+                          aController,
+                          secFlags,
+                          contentPolicyType,
++                         performanceStorage,
+                          loadGroup,
+                          nullptr, // aCallbacks
+                          aLoadFlags,
+                          ios);
+     } else {
+       rv = NS_NewChannel(getter_AddRefs(channel),
+                          uri,
+                          principal,
+                          secFlags,
+                          contentPolicyType,
++                         performanceStorage,
+                          loadGroup,
+                          nullptr, // aCallbacks
+                          aLoadFlags,
+                          ios);
+     }
+   }
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -986,17 +996,18 @@ private:
+         }
+       }
+     }
+ 
+     if (!channel) {
+       // Only top level workers' main script use the document charset for the
+       // script uri encoding. Otherwise, default encoding (UTF-8) is applied.
+       bool useDefaultEncoding = !(!parentWorker && IsMainWorkerScript());
+-      rv = ChannelFromScriptURL(principal, baseURI, parentDoc, loadGroup, ios,
++      rv = ChannelFromScriptURL(principal, baseURI, parentDoc, mWorkerPrivate,
++                                loadGroup, ios,
+                                 secMan, loadInfo.mURL,
+                                 mClientInfo, mController,
+                                 IsMainWorkerScript(),
+                                 mWorkerScriptType,
+                                 mWorkerPrivate->ContentPolicyType(), loadFlags,
+                                 useDefaultEncoding,
+                                 getter_AddRefs(channel));
+       if (NS_WARN_IF(NS_FAILED(rv))) {
+@@ -2263,18 +2274,18 @@ ChannelFromScriptURLMainThread(nsIPrinci
+ {
+   AssertIsOnMainThread();
+ 
+   nsCOMPtr<nsIIOService> ios(do_GetIOService());
+ 
+   nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
+   NS_ASSERTION(secMan, "This should never be null!");
+ 
+-  return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, aLoadGroup,
+-                              ios, secMan, aScriptURL, aClientInfo,
++  return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, nullptr,
++                              aLoadGroup, ios, secMan, aScriptURL, aClientInfo,
+                               Maybe<ServiceWorkerDescriptor>(),
+                               true, WorkerScript, aMainScriptContentPolicyType,
+                               nsIRequest::LOAD_NORMAL, aDefaultURIEncoding,
+                               aChannel);
+ }
+ 
+ nsresult
+ ChannelFromScriptURLWorkerThread(JSContext* aCx,
+diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp
+--- a/dom/workers/ServiceWorkerScriptCache.cpp
++++ b/dom/workers/ServiceWorkerScriptCache.cpp
+@@ -725,17 +725,20 @@ CompareNetwork::Initialize(nsIPrincipal*
+   nsContentPolicyType contentPolicyType =
+       mIsMainScript ? nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER
+                     : nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS;
+ 
+   // Note that because there is no "serviceworker" RequestContext type, we can
+   // use the TYPE_INTERNAL_SCRIPT content policy types when loading a service
+   // worker.
+   rv = NS_NewChannel(getter_AddRefs(mChannel), uri, aPrincipal, secFlags,
+-                     contentPolicyType, loadGroup, nullptr /* aCallbacks */,
++                     contentPolicyType,
++                     nullptr, /* aPerformanceStorage */
++                     loadGroup,
++                     nullptr /* aCallbacks */,
+                      mLoadFlags);
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     return rv;
+   }
+ 
+   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
+   if (httpChannel) {
+     // Spec says no redirects allowed for top-level SW scripts.
+diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
+--- a/dom/workers/WorkerPrivate.cpp
++++ b/dom/workers/WorkerPrivate.cpp
+@@ -7209,16 +7209,24 @@ WorkerPrivate::DumpCrashInformation(nsAC
+   nsTObserverArray<WorkerHolder*>::ForwardIterator iter(mHolders);
+   while (iter.HasMore()) {
+     WorkerHolder* holder = iter.GetNext();
+     aString.Append("|");
+     aString.Append(holder->Name());
+   }
+ }
+ 
++PerformanceStorage*
++WorkerPrivate::GetPerformanceStorage()
++{
++  AssertIsOnMainThread();
++  // TODO
++  return nullptr;
++}
++
+ NS_IMPL_ISUPPORTS_INHERITED0(ExternalRunnableWrapper, WorkerRunnable)
+ 
+ template <class Derived>
+ NS_IMPL_ADDREF(WorkerPrivateParent<Derived>::EventTarget)
+ 
+ template <class Derived>
+ NS_IMPL_RELEASE(WorkerPrivateParent<Derived>::EventTarget)
+ 
+diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
+--- a/dom/workers/WorkerPrivate.h
++++ b/dom/workers/WorkerPrivate.h
+@@ -63,16 +63,17 @@ struct RuntimeStats;
+ namespace mozilla {
+ class ThrottledEventQueue;
+ namespace dom {
+ class ClientInfo;
+ class ClientSource;
+ class Function;
+ class MessagePort;
+ class MessagePortIdentifier;
++class PerformanceStorage;
+ class PromiseNativeHandler;
+ class StructuredCloneHolder;
+ class WorkerDebuggerGlobalScope;
+ class WorkerGlobalScope;
+ struct WorkerOptions;
+ } // namespace dom
+ namespace ipc {
+ class PrincipalInfo;
+@@ -1507,16 +1508,19 @@ public:
+   GetController() const;
+ 
+   void
+   Control(const ServiceWorkerDescriptor& aServiceWorker);
+ 
+   void
+   ExecutionReady();
+ 
++  PerformanceStorage*
++  GetPerformanceStorage();
++
+ private:
+   WorkerPrivate(WorkerPrivate* aParent,
+                 const nsAString& aScriptURL, bool aIsChromeWorker,
+                 WorkerType aWorkerType, const nsAString& aWorkerName,
+                 const nsACString& aServiceWorkerScope,
+                 WorkerLoadInfo& aLoadInfo);
+ 
+   bool
+diff --git a/dom/xbl/nsXBLService.cpp b/dom/xbl/nsXBLService.cpp
+--- a/dom/xbl/nsXBLService.cpp
++++ b/dom/xbl/nsXBLService.cpp
+@@ -1107,24 +1107,26 @@ nsXBLService::FetchBindingDocument(nsICo
+ 
+     rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
+                                               aDocumentURI,
+                                               aBoundDocument,
+                                               aOriginPrincipal,
+                                               nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
+                                               nsILoadInfo::SEC_ALLOW_CHROME,
+                                               nsIContentPolicy::TYPE_XBL,
++                                              nullptr, // aPerformanceStorage
+                                               loadGroup);
+   }
+   else {
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        aDocumentURI,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
+                        nsIContentPolicy::TYPE_XBL,
++                       nullptr, // PerformanceStorage
+                        loadGroup);
+   }
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   if (!aForceSyncLoad) {
+     // We can be asynchronous
+     nsXBLStreamListener* xblListener =
+       new nsXBLStreamListener(aBoundDocument, xblSink, doc);
+diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
+--- a/dom/xhr/XMLHttpRequestMainThread.cpp
++++ b/dom/xhr/XMLHttpRequestMainThread.cpp
+@@ -2480,37 +2480,40 @@ XMLHttpRequestMainThread::CreateChannel(
+   nsresult rv;
+   nsCOMPtr<nsIDocument> responsibleDocument = GetDocumentIfCurrent();
+   if (responsibleDocument && responsibleDocument->NodePrincipal() == mPrincipal) {
+     rv = NS_NewChannel(getter_AddRefs(mChannel),
+                        mRequestURL,
+                        responsibleDocument,
+                        secFlags,
+                        nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
++                       nullptr, // aPerformanceStorage
+                        loadGroup,
+                        nullptr,   // aCallbacks
+                        loadFlags);
+   } else if (mClientInfo.isSome()) {
+     rv = NS_NewChannel(getter_AddRefs(mChannel),
+                        mRequestURL,
+                        mPrincipal,
+                        mClientInfo.ref(),
+                        mController,
+                        secFlags,
+                        nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
++                       mPerformanceStorage, // aPerformanceStorage
+                        loadGroup,
+                        nullptr,   // aCallbacks
+                        loadFlags);
+   } else {
+     // Otherwise use the principal.
+     rv = NS_NewChannel(getter_AddRefs(mChannel),
+                        mRequestURL,
+                        mPrincipal,
+                        secFlags,
+                        nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
++                       mPerformanceStorage, // aPerformanceStorage
+                        loadGroup,
+                        nullptr,   // aCallbacks
+                        loadFlags);
+   }
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
+   if (httpChannel) {
+diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h
+--- a/dom/xhr/XMLHttpRequestMainThread.h
++++ b/dom/xhr/XMLHttpRequestMainThread.h
+@@ -36,16 +36,17 @@
+ #include "mozilla/MemoryReporting.h"
+ #include "mozilla/NotNull.h"
+ #include "mozilla/dom/MutableBlobStorage.h"
+ #include "mozilla/dom/BodyExtractor.h"
+ #include "mozilla/dom/ClientInfo.h"
+ #include "mozilla/dom/TypedArray.h"
+ #include "mozilla/dom/File.h"
+ #include "mozilla/dom/FormData.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozilla/dom/ServiceWorkerDescriptor.h"
+ #include "mozilla/dom/URLSearchParams.h"
+ #include "mozilla/dom/XMLHttpRequest.h"
+ #include "mozilla/dom/XMLHttpRequestBinding.h"
+ #include "mozilla/dom/XMLHttpRequestEventTarget.h"
+ #include "mozilla/dom/XMLHttpRequestString.h"
+ #include "mozilla/Encoding.h"
+ 
+@@ -196,30 +197,32 @@ public:
+     ENUM_MAX
+   };
+ 
+   XMLHttpRequestMainThread();
+ 
+   void Construct(nsIPrincipal* aPrincipal,
+                  nsIGlobalObject* aGlobalObject,
+                  nsIURI* aBaseURI = nullptr,
+-                 nsILoadGroup* aLoadGroup = nullptr)
++                 nsILoadGroup* aLoadGroup = nullptr,
++                 PerformanceStorage* aPerformanceStorage = nullptr)
+   {
+     MOZ_ASSERT(aPrincipal);
+     nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobalObject);
+     if (win) {
+       MOZ_ASSERT(win->IsInnerWindow());
+       if (win->GetExtantDoc()) {
+         mStyleBackend = win->GetExtantDoc()->GetStyleBackendType();
+       }
+     }
+     mPrincipal = aPrincipal;
+     BindToOwner(aGlobalObject);
+     mBaseURI = aBaseURI;
+     mLoadGroup = aLoadGroup;
++    mPerformanceStorage = aPerformanceStorage;
+   }
+ 
+   void InitParameters(bool aAnon, bool aSystem);
+ 
+   void SetParameters(bool aAnon, bool aSystem)
+   {
+     mIsAnon = aAnon || aSystem;
+     mIsSystem = aSystem;
+@@ -581,16 +584,18 @@ protected:
+   nsCOMPtr<nsIPrincipal> mPrincipal;
+   nsCOMPtr<nsIChannel> mChannel;
+   nsCString mRequestMethod;
+   nsCOMPtr<nsIURI> mRequestURL;
+   nsCOMPtr<nsIDocument> mResponseXML;
+ 
+   nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
+ 
++  RefPtr<PerformanceStorage> mPerformanceStorage;
++
+   // used to implement getAllResponseHeaders()
+   class nsHeaderVisitor : public nsIHttpHeaderVisitor
+   {
+     struct HeaderEntry final
+     {
+       nsCString mName;
+       nsCString mValue;
+ 
+diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp
+--- a/dom/xhr/XMLHttpRequestWorker.cpp
++++ b/dom/xhr/XMLHttpRequestWorker.cpp
+@@ -868,17 +868,18 @@ Proxy::Init()
+     return false;
+   }
+ 
+   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(ownerWindow);
+ 
+   mXHR = new XMLHttpRequestMainThread();
+   mXHR->Construct(mWorkerPrivate->GetPrincipal(), global,
+                   mWorkerPrivate->GetBaseURI(),
+-                  mWorkerPrivate->GetLoadGroup());
++                  mWorkerPrivate->GetLoadGroup(),
++                  mWorkerPrivate->GetPerformanceStorage());
+ 
+   mXHR->SetParameters(mMozAnon, mMozSystem);
+   mXHR->SetClientInfoAndController(mClientInfo, mController);
+ 
+   ErrorResult rv;
+   mXHRUpload = mXHR->GetUpload(rv);
+   if (NS_WARN_IF(rv.Failed())) {
+     mXHR = nullptr;
+diff --git a/dom/xml/XMLDocument.cpp b/dom/xml/XMLDocument.cpp
+--- a/dom/xml/XMLDocument.cpp
++++ b/dom/xml/XMLDocument.cpp
+@@ -429,16 +429,17 @@ XMLDocument::Load(const nsAString& aUrl,
+   // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active,
+   // which in turn keeps STOP button from becoming active
+   rv = NS_NewChannel(getter_AddRefs(channel),
+                      uri,
+                      callingDoc ? callingDoc.get() :
+                                   static_cast<nsIDocument*>(this),
+                      nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
+                      nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
++                     nullptr, // aPerformanceStorage
+                      loadGroup,
+                      req,
+                      nsIRequest::LOAD_BACKGROUND);
+ 
+   if (NS_FAILED(rv)) {
+     aRv.Throw(rv);
+     return false;
+   }
+diff --git a/dom/xslt/base/txURIUtils.cpp b/dom/xslt/base/txURIUtils.cpp
+--- a/dom/xslt/base/txURIUtils.cpp
++++ b/dom/xslt/base/txURIUtils.cpp
+@@ -53,16 +53,17 @@ URIUtils::ResetWithSource(nsIDocument *a
+     nsCOMPtr<nsIChannel> channel = sourceDoc->GetChannel();
+     if (!channel) {
+         // Need to synthesize one
+         nsresult rv = NS_NewChannel(getter_AddRefs(channel),
+                                     sourceDoc->GetDocumentURI(),
+                                     sourceDoc,
+                                     nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                                     nsIContentPolicy::TYPE_OTHER,
++                                    nullptr, // aPerformanceStorage
+                                     loadGroup,
+                                     nullptr, // aCallbacks
+                                     nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
+ 
+         if (NS_FAILED(rv)) {
+             return;
+         }
+     }
+diff --git a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
++++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+@@ -450,16 +450,17 @@ txCompileObserver::startLoad(nsIURI* aUr
+     nsCOMPtr<nsIChannel> channel;
+     nsresult rv = NS_NewChannelWithTriggeringPrincipal(
+                     getter_AddRefs(channel),
+                     aUri,
+                     mLoaderDocument,
+                     aReferrerPrincipal, // triggeringPrincipal
+                     nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
+                     nsIContentPolicy::TYPE_XSLT,
++                    nullptr, // aPerformanceStorage
+                     loadGroup);
+ 
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     channel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
+ 
+     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
+     if (httpChannel) {
+diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp
+--- a/dom/xul/XULDocument.cpp
++++ b/dom/xul/XULDocument.cpp
+@@ -2638,16 +2638,17 @@ XULDocument::LoadOverlayInternal(nsIURI*
+         // with the right principal and in the correct
+         // compartment.
+         rv = NS_NewChannel(getter_AddRefs(channel),
+                            aURI,
+                            NodePrincipal(),
+                            nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
+                            nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                            nsIContentPolicy::TYPE_OTHER,
++                           nullptr, // PerformanceStorage
+                            group);
+ 
+         if (NS_SUCCEEDED(rv)) {
+             rv = channel->AsyncOpen2(listener);
+         }
+ 
+         if (NS_FAILED(rv)) {
+             // Abandon this prototype
+diff --git a/extensions/pref/autoconfig/src/nsAutoConfig.cpp b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
+--- a/extensions/pref/autoconfig/src/nsAutoConfig.cpp
++++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
+@@ -292,16 +292,17 @@ nsresult nsAutoConfig::downloadAutoConfi
+ 
+     MOZ_LOG(MCD, LogLevel::Debug, ("running MCD url %s\n", mConfigURL.get()));
+     // open a channel for the url
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        url,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,  // PerformanceStorage
+                        nullptr,  // loadGroup
+                        nullptr,  // aCallbacks
+                        nsIRequest::INHIBIT_PERSISTENT_CACHING |
+                        nsIRequest::LOAD_BYPASS_CACHE);
+ 
+     if (NS_FAILED(rv))
+         return rv;
+ 
+diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp
+--- a/image/imgLoader.cpp
++++ b/image/imgLoader.cpp
+@@ -801,16 +801,17 @@ NewImageChannel(nsIChannel** aResult,
+   // the principal is that of the user stylesheet.
+   if (requestingNode && aTriggeringPrincipal) {
+     rv = NS_NewChannelWithTriggeringPrincipal(aResult,
+                                               aURI,
+                                               requestingNode,
+                                               aTriggeringPrincipal,
+                                               securityFlags,
+                                               aPolicyType,
++                                              nullptr,   // PerformanceStorage
+                                               nullptr,   // loadGroup
+                                               callbacks,
+                                               aLoadFlags);
+ 
+     if (NS_FAILED(rv)) {
+       return rv;
+     }
+ 
+@@ -832,16 +833,17 @@ NewImageChannel(nsIChannel** aResult,
+     // triggeringPrincipal should always be the systemPrincipal.
+     // However, there are exceptions: one is Notifications which create a
+     // channel in the parent prcoess in which case we can't get a requestingNode.
+     rv = NS_NewChannel(aResult,
+                        aURI,
+                        nsContentUtils::GetSystemPrincipal(),
+                        securityFlags,
+                        aPolicyType,
++                       nullptr,   // PerformanceStorage
+                        nullptr,   // loadGroup
+                        callbacks,
+                        aLoadFlags);
+ 
+     if (NS_FAILED(rv)) {
+       return rv;
+     }
+ 
+diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp
+--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
++++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
+@@ -233,16 +233,17 @@ class MOZ_STACK_CLASS ComponentLoaderInf
+     nsIChannel* ScriptChannel() { MOZ_ASSERT(mScriptChannel); return mScriptChannel; }
+     nsresult EnsureScriptChannel() {
+         BEGIN_ENSURE(ScriptChannel, IOService, URI);
+         return NS_NewChannel(getter_AddRefs(mScriptChannel),
+                              mURI,
+                              nsContentUtils::GetSystemPrincipal(),
+                              nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                              nsIContentPolicy::TYPE_SCRIPT,
++                             nullptr, // aPerformanceStorage
+                              nullptr, // aLoadGroup
+                              nullptr, // aCallbacks
+                              nsIRequest::LOAD_NORMAL,
+                              mIOService);
+     }
+ 
+     nsIURI* ResolvedURI() { MOZ_ASSERT(mResolvedURI); return mResolvedURI; }
+     nsresult EnsureResolvedURI() {
+diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
++++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+@@ -462,16 +462,17 @@ mozJSSubScriptLoader::ReadScriptAsync(ns
+     // lookups (bug 632490).
+     nsCOMPtr<nsIChannel> channel;
+     nsresult rv;
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        uri,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,  // aPerformanceStorage
+                        nullptr,  // aLoadGroup
+                        nullptr,  // aCallbacks
+                        nsIRequest::LOAD_NORMAL,
+                        serv);
+ 
+     if (!NS_SUCCEEDED(rv)) {
+         return rv;
+     }
+@@ -512,16 +513,17 @@ mozJSSubScriptLoader::ReadScript(nsIURI*
+     nsCOMPtr<nsIChannel> chan;
+     nsCOMPtr<nsIInputStream> instream;
+     nsresult rv;
+     rv = NS_NewChannel(getter_AddRefs(chan),
+                        uri,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,  // PerformanceStorage
+                        nullptr,  // aLoadGroup
+                        nullptr,  // aCallbacks
+                        nsIRequest::LOAD_NORMAL,
+                        serv);
+ 
+     if (NS_SUCCEEDED(rv)) {
+         chan->SetContentType(NS_LITERAL_CSTRING("application/javascript"));
+         rv = chan->Open2(getter_AddRefs(instream));
+diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp
+--- a/layout/style/FontFaceSet.cpp
++++ b/layout/style/FontFaceSet.cpp
+@@ -641,16 +641,17 @@ FontFaceSet::StartLoad(gfxUserFontEntry*
+   // being loaded might have a different origin from the principal of the
+   // stylesheet that initiated the font load.
+   rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
+                                             aFontFaceSrc->mURI->get(),
+                                             mDocument,
+                                             principal ? principal->get() : nullptr,
+                                             nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
+                                             nsIContentPolicy::TYPE_FONT,
++                                            nullptr, // PerformanceStorage
+                                             loadGroup);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   RefPtr<nsFontFaceLoader> fontLoader =
+     new nsFontFaceLoader(aUserFontEntry, aFontFaceSrc->mURI->get(), this,
+                          channel);
+ 
+   if (LOG_ENABLED()) {
+diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp
+--- a/layout/style/Loader.cpp
++++ b/layout/style/Loader.cpp
+@@ -1538,31 +1538,33 @@ Loader::LoadSheet(SheetLoadData* aLoadDa
+   // origin)  that is applying the styles.
+   if (aLoadData->mRequestingNode && aLoadData->mLoaderPrincipal) {
+     rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
+                                               aLoadData->mURI,
+                                               aLoadData->mRequestingNode,
+                                               aLoadData->mLoaderPrincipal,
+                                               securityFlags,
+                                               contentPolicyType,
++                                              nullptr, // Performancestorage
+                                               loadGroup,
+                                               nullptr,   // aCallbacks
+                                               nsIChannel::LOAD_NORMAL |
+                                               nsIChannel::LOAD_CLASSIFY_URI);
+   }
+   else {
+     // either we are loading something inside a document, in which case
+     // we should always have a requestingNode, or we are loading something
+     // outside a document, in which case the loadingPrincipal and the
+     // triggeringPrincipal should always be the systemPrincipal.
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        aLoadData->mURI,
+                        nsContentUtils::GetSystemPrincipal(),
+                        securityFlags,
+                        contentPolicyType,
++                       nullptr, // aPerformanceStorage
+                        loadGroup,
+                        nullptr,   // aCallbacks
+                        nsIChannel::LOAD_NORMAL |
+                        nsIChannel::LOAD_CLASSIFY_URI);
+   }
+ 
+   if (NS_FAILED(rv)) {
+ #ifdef DEBUG
+diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp
+--- a/modules/libjar/nsJARChannel.cpp
++++ b/modules/libjar/nsJARChannel.cpp
+@@ -811,16 +811,17 @@ nsJARChannel::AsyncOpen(nsIStreamListene
+ 
+         // kick off an async download of the base URI...
+         nsCOMPtr<nsIStreamListener> downloader = new MemoryDownloader(this);
+         uint32_t loadFlags =
+             mLoadFlags & ~(LOAD_DOCUMENT_URI | LOAD_CALL_CONTENT_SNIFFERS);
+         rv = NS_NewChannelInternal(getter_AddRefs(channel),
+                                    mJarBaseURI,
+                                    mLoadInfo,
++                                   nullptr, // PerformanceStorage
+                                    mLoadGroup,
+                                    mCallbacks,
+                                    loadFlags);
+         if (NS_FAILED(rv)) {
+             mIsPending = false;
+             mListenerContext = nullptr;
+             mListener = nullptr;
+             mCallbacks = nullptr;
+diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
+--- a/netwerk/base/LoadInfo.cpp
++++ b/netwerk/base/LoadInfo.cpp
+@@ -4,16 +4,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/. */
+ 
+ #include "mozilla/LoadInfo.h"
+ 
+ #include "mozilla/Assertions.h"
+ #include "mozilla/dom/ClientIPCTypes.h"
+ #include "mozilla/dom/ClientSource.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozilla/dom/TabChild.h"
+ #include "mozilla/dom/ToJSValue.h"
+ #include "mozIThirdPartyUtil.h"
+ #include "nsFrameLoader.h"
+ #include "nsIContentSecurityPolicy.h"
+ #include "nsIDocShell.h"
+ #include "nsIDocument.h"
+ #include "nsIDOMDocument.h"
+@@ -326,16 +327,17 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
+   , mPrincipalToInherit(rhs.mPrincipalToInherit)
+   , mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal)
+   , mResultPrincipalURI(rhs.mResultPrincipalURI)
+   , mClientInfo(rhs.mClientInfo)
+   // mReservedClientSource must be handled specially during redirect
+   // mReservedClientInfo must be handled specially during redirect
+   // mInitialClientInfo must be handled specially during redirect
+   , mController(rhs.mController)
++  , mPerformanceStorage(rhs.mPerformanceStorage)
+   , mLoadingContext(rhs.mLoadingContext)
+   , mContextForTopLevelLoad(rhs.mContextForTopLevelLoad)
+   , mSecurityFlags(rhs.mSecurityFlags)
+   , mInternalContentPolicyType(rhs.mInternalContentPolicyType)
+   , mTainting(rhs.mTainting)
+   , mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests)
+   , mVerifySignedContent(rhs.mVerifySignedContent)
+   , mEnforceSRI(rhs.mEnforceSRI)
+@@ -1244,10 +1246,22 @@ LoadInfo::ClearController()
+ }
+ 
+ const Maybe<ServiceWorkerDescriptor>&
+ LoadInfo::GetController()
+ {
+   return mController;
+ }
+ 
++void
++LoadInfo::SetPerformanceStorage(PerformanceStorage* aPerformanceStorage)
++{
++  mPerformanceStorage = aPerformanceStorage;
++}
++
++PerformanceStorage*
++LoadInfo::GetPerformanceStorage()
++{
++  return mPerformanceStorage;
++}
++
+ } // namespace net
+ } // namespace mozilla
+diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
+--- a/netwerk/base/LoadInfo.h
++++ b/netwerk/base/LoadInfo.h
+@@ -19,16 +19,17 @@
+ #include "mozilla/dom/ServiceWorkerDescriptor.h"
+ 
+ class nsINode;
+ class nsPIDOMWindowOuter;
+ 
+ namespace mozilla {
+ 
+ namespace dom {
++class PerformanceStorage;
+ class XMLHttpRequestMainThread;
+ }
+ 
+ namespace net {
+ class OptionalLoadInfoArgs;
+ } // namespace net
+ 
+ namespace ipc {
+@@ -161,16 +162,17 @@ private:
+   nsCOMPtr<nsIPrincipal>           mSandboxedLoadingPrincipal;
+   nsCOMPtr<nsIURI>                 mResultPrincipalURI;
+ 
+   Maybe<mozilla::dom::ClientInfo>               mClientInfo;
+   UniquePtr<mozilla::dom::ClientSource>         mReservedClientSource;
+   Maybe<mozilla::dom::ClientInfo>               mReservedClientInfo;
+   Maybe<mozilla::dom::ClientInfo>               mInitialClientInfo;
+   Maybe<mozilla::dom::ServiceWorkerDescriptor>  mController;
++  RefPtr<mozilla::dom::PerformanceStorage>      mPerformanceStorage;
+ 
+   nsWeakPtr                        mLoadingContext;
+   nsWeakPtr                        mContextForTopLevelLoad;
+   nsSecurityFlags                  mSecurityFlags;
+   nsContentPolicyType              mInternalContentPolicyType;
+   LoadTainting                     mTainting;
+   bool                             mUpgradeInsecureRequests;
+   bool                             mVerifySignedContent;
+diff --git a/netwerk/base/Predictor.cpp b/netwerk/base/Predictor.cpp
+--- a/netwerk/base/Predictor.cpp
++++ b/netwerk/base/Predictor.cpp
+@@ -1412,16 +1412,17 @@ Predictor::Prefetch(nsIURI *uri, nsIURI 
+   referrer->GetAsciiSpec(strReferrer);
+   PREDICTOR_LOG(("Predictor::Prefetch uri=%s referrer=%s verifier=%p",
+                  strUri.get(), strReferrer.get(), verifier));
+   nsCOMPtr<nsIChannel> channel;
+   nsresult rv = NS_NewChannel(getter_AddRefs(channel), uri,
+                               nsContentUtils::GetSystemPrincipal(),
+                               nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                               nsIContentPolicy::TYPE_OTHER,
++                              nullptr, /* aPerformanceStorage */
+                               nullptr, /* aLoadGroup */
+                               nullptr, /* aCallbacks */
+                               nsIRequest::LOAD_BACKGROUND);
+ 
+   if (NS_FAILED(rv)) {
+     PREDICTOR_LOG(("    NS_NewChannel failed rv=0x%" PRIX32, static_cast<uint32_t>(rv)));
+     return rv;
+   }
+diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
+--- a/netwerk/base/nsILoadInfo.idl
++++ b/netwerk/base/nsILoadInfo.idl
+@@ -20,16 +20,17 @@ native LoadContextRef(already_AddRefed<n
+ #include "mozilla/LoadTainting.h"
+ #include "mozilla/UniquePtr.h"
+ #include "nsStringFwd.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ class ClientInfo;
+ class ClientSource;
++class PerformanceStorage;
+ class ServiceWorkerDescriptor;
+ } // namespace dom
+ } // namespace mozilla
+ %}
+ 
+ [ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
+ native OriginAttributes(mozilla::OriginAttributes);
+ [ref] native const_OriginAttributesRef(const mozilla::OriginAttributes);
+@@ -37,16 +38,17 @@ native OriginAttributes(mozilla::OriginA
+ [ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
+ [ref] native PrincipalArrayRef(const nsTArray<nsCOMPtr<nsIPrincipal>>);
+ [ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo);
+       native UniqueClientSource(mozilla::UniquePtr<mozilla::dom::ClientSource>);
+       native UniqueClientSourceMove(mozilla::UniquePtr<mozilla::dom::ClientSource>&&);
+ [ref] native const_MaybeClientInfoRef(const mozilla::Maybe<mozilla::dom::ClientInfo>);
+ [ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor);
+ [ref] native const_MaybeServiceWorkerDescriptorRef(const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>);
++[ptr] native PerformanceStoragePtr(mozilla::dom::PerformanceStorage);
+ 
+ typedef unsigned long nsSecurityFlags;
+ 
+ /**
+  * The LoadInfo object contains information about a network load, why it
+  * was started, and how we plan on using the resulting response.
+  * If a network request is redirected, the new channel will receive a new
+  * LoadInfo object. The new object will contain mostly the same
+@@ -938,9 +940,23 @@ interface nsILoadInfo : nsISupports
+   void ClearController();
+ 
+   /**
+    * Get the service worker controlling this network request, if one has
+    * been set.
+    */
+   [noscript, nostdcall, notxpcom]
+   const_MaybeServiceWorkerDescriptorRef GetController();
++
++  /**
++   * Set a custom performance storage. This is meant to be executed only for
++   * workers. If a PerformanceStorage is not set, the loadingDocument->Window
++   * Performance object will be used instead.
++   */
++  [noscript, nostdcall, notxpcom]
++  void SetPerformanceStorage(in PerformanceStoragePtr aPerformanceStorage);
++
++  /**
++   * Get the PerformanceStorage.
++   */
++  [noscript, nostdcall, notxpcom]
++  PerformanceStoragePtr GetPerformanceStorage();
+ };
+diff --git a/netwerk/base/nsIncrementalDownload.cpp b/netwerk/base/nsIncrementalDownload.cpp
+--- a/netwerk/base/nsIncrementalDownload.cpp
++++ b/netwerk/base/nsIncrementalDownload.cpp
+@@ -245,16 +245,17 @@ nsIncrementalDownload::ProcessTimeout()
+   // Fetch next chunk
+ 
+   nsCOMPtr<nsIChannel> channel;
+   nsresult rv = NS_NewChannel(getter_AddRefs(channel),
+                               mFinalURI,
+                               nsContentUtils::GetSystemPrincipal(),
+                               nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                               nsIContentPolicy::TYPE_OTHER,
++                              nullptr,   // PerformanceStorage
+                               nullptr,   // loadGroup
+                               this,      // aCallbacks
+                               mLoadFlags);
+ 
+   if (NS_FAILED(rv))
+     return rv;
+ 
+   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(channel, &rv);
+diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
+--- a/netwerk/base/nsNetUtil.cpp
++++ b/netwerk/base/nsNetUtil.cpp
+@@ -77,16 +77,17 @@
+ #include "nsICertBlocklist.h"
+ #include "nsICertOverrideService.h"
+ 
+ #include <limits>
+ 
+ using namespace mozilla;
+ using namespace mozilla::net;
+ using mozilla::dom::ClientInfo;
++using mozilla::dom::PerformanceStorage;
+ using mozilla::dom::ServiceWorkerDescriptor;
+ 
+ #define DEFAULT_RP 3
+ #define DEFAULT_PRIVATE_RP 2
+ 
+ static uint32_t sDefaultRp = DEFAULT_RP;
+ static uint32_t defaultPrivateRp = DEFAULT_PRIVATE_RP;
+ 
+@@ -158,16 +159,17 @@ NS_NewFileURI(nsIURI **result,
+         rv = ioService->NewFileURI(spec, result);
+     return rv;
+ }
+ 
+ nsresult
+ NS_NewChannelInternal(nsIChannel           **outChannel,
+                       nsIURI                *aUri,
+                       nsILoadInfo           *aLoadInfo,
++                      PerformanceStorage    *aPerformanceStorage /* = nullptr */,
+                       nsILoadGroup          *aLoadGroup /* = nullptr */,
+                       nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+                       nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+                       nsIIOService          *aIoService /* = nullptr */)
+ {
+   // NS_NewChannelInternal is mostly called for channel redirects. We should allow
+   // the creation of a channel even if the original channel did not have a loadinfo
+   // attached.
+@@ -203,16 +205,24 @@ NS_NewChannelInternal(nsIChannel        
+   MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
+ #endif
+ 
+   if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
+     rv = channel->SetLoadFlags(aLoadFlags);
+     NS_ENSURE_SUCCESS(rv, rv);
+   }
+ 
++  if (aPerformanceStorage) {
++    nsCOMPtr<nsILoadInfo> loadInfo;
++    rv = channel->GetLoadInfo(getter_AddRefs(loadInfo));
++    NS_ENSURE_SUCCESS(rv, rv);
++
++    loadInfo->SetPerformanceStorage(aPerformanceStorage);
++  }
++
+   channel.forget(outChannel);
+   return NS_OK;
+ }
+ 
+ namespace {
+ 
+ void
+ AssertLoadingPrincipalAndClientInfoMatch(nsIPrincipal* aLoadingPrincipal,
+@@ -263,44 +273,47 @@ AssertLoadingPrincipalAndClientInfoMatch
+ }
+ 
+ nsresult
+ NS_NewChannel(nsIChannel           **outChannel,
+               nsIURI                *aUri,
+               nsIPrincipal          *aLoadingPrincipal,
+               nsSecurityFlags        aSecurityFlags,
+               nsContentPolicyType    aContentPolicyType,
++              PerformanceStorage    *aPerformanceStorage /* nullptr */,
+               nsILoadGroup          *aLoadGroup /* = nullptr */,
+               nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+               nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+               nsIIOService          *aIoService /* = nullptr */)
+ {
+   return NS_NewChannelInternal(outChannel,
+                                aUri,
+                                nullptr, // aLoadingNode,
+                                aLoadingPrincipal,
+                                nullptr, // aTriggeringPrincipal
+                                Maybe<ClientInfo>(),
+                                Maybe<ServiceWorkerDescriptor>(),
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ nsresult
+ NS_NewChannel(nsIChannel           **outChannel,
+               nsIURI                *aUri,
+               nsIPrincipal          *aLoadingPrincipal,
+               const ClientInfo      &aLoadingClientInfo,
+               const Maybe<ServiceWorkerDescriptor>& aController,
+               nsSecurityFlags        aSecurityFlags,
+               nsContentPolicyType    aContentPolicyType,
++              PerformanceStorage    *aPerformanceStorage /* nullptr */,
+               nsILoadGroup          *aLoadGroup /* = nullptr */,
+               nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+               nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+               nsIIOService          *aIoService /* = nullptr */)
+ {
+   AssertLoadingPrincipalAndClientInfoMatch(aLoadingPrincipal,
+                                            aLoadingClientInfo,
+                                            aContentPolicyType);
+@@ -312,32 +325,34 @@ NS_NewChannel(nsIChannel           **out
+                                aUri,
+                                nullptr, // aLoadingNode,
+                                aLoadingPrincipal,
+                                nullptr, // aTriggeringPrincipal
+                                loadingClientInfo,
+                                aController,
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ nsresult
+ NS_NewChannelInternal(nsIChannel           **outChannel,
+                       nsIURI                *aUri,
+                       nsINode               *aLoadingNode,
+                       nsIPrincipal          *aLoadingPrincipal,
+                       nsIPrincipal          *aTriggeringPrincipal,
+                       const Maybe<ClientInfo>& aLoadingClientInfo,
+                       const Maybe<ServiceWorkerDescriptor>& aController,
+                       nsSecurityFlags        aSecurityFlags,
+                       nsContentPolicyType    aContentPolicyType,
++                      PerformanceStorage    *aPerformanceStorage /* nullptr */,
+                       nsILoadGroup          *aLoadGroup /* = nullptr */,
+                       nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+                       nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+                       nsIIOService          *aIoService /* = nullptr */)
+ {
+   NS_ENSURE_ARG_POINTER(outChannel);
+ 
+   nsCOMPtr<nsIIOService> grip;
+@@ -379,88 +394,101 @@ NS_NewChannelInternal(nsIChannel        
+   MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
+ #endif
+ 
+   if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
+     rv = channel->SetLoadFlags(aLoadFlags);
+     NS_ENSURE_SUCCESS(rv, rv);
+   }
+ 
++  if (aPerformanceStorage) {
++    nsCOMPtr<nsILoadInfo> loadInfo;
++    rv = channel->GetLoadInfo(getter_AddRefs(loadInfo));
++    NS_ENSURE_SUCCESS(rv, rv);
++
++    loadInfo->SetPerformanceStorage(aPerformanceStorage);
++  }
++
+   channel.forget(outChannel);
+   return NS_OK;
+ }
+ 
+ nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsINode               *aLoadingNode,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     PerformanceStorage    *aPerformanceStorage /* = nullptr */,
+                                      nsILoadGroup          *aLoadGroup /* = nullptr */,
+                                      nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+                                      nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+                                      nsIIOService          *aIoService /* = nullptr */)
+ {
+   MOZ_ASSERT(aLoadingNode);
+   NS_ASSERTION(aTriggeringPrincipal, "Can not create channel without a triggering Principal!");
+   return NS_NewChannelInternal(outChannel,
+                                aUri,
+                                aLoadingNode,
+                                aLoadingNode->NodePrincipal(),
+                                aTriggeringPrincipal,
+                                Maybe<ClientInfo>(),
+                                Maybe<ServiceWorkerDescriptor>(),
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsIPrincipal          *aLoadingPrincipal,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     PerformanceStorage    *aPerformanceStorage /* = nullptr */,
+                                      nsILoadGroup          *aLoadGroup /* = nullptr */,
+                                      nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+                                      nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+                                      nsIIOService          *aIoService /* = nullptr */)
+ {
+   NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!");
+   return NS_NewChannelInternal(outChannel,
+                                aUri,
+                                nullptr, // aLoadingNode
+                                aLoadingPrincipal,
+                                aTriggeringPrincipal,
+                                Maybe<ClientInfo>(),
+                                Maybe<ServiceWorkerDescriptor>(),
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsIPrincipal          *aLoadingPrincipal,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      const ClientInfo      &aLoadingClientInfo,
+                                      const Maybe<ServiceWorkerDescriptor>& aController,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     PerformanceStorage    *aPerformanceStorage /* = nullptr */,
+                                      nsILoadGroup          *aLoadGroup /* = nullptr */,
+                                      nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+                                      nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+                                      nsIIOService          *aIoService /* = nullptr */)
+ {
+   AssertLoadingPrincipalAndClientInfoMatch(aLoadingPrincipal,
+                                            aLoadingClientInfo,
+                                            aContentPolicyType);
+@@ -472,43 +500,46 @@ NS_NewChannelWithTriggeringPrincipal(nsI
+                                aUri,
+                                nullptr, // aLoadingNode
+                                aLoadingPrincipal,
+                                aTriggeringPrincipal,
+                                loadingClientInfo,
+                                aController,
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ nsresult
+ NS_NewChannel(nsIChannel           **outChannel,
+               nsIURI                *aUri,
+               nsINode               *aLoadingNode,
+               nsSecurityFlags        aSecurityFlags,
+               nsContentPolicyType    aContentPolicyType,
++              PerformanceStorage    *aPerformanceStorage /* = nullptr */,
+               nsILoadGroup          *aLoadGroup /* = nullptr */,
+               nsIInterfaceRequestor *aCallbacks /* = nullptr */,
+               nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
+               nsIIOService          *aIoService /* = nullptr */)
+ {
+   NS_ASSERTION(aLoadingNode, "Can not create channel without a loading Node!");
+   return NS_NewChannelInternal(outChannel,
+                                aUri,
+                                aLoadingNode,
+                                aLoadingNode->NodePrincipal(),
+                                nullptr, // aTriggeringPrincipal
+                                Maybe<ClientInfo>(),
+                                Maybe<ServiceWorkerDescriptor>(),
+                                aSecurityFlags,
+                                aContentPolicyType,
++                               aPerformanceStorage,
+                                aLoadGroup,
+                                aCallbacks,
+                                aLoadFlags,
+                                aIoService);
+ }
+ 
+ nsresult
+ NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument)
+@@ -1030,16 +1061,17 @@ NS_NewStreamLoaderInternal(nsIStreamLoad
+                                        aUri,
+                                        aLoadingNode,
+                                        aLoadingPrincipal,
+                                        nullptr, // aTriggeringPrincipal
+                                        Maybe<ClientInfo>(),
+                                        Maybe<ServiceWorkerDescriptor>(),
+                                        aSecurityFlags,
+                                        aContentPolicyType,
++                                       nullptr, // PerformanceStorage
+                                        aLoadGroup,
+                                        aCallbacks,
+                                        aLoadFlags);
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
+   if (httpChannel) {
+     rv = httpChannel->SetReferrer(aReferrer);
+diff --git a/netwerk/base/nsNetUtil.h b/netwerk/base/nsNetUtil.h
+--- a/netwerk/base/nsNetUtil.h
++++ b/netwerk/base/nsNetUtil.h
+@@ -53,16 +53,17 @@ class nsIIncrementalStreamLoaderObserver
+ class nsIUnicharStreamLoader;
+ class nsIUnicharStreamLoaderObserver;
+ 
+ namespace mozilla {
+ class Encoding;
+ class OriginAttributes;
+ namespace dom {
+ class ClientInfo;
++class PerformanceStorage;
+ class ServiceWorkerDescriptor;
+ } // namespace dom
+ } // namespace mozilla
+ 
+ template <class> class nsCOMPtr;
+ template <typename> struct already_AddRefed;
+ 
+ already_AddRefed<nsIIOService> do_GetIOService(nsresult *error = 0);
+@@ -154,105 +155,113 @@ nsresult NS_NewChannelInternal(nsIChanne
+                                nsIURI                *aUri,
+                                nsINode               *aLoadingNode,
+                                nsIPrincipal          *aLoadingPrincipal,
+                                nsIPrincipal          *aTriggeringPrincipal,
+                                const mozilla::Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
+                                const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
+                                nsSecurityFlags        aSecurityFlags,
+                                nsContentPolicyType    aContentPolicyType,
++                               mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+                                nsILoadGroup          *aLoadGroup = nullptr,
+                                nsIInterfaceRequestor *aCallbacks = nullptr,
+                                nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+                                nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult NS_NewChannelInternal(nsIChannel           **outChannel,
+                                nsIURI                *aUri,
+                                nsILoadInfo           *aLoadInfo,
++                               mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+                                nsILoadGroup          *aLoadGroup = nullptr,
+                                nsIInterfaceRequestor *aCallbacks = nullptr,
+                                nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+                                nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsINode               *aLoadingNode,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+                                      nsILoadGroup          *aLoadGroup = nullptr,
+                                      nsIInterfaceRequestor *aCallbacks = nullptr,
+                                      nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+                                      nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsIPrincipal          *aLoadingPrincipal,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+                                      nsILoadGroup          *aLoadGroup = nullptr,
+                                      nsIInterfaceRequestor *aCallbacks = nullptr,
+                                      nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+                                      nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannelWithTriggeringPrincipal(nsIChannel           **outChannel,
+                                      nsIURI                *aUri,
+                                      nsIPrincipal          *aLoadingPrincipal,
+                                      nsIPrincipal          *aTriggeringPrincipal,
+                                      const mozilla::dom::ClientInfo& aLoadingClientInfo,
+                                      const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
+                                      nsSecurityFlags        aSecurityFlags,
+                                      nsContentPolicyType    aContentPolicyType,
++                                     mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+                                      nsILoadGroup          *aLoadGroup = nullptr,
+                                      nsIInterfaceRequestor *aCallbacks = nullptr,
+                                      nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+                                      nsIIOService          *aIoService = nullptr);
+ 
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannel(nsIChannel           **outChannel,
+               nsIURI                *aUri,
+               nsINode               *aLoadingNode,
+               nsSecurityFlags        aSecurityFlags,
+               nsContentPolicyType    aContentPolicyType,
++              mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+               nsILoadGroup          *aLoadGroup = nullptr,
+               nsIInterfaceRequestor *aCallbacks = nullptr,
+               nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+               nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannel(nsIChannel           **outChannel,
+               nsIURI                *aUri,
+               nsIPrincipal          *aLoadingPrincipal,
+               nsSecurityFlags        aSecurityFlags,
+               nsContentPolicyType    aContentPolicyType,
++              mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+               nsILoadGroup          *aLoadGroup = nullptr,
+               nsIInterfaceRequestor *aCallbacks = nullptr,
+               nsLoadFlags            aLoadFlags = nsIRequest::LOAD_NORMAL,
+               nsIIOService          *aIoService = nullptr);
+ 
+ // See NS_NewChannelInternal for usage and argument description
+ nsresult
+ NS_NewChannel(nsIChannel** outChannel,
+               nsIURI* aUri,
+               nsIPrincipal* aLoadingPrincipal,
+               const mozilla::dom::ClientInfo& aLoadingClientInfo,
+               const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
+               nsSecurityFlags aSecurityFlags,
+               nsContentPolicyType aContentPolicyType,
++              mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
+               nsILoadGroup* aLoadGroup = nullptr,
+               nsIInterfaceRequestor* aCallbacks = nullptr,
+               nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
+               nsIIOService* aIoService = nullptr);
+ 
+ nsresult NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument);
+ 
+ nsresult NS_MakeAbsoluteURI(nsACString       &result,
+diff --git a/netwerk/base/nsPACMan.cpp b/netwerk/base/nsPACMan.cpp
+--- a/netwerk/base/nsPACMan.cpp
++++ b/netwerk/base/nsPACMan.cpp
+@@ -494,16 +494,17 @@ nsPACMan::StartLoading()
+       if (pacURI) {
+         nsresult rv = pacURI->GetSpec(mNormalPACURISpec);
+         MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+         NS_NewChannel(getter_AddRefs(channel),
+                       pacURI,
+                       nsContentUtils::GetSystemPrincipal(),
+                       nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                       nsIContentPolicy::TYPE_OTHER,
++                      nullptr, // PerformanceStorage,
+                       nullptr, // aLoadGroup
+                       nullptr, // aCallbacks
+                       nsIRequest::LOAD_NORMAL,
+                       ios);
+       }
+       else {
+         LOG(("nsPACMan::StartLoading Failed pacspec uri conversion %s\n",
+              mPACURISpec.get()));
+diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp
+--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
++++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
+@@ -147,17 +147,17 @@ FTPChannelParent::DoAsyncOpen(const URIP
+   OriginAttributes attrs;
+   rv = loadInfo->GetOriginAttributes(&attrs);
+   if (NS_FAILED(rv)) {
+     return SendFailedAsyncOpen(rv);
+   }
+ 
+   nsCOMPtr<nsIChannel> chan;
+   rv = NS_NewChannelInternal(getter_AddRefs(chan), uri, loadInfo,
+-                             nullptr, nullptr,
++                             nullptr, nullptr, nullptr,
+                              nsIRequest::LOAD_NORMAL, ios);
+ 
+   if (NS_FAILED(rv))
+     return SendFailedAsyncOpen(rv);
+ 
+   mChannel = chan;
+ 
+   // later on mChannel may become an HTTP channel (we'll be redirected to one
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -1776,16 +1776,17 @@ HttpChannelChild::SetupRedirect(nsIURI* 
+   rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsIChannel> newChannel;
+   nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(uri, redirectFlags);
+   rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
+                              uri,
+                              redirectLoadInfo,
++                             nullptr, // PerformanceStorage
+                              nullptr, // aLoadGroup
+                              nullptr, // aCallbacks
+                              nsIRequest::LOAD_NORMAL,
+                              ioService);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   // We won't get OnStartRequest, set cookies here.
+   mResponseHead = new nsHttpResponseHead(*responseHead);
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -526,17 +526,17 @@ HttpChannelParent::DoAsyncOpen(  const U
+   }
+ 
+   if (!loadInfo) {
+     return SendFailedAsyncOpen(NS_ERROR_UNEXPECTED);
+   }
+ 
+   nsCOMPtr<nsIChannel> channel;
+   rv = NS_NewChannelInternal(getter_AddRefs(channel), uri, loadInfo,
+-                             nullptr, nullptr, aLoadFlags, ios);
++                             nullptr, nullptr, nullptr, aLoadFlags, ios);
+   if (NS_FAILED(rv)) {
+     return SendFailedAsyncOpen(rv);
+   }
+ 
+   RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(channel, &rv);
+   if (NS_FAILED(rv)) {
+     return SendFailedAsyncOpen(rv);
+   }
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
++++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+@@ -207,16 +207,17 @@ InterceptedHttpChannel::FollowSyntheticR
+                                                  mRequestHead.ParsedMethod());
+ 
+   nsCOMPtr<nsIChannel> newChannel;
+   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
+     CloneLoadInfoForRedirect(redirectURI, redirectFlags);
+   rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
+                              redirectURI,
+                              redirectLoadInfo,
++                             nullptr, // PerformanceStorage
+                              nullptr, // aLoadGroup
+                              nullptr, // aCallbacks
+                              mLoadFlags,
+                              ioService);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   rv = SetupReplacementChannel(redirectURI, newChannel, !rewriteToGET,
+                                redirectFlags);
+@@ -660,16 +661,17 @@ InterceptedHttpChannel::ResetInterceptio
+   uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
+ 
+   nsCOMPtr<nsIChannel> newChannel;
+   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
+     CloneLoadInfoForRedirect(mURI, flags);
+   nsresult rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
+                                       mURI,
+                                       redirectLoadInfo,
++                                      nullptr, // PerformanceStorage
+                                       nullptr, // aLoadGroup
+                                       nullptr, // aCallbacks
+                                       mLoadFlags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   rv = SetupReplacementChannel(mURI, newChannel, true, flags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp
+--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
++++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
+@@ -1504,16 +1504,17 @@ nsCORSListenerProxy::StartCORSPreflight(
+   // check won't be safe any more.
+   loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER |
+                nsIRequest::LOAD_ANONYMOUS;
+ 
+   nsCOMPtr<nsIChannel> preflightChannel;
+   rv = NS_NewChannelInternal(getter_AddRefs(preflightChannel),
+                              uri,
+                              loadInfo,
++                             nullptr, // PerformanceStorage
+                              loadGroup,
+                              nullptr,   // aCallbacks
+                              loadFlags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   // Set method and headers
+   nsCOMPtr<nsIHttpChannel> preHttp = do_QueryInterface(preflightChannel);
+   NS_ASSERTION(preHttp, "Failed to QI to nsIHttpChannel!");
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -2728,16 +2728,17 @@ nsHttpChannel::StartRedirectChannelToURI
+ 
+     nsCOMPtr<nsIIOService> ioService;
+     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
+                                upgradedURI,
+                                redirectLoadInfo,
++                               nullptr, // PerformanceStorage
+                                nullptr, // aLoadGroup
+                                nullptr, // aCallbacks
+                                nsIRequest::LOAD_NORMAL,
+                                ioService);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     rv = SetupReplacementChannel(upgradedURI, newChannel, true, flags);
+     NS_ENSURE_SUCCESS(rv, rv);
+@@ -5442,16 +5443,17 @@ nsHttpChannel::ContinueProcessRedirectio
+     else
+         redirectFlags = nsIChannelEventSink::REDIRECT_TEMPORARY;
+ 
+     nsCOMPtr<nsIChannel> newChannel;
+     nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(mRedirectURI, redirectFlags);
+     rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
+                                mRedirectURI,
+                                redirectLoadInfo,
++                               nullptr, // PerformanceStorage
+                                nullptr, // aLoadGroup
+                                nullptr, // aCallbacks
+                                nsIRequest::LOAD_NORMAL,
+                                ioService);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     rv = SetupReplacementChannel(mRedirectURI, newChannel,
+                                  !rewriteToGET, redirectFlags);
+@@ -8365,16 +8367,17 @@ nsresult nsHttpChannel::OnPush(const nsA
+     nsCOMPtr<nsIIOService> ioService;
+     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     nsCOMPtr<nsIChannel> pushChannel;
+     rv = NS_NewChannelInternal(getter_AddRefs(pushChannel),
+                                pushResource,
+                                mLoadInfo,
++                               nullptr, // PerformanceStorage
+                                nullptr, // aLoadGroup
+                                nullptr, // aCallbacks
+                                nsIRequest::LOAD_NORMAL,
+                                ioService);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     nsCOMPtr<nsIHttpChannel> pushHttpChannel = do_QueryInterface(pushChannel);
+     MOZ_ASSERT(pushHttpChannel);
+diff --git a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
++++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+@@ -112,16 +112,17 @@ WyciwygChannelParent::RecvInit(const URI
+ 
+   nsCOMPtr<nsIChannel> chan;
+   rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(chan),
+                                            uri,
+                                            requestingPrincipal,
+                                            triggeringPrincipal,
+                                            aSecurityFlags,
+                                            aContentPolicyType,
++                                           nullptr,   // PerformanceStorage
+                                            nullptr,   // loadGroup
+                                            nullptr,   // aCallbacks
+                                            nsIRequest::LOAD_NORMAL,
+                                            ios);
+ 
+   if (NS_FAILED(rv)) {
+     if (!SendCancelEarly(rv)) {
+       return IPC_FAIL_NO_REASON(this);
+diff --git a/rdf/base/nsRDFXMLDataSource.cpp b/rdf/base/nsRDFXMLDataSource.cpp
+--- a/rdf/base/nsRDFXMLDataSource.cpp
++++ b/rdf/base/nsRDFXMLDataSource.cpp
+@@ -936,16 +936,17 @@ RDFXMLDataSourceImpl::Refresh(bool aBloc
+     else {
+         // Null LoadGroup ?
+         nsCOMPtr<nsIChannel> channel;
+         rv = NS_NewChannel(getter_AddRefs(channel),
+                            mURL,
+                            nsContentUtils::GetSystemPrincipal(),
+                            nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                            nsIContentPolicy::TYPE_OTHER,
++                           nullptr, // aPerformanceStorage
+                            nullptr, // aLoadGroup
+                            this);   // aCallbacks
+         NS_ENSURE_SUCCESS(rv, rv);
+         rv = channel->AsyncOpen2(this);
+         NS_ENSURE_SUCCESS(rv, rv);
+ 
+         // So we don't try to issue two asynchronous loads at once.
+         mLoadState = eLoadState_Pending;
+diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
++++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+@@ -2105,16 +2105,17 @@ nsUrlClassifierDBService::SendThreatHitR
+                        nsIChannel::LOAD_BYPASS_CACHE;
+ 
+   nsCOMPtr<nsIChannel> reportChannel;
+   rv = NS_NewChannel(getter_AddRefs(reportChannel),
+                      reportURI,
+                      nsContentUtils::GetSystemPrincipal(),
+                      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                      nsIContentPolicy::TYPE_OTHER,
++                     nullptr,  // aPerformanceStorage
+                      nullptr,  // aLoadGroup
+                      nullptr,
+                      loadFlags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   // Safe Browsing has a separate cookie jar
+   nsCOMPtr<nsILoadInfo> loadInfo = reportChannel->GetLoadInfo();
+   mozilla::OriginAttributes attrs;
+diff --git a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
++++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+@@ -133,16 +133,17 @@ nsUrlClassifierStreamUpdater::FetchUpdat
+   nsresult rv;
+   uint32_t loadFlags = nsIChannel::INHIBIT_CACHING |
+                        nsIChannel::LOAD_BYPASS_CACHE;
+   rv = NS_NewChannel(getter_AddRefs(mChannel),
+                      aUpdateUrl,
+                      nsContentUtils::GetSystemPrincipal(),
+                      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                      nsIContentPolicy::TYPE_OTHER,
++                     nullptr,  // aPerformanceStorage
+                      nullptr,  // aLoadGroup
+                      this,     // aInterfaceRequestor
+                      loadFlags);
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
+   mozilla::OriginAttributes attrs;
+diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.cpp b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
++++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+@@ -176,16 +176,17 @@ nsManifestCheck::Begin()
+ 
+     rv = mManifestHash->Init(nsICryptoHash::MD5);
+     NS_ENSURE_SUCCESS(rv, rv);
+     rv = NS_NewChannel(getter_AddRefs(mChannel),
+                        mURI,
+                        mLoadingPrincipal,
+                        nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,   // PerformanceStorage
+                        nullptr,   // loadGroup
+                        nullptr,   // aCallbacks
+                        nsIRequest::LOAD_BYPASS_CACHE);
+ 
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     // configure HTTP specific stuff
+     nsCOMPtr<nsIHttpChannel> httpChannel =
+@@ -373,16 +374,17 @@ nsOfflineCacheUpdateItem::OpenChannel(ns
+ 
+     flags |= mLoadFlags;
+ 
+     rv = NS_NewChannel(getter_AddRefs(mChannel),
+                        mURI,
+                        mLoadingPrincipal,
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr,   // PerformanceStorage
+                        nullptr,  // aLoadGroup
+                        this,     // aCallbacks
+                        flags);
+ 
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
+         do_QueryInterface(mChannel, &rv);
+diff --git a/uriloader/prefetch/nsPrefetchService.cpp b/uriloader/prefetch/nsPrefetchService.cpp
+--- a/uriloader/prefetch/nsPrefetchService.cpp
++++ b/uriloader/prefetch/nsPrefetchService.cpp
+@@ -147,16 +147,17 @@ nsPrefetchNode::OpenChannel()
+                                         mURI,
+                                         source,
+                                         source->NodePrincipal(),
+                                         nullptr,   //aTriggeringPrincipal
+                                         Maybe<ClientInfo>(),
+                                         Maybe<ServiceWorkerDescriptor>(),
+                                         securityFlags,
+                                         mPolicyType,
++                                        nullptr,   // aPerformanceStorage
+                                         loadGroup, // aLoadGroup
+                                         this,      // aCallbacks
+                                         nsIRequest::LOAD_BACKGROUND |
+                                         nsICachingChannel::LOAD_ONLY_IF_MODIFIED);
+ 
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     // configure HTTP specific stuff
+diff --git a/widget/windows/nsDataObj.cpp b/widget/windows/nsDataObj.cpp
+--- a/widget/windows/nsDataObj.cpp
++++ b/widget/windows/nsDataObj.cpp
+@@ -72,16 +72,17 @@ nsresult nsDataObj::CStream::Init(nsIURI
+     return NS_ERROR_FAILURE;
+   }
+   nsresult rv;
+   rv = NS_NewChannel(getter_AddRefs(mChannel),
+                      pSourceURI,
+                      aRequestingPrincipal,
+                      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS,
+                      aContentPolicyType,
++                     nullptr,   // PerformanceStorage
+                      nullptr,   // loadGroup
+                      nullptr,   // aCallbacks
+                      nsIRequest::LOAD_FROM_CACHE);
+ 
+   NS_ENSURE_SUCCESS(rv, rv);
+   rv = mChannel->AsyncOpen2(this);
+   NS_ENSURE_SUCCESS(rv, rv);
+   return NS_OK;
+diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/directory/nsDirectoryViewer.cpp
+--- a/xpfe/components/directory/nsDirectoryViewer.cpp
++++ b/xpfe/components/directory/nsDirectoryViewer.cpp
+@@ -1276,16 +1276,17 @@ nsDirectoryViewerFactory::CreateInstance
+     if (NS_FAILED(rv)) return rv;
+ 
+     nsCOMPtr<nsIChannel> channel;
+     rv = NS_NewChannel(getter_AddRefs(channel),
+                        uri,
+                        nsContentUtils::GetSystemPrincipal(),
+                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                        nsIContentPolicy::TYPE_OTHER,
++                       nullptr, // PerformanceStorage
+                        aLoadGroup);
+     if (NS_FAILED(rv)) return rv;
+ 
+     nsCOMPtr<nsIStreamListener> listener;
+     rv = factory->CreateInstance(aCommand, channel, aLoadGroup,
+                                  NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"),
+                                  aContainer, aExtraInfo, getter_AddRefs(listener),
+                                  aDocViewerResult);

+ 417 - 0
mozilla-release/patches/1425458-1-60a1.patch

@@ -0,0 +1,417 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810651 -3600
+# Node ID 8101a66c3180397c79a8e9bb18f5ade2b19cf976
+# Parent  0c35592dedc4f130cdc889fca1417d81a5721456
+Bug 1425458 - Resource timing entries Workers - part 1 - PerformanceStorage on main-thread, r=smaug
+
+diff --git a/dom/performance/Performance.h b/dom/performance/Performance.h
+--- a/dom/performance/Performance.h
++++ b/dom/performance/Performance.h
+@@ -8,28 +8,28 @@
+ #define mozilla_dom_Performance_h
+ 
+ #include "mozilla/Attributes.h"
+ #include "mozilla/DOMEventTargetHelper.h"
+ #include "nsCOMPtr.h"
+ #include "nsDOMNavigationTiming.h"
+ 
+ class nsITimedChannel;
+-class nsIHttpChannel;
+ 
+ namespace mozilla {
+ 
+ class ErrorResult;
+ 
+ namespace dom {
+ 
+ class PerformanceEntry;
+ class PerformanceNavigation;
+ class PerformanceObserver;
+ class PerformanceService;
++class PerformanceStorage;
+ class PerformanceTiming;
+ 
+ namespace workers {
+ class WorkerPrivate;
+ }
+ 
+ // Base class for main-thread and worker Performance API
+ class Performance : public DOMEventTargetHelper
+@@ -56,18 +56,17 @@ public:
+ 
+   virtual void GetEntriesByType(const nsAString& aEntryType,
+                                 nsTArray<RefPtr<PerformanceEntry>>& aRetval);
+ 
+   virtual void GetEntriesByName(const nsAString& aName,
+                                 const Optional<nsAString>& aEntryType,
+                                 nsTArray<RefPtr<PerformanceEntry>>& aRetval);
+ 
+-  virtual void AddEntry(nsIHttpChannel* channel,
+-                        nsITimedChannel* timedChannel) = 0;
++  virtual PerformanceStorage* AsPerformanceStorage() = 0;
+ 
+   void ClearResourceTimings();
+ 
+   DOMHighResTimeStamp Now() const;
+ 
+   DOMHighResTimeStamp TimeOrigin();
+ 
+   void Mark(const nsAString& aName, ErrorResult& aRv);
+diff --git a/dom/performance/PerformanceMainThread.h b/dom/performance/PerformanceMainThread.h
+--- a/dom/performance/PerformanceMainThread.h
++++ b/dom/performance/PerformanceMainThread.h
+@@ -3,31 +3,38 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef mozilla_dom_PerformanceMainThread_h
+ #define mozilla_dom_PerformanceMainThread_h
+ 
+ #include "Performance.h"
++#include "PerformanceStorage.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class PerformanceMainThread final : public Performance
++                                  , public PerformanceStorage
+ {
+ public:
+   PerformanceMainThread(nsPIDOMWindowInner* aWindow,
+                         nsDOMNavigationTiming* aDOMTiming,
+                         nsITimedChannel* aChannel);
+ 
+   NS_DECL_ISUPPORTS_INHERITED
+   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PerformanceMainThread,
+                                                          Performance)
+ 
++  PerformanceStorage* AsPerformanceStorage() override
++  {
++    return this;
++  }
++
+   virtual PerformanceTiming* Timing() override;
+ 
+   virtual PerformanceNavigation* Navigation() override;
+ 
+   virtual void AddEntry(nsIHttpChannel* channel,
+                         nsITimedChannel* timedChannel) override;
+ 
+   TimeStamp CreationTimeStamp() const override;
+diff --git a/dom/performance/PerformanceWorker.h b/dom/performance/PerformanceWorker.h
+--- a/dom/performance/PerformanceWorker.h
++++ b/dom/performance/PerformanceWorker.h
+@@ -16,34 +16,34 @@ namespace workers {
+ class WorkerPrivate;
+ }
+ 
+ class PerformanceWorker final : public Performance
+ {
+ public:
+   explicit PerformanceWorker(workers::WorkerPrivate* aWorkerPrivate);
+ 
++  PerformanceStorage* AsPerformanceStorage() override
++  {
++    MOZ_CRASH("This should not be called on workers.");
++    return nullptr;
++  }
++
+   virtual PerformanceTiming* Timing() override
+   {
+     MOZ_CRASH("This should not be called on workers.");
+     return nullptr;
+   }
+ 
+   virtual PerformanceNavigation* Navigation() override
+   {
+     MOZ_CRASH("This should not be called on workers.");
+     return nullptr;
+   }
+ 
+-  virtual void AddEntry(nsIHttpChannel* channel,
+-                        nsITimedChannel* timedChannel) override
+-  {
+-    MOZ_CRASH("This should not be called on workers.");
+-  }
+-
+   TimeStamp CreationTimeStamp() const override;
+ 
+   DOMHighResTimeStamp CreationTime() const override;
+ 
+   virtual void GetMozMemory(JSContext *aCx,
+                             JS::MutableHandle<JSObject*> aObj) override
+   {
+     MOZ_CRASH("This should not be called on workers.");
+diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
+--- a/netwerk/protocol/http/HttpBaseChannel.cpp
++++ b/netwerk/protocol/http/HttpBaseChannel.cpp
+@@ -37,16 +37,17 @@
+ #include "nsIMutableArray.h"
+ #include "nsIScriptSecurityManager.h"
+ #include "nsIObserverService.h"
+ #include "nsProxyRelease.h"
+ #include "nsPIDOMWindow.h"
+ #include "nsIDocShell.h"
+ #include "nsINetworkInterceptController.h"
+ #include "mozilla/dom/Performance.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozIThirdPartyUtil.h"
+ #include "nsStreamUtils.h"
+ #include "nsThreadUtils.h"
+ #include "nsContentSecurityManager.h"
+ #include "nsIChannelEventSink.h"
+ #include "nsILoadGroupChild.h"
+ #include "mozilla/ConsoleReportCollector.h"
+ #include "LoadInfo.h"
+@@ -4160,18 +4161,18 @@ IMPL_TIMING_ATTR(ResponseStart)
+ IMPL_TIMING_ATTR(ResponseEnd)
+ IMPL_TIMING_ATTR(CacheReadStart)
+ IMPL_TIMING_ATTR(CacheReadEnd)
+ IMPL_TIMING_ATTR(RedirectStart)
+ IMPL_TIMING_ATTR(RedirectEnd)
+ 
+ #undef IMPL_TIMING_ATTR
+ 
+-mozilla::dom::Performance*
+-HttpBaseChannel::GetPerformance()
++mozilla::dom::PerformanceStorage*
++HttpBaseChannel::GetPerformanceStorage()
+ {
+   // If performance timing is disabled, there is no need for the Performance
+   // object anymore.
+   if (!mTimingEnabled) {
+     return nullptr;
+   }
+ 
+   // There is no point in continuing, since the performance object in the parent
+@@ -4179,16 +4180,22 @@ HttpBaseChannel::GetPerformance()
+   if (XRE_IsE10sParentProcess()) {
+     return nullptr;
+   }
+ 
+   if (!mLoadInfo) {
+     return nullptr;
+   }
+ 
++  // If a custom performance storage is set, let's use it.
++  mozilla::dom::PerformanceStorage* performanceStorage = mLoadInfo->GetPerformanceStorage();
++  if (performanceStorage) {
++    return performanceStorage;
++  }
++
+   // We don't need to report the resource timing entry for a TYPE_DOCUMENT load.
+   if (mLoadInfo->GetExternalContentPolicyType() == nsIContentPolicyBase::TYPE_DOCUMENT) {
+     return nullptr;
+   }
+ 
+   nsCOMPtr<nsIDOMDocument> domDocument;
+   mLoadInfo->GetLoadingDocument(getter_AddRefs(domDocument));
+   if (!domDocument) {
+@@ -4208,22 +4215,22 @@ HttpBaseChannel::GetPerformance()
+     return nullptr;
+   }
+ 
+   nsCOMPtr<nsPIDOMWindowInner> innerWindow = loadingDocument->GetInnerWindow();
+   if (!innerWindow) {
+     return nullptr;
+   }
+ 
+-  mozilla::dom::Performance* docPerformance = innerWindow->GetPerformance();
+-  if (!docPerformance) {
++  mozilla::dom::Performance* performance = innerWindow->GetPerformance();
++  if (!performance) {
+     return nullptr;
+   }
+ 
+-  return docPerformance;
++  return performance->AsPerformanceStorage();
+ }
+ 
+ NS_IMETHODIMP
+ HttpBaseChannel::SetReportResourceTiming(bool enabled) {
+   mReportTiming = enabled;
+   return NS_OK;
+ }
+ 
+diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
+--- a/netwerk/protocol/http/HttpBaseChannel.h
++++ b/netwerk/protocol/http/HttpBaseChannel.h
+@@ -57,17 +57,17 @@
+ 
+ 
+ class nsISecurityConsoleMessage;
+ class nsIPrincipal;
+ 
+ namespace mozilla {
+ 
+ namespace dom {
+-class Performance;
++class PerformanceStorage;
+ }
+ 
+ class LogCollector;
+ 
+ namespace net {
+ extern mozilla::LazyLogModule gHttpLog;
+ 
+ /*
+@@ -420,17 +420,17 @@ protected:
+   virtual void ReleaseListeners();
+ 
+   // This is fired only when a cookie is created due to the presence of
+   // Set-Cookie header in the response header of any network request.
+   // This notification will come only after the "http-on-examine-response"
+   // was fired.
+   void NotifySetCookie(char const *aCookie);
+ 
+-  mozilla::dom::Performance* GetPerformance();
++  mozilla::dom::PerformanceStorage* GetPerformanceStorage();
+   nsIURI* GetReferringPage();
+   nsPIDOMWindowInner* GetInnerDOMWindow();
+ 
+   void AddCookiesToRequest();
+   virtual MOZ_MUST_USE nsresult
+   SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod,
+                           uint32_t redirectFlags);
+ 
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -30,17 +30,17 @@
+ #include "nsContentPolicyUtils.h"
+ #include "nsGlobalWindow.h"
+ #include "nsStringStream.h"
+ #include "nsHttpChannel.h"
+ #include "nsHttpHandler.h"
+ #include "nsNetUtil.h"
+ #include "nsSerializationHelper.h"
+ #include "mozilla/Attributes.h"
+-#include "mozilla/dom/Performance.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "mozilla/ipc/InputStreamUtils.h"
+ #include "mozilla/ipc/URIUtils.h"
+ #include "mozilla/ipc/BackgroundUtils.h"
+ #include "mozilla/net/ChannelDiverterChild.h"
+ #include "mozilla/net/DNS.h"
+ #include "SerializedLoadContext.h"
+ #include "nsInputStreamPump.h"
+ #include "InterceptedChannel.h"
+@@ -1221,19 +1221,19 @@ void
+ HttpChannelChild::DoPreOnStopRequest(nsresult aStatus)
+ {
+   LOG(("HttpChannelChild::DoPreOnStopRequest [this=%p status=%" PRIx32 "]\n",
+        this, static_cast<uint32_t>(aStatus)));
+   mIsPending = false;
+ 
+   MaybeCallSynthesizedCallback();
+ 
+-  Performance* documentPerformance = GetPerformance();
+-  if (documentPerformance) {
+-      documentPerformance->AddEntry(this, this);
++  PerformanceStorage* performanceStorage = GetPerformanceStorage();
++  if (performanceStorage) {
++      performanceStorage->AddEntry(this, this);
+   }
+ 
+   if (!mCanceled && NS_SUCCEEDED(mStatus)) {
+     mStatus = aStatus;
+   }
+ }
+ 
+ void
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
++++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+@@ -2,17 +2,17 @@
+ /* vim: set sw=2 ts=8 et 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 "InterceptedHttpChannel.h"
+ #include "nsContentSecurityManager.h"
+ #include "nsEscape.h"
+-#include "mozilla/dom/Performance.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ 
+ namespace mozilla {
+ namespace net {
+ 
+ NS_IMPL_ISUPPORTS_INHERITED(InterceptedHttpChannel,
+                             HttpBaseChannel,
+                             nsIInterceptedChannel,
+                             nsICacheInfoChannel,
+@@ -1030,20 +1030,20 @@ InterceptedHttpChannel::OnStopRequest(ns
+   // Its possible that we have any async runnable queued to report some
+   // progress when OnStopRequest() is triggered.  Report any left over
+   // progress immediately.  The extra runnable will then do nothing thanks
+   // to the ReleaseListeners() call below.
+   MaybeCallStatusAndProgress();
+ 
+   mIsPending = false;
+ 
+-  // Register entry to the Performance resource timing
+-  mozilla::dom::Performance* documentPerformance = GetPerformance();
+-  if (documentPerformance) {
+-    documentPerformance->AddEntry(this, this);
++  // Register entry to the PerformanceStorage resource timing
++  mozilla::dom::PerformanceStorage* performanceStorage = GetPerformanceStorage();
++  if (performanceStorage) {
++    performanceStorage->AddEntry(this, this);
+   }
+ 
+   if (mListener) {
+     mListener->OnStopRequest(this, mListenerContext, mStatus);
+   }
+ 
+   gHttpHandler->OnStopRequest(this);
+ 
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -81,17 +81,17 @@
+ #include "nsInputStreamPump.h"
+ #include "nsURLHelper.h"
+ #include "nsISocketTransport.h"
+ #include "nsIStreamConverterService.h"
+ #include "nsISiteSecurityService.h"
+ #include "nsString.h"
+ #include "nsCRT.h"
+ #include "CacheObserver.h"
+-#include "mozilla/dom/Performance.h"
++#include "mozilla/dom/PerformanceStorage.h"
+ #include "AlternateServices.h"
+ #include "InterceptedChannel.h"
+ #include "nsIHttpPushListener.h"
+ #include "nsIX509Cert.h"
+ #include "ScopedNSSTypes.h"
+ #include "NullPrincipal.h"
+ #include "nsIDeprecationWarner.h"
+ #include "nsIDocument.h"
+@@ -7187,20 +7187,20 @@ nsHttpChannel::OnStopRequest(nsIRequest 
+                 LOG(("FinalizeCacheEntry failed (%08x)",
+                      static_cast<uint32_t>(rv)));
+             }
+         }
+     }
+ 
+     ReportRcwnStats(isFromNet);
+ 
+-    // Register entry to the Performance resource timing
+-    mozilla::dom::Performance* documentPerformance = GetPerformance();
+-    if (documentPerformance) {
+-        documentPerformance->AddEntry(this, this);
++    // Register entry to the PerformanceStorage resource timing
++    mozilla::dom::PerformanceStorage* performanceStorage = GetPerformanceStorage();
++    if (performanceStorage) {
++        performanceStorage->AddEntry(this, this);
+     }
+ 
+     if (mListener) {
+         LOG(("nsHttpChannel %p calling OnStopRequest\n", this));
+         MOZ_ASSERT(mOnStartRequestCalled,
+                    "OnStartRequest should be called before OnStopRequest");
+         MOZ_ASSERT(!mOnStopRequestCalled,
+                    "We should not call OnStopRequest twice");

+ 1575 - 0
mozilla-release/patches/1425458-2-60a1.patch

@@ -0,0 +1,1575 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810651 -3600
+# Node ID cd25cfc3defe1fe948e0d6b408d841bce491a631
+# Parent  35b7f1030b102f9eebd55b0902e7cdfc3e917a23
+Bug 1425458 - Resource timing entries Workers - part 2 - PerformanceTimingData, r=smaug
+
+diff --git a/dom/performance/PerformanceMainThread.cpp b/dom/performance/PerformanceMainThread.cpp
+--- a/dom/performance/PerformanceMainThread.cpp
++++ b/dom/performance/PerformanceMainThread.cpp
+@@ -154,24 +154,24 @@ PerformanceMainThread::AddEntry(nsIHttpC
+     }
+ 
+     // The nsITimedChannel argument will be used to gather all the timings.
+     // The nsIHttpChannel argument will be used to check if any cross-origin
+     // redirects occurred.
+     // The last argument is the "zero time" (offset). Since we don't want
+     // any offset for the resource timing, this will be set to "0" - the
+     // resource timing returns a relative timing (no offset).
+-    RefPtr<PerformanceTiming> performanceTiming =
+-        new PerformanceTiming(this, timedChannel, channel,
+-            0);
++    UniquePtr<PerformanceTimingData> performanceTimingData(
++        new PerformanceTimingData(timedChannel, channel, 0));
+ 
+     // The PerformanceResourceTiming object will use the PerformanceTiming
+     // object to get all the required timings.
+     RefPtr<PerformanceResourceTiming> performanceEntry =
+-      new PerformanceResourceTiming(performanceTiming, this, entryName, channel);
++      new PerformanceResourceTiming(Move(performanceTimingData), this,
++                                    entryName);
+ 
+     // If the initiator type had no valid value, then set it to the default
+     // ("other") value.
+     if (initiatorType.IsEmpty()) {
+       initiatorType = NS_LITERAL_STRING("other");
+     }
+     performanceEntry->SetInitiatorType(initiatorType);
+     InsertResourceEntry(performanceEntry);
+@@ -320,21 +320,25 @@ PerformanceMainThread::CreationTime() co
+ {
+   return GetDOMTiming()->GetNavigationStart();
+ }
+ 
+ void
+ PerformanceMainThread::EnsureDocEntry()
+ {
+   if (!mDocEntry && nsContentUtils::IsPerformanceNavigationTimingEnabled()) {
++    UniquePtr<PerformanceTimingData> timing(
++      new PerformanceTimingData(mChannel, nullptr, 0));
++
+     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
+-    RefPtr<PerformanceTiming> timing =
+-      new PerformanceTiming(this, mChannel, nullptr, 0);
+-    mDocEntry = new PerformanceNavigationTiming(timing, this,
+-                                                httpChannel);
++    if (httpChannel) {
++      timing->SetPropertiesFromHttpChannel(httpChannel);
++    }
++
++    mDocEntry = new PerformanceNavigationTiming(Move(timing), this);
+   }
+ }
+ 
+ 
+ void
+ PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
+ {
+   // We return an empty list when 'privacy.resistFingerprinting' is on.
+diff --git a/dom/performance/PerformanceNavigation.cpp b/dom/performance/PerformanceNavigation.cpp
+--- a/dom/performance/PerformanceNavigation.cpp
++++ b/dom/performance/PerformanceNavigation.cpp
+@@ -31,13 +31,13 @@ PerformanceNavigation::WrapObject(JSCont
+                                   JS::Handle<JSObject*> aGivenProto)
+ {
+   return PerformanceNavigationBinding::Wrap(cx, this, aGivenProto);
+ }
+ 
+ uint16_t
+ PerformanceNavigation::RedirectCount() const
+ {
+-  return GetPerformanceTiming()->GetRedirectCount();
++  return GetPerformanceTiming()->Data()->GetRedirectCount();
+ }
+ 
+ } // dom namespace
+ } // mozilla namespace
+diff --git a/dom/performance/PerformanceNavigationTiming.cpp b/dom/performance/PerformanceNavigationTiming.cpp
+--- a/dom/performance/PerformanceNavigationTiming.cpp
++++ b/dom/performance/PerformanceNavigationTiming.cpp
+@@ -19,65 +19,65 @@ JSObject*
+ PerformanceNavigationTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+   return PerformanceNavigationTimingBinding::Wrap(aCx, this, aGivenProto);
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::UnloadEventStart() const
+ {
+-  return mTiming->GetDOMTiming()->GetUnloadEventStartHighRes();
++  return mPerformance->GetDOMTiming()->GetUnloadEventStartHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::UnloadEventEnd() const
+ {
+-  return mTiming->GetDOMTiming()->GetUnloadEventEndHighRes();
++  return mPerformance->GetDOMTiming()->GetUnloadEventEndHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::DomInteractive() const
+ {
+-  return mTiming->GetDOMTiming()->GetDomInteractiveHighRes();
++  return mPerformance->GetDOMTiming()->GetDomInteractiveHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::DomContentLoadedEventStart() const
+ {
+-  return mTiming->GetDOMTiming()->GetDomContentLoadedEventStartHighRes();
++  return mPerformance->GetDOMTiming()->GetDomContentLoadedEventStartHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::DomContentLoadedEventEnd() const
+ {
+-  return mTiming->GetDOMTiming()->GetDomContentLoadedEventEndHighRes();
++  return mPerformance->GetDOMTiming()->GetDomContentLoadedEventEndHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::DomComplete() const
+ {
+-  return mTiming->GetDOMTiming()->GetDomCompleteHighRes();
++  return mPerformance->GetDOMTiming()->GetDomCompleteHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::LoadEventStart() const
+ {
+-  return mTiming->GetDOMTiming()->GetLoadEventStartHighRes();
++  return mPerformance->GetDOMTiming()->GetLoadEventStartHighRes();
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceNavigationTiming::LoadEventEnd() const
+ {
+-  return mTiming->GetDOMTiming()->GetLoadEventEndHighRes();
++  return mPerformance->GetDOMTiming()->GetLoadEventEndHighRes();
+ }
+ 
+ NavigationType
+ PerformanceNavigationTiming::Type() const
+ {
+-  switch(mTiming->GetDOMTiming()->GetType()) {
++  switch(mPerformance->GetDOMTiming()->GetType()) {
+     case nsDOMNavigationTiming::TYPE_NAVIGATE:
+       return NavigationType::Navigate;
+       break;
+     case nsDOMNavigationTiming::TYPE_RELOAD:
+       return NavigationType::Reload;
+       break;
+     case nsDOMNavigationTiming::TYPE_BACK_FORWARD:
+       return NavigationType::Back_forward;
+@@ -87,10 +87,10 @@ PerformanceNavigationTiming::Type() cons
+       // We fallback to the default of Navigate.
+       return NavigationType::Navigate;
+   }
+ }
+ 
+ uint16_t
+ PerformanceNavigationTiming::RedirectCount() const
+ {
+-  return mTiming->GetRedirectCount();
++  return mTimingData->GetRedirectCount();
+ }
+diff --git a/dom/performance/PerformanceNavigationTiming.h b/dom/performance/PerformanceNavigationTiming.h
+--- a/dom/performance/PerformanceNavigationTiming.h
++++ b/dom/performance/PerformanceNavigationTiming.h
+@@ -24,21 +24,20 @@ class PerformanceNavigationTiming final
+ {
+ public:
+   NS_DECL_ISUPPORTS_INHERITED
+ 
+   // Note that aPerformanceTiming must be initalized with zeroTime = 0
+   // so that timestamps are relative to startTime, as opposed to the
+   // performance.timing object for which timestamps are absolute and has a
+   // zeroTime initialized to navigationStart
+-  explicit PerformanceNavigationTiming(PerformanceTiming* aPerformanceTiming,
+-                                       Performance* aPerformance,
+-                                       nsIHttpChannel* aChannel)
+-    : PerformanceResourceTiming(aPerformanceTiming, aPerformance,
+-                                NS_LITERAL_STRING("document"), aChannel) {
++  PerformanceNavigationTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
++                              Performance* aPerformance)
++    : PerformanceResourceTiming(Move(aPerformanceTiming), aPerformance,
++                                NS_LITERAL_STRING("document")) {
+       SetEntryType(NS_LITERAL_STRING("navigation"));
+       SetInitiatorType(NS_LITERAL_STRING("navigation"));
+     }
+ 
+   DOMHighResTimeStamp Duration() const override
+   {
+     return nsRFPService::ReduceTimePrecisionAsMSecs(LoadEventEnd() - StartTime());
+   }
+diff --git a/dom/performance/PerformanceResourceTiming.cpp b/dom/performance/PerformanceResourceTiming.cpp
+--- a/dom/performance/PerformanceResourceTiming.cpp
++++ b/dom/performance/PerformanceResourceTiming.cpp
+@@ -6,90 +6,60 @@
+ 
+ #include "PerformanceResourceTiming.h"
+ #include "mozilla/dom/PerformanceResourceTimingBinding.h"
+ 
+ using namespace mozilla::dom;
+ 
+ NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceResourceTiming,
+                                    PerformanceEntry,
+-                                   mTiming)
++                                   mPerformance)
+ 
+ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceResourceTiming,
+                                                PerformanceEntry)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_END
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceResourceTiming)
+ NS_INTERFACE_MAP_END_INHERITING(PerformanceEntry)
+ 
+ NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
+ NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
+ 
+-PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
++PerformanceResourceTiming::PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
+                                                      Performance* aPerformance,
+-                                                     const nsAString& aName,
+-                                                     nsIHttpChannel* aChannel)
+-: PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource")),
+-  mTiming(aPerformanceTiming),
+-  mEncodedBodySize(0),
+-  mTransferSize(0),
+-  mDecodedBodySize(0)
++                                                     const nsAString& aName)
++  : PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource"))
++  , mTimingData(Move(aPerformanceTiming))
++  , mPerformance(aPerformance)
+ {
+   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
+-  SetPropertiesFromChannel(aChannel);
+-}
+-
+-void
+-PerformanceResourceTiming::SetPropertiesFromChannel(nsIHttpChannel* aChannel)
+-{
+-  if (!aChannel) {
+-    return;
+-  }
+-
+-  nsAutoCString protocol;
+-  Unused << aChannel->GetProtocolVersion(protocol);
+-  SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
+-
+-  uint64_t encodedBodySize = 0;
+-  Unused << aChannel->GetEncodedBodySize(&encodedBodySize);
+-  SetEncodedBodySize(encodedBodySize);
+-
+-  uint64_t transferSize = 0;
+-  Unused << aChannel->GetTransferSize(&transferSize);
+-  SetTransferSize(transferSize);
+-
+-  uint64_t decodedBodySize = 0;
+-  Unused << aChannel->GetDecodedBodySize(&decodedBodySize);
+-  if (decodedBodySize == 0) {
+-    decodedBodySize = encodedBodySize;
+-  }
+-  SetDecodedBodySize(decodedBodySize);
+ }
+ 
+ PerformanceResourceTiming::~PerformanceResourceTiming()
+ {
+ }
+ 
+ DOMHighResTimeStamp
+ PerformanceResourceTiming::StartTime() const
+ {
+   // Force the start time to be the earliest of:
+   //  - RedirectStart
+   //  - WorkerStart
+   //  - AsyncOpen
+   // Ignore zero values.  The RedirectStart and WorkerStart values
+   // can come from earlier redirected channels prior to the AsyncOpen
+   // time being recorded.
+-  DOMHighResTimeStamp redirect = mTiming->RedirectStartHighRes();
++  DOMHighResTimeStamp redirect =
++    mTimingData->RedirectStartHighRes(mPerformance);
+   redirect = redirect ? redirect : DBL_MAX;
+ 
+-  DOMHighResTimeStamp worker = mTiming->WorkerStartHighRes();
++  DOMHighResTimeStamp worker = mTimingData->WorkerStartHighRes(mPerformance);
+   worker = worker ? worker : DBL_MAX;
+ 
+-  DOMHighResTimeStamp asyncOpen = mTiming->AsyncOpenHighRes();
++  DOMHighResTimeStamp asyncOpen = mTimingData->AsyncOpenHighRes(mPerformance);
+ 
+   return std::min(asyncOpen, std::min(redirect, worker));
+ }
+ 
+ JSObject*
+ PerformanceResourceTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+   return PerformanceResourceTimingBinding::Wrap(aCx, this, aGivenProto);
+@@ -101,10 +71,12 @@ PerformanceResourceTiming::SizeOfIncludi
+   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+ }
+ 
+ size_t
+ PerformanceResourceTiming::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+ {
+   return PerformanceEntry::SizeOfExcludingThis(aMallocSizeOf) +
+          mInitiatorType.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+-         mNextHopProtocol.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
++         (mTimingData
++            ? mTimingData->NextHopProtocol().SizeOfExcludingThisIfUnshared(aMallocSizeOf)
++            : 0);
+ }
+diff --git a/dom/performance/PerformanceResourceTiming.h b/dom/performance/PerformanceResourceTiming.h
+--- a/dom/performance/PerformanceResourceTiming.h
++++ b/dom/performance/PerformanceResourceTiming.h
+@@ -2,19 +2,18 @@
+ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef mozilla_dom_PerformanceResourceTiming_h___
+ #define mozilla_dom_PerformanceResourceTiming_h___
+ 
++#include "mozilla/UniquePtr.h"
+ #include "nsCOMPtr.h"
+-#include "nsIChannel.h"
+-#include "nsITimedChannel.h"
+ #include "Performance.h"
+ #include "PerformanceEntry.h"
+ #include "PerformanceTiming.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ // http://www.w3.org/TR/resource-timing/#performanceresourcetiming
+@@ -23,20 +22,19 @@ class PerformanceResourceTiming : public
+ public:
+   typedef mozilla::TimeStamp TimeStamp;
+ 
+   NS_DECL_ISUPPORTS_INHERITED
+   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
+       PerformanceResourceTiming,
+       PerformanceEntry)
+ 
+-  PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
++  PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTimingData,
+                             Performance* aPerformance,
+-                            const nsAString& aName,
+-                            nsIHttpChannel* aChannel = nullptr);
++                            const nsAString& aName);
+ 
+   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+ 
+ 
+   virtual DOMHighResTimeStamp StartTime() const override;
+ 
+   virtual DOMHighResTimeStamp Duration() const override
+   {
+@@ -50,150 +48,128 @@ public:
+ 
+   void SetInitiatorType(const nsAString& aInitiatorType)
+   {
+     mInitiatorType = aInitiatorType;
+   }
+ 
+   void GetNextHopProtocol(nsAString& aNextHopProtocol) const
+   {
+-    aNextHopProtocol = mNextHopProtocol;
+-  }
+-
+-  void SetNextHopProtocol(const nsAString& aNextHopProtocol)
+-  {
+-    mNextHopProtocol = aNextHopProtocol;
++    if (mTimingData) {
++      aNextHopProtocol = mTimingData->NextHopProtocol();
++    }
+   }
+ 
+   DOMHighResTimeStamp WorkerStart() const {
+-    return mTiming
+-        ? mTiming->WorkerStartHighRes()
++    return mTimingData
++        ? mTimingData->WorkerStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp FetchStart() const {
+-    return mTiming
+-        ? mTiming->FetchStartHighRes()
++    return mTimingData
++        ? mTimingData->FetchStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp RedirectStart() const {
+     // We have to check if all the redirect URIs had the same origin (since
+     // there is no check in RedirectEndHighRes())
+-    return mTiming && mTiming->ShouldReportCrossOriginRedirect()
+-        ? mTiming->RedirectStartHighRes()
++    return mTimingData && mTimingData->ShouldReportCrossOriginRedirect()
++        ? mTimingData->RedirectStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp RedirectEnd() const {
+     // We have to check if all the redirect URIs had the same origin (since
+     // there is no check in RedirectEndHighRes())
+-    return mTiming && mTiming->ShouldReportCrossOriginRedirect()
+-        ? mTiming->RedirectEndHighRes()
++    return mTimingData && mTimingData->ShouldReportCrossOriginRedirect()
++        ? mTimingData->RedirectEndHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp DomainLookupStart() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->DomainLookupStartHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->DomainLookupStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp DomainLookupEnd() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->DomainLookupEndHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->DomainLookupEndHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp ConnectStart() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->ConnectStartHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->ConnectStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp ConnectEnd() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->ConnectEndHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->ConnectEndHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp RequestStart() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->RequestStartHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->RequestStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp ResponseStart() const {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->ResponseStartHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ? mTimingData->ResponseStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp ResponseEnd() const {
+-    return mTiming
+-        ? mTiming->ResponseEndHighRes()
++    return mTimingData
++        ? mTimingData->ResponseEndHighRes(mPerformance)
+         : 0;
+   }
+ 
+   DOMHighResTimeStamp SecureConnectionStart() const
+   {
+-    return mTiming && mTiming->TimingAllowed()
+-        ? mTiming->SecureConnectionStartHighRes()
++    return mTimingData && mTimingData->TimingAllowed()
++        ?  mTimingData->SecureConnectionStartHighRes(mPerformance)
+         : 0;
+   }
+ 
+   virtual const PerformanceResourceTiming* ToResourceTiming() const override
+   {
+     return this;
+   }
+ 
+   uint64_t TransferSize() const
+   {
+-    return mTiming && mTiming->TimingAllowed() ? mTransferSize : 0;
++    return mTimingData ? mTimingData->TransferSize() : 0;
+   }
+ 
+   uint64_t EncodedBodySize() const
+   {
+-    return mTiming && mTiming->TimingAllowed() ? mEncodedBodySize : 0;
++    return mTimingData ? mTimingData->EncodedBodySize() : 0;
+   }
+ 
+   uint64_t DecodedBodySize() const
+   {
+-    return mTiming && mTiming->TimingAllowed() ? mDecodedBodySize : 0;
+-  }
+-
+-  void SetEncodedBodySize(uint64_t aEncodedBodySize)
+-  {
+-    mEncodedBodySize = aEncodedBodySize;
+-  }
+-
+-  void SetTransferSize(uint64_t aTransferSize)
+-  {
+-    mTransferSize = aTransferSize;
+-  }
+-
+-  void SetDecodedBodySize(uint64_t aDecodedBodySize)
+-  {
+-    mDecodedBodySize = aDecodedBodySize;
++    return mTimingData ? mTimingData->DecodedBodySize() : 0;
+   }
+ 
+   size_t
+   SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
+ 
+ protected:
+   virtual ~PerformanceResourceTiming();
+-  void SetPropertiesFromChannel(nsIHttpChannel* aChannel);
+ 
+   size_t
+   SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
+ 
+   nsString mInitiatorType;
+-  nsString mNextHopProtocol;
+-  RefPtr<PerformanceTiming> mTiming;
+-  uint64_t mEncodedBodySize;
+-  uint64_t mTransferSize;
+-  uint64_t mDecodedBodySize;
++  UniquePtr<PerformanceTimingData> mTimingData;
++  RefPtr<Performance> mPerformance;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif /* mozilla_dom_PerformanceResourceTiming_h___ */
+diff --git a/dom/performance/PerformanceTiming.cpp b/dom/performance/PerformanceTiming.cpp
+--- a/dom/performance/PerformanceTiming.cpp
++++ b/dom/performance/PerformanceTiming.cpp
+@@ -19,78 +19,76 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Pe
+ 
+ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
+ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
+ 
+ PerformanceTiming::PerformanceTiming(Performance* aPerformance,
+                                      nsITimedChannel* aChannel,
+                                      nsIHttpChannel* aHttpChannel,
+                                      DOMHighResTimeStamp aZeroTime)
+-  : mPerformance(aPerformance),
+-    mFetchStart(0.0),
+-    mZeroTime(nsRFPService::ReduceTimePrecisionAsMSecs(aZeroTime)),
+-    mRedirectCount(0),
+-    mTimingAllowed(true),
+-    mAllRedirectsSameOrigin(true),
+-    mInitialized(!!aChannel),
+-    mReportCrossOriginRedirect(true)
++  : mPerformance(aPerformance)
+ {
+   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
+ 
++  mTimingData.reset(new PerformanceTimingData(aChannel, aHttpChannel,
++                                              aZeroTime));
++
++  // Non-null aHttpChannel implies that this PerformanceTiming object is being
++  // used for subresources, which is irrelevant to this probe.
++  if (!aHttpChannel &&
++      nsContentUtils::IsPerformanceTimingEnabled() &&
++      IsTopLevelContentDocument()) {
++    Telemetry::Accumulate(Telemetry::TIME_TO_RESPONSE_START_MS,
++                          mTimingData->ResponseStartHighRes(aPerformance) -
++                            mTimingData->ZeroTime());
++  }
++}
++
++// Copy the timing info from the channel so we don't need to keep the channel
++// alive just to get the timestamps.
++PerformanceTimingData::PerformanceTimingData(nsITimedChannel* aChannel,
++                                             nsIHttpChannel* aHttpChannel,
++                                             DOMHighResTimeStamp aZeroTime)
++  : mZeroTime(0.0)
++  , mFetchStart(0.0)
++  , mEncodedBodySize(0)
++  , mTransferSize(0)
++  , mDecodedBodySize(0)
++  , mRedirectCount(0)
++  , mAllRedirectsSameOrigin(true)
++  , mReportCrossOriginRedirect(true)
++  , mSecureConnection(false)
++  , mTimingAllowed(true)
++  , mInitialized(false)
++{
++  mInitialized = !!aChannel;
++
++  mZeroTime = nsRFPService::ReduceTimePrecisionAsMSecs(aZeroTime);
+   if (!nsContentUtils::IsPerformanceTimingEnabled() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     mZeroTime = 0;
+   }
+ 
+-  // The aHttpChannel argument is null if this PerformanceTiming object is
+-  // being used for navigation timing (which is only relevant for documents).
+-  // It has a non-null value if this PerformanceTiming object is being used
+-  // for resource timing, which can include document loads, both toplevel and
+-  // in subframes, and resources linked from a document.
+-  if (aHttpChannel) {
+-    mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
+-    bool redirectsPassCheck = false;
+-    aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
+-    mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
+-  }
+-
+-  mSecureConnection = false;
+   nsCOMPtr<nsIURI> uri;
+   if (aHttpChannel) {
+     aHttpChannel->GetURI(getter_AddRefs(uri));
+   } else {
+     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
+     if (httpChannel) {
+       httpChannel->GetURI(getter_AddRefs(uri));
+     }
+   }
+ 
+   if (uri) {
+     nsresult rv = uri->SchemeIs("https", &mSecureConnection);
+     if (NS_FAILED(rv)) {
+       mSecureConnection = false;
+     }
+   }
+-  InitializeTimingInfo(aChannel);
+ 
+-  // Non-null aHttpChannel implies that this PerformanceTiming object is being
+-  // used for subresources, which is irrelevant to this probe.
+-  if (!aHttpChannel &&
+-      nsContentUtils::IsPerformanceTimingEnabled() &&
+-      IsTopLevelContentDocument()) {
+-    Telemetry::Accumulate(Telemetry::TIME_TO_RESPONSE_START_MS,
+-                          ResponseStartHighRes() - mZeroTime);
+-  }
+-}
+-
+-// Copy the timing info from the channel so we don't need to keep the channel
+-// alive just to get the timestamps.
+-void
+-PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
+-{
+   if (aChannel) {
+     aChannel->GetAsyncOpen(&mAsyncOpen);
+     aChannel->GetAllRedirectsSameOrigin(&mAllRedirectsSameOrigin);
+     aChannel->GetRedirectCount(&mRedirectCount);
+     aChannel->GetRedirectStart(&mRedirectStart);
+     aChannel->GetRedirectEnd(&mRedirectEnd);
+     aChannel->GetDomainLookupStart(&mDomainLookupStart);
+     aChannel->GetDomainLookupEnd(&mDomainLookupEnd);
+@@ -105,21 +103,21 @@ PerformanceTiming::InitializeTimingInfo(
+ 
+     aChannel->GetDispatchFetchEventStart(&mWorkerStart);
+     aChannel->GetHandleFetchEventStart(&mWorkerRequestStart);
+     // TODO: Track when FetchEvent.respondWith() promise resolves as
+     //       ServiceWorker interception responseStart?
+     aChannel->GetHandleFetchEventEnd(&mWorkerResponseEnd);
+ 
+     // The performance timing api essentially requires that the event timestamps
+-    // have a strict relation with each other. The truth, however, is the browser
+-    // engages in a number of speculative activities that sometimes mean connections
+-    // and lookups begin at different times. Workaround that here by clamping
+-    // these values to what we expect FetchStart to be.  This means the later of
+-    // AsyncOpen or WorkerStart times.
++    // have a strict relation with each other. The truth, however, is the
++    // browser engages in a number of speculative activities that sometimes mean
++    // connections and lookups begin at different times. Workaround that here by
++    // clamping these values to what we expect FetchStart to be.  This means the
++    // later of AsyncOpen or WorkerStart times.
+     if (!mAsyncOpen.IsNull()) {
+       // We want to clamp to the expected FetchStart value.  This is later of
+       // the AsyncOpen and WorkerStart values.
+       const TimeStamp* clampTime = &mAsyncOpen;
+       if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) {
+         clampTime = &mWorkerStart;
+       }
+ 
+@@ -140,52 +138,85 @@ PerformanceTiming::InitializeTimingInfo(
+         mSecureConnectionStart = *clampTime;
+       }
+ 
+       if (!mConnectEnd.IsNull() && mConnectEnd < *clampTime) {
+         mConnectEnd = *clampTime;
+       }
+     }
+   }
++
++  // The aHttpChannel argument is null if this PerformanceTiming object is
++  // being used for navigation timing (which is only relevant for documents).
++  // It has a non-null value if this PerformanceTiming object is being used
++  // for resource timing, which can include document loads, both toplevel and
++  // in subframes, and resources linked from a document.
++  if (aHttpChannel) {
++    mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
++    bool redirectsPassCheck = false;
++    aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
++    mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
++
++    SetPropertiesFromHttpChannel(aHttpChannel);
++  }
++}
++
++void
++PerformanceTimingData::SetPropertiesFromHttpChannel(nsIHttpChannel* aHttpChannel)
++{
++  MOZ_ASSERT(aHttpChannel);
++
++  nsAutoCString protocol;
++  Unused << aHttpChannel->GetProtocolVersion(protocol);
++  mNextHopProtocol = NS_ConvertUTF8toUTF16(protocol);
++
++  Unused << aHttpChannel->GetEncodedBodySize(&mEncodedBodySize);
++  Unused << aHttpChannel->GetTransferSize(&mTransferSize);
++  Unused << aHttpChannel->GetDecodedBodySize(&mDecodedBodySize);
++  if (mDecodedBodySize == 0) {
++    mDecodedBodySize = mEncodedBodySize;
++  }
+ }
+ 
+ PerformanceTiming::~PerformanceTiming()
+ {
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::FetchStartHighRes()
++PerformanceTimingData::FetchStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!mFetchStart) {
+     if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+         nsContentUtils::ShouldResistFingerprinting()) {
+       return mZeroTime;
+     }
+     MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be "
+         "valid if the performance timing is enabled");
+     if (!mAsyncOpen.IsNull()) {
+       if (!mWorkerRequestStart.IsNull() && mWorkerRequestStart > mAsyncOpen) {
+-        mFetchStart = TimeStampToDOMHighRes(mWorkerRequestStart);
++        mFetchStart = TimeStampToDOMHighRes(aPerformance, mWorkerRequestStart);
+       } else {
+-        mFetchStart = TimeStampToDOMHighRes(mAsyncOpen);
++        mFetchStart = TimeStampToDOMHighRes(aPerformance, mAsyncOpen);
+       }
+     }
+   }
+   return nsRFPService::ReduceTimePrecisionAsMSecs(mFetchStart);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::FetchStart()
+ {
+-  return static_cast<int64_t>(FetchStartHighRes());
++  return static_cast<int64_t>(mTimingData->FetchStartHighRes(mPerformance));
+ }
+ 
+ bool
+-PerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
+-                                      nsITimedChannel* aChannel)
++PerformanceTimingData::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
++                                          nsITimedChannel* aChannel)
+ {
+   if (!IsInitialized()) {
+     return false;
+   }
+ 
+   // Check that the current document passes the ckeck.
+   nsCOMPtr<nsILoadInfo> loadInfo;
+   aResourceChannel->GetLoadInfo(getter_AddRefs(loadInfo));
+@@ -203,306 +234,328 @@ PerformanceTiming::CheckAllowedOrigin(ns
+   nsCOMPtr<nsIPrincipal> principal = loadInfo->LoadingPrincipal();
+ 
+   // Check if the resource is either same origin as the page that started
+   // the load, or if the response contains the proper Timing-Allow-Origin
+   // header with the domain of the page that started the load.
+   return aChannel->TimingAllowCheck(principal);
+ }
+ 
+-bool
+-PerformanceTiming::TimingAllowed() const
+-{
+-  return mTimingAllowed;
+-}
+-
+ uint8_t
+-PerformanceTiming::GetRedirectCount() const
++PerformanceTimingData::GetRedirectCount() const
+ {
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return 0;
+   }
+   if (!mAllRedirectsSameOrigin) {
+     return 0;
+   }
+   return mRedirectCount;
+ }
+ 
+ bool
+-PerformanceTiming::ShouldReportCrossOriginRedirect() const
++PerformanceTimingData::ShouldReportCrossOriginRedirect() const
+ {
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return false;
+   }
+ 
+   // If the redirect count is 0, or if one of the cross-origin
+   // redirects doesn't have the proper Timing-Allow-Origin header,
+   // then RedirectStart and RedirectEnd will be set to zero
+   return (mRedirectCount != 0) && mReportCrossOriginRedirect;
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::AsyncOpenHighRes()
++PerformanceTimingData::AsyncOpenHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting() || mAsyncOpen.IsNull()) {
+     return mZeroTime;
+   }
+-  return nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(mAsyncOpen));
++  return nsRFPService::ReduceTimePrecisionAsMSecs(
++           TimeStampToDOMHighRes(aPerformance, mAsyncOpen));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::WorkerStartHighRes()
++PerformanceTimingData::WorkerStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting() || mWorkerStart.IsNull()) {
+     return mZeroTime;
+   }
+-  return nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(mWorkerStart));
++  return nsRFPService::ReduceTimePrecisionAsMSecs(
++           TimeStampToDOMHighRes(aPerformance, mWorkerStart));
+ }
+ 
+ /**
+  * RedirectStartHighRes() is used by both the navigation timing and the
+  * resource timing. Since, navigation timing and resource timing check and
+  * interpret cross-domain redirects in a different manner,
+  * RedirectStartHighRes() will make no checks for cross-domain redirect.
+  * It's up to the consumers of this method (PerformanceTiming::RedirectStart()
+  * and PerformanceResourceTiming::RedirectStart() to make such verifications.
+  *
+  * @return a valid timing if the Performance Timing is enabled
+  */
+ DOMHighResTimeStamp
+-PerformanceTiming::RedirectStartHighRes()
++PerformanceTimingData::RedirectStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+-  return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart);
++  return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRedirectStart);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::RedirectStart()
+ {
+-  if (!IsInitialized()) {
++  if (!mTimingData->IsInitialized()) {
+     return 0;
+   }
+   // We have to check if all the redirect URIs had the same origin (since there
+   // is no check in RedirectStartHighRes())
+-  if (mAllRedirectsSameOrigin && mRedirectCount) {
+-    return static_cast<int64_t>(RedirectStartHighRes());
++  if (mTimingData->AllRedirectsSameOrigin() &&
++      mTimingData->RedirectCountReal()) {
++    return static_cast<int64_t>(mTimingData->RedirectStartHighRes(mPerformance));
+   }
+   return 0;
+ }
+ 
+ /**
+  * RedirectEndHighRes() is used by both the navigation timing and the resource
+  * timing. Since, navigation timing and resource timing check and interpret
+  * cross-domain redirects in a different manner, RedirectEndHighRes() will make
+  * no checks for cross-domain redirect. It's up to the consumers of this method
+  * (PerformanceTiming::RedirectEnd() and
+  * PerformanceResourceTiming::RedirectEnd() to make such verifications.
+  *
+  * @return a valid timing if the Performance Timing is enabled
+  */
+ DOMHighResTimeStamp
+-PerformanceTiming::RedirectEndHighRes()
++PerformanceTimingData::RedirectEndHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+-  return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd);
++  return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRedirectEnd);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::RedirectEnd()
+ {
+-  if (!IsInitialized()) {
++  if (!mTimingData->IsInitialized()) {
+     return 0;
+   }
+   // We have to check if all the redirect URIs had the same origin (since there
+   // is no check in RedirectEndHighRes())
+-  if (mAllRedirectsSameOrigin && mRedirectCount) {
+-    return static_cast<int64_t>(RedirectEndHighRes());
++  if (mTimingData->AllRedirectsSameOrigin() &&
++      mTimingData->RedirectCountReal()) {
++    return static_cast<int64_t>(mTimingData->RedirectEndHighRes(mPerformance));
+   }
+   return 0;
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::DomainLookupStartHighRes()
++PerformanceTimingData::DomainLookupStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+-  return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart);
++  return TimeStampToReducedDOMHighResOrFetchStart(aPerformance,
++                                                  mDomainLookupStart);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::DomainLookupStart()
+ {
+-  return static_cast<int64_t>(DomainLookupStartHighRes());
++  return static_cast<int64_t>(mTimingData->DomainLookupStartHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::DomainLookupEndHighRes()
++PerformanceTimingData::DomainLookupEndHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+   // Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null
+-  return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes()
+-                                   : nsRFPService::ReduceTimePrecisionAsMSecs(
+-                                       TimeStampToDOMHighRes(mDomainLookupEnd));
++  return mDomainLookupEnd.IsNull()
++          ? DomainLookupStartHighRes(aPerformance)
++          : nsRFPService::ReduceTimePrecisionAsMSecs(
++              TimeStampToDOMHighRes(aPerformance, mDomainLookupEnd));
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::DomainLookupEnd()
+ {
+-  return static_cast<int64_t>(DomainLookupEndHighRes());
++  return static_cast<int64_t>(mTimingData->DomainLookupEndHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::ConnectStartHighRes()
++PerformanceTimingData::ConnectStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+-  return mConnectStart.IsNull() ? DomainLookupEndHighRes()
+-                                : nsRFPService::ReduceTimePrecisionAsMSecs(
+-                                    TimeStampToDOMHighRes(mConnectStart));
++  return mConnectStart.IsNull()
++           ? DomainLookupEndHighRes(aPerformance)
++           : nsRFPService::ReduceTimePrecisionAsMSecs(
++               TimeStampToDOMHighRes(aPerformance, mConnectStart));
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::ConnectStart()
+ {
+-  return static_cast<int64_t>(ConnectStartHighRes());
++  return static_cast<int64_t>(mTimingData->ConnectStartHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::SecureConnectionStartHighRes()
++PerformanceTimingData::SecureConnectionStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+   return !mSecureConnection
+     ? 0 // We use 0 here, because mZeroTime is sometimes set to the navigation
+         // start time.
+-    : (mSecureConnectionStart.IsNull() ? mZeroTime
+-                                       : nsRFPService::ReduceTimePrecisionAsMSecs(
+-                                           TimeStampToDOMHighRes(mSecureConnectionStart)));
++    : (mSecureConnectionStart.IsNull()
++        ? mZeroTime
++        : nsRFPService::ReduceTimePrecisionAsMSecs(
++            TimeStampToDOMHighRes(aPerformance, mSecureConnectionStart)));
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::SecureConnectionStart()
+ {
+-  return static_cast<int64_t>(SecureConnectionStartHighRes());
++  return static_cast<int64_t>(mTimingData->SecureConnectionStartHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::ConnectEndHighRes()
++PerformanceTimingData::ConnectEndHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+   // Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null
+-  return mConnectEnd.IsNull() ? ConnectStartHighRes()
+-                              : nsRFPService::ReduceTimePrecisionAsMSecs(
+-                                  TimeStampToDOMHighRes(mConnectEnd));
++  return mConnectEnd.IsNull()
++           ? ConnectStartHighRes(aPerformance)
++           : nsRFPService::ReduceTimePrecisionAsMSecs(
++               TimeStampToDOMHighRes(aPerformance, mConnectEnd));
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::ConnectEnd()
+ {
+-  return static_cast<int64_t>(ConnectEndHighRes());
++  return static_cast<int64_t>(mTimingData->ConnectEndHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::RequestStartHighRes()
++PerformanceTimingData::RequestStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+ 
+   if (mRequestStart.IsNull()) {
+     mRequestStart = mWorkerRequestStart;
+   }
+ 
+-  return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart);
++  return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRequestStart);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::RequestStart()
+ {
+-  return static_cast<int64_t>(RequestStartHighRes());
++  return static_cast<int64_t>(mTimingData->RequestStartHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::ResponseStartHighRes()
++PerformanceTimingData::ResponseStartHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+   if (mResponseStart.IsNull() ||
+      (!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
+     mResponseStart = mCacheReadStart;
+   }
+ 
+   if (mResponseStart.IsNull() ||
+       (!mRequestStart.IsNull() && mResponseStart < mRequestStart)) {
+     mResponseStart = mRequestStart;
+   }
+-  return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart);
++  return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mResponseStart);
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::ResponseStart()
+ {
+-  return static_cast<int64_t>(ResponseStartHighRes());
++  return static_cast<int64_t>(mTimingData->ResponseStartHighRes(mPerformance));
+ }
+ 
+ DOMHighResTimeStamp
+-PerformanceTiming::ResponseEndHighRes()
++PerformanceTimingData::ResponseEndHighRes(Performance* aPerformance)
+ {
++  MOZ_ASSERT(aPerformance);
++
+   if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
+       nsContentUtils::ShouldResistFingerprinting()) {
+     return mZeroTime;
+   }
+   if (mResponseEnd.IsNull() ||
+      (!mCacheReadEnd.IsNull() && mCacheReadEnd < mResponseEnd)) {
+     mResponseEnd = mCacheReadEnd;
+   }
+   if (mResponseEnd.IsNull()) {
+     mResponseEnd = mWorkerResponseEnd;
+   }
+   // Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null
+-  return mResponseEnd.IsNull() ? ResponseStartHighRes()
+-                               : nsRFPService::ReduceTimePrecisionAsMSecs(
+-                                   TimeStampToDOMHighRes(mResponseEnd));
++  return mResponseEnd.IsNull()
++           ? ResponseStartHighRes(aPerformance)
++           : nsRFPService::ReduceTimePrecisionAsMSecs(
++               TimeStampToDOMHighRes(aPerformance, mResponseEnd));
+ }
+ 
+ DOMTimeMilliSec
+ PerformanceTiming::ResponseEnd()
+ {
+-  return static_cast<int64_t>(ResponseEndHighRes());
+-}
+-
+-bool
+-PerformanceTiming::IsInitialized() const
+-{
+-  return mInitialized;
++  return static_cast<int64_t>(mTimingData->ResponseEndHighRes(mPerformance));
+ }
+ 
+ JSObject*
+ PerformanceTiming::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
+ {
+   return PerformanceTimingBinding::Wrap(cx, this, aGivenProto);
+ }
+ 
+diff --git a/dom/performance/PerformanceTiming.h b/dom/performance/PerformanceTiming.h
+--- a/dom/performance/PerformanceTiming.h
++++ b/dom/performance/PerformanceTiming.h
+@@ -15,16 +15,203 @@
+ #include "Performance.h"
+ 
+ class nsIHttpChannel;
+ class nsITimedChannel;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
++class PerformanceTimingData final
++{
++public:
++  PerformanceTimingData(nsITimedChannel* aChannel,
++                        nsIHttpChannel* aHttpChannel,
++                        DOMHighResTimeStamp aZeroTime);
++
++  void
++  SetPropertiesFromHttpChannel(nsIHttpChannel* aHttpChannel);
++
++  bool IsInitialized() const
++  {
++    return mInitialized;
++  }
++
++  const nsString& NextHopProtocol() const
++  {
++    return mNextHopProtocol;
++  }
++
++  uint64_t TransferSize() const
++  {
++    return mTimingAllowed ? mTransferSize : 0;
++  }
++
++  uint64_t EncodedBodySize() const
++  {
++    return mTimingAllowed ? mEncodedBodySize : 0;
++  }
++
++  uint64_t DecodedBodySize() const
++  {
++    return mTimingAllowed ? mDecodedBodySize : 0;
++  }
++
++  /**
++   * @param   aStamp
++   *          The TimeStamp recorded for a specific event. This TimeStamp can
++   *          be null.
++   * @return  the duration of an event with a given TimeStamp, relative to the
++   *          navigationStart TimeStamp (the moment the user landed on the
++   *          page), if the given TimeStamp is valid. Otherwise, it will return
++   *          the FetchStart timing value.
++   */
++  inline DOMHighResTimeStamp
++  TimeStampToReducedDOMHighResOrFetchStart(Performance* aPerformance,
++                                           TimeStamp aStamp)
++  {
++    MOZ_ASSERT(aPerformance);
++
++    return (!aStamp.IsNull())
++        ? nsRFPService::ReduceTimePrecisionAsMSecs(
++            TimeStampToDOMHighRes(aPerformance, aStamp))
++        : FetchStartHighRes(aPerformance);
++  }
++
++  /**
++   * The nsITimedChannel records an absolute timestamp for each event.
++   * The nsDOMNavigationTiming will record the moment when the user landed on
++   * the page. This is a window.performance unique timestamp, so it can be used
++   * for all the events (navigation timing and resource timing events).
++   *
++   * The algorithm operates in 2 steps:
++   * 1. The first step is to subtract the two timestamps: the argument (the
++   * event's timestamp) and the navigation start timestamp. This will result in
++   * a relative timestamp of the event (relative to the navigation start -
++   * window.performance.timing.navigationStart).
++   * 2. The second step is to add any required offset (the mZeroTime). For now,
++   * this offset value is either 0 (for the resource timing), or equal to
++   * "performance.navigationStart" (for navigation timing).
++   * For the resource timing, mZeroTime is set to 0, causing the result to be a
++   * relative time.
++   * For the navigation timing, mZeroTime is set to "performance.navigationStart"
++   * causing the result be an absolute time.
++   *
++   * @param   aStamp
++   *          The TimeStamp recorded for a specific event. This TimeStamp can't
++   *          be null.
++   * @return  number of milliseconds value as one of:
++   * - relative to the navigation start time, time the user has landed on the
++   *   page
++   * - an absolute wall clock time since the unix epoch
++   */
++  inline DOMHighResTimeStamp
++  TimeStampToDOMHighRes(Performance* aPerformance, TimeStamp aStamp) const
++  {
++    MOZ_ASSERT(aPerformance);
++    MOZ_ASSERT(!aStamp.IsNull());
++
++    TimeDuration duration =
++        aStamp - aPerformance->GetDOMTiming()->GetNavigationStartTimeStamp();
++    return duration.ToMilliseconds() + mZeroTime;
++  }
++
++  // The last channel's AsyncOpen time.  This may occur before the FetchStart
++  // in some cases.
++  DOMHighResTimeStamp AsyncOpenHighRes(Performance* aPerformance);
++
++  // High resolution (used by resource timing)
++  DOMHighResTimeStamp WorkerStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp FetchStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp RedirectStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp RedirectEndHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp DomainLookupStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp DomainLookupEndHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp ConnectStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp SecureConnectionStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp ConnectEndHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp RequestStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp ResponseStartHighRes(Performance* aPerformance);
++  DOMHighResTimeStamp ResponseEndHighRes(Performance* aPerformance);
++
++  DOMHighResTimeStamp ZeroTime() const { return mZeroTime; }
++
++  uint8_t RedirectCountReal() const { return mRedirectCount; }
++  uint8_t GetRedirectCount() const;
++
++  bool AllRedirectsSameOrigin() const { return mAllRedirectsSameOrigin; }
++
++  // If this is false the values of redirectStart/End will be 0 This is false if
++  // no redirects occured, or if any of the responses failed the
++  // timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
++  bool ShouldReportCrossOriginRedirect() const;
++
++  // Cached result of CheckAllowedOrigin. If false, security sensitive
++  // attributes of the resourceTiming object will be set to 0
++  bool TimingAllowed() const
++  {
++    return mTimingAllowed;
++  }
++
++private:
++  // Checks if the resource is either same origin as the page that started
++  // the load, or if the response contains the Timing-Allow-Origin header
++  // with a value of * or matching the domain of the loading Principal
++  bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
++                          nsITimedChannel* aChannel);
++
++  nsString mNextHopProtocol;
++
++  TimeStamp mAsyncOpen;
++  TimeStamp mRedirectStart;
++  TimeStamp mRedirectEnd;
++  TimeStamp mDomainLookupStart;
++  TimeStamp mDomainLookupEnd;
++  TimeStamp mConnectStart;
++  TimeStamp mSecureConnectionStart;
++  TimeStamp mConnectEnd;
++  TimeStamp mRequestStart;
++  TimeStamp mResponseStart;
++  TimeStamp mCacheReadStart;
++  TimeStamp mResponseEnd;
++  TimeStamp mCacheReadEnd;
++
++  // ServiceWorker interception timing information
++  TimeStamp mWorkerStart;
++  TimeStamp mWorkerRequestStart;
++  TimeStamp mWorkerResponseEnd;
++
++  // This is an offset that will be added to each timing ([ms] resolution).
++  // There are only 2 possible values: (1) logicaly equal to navigationStart
++  // TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
++  // are relative to the navigation start).
++  DOMHighResTimeStamp mZeroTime;
++
++  DOMHighResTimeStamp mFetchStart;
++
++  uint64_t mEncodedBodySize;
++  uint64_t mTransferSize;
++  uint64_t mDecodedBodySize;
++
++  uint8_t mRedirectCount;
++
++  bool mAllRedirectsSameOrigin;
++
++  // If the resourceTiming object should have non-zero redirectStart and
++  // redirectEnd attributes. It is false if there were no redirects, or if any
++  // of the responses didn't pass the timing-allow-check
++  bool mReportCrossOriginRedirect;
++
++  bool mSecureConnection;
++
++  bool mTimingAllowed;
++
++  bool mInitialized;
++};
++
+ // Script "performance.timing" object
+ class PerformanceTiming final : public nsWrapperCache
+ {
+ public:
+ /**
+  * @param   aPerformance
+  *          The performance object (the JS parent).
+  *          This will allow access to "window.performance.timing" attribute for
+@@ -55,67 +242,16 @@ public:
+     return mPerformance->GetDOMTiming();
+   }
+ 
+   Performance* GetParentObject() const
+   {
+     return mPerformance;
+   }
+ 
+-  /**
+-   * @param   aStamp
+-   *          The TimeStamp recorded for a specific event. This TimeStamp can
+-   *          be null.
+-   * @return  the duration of an event with a given TimeStamp, relative to the
+-   *          navigationStart TimeStamp (the moment the user landed on the
+-   *          page), if the given TimeStamp is valid. Otherwise, it will return
+-   *          the FetchStart timing value.
+-   */
+-  inline DOMHighResTimeStamp TimeStampToReducedDOMHighResOrFetchStart(TimeStamp aStamp)
+-  {
+-    return (!aStamp.IsNull())
+-        ? nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(aStamp))
+-        : FetchStartHighRes();
+-  }
+-
+-  /**
+-   * The nsITimedChannel records an absolute timestamp for each event.
+-   * The nsDOMNavigationTiming will record the moment when the user landed on
+-   * the page. This is a window.performance unique timestamp, so it can be used
+-   * for all the events (navigation timing and resource timing events).
+-   *
+-   * The algorithm operates in 2 steps:
+-   * 1. The first step is to subtract the two timestamps: the argument (the
+-   * envet's timesramp) and the navigation start timestamp. This will result in
+-   * a relative timestamp of the event (relative to the navigation start -
+-   * window.performance.timing.navigationStart).
+-   * 2. The second step is to add any required offset (the mZeroTime). For now,
+-   * this offset value is either 0 (for the resource timing), or equal to
+-   * "performance.navigationStart" (for navigation timing).
+-   * For the resource timing, mZeroTime is set to 0, causing the result to be a
+-   * relative time.
+-   * For the navigation timing, mZeroTime is set to "performance.navigationStart"
+-   * causing the result be an absolute time.
+-   *
+-   * @param   aStamp
+-   *          The TimeStamp recorded for a specific event. This TimeStamp can't
+-   *          be null.
+-   * @return  number of milliseconds value as one of:
+-   * - relative to the navigation start time, time the user has landed on the
+-   * page
+-   * - an absolute wall clock time since the unix epoch
+-   */
+-  inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
+-  {
+-    MOZ_ASSERT(!aStamp.IsNull());
+-    TimeDuration duration =
+-        aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
+-    return duration.ToMilliseconds() + mZeroTime;
+-  }
+-
+   virtual JSObject* WrapObject(JSContext *cx,
+                                JS::Handle<JSObject*> aGivenProto) override;
+ 
+   // PerformanceNavigation WebIDL methods
+   DOMTimeMilliSec NavigationStart() const
+   {
+     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
+         nsContentUtils::ShouldResistFingerprinting()) {
+@@ -140,50 +276,16 @@ public:
+     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
+         nsContentUtils::ShouldResistFingerprinting()) {
+       return 0;
+     }
+     return nsRFPService::ReduceTimePrecisionAsMSecs(
+       GetDOMTiming()->GetUnloadEventEnd());
+   }
+ 
+-  uint8_t GetRedirectCount() const;
+-
+-  // Checks if the resource is either same origin as the page that started
+-  // the load, or if the response contains the Timing-Allow-Origin header
+-  // with a value of * or matching the domain of the loading Principal
+-  bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
+-
+-  // Cached result of CheckAllowedOrigin. If false, security sensitive
+-  // attributes of the resourceTiming object will be set to 0
+-  bool TimingAllowed() const;
+-
+-  // If this is false the values of redirectStart/End will be 0
+-  // This is false if no redirects occured, or if any of the responses failed
+-  // the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
+-  bool ShouldReportCrossOriginRedirect() const;
+-
+-  // The last channel's AsyncOpen time.  This may occur before the FetchStart
+-  // in some cases.
+-  DOMHighResTimeStamp AsyncOpenHighRes();
+-
+-  // High resolution (used by resource timing)
+-  DOMHighResTimeStamp WorkerStartHighRes();
+-  DOMHighResTimeStamp FetchStartHighRes();
+-  DOMHighResTimeStamp RedirectStartHighRes();
+-  DOMHighResTimeStamp RedirectEndHighRes();
+-  DOMHighResTimeStamp DomainLookupStartHighRes();
+-  DOMHighResTimeStamp DomainLookupEndHighRes();
+-  DOMHighResTimeStamp ConnectStartHighRes();
+-  DOMHighResTimeStamp SecureConnectionStartHighRes();
+-  DOMHighResTimeStamp ConnectEndHighRes();
+-  DOMHighResTimeStamp RequestStartHighRes();
+-  DOMHighResTimeStamp ResponseStartHighRes();
+-  DOMHighResTimeStamp ResponseEndHighRes();
+-
+   // Low resolution (used by navigation timing)
+   DOMTimeMilliSec FetchStart();
+   DOMTimeMilliSec RedirectStart();
+   DOMTimeMilliSec RedirectEnd();
+   DOMTimeMilliSec DomainLookupStart();
+   DOMTimeMilliSec DomainLookupEnd();
+   DOMTimeMilliSec ConnectStart();
+   DOMTimeMilliSec SecureConnectionStart();
+@@ -267,61 +369,27 @@ public:
+     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
+         nsContentUtils::ShouldResistFingerprinting()) {
+       return 0;
+     }
+     return nsRFPService::ReduceTimePrecisionAsMSecs(
+       GetDOMTiming()->GetTimeToNonBlankPaint());
+   }
+ 
++  PerformanceTimingData* Data() const
++  {
++    return mTimingData.get();
++  }
++
+ private:
+   ~PerformanceTiming();
+ 
+-  bool IsInitialized() const;
+-  void InitializeTimingInfo(nsITimedChannel* aChannel);
+-
+   bool IsTopLevelContentDocument() const;
+ 
+   RefPtr<Performance> mPerformance;
+-  DOMHighResTimeStamp mFetchStart;
+ 
+-  // This is an offset that will be added to each timing ([ms] resolution).
+-  // There are only 2 possible values: (1) logicaly equal to navigationStart
+-  // TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
+-  // are relative to the navigation start).
+-  DOMHighResTimeStamp mZeroTime;
+-
+-  TimeStamp mAsyncOpen;
+-  TimeStamp mRedirectStart;
+-  TimeStamp mRedirectEnd;
+-  TimeStamp mDomainLookupStart;
+-  TimeStamp mDomainLookupEnd;
+-  TimeStamp mConnectStart;
+-  TimeStamp mSecureConnectionStart;
+-  TimeStamp mConnectEnd;
+-  TimeStamp mRequestStart;
+-  TimeStamp mResponseStart;
+-  TimeStamp mCacheReadStart;
+-  TimeStamp mResponseEnd;
+-  TimeStamp mCacheReadEnd;
+-
+-  // ServiceWorker interception timing information
+-  TimeStamp mWorkerStart;
+-  TimeStamp mWorkerRequestStart;
+-  TimeStamp mWorkerResponseEnd;
+-
+-  uint8_t mRedirectCount;
+-  bool mTimingAllowed;
+-  bool mAllRedirectsSameOrigin;
+-  bool mInitialized;
+-
+-  // If the resourceTiming object should have non-zero redirectStart and
+-  // redirectEnd attributes. It is false if there were no redirects, or if
+-  // any of the responses didn't pass the timing-allow-check
+-  bool mReportCrossOriginRedirect;
+-
+-  bool mSecureConnection;
++  UniquePtr<PerformanceTimingData> mTimingData;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif // mozilla_dom_PerformanceTiming_h

+ 793 - 0
mozilla-release/patches/1425458-3-60a1.patch

@@ -0,0 +1,793 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810652 -3600
+# Node ID 619d2fe88e78799e1e5606159e228597c07f8021
+# Parent  df08db41560b141ed1a0f12e233eb93ce13d40ac
+Bug 1425458 - Resource timing entries Workers - part 3 - PerformanceStorageWorker, r=smaug
+
+diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp
+--- a/dom/performance/Performance.cpp
++++ b/dom/performance/Performance.cpp
+@@ -433,16 +433,17 @@ Performance::InsertResourceEntry(Perform
+   MOZ_ASSERT(aEntry);
+   MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
+ 
+   // We won't add an entry when 'privacy.resistFingerprint' is true.
+   if (nsContentUtils::ShouldResistFingerprinting()) {
+     return;
+   }
+ 
++  // Don't add the entry if the buffer is full
+   if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
+     return;
+   }
+ 
+   mResourceEntries.InsertElementSorted(aEntry,
+                                        PerformanceEntryComparator());
+   if (mResourceEntries.Length() == mResourceTimingBufferSize) {
+     // call onresourcetimingbufferfull
+diff --git a/dom/performance/Performance.h b/dom/performance/Performance.h
+--- a/dom/performance/Performance.h
++++ b/dom/performance/Performance.h
+@@ -95,58 +95,54 @@ public:
+ 
+   virtual void GetMozMemory(JSContext *aCx,
+                             JS::MutableHandle<JSObject*> aObj) = 0;
+ 
+   virtual nsDOMNavigationTiming* GetDOMTiming() const = 0;
+ 
+   virtual nsITimedChannel* GetChannel() const = 0;
+ 
++  virtual TimeStamp CreationTimeStamp() const = 0;
++
+   void MemoryPressure();
+ 
+   size_t SizeOfUserEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
+   size_t SizeOfResourceEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
+ 
++  void InsertResourceEntry(PerformanceEntry* aEntry);
++
+ protected:
+   Performance();
+   explicit Performance(nsPIDOMWindowInner* aWindow);
+ 
+   virtual ~Performance();
+ 
+   virtual void InsertUserEntry(PerformanceEntry* aEntry);
+-  void InsertResourceEntry(PerformanceEntry* aEntry);
+ 
+   void ClearUserEntries(const Optional<nsAString>& aEntryName,
+                         const nsAString& aEntryType);
+ 
+   DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
+                                                ErrorResult& aRv);
+ 
+   virtual void DispatchBufferFullEvent() = 0;
+ 
+-  virtual TimeStamp CreationTimeStamp() const = 0;
+-
+   virtual DOMHighResTimeStamp CreationTime() const = 0;
+ 
+   virtual bool IsPerformanceTimingAttribute(const nsAString& aName)
+   {
+     return false;
+   }
+ 
+   virtual DOMHighResTimeStamp
+   GetPerformanceTimingFromString(const nsAString& aTimingName)
+   {
+     return 0;
+   }
+ 
+-  bool IsResourceEntryLimitReached() const
+-  {
+-    return mResourceEntries.Length() >= mResourceTimingBufferSize;
+-  }
+-
+   void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
+   void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
+                           uint64_t epoch);
+ 
+   void RunNotificationObserversTask();
+   void QueueEntry(PerformanceEntry* aEntry);
+ 
+   DOMHighResTimeStamp RoundTime(double aTime) const;
+diff --git a/dom/performance/PerformanceMainThread.cpp b/dom/performance/PerformanceMainThread.cpp
+--- a/dom/performance/PerformanceMainThread.cpp
++++ b/dom/performance/PerformanceMainThread.cpp
+@@ -113,74 +113,34 @@ PerformanceMainThread::Navigation()
+  * This method is not thread safe and can only be called on the main thread.
+  */
+ void
+ PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
+                                 nsITimedChannel* timedChannel)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+ 
+-  // Check if resource timing is prefed off.
+-  if (!nsContentUtils::IsResourceTimingEnabled()) {
+-    return;
+-  }
++  nsAutoString initiatorType;
++  nsAutoString entryName;
+ 
+-  // Don't add the entry if the buffer is full
+-  if (IsResourceEntryLimitReached()) {
++  UniquePtr<PerformanceTimingData> performanceTimingData(
++    PerformanceTimingData::Create(timedChannel, channel, 0, initiatorType,
++                                  entryName));
++  if (!performanceTimingData) {
+     return;
+   }
+ 
+-  if (channel && timedChannel) {
+-    nsAutoCString name;
+-    nsAutoString initiatorType;
+-    nsCOMPtr<nsIURI> originalURI;
+-
+-    timedChannel->GetInitiatorType(initiatorType);
+-
+-    // According to the spec, "The name attribute must return the resolved URL
+-    // of the requested resource. This attribute must not change even if the
+-    // fetch redirected to a different URL."
+-    channel->GetOriginalURI(getter_AddRefs(originalURI));
+-    originalURI->GetSpec(name);
+-    NS_ConvertUTF8toUTF16 entryName(name);
+-
+-    bool reportTiming = true;
+-    timedChannel->GetReportResourceTiming(&reportTiming);
++  // The PerformanceResourceTiming object will use the PerformanceTimingData
++  // object to get all the required timings.
++  RefPtr<PerformanceResourceTiming> performanceEntry =
++    new PerformanceResourceTiming(Move(performanceTimingData), this,
++                                  entryName);
+ 
+-    if (!reportTiming) {
+-#ifdef DEBUG_jwatt
+-      NS_WARNING(
+-        nsPrintfCString("Not reporting CORS resource: %s", name.get()).get());
+-#endif
+-      return;
+-    }
+-
+-    // The nsITimedChannel argument will be used to gather all the timings.
+-    // The nsIHttpChannel argument will be used to check if any cross-origin
+-    // redirects occurred.
+-    // The last argument is the "zero time" (offset). Since we don't want
+-    // any offset for the resource timing, this will be set to "0" - the
+-    // resource timing returns a relative timing (no offset).
+-    UniquePtr<PerformanceTimingData> performanceTimingData(
+-        new PerformanceTimingData(timedChannel, channel, 0));
+-
+-    // The PerformanceResourceTiming object will use the PerformanceTiming
+-    // object to get all the required timings.
+-    RefPtr<PerformanceResourceTiming> performanceEntry =
+-      new PerformanceResourceTiming(Move(performanceTimingData), this,
+-                                    entryName);
+-
+-    // If the initiator type had no valid value, then set it to the default
+-    // ("other") value.
+-    if (initiatorType.IsEmpty()) {
+-      initiatorType = NS_LITERAL_STRING("other");
+-    }
+-    performanceEntry->SetInitiatorType(initiatorType);
+-    InsertResourceEntry(performanceEntry);
+-  }
++  performanceEntry->SetInitiatorType(initiatorType);
++  InsertResourceEntry(performanceEntry);
+ }
+ 
+ // To be removed once bug 1124165 lands
+ bool
+ PerformanceMainThread::IsPerformanceTimingAttribute(const nsAString& aName)
+ {
+   // Note that toJSON is added to this list due to bug 1047848
+   static const char* attributes[] =
+diff --git a/dom/performance/PerformanceStorage.h b/dom/performance/PerformanceStorage.h
+--- a/dom/performance/PerformanceStorage.h
++++ b/dom/performance/PerformanceStorage.h
+@@ -10,25 +10,26 @@
+ #include "nsISupportsImpl.h"
+ 
+ class nsIHttpChannel;
+ class nsITimedChannel;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
++class PerformanceTimingData;
++
+ class PerformanceStorage
+ {
+ public:
+   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+ 
+   virtual void AddEntry(nsIHttpChannel* aChannel,
+                         nsITimedChannel* aTimedChannel) = 0;
+ 
+-
+ protected:
+   virtual ~PerformanceStorage() {}
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif // mozilla_dom_PerformanceStorage_h
+diff --git a/dom/performance/PerformanceStorageWorker.cpp b/dom/performance/PerformanceStorageWorker.cpp
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/PerformanceStorageWorker.cpp
+@@ -0,0 +1,271 @@
++/* -*- 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 "PerformanceStorageWorker.h"
++#include "WorkerPrivate.h"
++#include "WorkerHolder.h"
++
++namespace mozilla {
++namespace dom {
++
++using namespace workers;
++
++class PerformanceProxyData
++{
++public:
++  PerformanceProxyData(UniquePtr<PerformanceTimingData>&& aData,
++                       const nsAString& aInitiatorType,
++                       const nsAString& aEntryName)
++    : mData(Move(aData))
++    , mInitiatorType(aInitiatorType)
++    , mEntryName(aEntryName)
++  {}
++
++  UniquePtr<PerformanceTimingData> mData;
++  nsString mInitiatorType;
++  nsString mEntryName;
++};
++
++namespace {
++
++// This runnable calls InitializeOnWorker() on the worker thread. Here a
++// workerHolder is used to monitor when the worker thread is starting the
++// shutdown procedure.
++// Here we use control runnable because this code must be executed also when in
++// a sync event loop.
++class PerformanceStorageInitializer final : public WorkerControlRunnable
++{
++  RefPtr<PerformanceStorageWorker> mStorage;
++
++public:
++  PerformanceStorageInitializer(WorkerPrivate* aWorkerPrivate,
++                                PerformanceStorageWorker* aStorage)
++    : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
++    , mStorage(aStorage)
++  {}
++
++  bool
++  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
++  {
++    mStorage->InitializeOnWorker();
++    return true;
++  }
++
++  nsresult
++  Cancel() override
++  {
++    mStorage->ShutdownOnWorker();
++    return WorkerRunnable::Cancel();
++  }
++
++  bool
++  PreDispatch(WorkerPrivate* aWorkerPrivate) override
++  {
++    return true;
++  }
++
++  void
++  PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
++  {}
++};
++
++// Here we use control runnable because this code must be executed also when in
++// a sync event loop
++class PerformanceEntryAdder final : public WorkerControlRunnable
++{
++public:
++  PerformanceEntryAdder(WorkerPrivate* aWorkerPrivate,
++                        PerformanceStorageWorker* aStorage,
++                        UniquePtr<PerformanceProxyData>&& aData)
++    : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
++    , mStorage(aStorage)
++    , mData(Move(aData))
++  {}
++
++  bool
++  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
++  {
++    mStorage->AddEntryOnWorker(Move(mData));
++    return true;
++  }
++
++  nsresult
++  Cancel() override
++  {
++    mStorage->ShutdownOnWorker();
++    return WorkerRunnable::Cancel();
++  }
++
++  bool
++  PreDispatch(WorkerPrivate* aWorkerPrivate) override
++  {
++    return true;
++  }
++
++  void
++  PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
++  {}
++
++private:
++  RefPtr<PerformanceStorageWorker> mStorage;
++  UniquePtr<PerformanceProxyData> mData;
++};
++
++class PerformanceStorageWorkerHolder final : public WorkerHolder
++{
++  RefPtr<PerformanceStorageWorker> mStorage;
++
++public:
++  explicit PerformanceStorageWorkerHolder(PerformanceStorageWorker* aStorage)
++    : WorkerHolder("PerformanceStorageWorkerHolder",
++                   WorkerHolder::AllowIdleShutdownStart)
++    , mStorage(aStorage)
++  {}
++
++  bool
++  Notify(Status aStatus) override
++  {
++    if (mStorage) {
++      RefPtr<PerformanceStorageWorker> storage;
++      storage.swap(mStorage);
++      storage->ShutdownOnWorker();
++    }
++
++    return true;
++  }
++};
++
++} // anonymous
++
++/* static */ already_AddRefed<PerformanceStorageWorker>
++PerformanceStorageWorker::Create(WorkerPrivate* aWorkerPrivate)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++
++  RefPtr<PerformanceStorageWorker> storage =
++    new PerformanceStorageWorker(aWorkerPrivate);
++
++  RefPtr<PerformanceStorageInitializer> r =
++    new PerformanceStorageInitializer(aWorkerPrivate, storage);
++  if (NS_WARN_IF(!r->Dispatch())) {
++    return nullptr;
++  }
++
++  return storage.forget();
++}
++
++PerformanceStorageWorker::PerformanceStorageWorker(WorkerPrivate* aWorkerPrivate)
++  : mMutex("PerformanceStorageWorker::mMutex")
++  , mWorkerPrivate(aWorkerPrivate)
++  , mState(eInitializing)
++{
++}
++
++PerformanceStorageWorker::~PerformanceStorageWorker() = default;
++
++void
++PerformanceStorageWorker::AddEntry(nsIHttpChannel* aChannel,
++                                   nsITimedChannel* aTimedChannel)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++
++  MutexAutoLock lock(mMutex);
++
++  if (mState == eTerminated) {
++    return;
++  }
++
++  nsAutoString initiatorType;
++  nsAutoString entryName;
++
++  UniquePtr<PerformanceTimingData> performanceTimingData(
++    PerformanceTimingData::Create(aTimedChannel, aChannel, 0, initiatorType,
++                                  entryName));
++  if (!performanceTimingData) {
++    return;
++  }
++
++  UniquePtr<PerformanceProxyData> data(
++    new PerformanceProxyData(Move(performanceTimingData), initiatorType,
++                             entryName));
++
++  RefPtr<PerformanceEntryAdder> r =
++    new PerformanceEntryAdder(mWorkerPrivate, this, Move(data));
++  Unused << NS_WARN_IF(!r->Dispatch());
++}
++
++void
++PerformanceStorageWorker::InitializeOnWorker()
++{
++  MutexAutoLock lock(mMutex);
++  MOZ_ASSERT(mState == eInitializing);
++  MOZ_ASSERT(mWorkerPrivate);
++  mWorkerPrivate->AssertIsOnWorkerThread();
++
++  mWorkerHolder.reset(new PerformanceStorageWorkerHolder(this));
++  if (!mWorkerHolder->HoldWorker(mWorkerPrivate, Canceling)) {
++    MutexAutoUnlock lock(mMutex);
++    ShutdownOnWorker();
++    return;
++  }
++
++  // We are ready to accept entries.
++  mState = eReady;
++}
++
++void
++PerformanceStorageWorker::ShutdownOnWorker()
++{
++  MutexAutoLock lock(mMutex);
++
++  if (mState == eTerminated) {
++    return;
++  }
++
++  MOZ_ASSERT(mWorkerPrivate);
++  mWorkerPrivate->AssertIsOnWorkerThread();
++
++  mState = eTerminated;
++  mWorkerHolder = nullptr;
++  mWorkerPrivate = nullptr;
++}
++
++void
++PerformanceStorageWorker::AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData)
++{
++  RefPtr<Performance> performance;
++  UniquePtr<PerformanceProxyData> data = Move(aData);
++
++  {
++    MutexAutoLock lock(mMutex);
++
++    if (mState == eTerminated) {
++      return;
++    }
++
++    MOZ_ASSERT(mWorkerPrivate);
++    mWorkerPrivate->AssertIsOnWorkerThread();
++
++    MOZ_ASSERT(mState == eReady);
++
++    WorkerGlobalScope* scope = mWorkerPrivate->GlobalScope();
++    performance = scope->GetPerformance();
++  }
++
++  if (NS_WARN_IF(!performance)) {
++    return;
++  }
++
++  RefPtr<PerformanceResourceTiming> performanceEntry =
++    new PerformanceResourceTiming(Move(data->mData), performance,
++                                 data->mEntryName);
++  performanceEntry->SetInitiatorType(data->mInitiatorType);
++
++  performance->InsertResourceEntry(performanceEntry);
++}
++
++} // namespace dom
++} // namespace mozilla
+diff --git a/dom/performance/PerformanceStorageWorker.h b/dom/performance/PerformanceStorageWorker.h
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/PerformanceStorageWorker.h
+@@ -0,0 +1,64 @@
++/* -*- 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/. */
++
++#ifndef mozilla_dom_PerformanceStorageWorker_h
++#define mozilla_dom_PerformanceStorageWorker_h
++
++#include "PerformanceStorage.h"
++
++namespace mozilla {
++namespace dom {
++
++namespace workers {
++class WorkerHolder;
++class WorkerPrivate;
++}
++
++class PerformanceProxyData;
++
++class PerformanceStorageWorker final : public PerformanceStorage
++{
++public:
++  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PerformanceStorageWorker, override)
++
++  static already_AddRefed<PerformanceStorageWorker>
++  Create(workers::WorkerPrivate* aWorkerPrivate);
++
++  void InitializeOnWorker();
++
++  void ShutdownOnWorker();
++
++  void AddEntry(nsIHttpChannel* aChannel,
++                nsITimedChannel* aTimedChannel) override;
++
++  void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData);
++
++private:
++  explicit PerformanceStorageWorker(workers::WorkerPrivate* aWorkerPrivate);
++  ~PerformanceStorageWorker();
++
++  Mutex mMutex;
++
++  // Protected by mutex.
++  // This raw pointer is nullified when the WorkerHolder communicates the
++  // shutting down of the worker thread.
++  workers::WorkerPrivate* mWorkerPrivate;
++
++  // Protected by mutex.
++  enum {
++    eInitializing,
++    eReady,
++    eTerminated,
++  } mState;
++
++  // Touched on worker-thread only.
++  UniquePtr<WorkerHolder> mWorkerHolder;
++};
++
++} // namespace dom
++} // namespace mozilla
++
++#endif // mozilla_dom_PerformanceStorageWorker_h
+diff --git a/dom/performance/PerformanceTiming.cpp b/dom/performance/PerformanceTiming.cpp
+--- a/dom/performance/PerformanceTiming.cpp
++++ b/dom/performance/PerformanceTiming.cpp
+@@ -15,16 +15,68 @@
+ namespace mozilla {
+ namespace dom {
+ 
+ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceTiming, mPerformance)
+ 
+ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
+ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
+ 
++/* static */ PerformanceTimingData*
++PerformanceTimingData::Create(nsITimedChannel* aTimedChannel,
++                              nsIHttpChannel* aChannel,
++                              DOMHighResTimeStamp aZeroTime,
++                              nsAString& aInitiatorType,
++                              nsAString& aEntryName)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++
++  // Check if resource timing is prefed off.
++  if (!nsContentUtils::IsResourceTimingEnabled()) {
++    return nullptr;
++  }
++
++  if (!aChannel || !aTimedChannel) {
++    return nullptr;
++  }
++
++  bool reportTiming = true;
++  aTimedChannel->GetReportResourceTiming(&reportTiming);
++
++  if (!reportTiming) {
++    return nullptr;
++  }
++
++  aTimedChannel->GetInitiatorType(aInitiatorType);
++
++  // If the initiator type had no valid value, then set it to the default
++  // ("other") value.
++  if (aInitiatorType.IsEmpty()) {
++    aInitiatorType = NS_LITERAL_STRING("other");
++  }
++
++  // According to the spec, "The name attribute must return the resolved URL
++  // of the requested resource. This attribute must not change even if the
++  // fetch redirected to a different URL."
++  nsCOMPtr<nsIURI> originalURI;
++  aChannel->GetOriginalURI(getter_AddRefs(originalURI));
++
++  nsAutoCString name;
++  originalURI->GetSpec(name);
++  aEntryName = NS_ConvertUTF8toUTF16(name);
++
++  // The nsITimedChannel argument will be used to gather all the timings.
++  // The nsIHttpChannel argument will be used to check if any cross-origin
++  // redirects occurred.
++  // The last argument is the "zero time" (offset). Since we don't want
++  // any offset for the resource timing, this will be set to "0" - the
++  // resource timing returns a relative timing (no offset).
++  return new PerformanceTimingData(aTimedChannel, aChannel, 0);
++}
++
+ PerformanceTiming::PerformanceTiming(Performance* aPerformance,
+                                      nsITimedChannel* aChannel,
+                                      nsIHttpChannel* aHttpChannel,
+                                      DOMHighResTimeStamp aZeroTime)
+   : mPerformance(aPerformance)
+ {
+   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
+ 
+diff --git a/dom/performance/PerformanceTiming.h b/dom/performance/PerformanceTiming.h
+--- a/dom/performance/PerformanceTiming.h
++++ b/dom/performance/PerformanceTiming.h
+@@ -15,19 +15,31 @@
+ #include "Performance.h"
+ 
+ class nsIHttpChannel;
+ class nsITimedChannel;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
++class PerformanceTiming;
++
+ class PerformanceTimingData final
+ {
++  friend class PerformanceTiming;
++
+ public:
++  // This can return null.
++  static PerformanceTimingData*
++  Create(nsITimedChannel* aChannel,
++         nsIHttpChannel* aHttpChannel,
++         DOMHighResTimeStamp aZeroTime,
++         nsAString& aInitiatorType,
++         nsAString& aEntryName);
++
+   PerformanceTimingData(nsITimedChannel* aChannel,
+                         nsIHttpChannel* aHttpChannel,
+                         DOMHighResTimeStamp aZeroTime);
+ 
+   void
+   SetPropertiesFromHttpChannel(nsIHttpChannel* aHttpChannel);
+ 
+   bool IsInitialized() const
+@@ -104,18 +116,17 @@ public:
+    * - an absolute wall clock time since the unix epoch
+    */
+   inline DOMHighResTimeStamp
+   TimeStampToDOMHighRes(Performance* aPerformance, TimeStamp aStamp) const
+   {
+     MOZ_ASSERT(aPerformance);
+     MOZ_ASSERT(!aStamp.IsNull());
+ 
+-    TimeDuration duration =
+-        aStamp - aPerformance->GetDOMTiming()->GetNavigationStartTimeStamp();
++    TimeDuration duration = aStamp - aPerformance->CreationTimeStamp();
+     return duration.ToMilliseconds() + mZeroTime;
+   }
+ 
+   // The last channel's AsyncOpen time.  This may occur before the FetchStart
+   // in some cases.
+   DOMHighResTimeStamp AsyncOpenHighRes(Performance* aPerformance);
+ 
+   // High resolution (used by resource timing)
+diff --git a/dom/performance/moz.build b/dom/performance/moz.build
+--- a/dom/performance/moz.build
++++ b/dom/performance/moz.build
+@@ -14,31 +14,33 @@ EXPORTS.mozilla.dom += [
+     'PerformanceMeasure.h',
+     'PerformanceNavigation.h',
+     'PerformanceNavigationTiming.h',
+     'PerformanceObserver.h',
+     'PerformanceObserverEntryList.h',
+     'PerformanceResourceTiming.h',
+     'PerformanceService.h',
+     'PerformanceStorage.h',
++    'PerformanceStorageWorker.h',
+     'PerformanceTiming.h',
+ ]
+ 
+ UNIFIED_SOURCES += [
+     'Performance.cpp',
+     'PerformanceEntry.cpp',
+     'PerformanceMainThread.cpp',
+     'PerformanceMark.cpp',
+     'PerformanceMeasure.cpp',
+     'PerformanceNavigation.cpp',
+     'PerformanceNavigationTiming.cpp',
+     'PerformanceObserver.cpp',
+     'PerformanceObserverEntryList.cpp',
+     'PerformanceResourceTiming.cpp',
+     'PerformanceService.cpp',
++    'PerformanceStorageWorker.cpp',
+     'PerformanceTiming.cpp',
+     'PerformanceWorker.cpp',
+ ]
+ 
+ LOCAL_INCLUDES += [
+     '/dom/workers',
+ ]
+ 
+diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
+--- a/dom/workers/WorkerPrivate.cpp
++++ b/dom/workers/WorkerPrivate.cpp
+@@ -59,16 +59,17 @@
+ #include "mozilla/dom/FunctionBinding.h"
+ #include "mozilla/dom/IndexedDatabaseManager.h"
+ #include "mozilla/dom/MessageEvent.h"
+ #include "mozilla/dom/MessageEventBinding.h"
+ #include "mozilla/dom/MessagePort.h"
+ #include "mozilla/dom/MessagePortBinding.h"
+ #include "mozilla/dom/nsCSPUtils.h"
+ #include "mozilla/dom/Performance.h"
++#include "mozilla/dom/PerformanceStorageWorker.h"
+ #include "mozilla/dom/PMessagePort.h"
+ #include "mozilla/dom/Promise.h"
+ #include "mozilla/dom/PromiseDebugging.h"
+ #include "mozilla/dom/PromiseNativeHandler.h"
+ #include "mozilla/dom/SimpleGlobalObject.h"
+ #include "mozilla/dom/ScriptSettings.h"
+ #include "mozilla/dom/StructuredCloneHolder.h"
+ #include "mozilla/dom/TabChild.h"
+@@ -7213,18 +7214,22 @@ WorkerPrivate::DumpCrashInformation(nsAC
+     aString.Append(holder->Name());
+   }
+ }
+ 
+ PerformanceStorage*
+ WorkerPrivate::GetPerformanceStorage()
+ {
+   AssertIsOnMainThread();
+-  // TODO
+-  return nullptr;
++
++  if (!mPerformanceStorage) {
++    mPerformanceStorage = PerformanceStorageWorker::Create(this);
++  }
++
++  return mPerformanceStorage;
+ }
+ 
+ NS_IMPL_ISUPPORTS_INHERITED0(ExternalRunnableWrapper, WorkerRunnable)
+ 
+ template <class Derived>
+ NS_IMPL_ADDREF(WorkerPrivateParent<Derived>::EventTarget)
+ 
+ template <class Derived>
+diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
+--- a/dom/workers/WorkerPrivate.h
++++ b/dom/workers/WorkerPrivate.h
+@@ -1063,16 +1063,18 @@ class WorkerPrivate : public WorkerPriva
+ 
+   nsCOMPtr<nsITimer> mGCTimer;
+ 
+   RefPtr<MemoryReporter> mMemoryReporter;
+ 
+   // fired on the main thread if the worker script fails to load
+   nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
+ 
++  RefPtr<PerformanceStorage> mPerformanceStorage;
++
+   JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
+   TimeStamp mKillTime;
+   uint32_t mErrorHandlerRecursionCount;
+   uint32_t mNextTimeoutId;
+   Status mStatus;
+   UniquePtr<ClientSource> mClientSource;
+   bool mFrozen;
+   bool mTimerRunning;

+ 50 - 0
mozilla-release/patches/1425458-4-60a1.patch

@@ -0,0 +1,50 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810652 -3600
+# Node ID 4186a931f07c6a598db20122fdedf3e35539325d
+# Parent  537c13e6dd9d1b3e9051c4f2a45c0c398467e0ba
+Bug 1425458 - Resource timing entries Workers - part 4 - exposing partial interface, r=smaug
+
+diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp
+--- a/dom/performance/Performance.cpp
++++ b/dom/performance/Performance.cpp
+@@ -232,17 +232,16 @@ Performance::ClearUserEntries(const Opti
+       ++i;
+     }
+   }
+ }
+ 
+ void
+ Performance::ClearResourceTimings()
+ {
+-  MOZ_ASSERT(NS_IsMainThread());
+   mResourceEntries.Clear();
+ }
+ 
+ DOMHighResTimeStamp
+ Performance::RoundTime(double aTime) const
+ {
+   // Round down to the nearest 20us, because if the timer is too accurate people
+   // can do nasty timing attacks with it.
+diff --git a/dom/webidl/Performance.webidl b/dom/webidl/Performance.webidl
+--- a/dom/webidl/Performance.webidl
++++ b/dom/webidl/Performance.webidl
+@@ -37,17 +37,17 @@ partial interface Performance {
+ partial interface Performance {
+   PerformanceEntryList getEntries();
+   PerformanceEntryList getEntriesByType(DOMString entryType);
+   PerformanceEntryList getEntriesByName(DOMString name, optional DOMString
+     entryType);
+ };
+ 
+ // http://www.w3.org/TR/resource-timing/#extensions-performance-interface
+-[Exposed=Window]
++[Exposed=(Window,Worker)]
+ partial interface Performance {
+   void clearResourceTimings();
+   void setResourceTimingBufferSize(unsigned long maxSize);
+   attribute EventHandler onresourcetimingbufferfull;
+ };
+ 
+ // GC microbenchmarks, pref-guarded, not for general use (bug 1125412)
+ [Exposed=Window]

+ 51 - 0
mozilla-release/patches/1425458-5-60a1.patch

@@ -0,0 +1,51 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810652 -3600
+# Node ID 08827b793aff9b41786d28e05fbd08d1328b5a95
+# Parent  81ffa524632fc4e299bbc28fd1132d6b03a3a08d
+Bug 1425458 - Resource timing entries Workers - part 5 - dispatch resourcetimingbufferfull on workers, r=smaug
+
+diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp
+--- a/dom/performance/Performance.cpp
++++ b/dom/performance/Performance.cpp
+@@ -425,17 +425,17 @@ Performance::SetResourceTimingBufferSize
+ {
+   mResourceTimingBufferSize = aMaxSize;
+ }
+ 
+ void
+ Performance::InsertResourceEntry(PerformanceEntry* aEntry)
+ {
+   MOZ_ASSERT(aEntry);
+-  MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
++  MOZ_ASSERT(mResourceEntries.Length() <= mResourceTimingBufferSize);
+ 
+   // We won't add an entry when 'privacy.resistFingerprint' is true.
+   if (nsContentUtils::ShouldResistFingerprinting()) {
+     return;
+   }
+ 
+   // Don't add the entry if the buffer is full
+   if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
+diff --git a/dom/performance/PerformanceWorker.h b/dom/performance/PerformanceWorker.h
+--- a/dom/performance/PerformanceWorker.h
++++ b/dom/performance/PerformanceWorker.h
+@@ -63,17 +63,17 @@ public:
+ 
+ protected:
+   ~PerformanceWorker();
+ 
+   void InsertUserEntry(PerformanceEntry* aEntry) override;
+ 
+   void DispatchBufferFullEvent() override
+   {
+-    MOZ_CRASH("This should not be called on workers.");
++    // Nothing to do here. See bug 1432758.
+   }
+ 
+ private:
+   workers::WorkerPrivate* mWorkerPrivate;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla

+ 72 - 0
mozilla-release/patches/1425458-6-60a1.patch

@@ -0,0 +1,72 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810652 -3600
+# Node ID dfd991faa7cb6e3bcc1f9e48dbe5b547f96aba28
+# Parent  a7e885c4db3502ae20bbe540c025a4fa1639bcba
+Bug 1425458 - Resource timing entries Workers - part 6 - PerformanceResourceTiming exposed, r=smaug
+
+diff --git a/dom/webidl/PerformanceResourceTiming.webidl b/dom/webidl/PerformanceResourceTiming.webidl
+--- a/dom/webidl/PerformanceResourceTiming.webidl
++++ b/dom/webidl/PerformanceResourceTiming.webidl
+@@ -5,16 +5,17 @@
+  *
+  * The origin of this IDL file is
+  * https://w3c.github.io/resource-timing/#performanceresourcetiming
+  *
+  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+  * liability, trademark and document use rules apply.
+  */
+ 
++[Exposed=(Window,Worker)]
+ interface PerformanceResourceTiming : PerformanceEntry
+ {
+   readonly attribute DOMString initiatorType;
+   readonly attribute DOMString nextHopProtocol;
+ 
+   readonly attribute DOMHighResTimeStamp workerStart;
+   readonly attribute DOMHighResTimeStamp redirectStart;
+   readonly attribute DOMHighResTimeStamp redirectEnd;
+diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+--- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
++++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+@@ -182,16 +182,18 @@ var interfaceNamesInGlobalScope =
+     "PerformanceMark",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PerformanceMeasure",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PerformanceObserver",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PerformanceObserverEntryList",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
++    "PerformanceResourceTiming",
++// IMPORTANT: Do not change this list without review from a DOM peer!
+     "ProgressEvent",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PushEvent",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PushManager",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     "PushMessageData",
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js
+--- a/dom/workers/test/test_worker_interfaces.js
++++ b/dom/workers/test/test_worker_interfaces.js
+@@ -176,16 +176,18 @@ var interfaceNamesInGlobalScope =
+     {name: "PerformanceMark", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PerformanceMeasure", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PerformanceObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PerformanceObserverEntryList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
++    {name: "PerformanceResourceTiming", insecureContext: true},
++// IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "ProgressEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PushManager", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PushSubscription", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+     {name: "PushSubscriptionOptions", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!

+ 197 - 0
mozilla-release/patches/1425458-7no8or9-60a1.patch

@@ -0,0 +1,197 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1516810652 -3600
+# Node ID e08739c23a5e7ad129e1c20f15e8d800b6318832
+# Parent  14e0b437b9a8260db75fd5a69500d2b10762d5d7
+Bug 1425458 - Resource timing entries Workers - part 7 - mochitests, r=smaug
+
+diff --git a/dom/performance/tests/empty.js b/dom/performance/tests/empty.js
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/tests/empty.js
+@@ -0,0 +1,1 @@
++/* Nothing here */
+diff --git a/dom/performance/tests/mochitest.ini b/dom/performance/tests/mochitest.ini
+--- a/dom/performance/tests/mochitest.ini
++++ b/dom/performance/tests/mochitest.ini
+@@ -1,16 +1,20 @@
+ [DEFAULT]
+ support-files =
+   test_performance_observer.js
+   test_performance_user_timing.js
+   test_worker_performance_now.js
+   worker_performance_user_timing.js
+   worker_performance_observer.js
+   sharedworker_performance_user_timing.js
++  test_worker_performance_entries.js
++  test_worker_performance_entries.sjs
++  empty.js
+ 
+ [test_performance_observer.html]
+ [test_performance_user_timing.html]
+ [test_worker_user_timing.html]
+ [test_worker_observer.html]
+ [test_sharedWorker_performance_user_timing.html]
+ [test_worker_performance_now.html]
+ [test_timeOrigin.html]
++[test_worker_performance_entries.html]
+diff --git a/dom/performance/tests/test_worker_performance_entries.html b/dom/performance/tests/test_worker_performance_entries.html
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/tests/test_worker_performance_entries.html
+@@ -0,0 +1,31 @@
++<!-- Any copyright is dedicated to the Public Domain.
++   - http://creativecommons.org/publicdomain/zero/1.0/ -->
++<!DOCTYPE HTML>
++<html>
++<head>
++  <title>PerformanceResouceTiming in workers</title>
++  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
++  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
++</head>
++<body>
++<script class="testbody" type="text/javascript">
++
++SimpleTest.waitForExplicitFinish();
++var worker = new Worker('test_worker_performance_entries.js');
++worker.onmessage = function(event) {
++  if (event.data.type == "check") {
++    ok(event.data.status, event.data.msg);
++    return;
++  }
++
++  if (event.data.type == "finish") {
++    SimpleTest.finish();
++    return;
++  }
++
++  ok(false, "?!?");
++}
++
++</script>
++</body>
++</html>
+diff --git a/dom/performance/tests/test_worker_performance_entries.js b/dom/performance/tests/test_worker_performance_entries.js
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/tests/test_worker_performance_entries.js
+@@ -0,0 +1,102 @@
++function ok(a, msg) {
++  postMessage({type: "check", status: !!a, msg });
++}
++
++function is(a, b, msg) {
++  ok(a === b, msg);
++}
++
++function finish(a, msg) {
++  postMessage({type: "finish" });
++}
++
++function check(resource, initiatorType, protocol) {
++  let entries = performance.getEntries();
++  ok(entries.length == 1, "We have an entry");
++
++  ok(entries[0] instanceof PerformanceEntry,
++     "The entry is a PerformanceEntry");
++  ok(entries[0].name.endsWith(resource), "The entry has been found!");
++
++  is(entries[0].entryType, "resource", "Correct EntryType");
++  ok(entries[0].startTime > 0, "We have a startTime");
++  ok(entries[0].duration > 0, "We have a duration");
++
++  ok(entries[0] instanceof PerformanceResourceTiming,
++     "The entry is a PerformanceResourceTiming");
++
++  is(entries[0].initiatorType, initiatorType, "Correct initiatorType");
++  is(entries[0].nextHopProtocol, protocol, "Correct protocol");
++
++  performance.clearResourceTimings();
++}
++
++function simple_checks() {
++  ok("performance" in self, "We have self.performance");
++  performance.clearResourceTimings();
++  next();
++}
++
++function fetch_request() {
++  fetch("test_worker_performance_entries.sjs")
++  .then(r => r.blob())
++  .then(blob => {
++    check("test_worker_performance_entries.sjs", "fetch", "http/1.1");
++  })
++  .then(next);
++}
++
++function xhr_request() {
++  let xhr = new XMLHttpRequest();
++  xhr.open("GET", "test_worker_performance_entries.sjs");
++  xhr.send();
++  xhr.onload = () => {
++    check("test_worker_performance_entries.sjs", "xmlhttprequest", "http/1.1");
++    next();
++  }
++}
++
++function sync_xhr_request() {
++  let xhr = new XMLHttpRequest();
++  xhr.open("GET", "test_worker_performance_entries.sjs", false);
++  xhr.send();
++  check("test_worker_performance_entries.sjs", "xmlhttprequest", "http/1.1");
++  next();
++}
++
++function import_script() {
++  importScripts(["empty.js"]);
++  check("empty.js", "other", "http/1.1");
++  next();
++}
++
++function redirect() {
++  fetch("test_worker_performance_entries.sjs?redirect")
++  .then(r => r.text())
++  .then(text => {
++    is(text, "Hello world \\o/", "The redirect worked correctly");
++    check("test_worker_performance_entries.sjs?redirect", "fetch", "http/1.1");
++  })
++  .then(next);
++}
++
++let tests = [
++  simple_checks,
++  fetch_request,
++  xhr_request,
++  sync_xhr_request,
++  import_script,
++  redirect,
++];
++
++function next() {
++  if (!tests.length) {
++    finish();
++    return;
++  }
++
++  let test = tests.shift();
++  test();
++}
++
++next();
+diff --git a/dom/performance/tests/test_worker_performance_entries.sjs b/dom/performance/tests/test_worker_performance_entries.sjs
+new file mode 100644
+--- /dev/null
++++ b/dom/performance/tests/test_worker_performance_entries.sjs
+@@ -0,0 +1,12 @@
++function handleRequest(request, response)
++{
++  response.setHeader("Content-Type", "text/html");
++
++  if (request.queryString == "redirect") {
++    response.setStatusLine(request.httpVersion, 302, "See Other");
++    response.setHeader("Location", "test_worker_performance_entries.sjs?ok");
++  } else {
++    response.setStatusLine(request.httpVersion, 200, "OK");
++    response.write("Hello world \\o/");
++  }
++}

+ 2314 - 0
mozilla-release/patches/1429014-59a1.patch

@@ -0,0 +1,2314 @@
+# HG changeset patch
+# User Boris Zbarsky <bzbarsky@mit.edu>
+# Date 1516131598 18000
+# Node ID fd6dca879e6a5f2a3cf1b9be4e9e992176193dd0
+# Parent  591f1703de4d701e84206120eda0ec766b60335f
+Bug 1429014.  Make test_interfaces require explicit opt-in to add a non-SecureContext interface.  r=bkelly
+
+The big data tables had the following search-and-replaces done on them:
+
+  name: "\([^"]+\)" -> name: "\1", insecureContext: true
+
+  "\([^"]+\)",$ -> {name: "\1", insecureContext: true},
+
+followed by removal of both isSecureContext and insecureContext annotations
+where both appeared.
+
+MozReview-Commit-ID: BkqAwXFf48x
+
+diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochitest/general/test_interfaces.js
+--- a/dom/tests/mochitest/general/test_interfaces.js
++++ b/dom/tests/mochitest/general/test_interfaces.js
+@@ -20,67 +20,67 @@
+ // ];
+ //
+ // See createInterfaceMap() below for a complete list of properties.
+ 
+ // IMPORTANT: Do not change this list without review from
+ //            a JavaScript Engine peer!
+ var ecmaGlobals =
+   [
+-    "Array",
+-    "ArrayBuffer",
+-    {name: "Atomics", disabled: true},
+-    "Boolean",
+-    {name: "ByteLengthQueuingStrategy", disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
+-    {name: "CountQueuingStrategy", disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
+-    "DataView",
+-    "Date",
+-    "Error",
+-    "EvalError",
+-    "Float32Array",
+-    "Float64Array",
+-    "Function",
++    {name: "Array", insecureContext: true},
++    {name: "ArrayBuffer", insecureContext: true},
++    {name: "Atomics", insecureContext: true, disabled: true},
++    {name: "Boolean", insecureContext: true},
++    {name: "ByteLengthQueuingStrategy", insecureContext: true, disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
++    {name: "CountQueuingStrategy", insecureContext: true, disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
++    {name: "DataView", insecureContext: true},
++    {name: "Date", insecureContext: true},
++    {name: "Error", insecureContext: true},
++    {name: "EvalError", insecureContext: true},
++    {name: "Float32Array", insecureContext: true},
++    {name: "Float64Array", insecureContext: true},
++    {name: "Function", insecureContext: true},
+     // NB: We haven't bothered to resolve constants like Infinity and NaN on
+     // Xrayed windows (which are seen from the XBL scope). We could support
+     // this if needed with some refactoring.
+-    {name: "Infinity", xbl: false},
+-    "Int16Array",
+-    "Int32Array",
+-    "Int8Array",
+-    "InternalError",
+-    "Intl",
+-    "JSON",
+-    "Map",
+-    "Math",
+-    {name: "NaN", xbl: false},
+-    "Number",
+-    "Object",
+-    "Promise",
+-    "Proxy",
+-    "RangeError",
+-    {name: "ReadableStream", disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
+-    "ReferenceError",
+-    "Reflect",
+-    "RegExp",
+-    "Set",
+-    {name: "SharedArrayBuffer", disabled: true},
+-    {name: "SIMD", nightly: true},
+-    "String",
+-    "Symbol",
+-    "SyntaxError",
+-    {name: "TypedObject", nightly: true},
+-    "TypeError",
+-    "Uint16Array",
+-    "Uint32Array",
+-    "Uint8Array",
+-    "Uint8ClampedArray",
+-    "URIError",
+-    "WeakMap",
+-    "WeakSet",
+-    {name: "WebAssembly", disabled: !SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()}
++    {name: "Infinity", insecureContext: true, xbl: false},
++    {name: "Int16Array", insecureContext: true},
++    {name: "Int32Array", insecureContext: true},
++    {name: "Int8Array", insecureContext: true},
++    {name: "InternalError", insecureContext: true},
++    {name: "Intl", insecureContext: true},
++    {name: "JSON", insecureContext: true},
++    {name: "Map", insecureContext: true},
++    {name: "Math", insecureContext: true},
++    {name: "NaN", insecureContext: true, xbl: false},
++    {name: "Number", insecureContext: true},
++    {name: "Object", insecureContext: true},
++    {name: "Promise", insecureContext: true},
++    {name: "Proxy", insecureContext: true},
++    {name: "RangeError", insecureContext: true},
++    {name: "ReadableStream", insecureContext: true, disabled: !SpecialPowers.Cu.getJSTestingFunctions().streamsAreEnabled()},
++    {name: "ReferenceError", insecureContext: true},
++    {name: "Reflect", insecureContext: true},
++    {name: "RegExp", insecureContext: true},
++    {name: "Set", insecureContext: true},
++    {name: "SharedArrayBuffer", insecureContext: true, disabled: true},
++    {name: "SIMD", insecureContext: true, nightly: true},
++    {name: "String", insecureContext: true},
++    {name: "Symbol", insecureContext: true},
++    {name: "SyntaxError", insecureContext: true},
++    {name: "TypedObject", insecureContext: true, nightly: true},
++    {name: "TypeError", insecureContext: true},
++    {name: "Uint16Array", insecureContext: true},
++    {name: "Uint32Array", insecureContext: true},
++    {name: "Uint8Array", insecureContext: true},
++    {name: "Uint8ClampedArray", insecureContext: true},
++    {name: "URIError", insecureContext: true},
++    {name: "WeakMap", insecureContext: true},
++    {name: "WeakSet", insecureContext: true},
++    {name: "WebAssembly", insecureContext: true, disabled: !SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()}
+   ];
+ // IMPORTANT: Do not change the list above without review from
+ //            a JavaScript Engine peer!
+ 
+ // IMPORTANT: Do not change the list below without review from a DOM peer,
+ //            except to remove items from it!
+ //
+ // This is a list of interfaces that were prefixed with 'moz' instead of 'Moz'.
+@@ -96,1182 +96,1187 @@ var legacyMozPrefixedInterfaces =
+   ];
+ // IMPORTANT: Do not change the list above without review from a DOM peer,
+ //            except to remove items from it!
+ 
+ // IMPORTANT: Do not change the list below without review from a DOM peer!
+ var interfaceNamesInGlobalScope =
+   [
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AbortController",
++    {name: "AbortController", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AbortSignal",
++    {name: "AbortSignal", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AnalyserNode",
++    {name: "AnalyserNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "Animation"},
++    {name: "Animation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "AnimationEffectReadOnly", release: false},
++    {name: "AnimationEffectReadOnly", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "AnimationEffectTiming", release: false},
++    {name: "AnimationEffectTiming", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "AnimationEffectTimingReadOnly", release: false},
++    {name: "AnimationEffectTimingReadOnly", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AnimationEvent",
++    {name: "AnimationEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "AnimationPlaybackEvent", release: false},
++    {name: "AnimationPlaybackEvent", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "AnimationTimeline", release: false},
++    {name: "AnimationTimeline", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Attr",
++    {name: "Attr", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Audio",
++    {name: "Audio", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioBuffer",
++    {name: "AudioBuffer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioContext",
++    {name: "AudioContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioBufferSourceNode",
++    {name: "AudioBufferSourceNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioDestinationNode",
++    {name: "AudioDestinationNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioListener",
++    {name: "AudioListener", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioNode",
++    {name: "AudioNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioParam",
++    {name: "AudioParam", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioProcessingEvent",
++    {name: "AudioProcessingEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioScheduledSourceNode",
++    {name: "AudioScheduledSourceNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AudioStreamTrack",
++    {name: "AudioStreamTrack", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BarProp",
++    {name: "BarProp", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BaseAudioContext",
++    {name: "BaseAudioContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BatteryManager",
++    {name: "BatteryManager", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BeforeUnloadEvent",
++    {name: "BeforeUnloadEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BiquadFilterNode",
++    {name: "BiquadFilterNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Blob",
++    {name: "Blob", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BlobEvent",
++    {name: "BlobEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "BoxObject", xbl: true},
++    {name: "BoxObject", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BroadcastChannel",
++    {name: "BroadcastChannel", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Cache",
++    {name: "Cache", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CacheStorage",
++    {name: "CacheStorage", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CanvasCaptureMediaStream",
++    {name: "CanvasCaptureMediaStream", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CanvasGradient",
++    {name: "CanvasGradient", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CanvasPattern",
++    {name: "CanvasPattern", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CanvasRenderingContext2D",
++    {name: "CanvasRenderingContext2D", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CaretPosition",
++    {name: "CaretPosition", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CDATASection",
++    {name: "CDATASection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ChannelMergerNode",
++    {name: "ChannelMergerNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ChannelSplitterNode",
++    {name: "ChannelSplitterNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CharacterData",
++    {name: "CharacterData", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ChromeNodeList", xbl: true},
++    {name: "ChromeNodeList", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ChromeWindow", xbl: true},
++    {name: "ChromeWindow", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ClipboardEvent",
++    {name: "ClipboardEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CloseEvent",
++    {name: "CloseEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "CommandEvent", xbl: true},
++    {name: "CommandEvent", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Comment",
++    {name: "Comment", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CompositionEvent",
++    {name: "CompositionEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ConstantSourceNode",
++    {name: "ConstantSourceNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ConvolverNode",
++    {name: "ConvolverNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Crypto",
++    {name: "Crypto", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CryptoKey",
++    {name: "CryptoKey", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSS",
++    {name: "CSS", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSS2Properties",
++    {name: "CSS2Properties", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "CSSAnimation", release: false},
++    {name: "CSSAnimation", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSConditionRule",
++    {name: "CSSConditionRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSCounterStyleRule",
++    {name: "CSSCounterStyleRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSFontFaceRule",
++    {name: "CSSFontFaceRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSFontFeatureValuesRule",
++    {name: "CSSFontFeatureValuesRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSGroupingRule",
++    {name: "CSSGroupingRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSImportRule",
++    {name: "CSSImportRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSKeyframeRule",
++    {name: "CSSKeyframeRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSKeyframesRule",
++    {name: "CSSKeyframesRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSMediaRule",
++    {name: "CSSMediaRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSMozDocumentRule",
++    {name: "CSSMozDocumentRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSNamespaceRule",
++    {name: "CSSNamespaceRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSPageRule",
++    {name: "CSSPageRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSPrimitiveValue",
++    {name: "CSSPrimitiveValue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "CSSPseudoElement", release: false},
++    {name: "CSSPseudoElement", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSRule",
++    {name: "CSSRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSRuleList",
++    {name: "CSSRuleList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSStyleDeclaration",
++    {name: "CSSStyleDeclaration", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSStyleRule",
++    {name: "CSSStyleRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSStyleSheet",
++    {name: "CSSStyleSheet", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSSupportsRule",
++    {name: "CSSSupportsRule", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "CSSTransition", release: false},
++    {name: "CSSTransition", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSValue",
++    {name: "CSSValue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CSSValueList",
++    {name: "CSSValueList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CustomElementRegistry",
++    {name: "CustomElementRegistry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CustomEvent",
++    {name: "CustomEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DataChannel",
++    {name: "DataChannel", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DataTransfer",
++    {name: "DataTransfer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DataTransferItem",
++    {name: "DataTransferItem", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DataTransferItemList",
++    {name: "DataTransferItemList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DelayNode",
++    {name: "DelayNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DeviceLightEvent",
++    {name: "DeviceLightEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DeviceMotionEvent",
++    {name: "DeviceMotionEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DeviceOrientationEvent",
++    {name: "DeviceOrientationEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DeviceProximityEvent",
++    {name: "DeviceProximityEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Directory",
++    {name: "Directory", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Document",
++    {name: "Document", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DocumentFragment",
++    {name: "DocumentFragment", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "DocumentTimeline", release: false},
++    {name: "DocumentTimeline", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DocumentType",
++    {name: "DocumentType", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "DOMConstructor", xbl: true},
++    {name: "DOMConstructor", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMCursor",
++    {name: "DOMCursor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMException",
++    {name: "DOMException", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMImplementation",
++    {name: "DOMImplementation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMMatrix",
++    {name: "DOMMatrix", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMMatrixReadOnly",
++    {name: "DOMMatrixReadOnly", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMParser",
++    {name: "DOMParser", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMPoint",
++    {name: "DOMPoint", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMPointReadOnly",
++    {name: "DOMPointReadOnly", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMQuad",
++    {name: "DOMQuad", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMRect",
++    {name: "DOMRect", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMRectList",
++    {name: "DOMRectList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMRectReadOnly",
++    {name: "DOMRectReadOnly", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMRequest",
++    {name: "DOMRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMStringList",
++    {name: "DOMStringList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMStringMap",
++    {name: "DOMStringMap", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMTokenList",
++    {name: "DOMTokenList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DragEvent",
++    {name: "DragEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DynamicsCompressorNode",
++    {name: "DynamicsCompressorNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Element",
++    {name: "Element", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ErrorEvent",
++    {name: "ErrorEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Event",
++    {name: "Event", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "EventSource",
++    {name: "EventSource", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "EventTarget",
++    {name: "EventTarget", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "File",
++    {name: "File", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileList",
++    {name: "FileList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileReader",
++    {name: "FileReader", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileSystem",
++    {name: "FileSystem", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileSystemDirectoryEntry",
++    {name: "FileSystemDirectoryEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileSystemDirectoryReader",
++    {name: "FileSystemDirectoryReader", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileSystemEntry",
++    {name: "FileSystemEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileSystemFileEntry",
++    {name: "FileSystemFileEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FocusEvent",
++    {name: "FocusEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FormData",
++    {name: "FormData", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FontFace",
++    {name: "FontFace", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FontFaceSet",
++    {name: "FontFaceSet", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FontFaceSetLoadEvent",
++    {name: "FontFaceSetLoadEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GainNode",
++    {name: "GainNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Gamepad",
++    {name: "Gamepad", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadAxisMoveEvent",
++    {name: "GamepadAxisMoveEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadButtonEvent",
++    {name: "GamepadButtonEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadButton",
++    {name: "GamepadButton", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadEvent",
++    {name: "GamepadEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadHapticActuator",
++    {name: "GamepadHapticActuator", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "GamepadPose",
++    {name: "GamepadPose", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HashChangeEvent",
++    {name: "HashChangeEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Headers",
++    {name: "Headers", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "History",
++    {name: "History", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLAllCollection",
++    {name: "HTMLAllCollection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLAnchorElement",
++    {name: "HTMLAnchorElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLAreaElement",
++    {name: "HTMLAreaElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLAudioElement",
++    {name: "HTMLAudioElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLBaseElement",
++    {name: "HTMLBaseElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLBodyElement",
++    {name: "HTMLBodyElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLBRElement",
++    {name: "HTMLBRElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLButtonElement",
++    {name: "HTMLButtonElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLCanvasElement",
++    {name: "HTMLCanvasElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLCollection",
++    {name: "HTMLCollection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDataElement",
++    {name: "HTMLDataElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDataListElement",
++    {name: "HTMLDataListElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDetailsElement",
++    {name: "HTMLDetailsElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "HTMLDialogElement", disabled: true},
++    {name: "HTMLDialogElement", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDirectoryElement",
++    {name: "HTMLDirectoryElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDivElement",
++    {name: "HTMLDivElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDListElement",
++    {name: "HTMLDListElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLDocument",
++    {name: "HTMLDocument", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLElement",
++    {name: "HTMLElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLEmbedElement",
++    {name: "HTMLEmbedElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFieldSetElement",
++    {name: "HTMLFieldSetElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFontElement",
++    {name: "HTMLFontElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFormControlsCollection",
++    {name: "HTMLFormControlsCollection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFormElement",
++    {name: "HTMLFormElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFrameElement",
++    {name: "HTMLFrameElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLFrameSetElement",
++    {name: "HTMLFrameSetElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLHeadElement",
++    {name: "HTMLHeadElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLHeadingElement",
++    {name: "HTMLHeadingElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLHRElement",
++    {name: "HTMLHRElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLHtmlElement",
++    {name: "HTMLHtmlElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLIFrameElement",
++    {name: "HTMLIFrameElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLImageElement",
++    {name: "HTMLImageElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLInputElement",
++    {name: "HTMLInputElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLLabelElement",
++    {name: "HTMLLabelElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLLegendElement",
++    {name: "HTMLLegendElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLLIElement",
++    {name: "HTMLLIElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLLinkElement",
++    {name: "HTMLLinkElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMapElement",
++    {name: "HTMLMapElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMediaElement",
++    {name: "HTMLMediaElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMenuElement",
++    {name: "HTMLMenuElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMenuItemElement",
++    {name: "HTMLMenuItemElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMetaElement",
++    {name: "HTMLMetaElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLMeterElement",
++    {name: "HTMLMeterElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLModElement",
++    {name: "HTMLModElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLObjectElement",
++    {name: "HTMLObjectElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLOListElement",
++    {name: "HTMLOListElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLOptGroupElement",
++    {name: "HTMLOptGroupElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLOptionElement",
++    {name: "HTMLOptionElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLOptionsCollection",
++    {name: "HTMLOptionsCollection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLOutputElement",
++    {name: "HTMLOutputElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLParagraphElement",
++    {name: "HTMLParagraphElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLParamElement",
++    {name: "HTMLParamElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLPreElement",
++    {name: "HTMLPreElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLPictureElement",
++    {name: "HTMLPictureElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLProgressElement",
++    {name: "HTMLProgressElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLQuoteElement",
++    {name: "HTMLQuoteElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLScriptElement",
++    {name: "HTMLScriptElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLSelectElement",
++    {name: "HTMLSelectElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "HTMLSlotElement", disabled: true},
++    {name: "HTMLSlotElement", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLSourceElement",
++    {name: "HTMLSourceElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLSpanElement",
++    {name: "HTMLSpanElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLStyleElement",
++    {name: "HTMLStyleElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableCaptionElement",
++    {name: "HTMLTableCaptionElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableCellElement",
++    {name: "HTMLTableCellElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableColElement",
++    {name: "HTMLTableColElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableElement",
++    {name: "HTMLTableElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableRowElement",
++    {name: "HTMLTableRowElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTableSectionElement",
++    {name: "HTMLTableSectionElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTemplateElement",
++    {name: "HTMLTemplateElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTextAreaElement",
++    {name: "HTMLTextAreaElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTimeElement",
++    {name: "HTMLTimeElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTitleElement",
++    {name: "HTMLTitleElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLTrackElement",
++    {name: "HTMLTrackElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLUListElement",
++    {name: "HTMLUListElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLUnknownElement",
++    {name: "HTMLUnknownElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "HTMLVideoElement",
++    {name: "HTMLVideoElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "IdleDeadline"},
++    {name: "IdleDeadline", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBCursor",
++    {name: "IDBCursor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBCursorWithValue",
++    {name: "IDBCursorWithValue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBDatabase",
++    {name: "IDBDatabase", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBFactory",
++    {name: "IDBFactory", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBFileHandle",
++    {name: "IDBFileHandle", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBFileRequest",
++    {name: "IDBFileRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBIndex",
++    {name: "IDBIndex", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBKeyRange",
++    {name: "IDBKeyRange", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBMutableFile",
++    {name: "IDBMutableFile", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBObjectStore",
++    {name: "IDBObjectStore", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBOpenDBRequest",
++    {name: "IDBOpenDBRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBRequest",
++    {name: "IDBRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBTransaction",
++    {name: "IDBTransaction", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBVersionChangeEvent",
++    {name: "IDBVersionChangeEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IIRFilterNode",
++    {name: "IIRFilterNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Image",
++    {name: "Image", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageBitmap",
++    {name: "ImageBitmap", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageBitmapRenderingContext",
++    {name: "ImageBitmapRenderingContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ImageCapture", disabled: true},
++    {name: "ImageCapture", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ImageCaptureErrorEvent", disabled: true},
++    {name: "ImageCaptureErrorEvent", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageData",
++    {name: "ImageData", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "InputEvent",
++    {name: "InputEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "InstallTrigger",
++    {name: "InstallTrigger", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IntersectionObserver",
++    {name: "IntersectionObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IntersectionObserverEntry",
++    {name: "IntersectionObserverEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "KeyEvent",
++    {name: "KeyEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "KeyboardEvent",
++    {name: "KeyboardEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "KeyframeEffectReadOnly", release: false},
++    {name: "KeyframeEffectReadOnly", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "KeyframeEffect", release: false},
++    {name: "KeyframeEffect", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "LocalMediaStream",
++    {name: "LocalMediaStream", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Location",
++    {name: "Location", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaDeviceInfo",
++    {name: "MediaDeviceInfo", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaDevices",
++    {name: "MediaDevices", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaElementAudioSourceNode",
++    {name: "MediaElementAudioSourceNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaError",
++    {name: "MediaError", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeyError",
++    {name: "MediaKeyError", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaEncryptedEvent",
++    {name: "MediaEncryptedEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeys",
++    {name: "MediaKeys", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeySession",
++    {name: "MediaKeySession", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeySystemAccess",
++    {name: "MediaKeySystemAccess", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeyMessageEvent",
++    {name: "MediaKeyMessageEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaKeyStatusMap",
++    {name: "MediaKeyStatusMap", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaList",
++    {name: "MediaList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaQueryList",
++    {name: "MediaQueryList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaQueryListEvent",
++    {name: "MediaQueryListEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaRecorder",
++    {name: "MediaRecorder", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaRecorderErrorEvent",
++    {name: "MediaRecorderErrorEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaSource",
++    {name: "MediaSource", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStream",
++    {name: "MediaStream", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStreamAudioDestinationNode",
++    {name: "MediaStreamAudioDestinationNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStreamAudioSourceNode",
++    {name: "MediaStreamAudioSourceNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStreamEvent",
++    {name: "MediaStreamEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStreamTrackEvent",
++    {name: "MediaStreamTrackEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MediaStreamTrack",
++    {name: "MediaStreamTrack", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "MenuBoxObject", xbl: true},
++    {name: "MenuBoxObject", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessageChannel",
++    {name: "MessageChannel", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessageEvent",
++    {name: "MessageEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessagePort",
++    {name: "MessagePort", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MimeType",
++    {name: "MimeType", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MimeTypeArray",
++    {name: "MimeTypeArray", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MouseEvent",
++    {name: "MouseEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MouseScrollEvent",
++    {name: "MouseScrollEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "mozRTCIceCandidate",
++    {name: "mozRTCIceCandidate", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "mozRTCPeerConnection",
++    {name: "mozRTCPeerConnection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "mozRTCSessionDescription",
++    {name: "mozRTCSessionDescription", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MutationEvent",
++    {name: "MutationEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MutationObserver",
++    {name: "MutationObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MutationRecord",
++    {name: "MutationRecord", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "NamedNodeMap",
++    {name: "NamedNodeMap", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Navigator",
++    {name: "Navigator", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "NetworkInformation", desktop: false},
++    {name: "NetworkInformation", insecureContext: true, desktop: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Node",
++    {name: "Node", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "NodeFilter",
++    {name: "NodeFilter", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "NodeIterator",
++    {name: "NodeIterator", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "NodeList",
++    {name: "NodeList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Notification",
++    {name: "Notification", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "OffscreenCanvas", disabled: true},
++    {name: "OffscreenCanvas", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "OfflineAudioCompletionEvent",
++    {name: "OfflineAudioCompletionEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "OfflineAudioContext",
++    {name: "OfflineAudioContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "OfflineResourceList",
++    {name: "OfflineResourceList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Option",
++    {name: "Option", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "OscillatorNode",
++    {name: "OscillatorNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PageTransitionEvent",
++    {name: "PageTransitionEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PaintRequest",
++    {name: "PaintRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PaintRequestList",
++    {name: "PaintRequestList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PannerNode",
++    {name: "PannerNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Path2D",
++    {name: "Path2D", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Performance",
++    {name: "Performance", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceEntry",
++    {name: "PerformanceEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceMark",
++    {name: "PerformanceMark", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceMeasure",
++    {name: "PerformanceMeasure", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceNavigation",
++    {name: "PerformanceNavigation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceNavigationTiming",
++    {name: "PerformanceNavigationTiming", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceObserver",
++    {name: "PerformanceObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceObserverEntryList",
++    {name: "PerformanceObserverEntryList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceResourceTiming",
++    {name: "PerformanceResourceTiming", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceTiming",
++    {name: "PerformanceTiming", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PeriodicWave",
++    {name: "PeriodicWave", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Permissions",
++    {name: "Permissions", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PermissionStatus",
++    {name: "PermissionStatus", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Plugin",
++    {name: "Plugin", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PluginArray",
++    {name: "PluginArray", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "PointerEvent", android: false},
++    {name: "PointerEvent", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PopStateEvent",
++    {name: "PopStateEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PopupBlockedEvent",
++    {name: "PopupBlockedEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "PopupBoxObject", xbl: true},
++    {name: "PopupBoxObject", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ProcessingInstruction",
++    {name: "ProcessingInstruction", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ProgressEvent",
++    {name: "ProgressEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushManager",
++    {name: "PushManager", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushSubscription",
++    {name: "PushSubscription", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushSubscriptionOptions",
++    {name: "PushSubscriptionOptions", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RadioNodeList",
++    {name: "RadioNodeList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Range",
++    {name: "Range", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Rect",
++    {name: "Rect", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Request",
++    {name: "Request", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ResizeObserver",
++    {name: "ResizeObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ResizeObserverEntry",
++    {name: "ResizeObserverEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ResizeObserverSize",
++    {name: "ResizeObserverSize", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Response",
++    {name: "Response", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RGBColor",
++    {name: "RGBColor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCCertificate",
++    {name: "RTCCertificate", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCDataChannelEvent",
++    {name: "RTCDataChannelEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCDTMFSender",
++    {name: "RTCDTMFSender", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCDTMFToneChangeEvent",
++    {name: "RTCDTMFToneChangeEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCIceCandidate",
++    {name: "RTCIceCandidate", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCPeerConnection",
++    {name: "RTCPeerConnection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCPeerConnectionIceEvent",
++    {name: "RTCPeerConnectionIceEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCRtpReceiver",
++    {name: "RTCRtpReceiver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCRtpSender",
++    {name: "RTCRtpSender", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCRtpTransceiver",
++    {name: "RTCRtpTransceiver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCSessionDescription",
++    {name: "RTCSessionDescription", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCStatsReport",
++    {name: "RTCStatsReport", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "RTCTrackEvent",
++    {name: "RTCTrackEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Screen",
++    {name: "Screen", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ScreenOrientation",
++    {name: "ScreenOrientation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ScriptProcessorNode",
++    {name: "ScriptProcessorNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ScrollAreaEvent",
++    {name: "ScrollAreaEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SecurityPolicyViolationEvent", release: false},
++    {name: "SecurityPolicyViolationEvent", insecureContext: true, release: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Selection",
++    {name: "Selection", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ServiceWorker",
++    {name: "ServiceWorker", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ServiceWorkerContainer",
++    {name: "ServiceWorkerContainer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ServiceWorkerRegistration",
++    {name: "ServiceWorkerRegistration", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ScopedCredential", disabled: true},
++    {name: "ScopedCredential", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ScopedCredentialInfo", disabled: true},
++    {name: "ScopedCredentialInfo", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "ShadowRoot", disabled: true},
++    {name: "ShadowRoot", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SharedWorker",
++    {name: "SharedWorker", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SimpleGestureEvent", xbl: true},
++    {name: "SimpleGestureEvent", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SimpleTest", xbl: false},
++    {name: "SimpleTest", insecureContext: true, xbl: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SourceBuffer",
++    {name: "SourceBuffer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SourceBufferList",
++    {name: "SourceBufferList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpeechSynthesisErrorEvent", android: false},
++    {name: "SpeechSynthesisErrorEvent", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpeechSynthesisEvent", android: false},
++    {name: "SpeechSynthesisEvent", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpeechSynthesis", android: false},
++    {name: "SpeechSynthesis", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpeechSynthesisUtterance", android: false},
++    {name: "SpeechSynthesisUtterance", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpeechSynthesisVoice", android: false},
++    {name: "SpeechSynthesisVoice", insecureContext: true, android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "SpecialPowers", xbl: false},
++    {name: "SpecialPowers", insecureContext: true, xbl: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "StereoPannerNode",
++    {name: "StereoPannerNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Storage",
++    {name: "Storage", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "StorageEvent",
++    {name: "StorageEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "StorageManager", isSecureContext: true, android: false},
++    {name: "StorageManager", android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "StyleSheet",
++    {name: "StyleSheet", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "StyleSheetList",
++    {name: "StyleSheetList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SubtleCrypto",
++    {name: "SubtleCrypto", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAElement",
++    {name: "SVGAElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAngle",
++    {name: "SVGAngle", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedAngle",
++    {name: "SVGAnimatedAngle", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedBoolean",
++    {name: "SVGAnimatedBoolean", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedEnumeration",
++    {name: "SVGAnimatedEnumeration", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedInteger",
++    {name: "SVGAnimatedInteger", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedLength",
++    {name: "SVGAnimatedLength", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedLengthList",
++    {name: "SVGAnimatedLengthList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedNumber",
++    {name: "SVGAnimatedNumber", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedNumberList",
++    {name: "SVGAnimatedNumberList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedPreserveAspectRatio",
++    {name: "SVGAnimatedPreserveAspectRatio", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedRect",
++    {name: "SVGAnimatedRect", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedString",
++    {name: "SVGAnimatedString", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimatedTransformList",
++    {name: "SVGAnimatedTransformList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimateElement",
++    {name: "SVGAnimateElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimateMotionElement",
++    {name: "SVGAnimateMotionElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimateTransformElement",
++    {name: "SVGAnimateTransformElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGAnimationElement",
++    {name: "SVGAnimationElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGCircleElement",
++    {name: "SVGCircleElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGClipPathElement",
++    {name: "SVGClipPathElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGComponentTransferFunctionElement",
++    {name: "SVGComponentTransferFunctionElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGDefsElement",
++    {name: "SVGDefsElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGDescElement",
++    {name: "SVGDescElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGElement",
++    {name: "SVGElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGEllipseElement",
++    {name: "SVGEllipseElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEBlendElement",
++    {name: "SVGFEBlendElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEColorMatrixElement",
++    {name: "SVGFEColorMatrixElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEComponentTransferElement",
++    {name: "SVGFEComponentTransferElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFECompositeElement",
++    {name: "SVGFECompositeElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEConvolveMatrixElement",
++    {name: "SVGFEConvolveMatrixElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEDiffuseLightingElement",
++    {name: "SVGFEDiffuseLightingElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEDisplacementMapElement",
++    {name: "SVGFEDisplacementMapElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEDistantLightElement",
++    {name: "SVGFEDistantLightElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEDropShadowElement",
++    {name: "SVGFEDropShadowElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEFloodElement",
++    {name: "SVGFEFloodElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEFuncAElement",
++    {name: "SVGFEFuncAElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEFuncBElement",
++    {name: "SVGFEFuncBElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEFuncGElement",
++    {name: "SVGFEFuncGElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEFuncRElement",
++    {name: "SVGFEFuncRElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEGaussianBlurElement",
++    {name: "SVGFEGaussianBlurElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEImageElement",
++    {name: "SVGFEImageElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEMergeElement",
++    {name: "SVGFEMergeElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEMergeNodeElement",
++    {name: "SVGFEMergeNodeElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEMorphologyElement",
++    {name: "SVGFEMorphologyElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEOffsetElement",
++    {name: "SVGFEOffsetElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFEPointLightElement",
++    {name: "SVGFEPointLightElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFESpecularLightingElement",
++    {name: "SVGFESpecularLightingElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFESpotLightElement",
++    {name: "SVGFESpotLightElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFETileElement",
++    {name: "SVGFETileElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFETurbulenceElement",
++    {name: "SVGFETurbulenceElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGFilterElement",
++    {name: "SVGFilterElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGForeignObjectElement",
++    {name: "SVGForeignObjectElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGGElement",
++    {name: "SVGGElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGGeometryElement",
++    {name: "SVGGeometryElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGGradientElement",
++    {name: "SVGGradientElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGGraphicsElement",
++    {name: "SVGGraphicsElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGImageElement",
++    {name: "SVGImageElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGLength",
++    {name: "SVGLength", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGLengthList",
++    {name: "SVGLengthList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGLinearGradientElement",
++    {name: "SVGLinearGradientElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGLineElement",
++    {name: "SVGLineElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGMarkerElement",
++    {name: "SVGMarkerElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGMaskElement",
++    {name: "SVGMaskElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGMatrix",
++    {name: "SVGMatrix", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGMetadataElement",
++    {name: "SVGMetadataElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGMPathElement",
++    {name: "SVGMPathElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGNumber",
++    {name: "SVGNumber", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGNumberList",
++    {name: "SVGNumberList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPathElement",
++    {name: "SVGPathElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPathSegList",
++    {name: "SVGPathSegList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPatternElement",
++    {name: "SVGPatternElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPoint",
++    {name: "SVGPoint", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPointList",
++    {name: "SVGPointList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPolygonElement",
++    {name: "SVGPolygonElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPolylineElement",
++    {name: "SVGPolylineElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGPreserveAspectRatio",
++    {name: "SVGPreserveAspectRatio", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGRadialGradientElement",
++    {name: "SVGRadialGradientElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGRect",
++    {name: "SVGRect", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGRectElement",
++    {name: "SVGRectElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGScriptElement",
++    {name: "SVGScriptElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGSetElement",
++    {name: "SVGSetElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGStopElement",
++    {name: "SVGStopElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGStringList",
++    {name: "SVGStringList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGStyleElement",
++    {name: "SVGStyleElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGSVGElement",
++    {name: "SVGSVGElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGSwitchElement",
++    {name: "SVGSwitchElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGSymbolElement",
++    {name: "SVGSymbolElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTextContentElement",
++    {name: "SVGTextContentElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTextElement",
++    {name: "SVGTextElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTextPathElement",
++    {name: "SVGTextPathElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTextPositioningElement",
++    {name: "SVGTextPositioningElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTitleElement",
++    {name: "SVGTitleElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTransform",
++    {name: "SVGTransform", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTransformList",
++    {name: "SVGTransformList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGTSpanElement",
++    {name: "SVGTSpanElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGUnitTypes",
++    {name: "SVGUnitTypes", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGUseElement",
++    {name: "SVGUseElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGViewElement",
++    {name: "SVGViewElement", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SVGZoomAndPan",
++    {name: "SVGZoomAndPan", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Text",
++    {name: "Text", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextDecoder",
++    {name: "TextDecoder", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextEncoder",
++    {name: "TextEncoder", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextMetrics",
++    {name: "TextMetrics", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextTrack",
++    {name: "TextTrack", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextTrackCue",
++    {name: "TextTrackCue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextTrackCueList",
++    {name: "TextTrackCueList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextTrackList",
++    {name: "TextTrackList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TimeEvent",
++    {name: "TimeEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TimeRanges",
++    {name: "TimeRanges", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Touch",
++    {name: "Touch", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TouchEvent",
++    {name: "TouchEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TouchList",
++    {name: "TouchList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TrackEvent",
++    {name: "TrackEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TransitionEvent",
++    {name: "TransitionEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "TreeColumn", xbl: true},
++    {name: "TreeColumn", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "TreeColumns", xbl: true},
++    {name: "TreeColumns", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "TreeContentView", xbl: true},
++    {name: "TreeContentView", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TreeWalker",
++    {name: "TreeWalker", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "U2F", disabled: true},
++    {name: "U2F", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "UIEvent",
++    {name: "UIEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "URL",
++    {name: "URL", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "URLSearchParams",
++    {name: "URLSearchParams", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "UserProximityEvent",
++    {name: "UserProximityEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ValidityState",
++    {name: "ValidityState", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "VideoPlaybackQuality",
++    {name: "VideoPlaybackQuality", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "VideoStreamTrack",
++    {name: "VideoStreamTrack", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRDisplay", releaseNonWindows: false},
++    {name: "VRDisplay", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRDisplayCapabilities", releaseNonWindows: false},
++    {name: "VRDisplayCapabilities", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRDisplayEvent", releaseNonWindows: false},
++    {name: "VRDisplayEvent", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VREyeParameters", releaseNonWindows: false},
++    {name: "VREyeParameters", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRFieldOfView", releaseNonWindows: false},
++    {name: "VRFieldOfView", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRFrameData", releaseNonWindows: false},
++    {name: "VRFrameData", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRPose", releaseNonWindows: false},
++    {name: "VRPose", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "VRStageParameters", releaseNonWindows: false},
++    {name: "VRStageParameters", insecureContext: true, releaseNonWindows: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "VTTCue",
++    {name: "VTTCue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "VTTRegion",
++    {name: "VTTRegion", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WaveShaperNode",
++    {name: "WaveShaperNode", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "WebAuthnAssertion", disabled: true},
++    {name: "WebAuthnAssertion", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "WebAuthnAttestation", disabled: true},
++    {name: "WebAuthnAttestation", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "WebAuthentication", disabled: true},
++    {name: "WebAuthentication", insecureContext: true, disabled: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLActiveInfo",
++    {name: "WebGLActiveInfo", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLBuffer",
++    {name: "WebGLBuffer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLContextEvent",
++    {name: "WebGLContextEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLFramebuffer",
++    {name: "WebGLFramebuffer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLProgram",
++    {name: "WebGLProgram", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLQuery",
++    {name: "WebGLQuery", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLRenderbuffer",
++    {name: "WebGLRenderbuffer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLRenderingContext",
++    {name: "WebGLRenderingContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGL2RenderingContext",
++    {name: "WebGL2RenderingContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLSampler",
++    {name: "WebGLSampler", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLShader",
++    {name: "WebGLShader", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLShaderPrecisionFormat",
++    {name: "WebGLShaderPrecisionFormat", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLSync",
++    {name: "WebGLSync", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLTexture",
++    {name: "WebGLTexture", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLTransformFeedback",
++    {name: "WebGLTransformFeedback", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLUniformLocation",
++    {name: "WebGLUniformLocation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebGLVertexArrayObject",
++    {name: "WebGLVertexArrayObject", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebKitCSSMatrix",
++    {name: "WebKitCSSMatrix", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebSocket",
++    {name: "WebSocket", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WheelEvent",
++    {name: "WheelEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Window",
++    {name: "Window", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Worker",
++    {name: "Worker", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLDocument",
++    {name: "XMLDocument", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequest",
++    {name: "XMLHttpRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequestEventTarget",
++    {name: "XMLHttpRequestEventTarget", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequestUpload",
++    {name: "XMLHttpRequestUpload", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLSerializer",
++    {name: "XMLSerializer", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLStylesheetProcessingInstruction",
++    {name: "XMLStylesheetProcessingInstruction", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XPathEvaluator",
++    {name: "XPathEvaluator", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XPathExpression",
++    {name: "XPathExpression", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XPathResult",
++    {name: "XPathResult", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XSLTProcessor",
++    {name: "XSLTProcessor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULButtonElement", xbl: true},
++    {name: "XULButtonElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULCheckboxElement", xbl: true},
++    {name: "XULCheckboxElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULCommandEvent", xbl: true},
++    {name: "XULCommandEvent", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULControlElement", xbl: true},
++    {name: "XULControlElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULDocument", xbl: true},
++    {name: "XULDocument", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULElement", xbl: true},
++    {name: "XULElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULLabeledControlElement", xbl: true},
++    {name: "XULLabeledControlElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULPopupElement", xbl: true},
++    {name: "XULPopupElement", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULTemplateBuilder", xbl: true},
++    {name: "XULTemplateBuilder", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULTreeBuilder", xbl: true},
++    {name: "XULTreeBuilder", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "XULTreeBuilderObserver", xbl: true},
++    {name: "XULTreeBuilderObserver", insecureContext: true, xbl: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+   ];
+ // IMPORTANT: Do not change the list above without review from a DOM peer!
+ 
+ function createInterfaceMap(isXBLScope) {
+   var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
+   var isNightly = version.endsWith("a1");
+   var isRelease = !version.includes("a");
+   var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
+   var isMac = /Mac OS/.test(navigator.oscpu);
+   var isWindows = /Windows/.test(navigator.oscpu);
+   var isAndroid = navigator.userAgent.includes("Android");
+   var isLinux = /Linux/.test(navigator.oscpu) && !isAndroid;
+-  var isSecureContext = window.isSecureContext;
++  var isInsecureContext = !window.isSecureContext;
+ 
+   var interfaceMap = {};
+ 
+   function addInterfaces(interfaces)
+   {
+     for (var entry of interfaces) {
+       if (typeof(entry) === "string") {
+-        interfaceMap[entry] = true;
++        interfaceMap[entry] = !isInsecureContext;
+       } else {
+         ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
+         if ((entry.nightly === !isNightly) ||
+             (entry.nightlyAndroid === !(isAndroid && isNightly) && isAndroid) ||
+             (entry.xbl === !isXBLScope) ||
+             (entry.desktop === !isDesktop) ||
+             (entry.windows === !isWindows) ||
+             (entry.releaseNonWindows === !isRelease && !isWindows) ||
+             (entry.mac === !isMac) ||
+             (entry.linux === !isLinux) ||
+             (entry.android === !isAndroid && !entry.nightlyAndroid) ||
+             (entry.release === !isRelease) ||
+-            (entry.isSecureContext === !isSecureContext) ||
++	    // The insecureContext test is very purposefully converting
++	    // entry.insecureContext to boolean, so undefined will convert to
++	    // false.  That way entries without an insecureContext annotation
++	    // will get treated as "insecureContext: false", which means exposed
++	    // only in secure contexts.
++            (isInsecureContext && !Boolean(entry.insecureContext)) ||
+             entry.disabled) {
+           interfaceMap[entry.name] = false;
+         } else {
+           interfaceMap[entry.name] = true;
+         }
+       }
+     }
+   }
+diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js
+--- a/dom/workers/test/test_worker_interfaces.js
++++ b/dom/workers/test/test_worker_interfaces.js
+@@ -4,276 +4,282 @@
+ 
+ // This file lists global interfaces we want exposed and verifies they
+ // are what we intend. Each entry in the arrays below can either be a
+ // simple string with the interface name, or an object with a 'name'
+ // property giving the interface name as a string, and additional
+ // properties which qualify the exposure of that interface. For example:
+ //
+ // [
+-//   "AGlobalInterface",
++//   "AGlobalInterface", // secure context only
+ //   { name: "ExperimentalThing", release: false },
+ //   { name: "ReallyExperimentalThing", nightly: true },
+ //   { name: "DesktopOnlyThing", desktop: true },
+ //   { name: "FancyControl", xbl: true },
+ //   { name: "DisabledEverywhere", disabled: true },
+ // ];
+ //
+ // See createInterfaceMap() below for a complete list of properties.
+ 
+ // IMPORTANT: Do not change this list without review from
+ //            a JavaScript Engine peer!
+ var ecmaGlobals =
+   [
+-    "Array",
+-    "ArrayBuffer",
+-    {name: "Atomics", disabled: true},
+-    "Boolean",
+-    {name: "ByteLengthQueuingStrategy", optional: true},
+-    {name: "CountQueuingStrategy", optional: true},
+-    "DataView",
+-    "Date",
+-    "Error",
+-    "EvalError",
+-    "Float32Array",
+-    "Float64Array",
+-    "Function",
+-    "Infinity",
+-    "Int16Array",
+-    "Int32Array",
+-    "Int8Array",
+-    "InternalError",
+-    "Intl",
+-    "JSON",
+-    "Map",
+-    "Math",
+-    "NaN",
+-    "Number",
+-    "Object",
+-    "Promise",
+-    "Proxy",
+-    "RangeError",
+-    {name: "ReadableStream", optional: true},
+-    "ReferenceError",
+-    "Reflect",
+-    "RegExp",
+-    "Set",
+-    {name: "SharedArrayBuffer", disabled: true},
+-    {name: "SIMD", nightly: true},
+-    "String",
+-    "Symbol",
+-    "SyntaxError",
+-    {name: "TypedObject", nightly: true},
+-    "TypeError",
+-    "Uint16Array",
+-    "Uint32Array",
+-    "Uint8Array",
+-    "Uint8ClampedArray",
+-    "URIError",
+-    "WeakMap",
+-    "WeakSet",
+-    {name: "WebAssembly", optional: true}
++    {name: "Array", insecureContext: true},
++    {name: "ArrayBuffer", insecureContext: true},
++    {name: "Atomics", insecureContext: true, disabled: true},
++    {name: "Boolean", insecureContext: true},
++    {name: "ByteLengthQueuingStrategy", insecureContext: true, optional: true},
++    {name: "CountQueuingStrategy", insecureContext: true, optional: true},
++    {name: "DataView", insecureContext: true},
++    {name: "Date", insecureContext: true},
++    {name: "Error", insecureContext: true},
++    {name: "EvalError", insecureContext: true},
++    {name: "Float32Array", insecureContext: true},
++    {name: "Float64Array", insecureContext: true},
++    {name: "Function", insecureContext: true},
++    {name: "Infinity", insecureContext: true},
++    {name: "Int16Array", insecureContext: true},
++    {name: "Int32Array", insecureContext: true},
++    {name: "Int8Array", insecureContext: true},
++    {name: "InternalError", insecureContext: true},
++    {name: "Intl", insecureContext: true},
++    {name: "JSON", insecureContext: true},
++    {name: "Map", insecureContext: true},
++    {name: "Math", insecureContext: true},
++    {name: "NaN", insecureContext: true},
++    {name: "Number", insecureContext: true},
++    {name: "Object", insecureContext: true},
++    {name: "Promise", insecureContext: true},
++    {name: "Proxy", insecureContext: true},
++    {name: "RangeError", insecureContext: true},
++    {name: "ReadableStream", insecureContext: true, optional: true},
++    {name: "ReferenceError", insecureContext: true},
++    {name: "Reflect", insecureContext: true},
++    {name: "RegExp", insecureContext: true},
++    {name: "Set", insecureContext: true},
++    {name: "SharedArrayBuffer", insecureContext: true, disabled: true},
++    {name: "SIMD", insecureContext: true, nightly: true},
++    {name: "String", insecureContext: true},
++    {name: "Symbol", insecureContext: true},
++    {name: "SyntaxError", insecureContext: true},
++    {name: "TypedObject", insecureContext: true, nightly: true},
++    {name: "TypeError", insecureContext: true},
++    {name: "Uint16Array", insecureContext: true},
++    {name: "Uint32Array", insecureContext: true},
++    {name: "Uint8Array", insecureContext: true},
++    {name: "Uint8ClampedArray", insecureContext: true},
++    {name: "URIError", insecureContext: true},
++    {name: "WeakMap", insecureContext: true},
++    {name: "WeakSet", insecureContext: true},
++    {name: "WebAssembly", insecureContext: true, optional: true}
+   ];
+ // IMPORTANT: Do not change the list above without review from
+ //            a JavaScript Engine peer!
+ 
+ // IMPORTANT: Do not change the list below without review from a DOM peer!
+ var interfaceNamesInGlobalScope =
+   [
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AbortController",
++    {name: "AbortController", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "AbortSignal",
++    {name: "AbortSignal", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Blob",
++    {name: "Blob", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "BroadcastChannel",
++    {name: "BroadcastChannel", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Cache",
++    {name: "Cache", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CacheStorage",
++    {name: "CacheStorage", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CloseEvent",
++    {name: "CloseEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Crypto",
++    {name: "Crypto", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "CustomEvent",
++    {name: "CustomEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DedicatedWorkerGlobalScope",
++    {name: "DedicatedWorkerGlobalScope", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Directory",
++    {name: "Directory", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMCursor",
++    {name: "DOMCursor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMException",
++    {name: "DOMException", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMRequest",
++    {name: "DOMRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "DOMStringList",
++    {name: "DOMStringList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ErrorEvent",
++    {name: "ErrorEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Event",
++    {name: "Event", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "EventSource",
++    {name: "EventSource", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "EventTarget",
++    {name: "EventTarget", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "File",
++    {name: "File", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileList",
++    {name: "FileList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileReader",
++    {name: "FileReader", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FileReaderSync",
++    {name: "FileReaderSync", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "FormData",
++    {name: "FormData", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Headers",
++    {name: "Headers", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBCursor",
++    {name: "IDBCursor", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBCursorWithValue",
++    {name: "IDBCursorWithValue", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBDatabase",
++    {name: "IDBDatabase", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBFactory",
++    {name: "IDBFactory", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBIndex",
++    {name: "IDBIndex", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBKeyRange",
++    {name: "IDBKeyRange", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBObjectStore",
++    {name: "IDBObjectStore", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBOpenDBRequest",
++    {name: "IDBOpenDBRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBRequest",
++    {name: "IDBRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBTransaction",
++    {name: "IDBTransaction", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "IDBVersionChangeEvent",
++    {name: "IDBVersionChangeEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageBitmap",
++    {name: "ImageBitmap", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageBitmapRenderingContext",
++    {name: "ImageBitmapRenderingContext", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ImageData",
++    {name: "ImageData", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessageChannel",
++    {name: "MessageChannel", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessageEvent",
++    {name: "MessageEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "MessagePort",
++    {name: "MessagePort", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "NetworkInformation", android: true },
++    { name: "NetworkInformation", insecureContext: true, android: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Notification",
++    {name: "Notification", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "OffscreenCanvas", disabled: true },
++    { name: "OffscreenCanvas", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Performance",
++    {name: "Performance", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceEntry",
++    {name: "PerformanceEntry", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceMark",
++    {name: "PerformanceMark", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceMeasure",
++    {name: "PerformanceMeasure", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceObserver",
++    {name: "PerformanceObserver", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PerformanceObserverEntryList",
++    {name: "PerformanceObserverEntryList", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ProgressEvent",
++    {name: "ProgressEvent", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushManager",
++    {name: "PushManager", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushSubscription",
++    {name: "PushSubscription", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "PushSubscriptionOptions",
++    {name: "PushSubscriptionOptions", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Request",
++    {name: "Request", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Response",
++    {name: "Response", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "ServiceWorkerRegistration",
++    {name: "ServiceWorkerRegistration", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    {name: "StorageManager", isSecureContext: true, android: false},
++    {name: "StorageManager", android: false},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "SubtleCrypto",
++    {name: "SubtleCrypto", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextDecoder",
++    {name: "TextDecoder", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "TextEncoder",
++    {name: "TextEncoder", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequest",
++    {name: "XMLHttpRequest", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequestEventTarget",
++    {name: "XMLHttpRequestEventTarget", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "XMLHttpRequestUpload",
++    {name: "XMLHttpRequestUpload", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "URL",
++    {name: "URL", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "URLSearchParams",
++    {name: "URLSearchParams", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLActiveInfo", disabled: true },
++    { name: "WebGLActiveInfo", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLBuffer", disabled: true },
++    { name: "WebGLBuffer", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLContextEvent", disabled: true },
++    { name: "WebGLContextEvent", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLFramebuffer", disabled: true },
++    { name: "WebGLFramebuffer", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLProgram", disabled: true },
++    { name: "WebGLProgram", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLRenderbuffer", disabled: true },
++    { name: "WebGLRenderbuffer", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLRenderingContext", disabled: true },
++    { name: "WebGLRenderingContext", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLShader", disabled: true },
++    { name: "WebGLShader", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLShaderPrecisionFormat", disabled: true },
++    { name: "WebGLShaderPrecisionFormat", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLTexture", disabled: true },
++    { name: "WebGLTexture", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    { name: "WebGLUniformLocation", disabled: true },
++    { name: "WebGLUniformLocation", insecureContext: true, disabled: true },
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WebSocket",
++    {name: "WebSocket", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "Worker",
++    {name: "Worker", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WorkerGlobalScope",
++    {name: "WorkerGlobalScope", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WorkerLocation",
++    {name: "WorkerLocation", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+-    "WorkerNavigator",
++    {name: "WorkerNavigator", insecureContext: true},
+ // IMPORTANT: Do not change this list without review from a DOM peer!
+   ];
+ // IMPORTANT: Do not change the list above without review from a DOM peer!
+ 
+ function createInterfaceMap(version, userAgent) {
+   var isNightly = version.endsWith("a1");
+   var isRelease = !version.includes("a");
+   var isDesktop = !/Mobile|Tablet/.test(userAgent);
+   var isAndroid = !!navigator.userAgent.includes("Android");
++  var isInsecureContext = !self.isSecureContext;
+ 
+   var interfaceMap = {};
+ 
+   function addInterfaces(interfaces)
+   {
+     for (var entry of interfaces) {
+       if (typeof(entry) === "string") {
+-        interfaceMap[entry] = true;
++        interfaceMap[entry] = !isInsecureContext;
+       } else {
+         ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
+         if ((entry.nightly === !isNightly) ||
+             (entry.nightlyAndroid === !(isAndroid && isNightly) && isAndroid) ||
+             (entry.desktop === !isDesktop) ||
+             (entry.android === !isAndroid && !entry.nightlyAndroid) ||
+             (entry.release === !isRelease) ||
+-            (entry.isSecureContext === !isSecureContext) ||
++      	    // The insecureContext test is very purposefully converting
++	    // entry.insecureContext to boolean, so undefined will convert to
++	    // false.  That way entries without an insecureContext annotation
++	    // will get treated as "insecureContext: false", which means exposed
++	    // only in secure contexts.
++            (isInsecureContext && !Boolean(entry.insecureContext)) ||
+             entry.disabled) {
+           interfaceMap[entry.name] = false;
+         } else if (entry.optional) {
+           interfaceMap[entry.name] = "optional";
+         } else {
+           interfaceMap[entry.name] = true;
+         }
+       }

+ 140 - 0
mozilla-release/patches/1431847-1-60a1.patch

@@ -0,0 +1,140 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516816035 18000
+# Node ID 678870d854300aa0d22facfab39fedcd6f19ad01
+# Parent  2e5eda1dc6fb856a4869c6b61d77ce8825ae4de1
+Bug 1431847 P1 Send mCorsMode, mRedirectMode, and mFetchCacheMode to HttpChannelParent. r=valentin
+
+diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh
+--- a/netwerk/ipc/NeckoChannelParams.ipdlh
++++ b/netwerk/ipc/NeckoChannelParams.ipdlh
+@@ -168,16 +168,19 @@ struct HttpChannelOpenArgs
+   uint32_t                    cacheKey;
+   uint64_t                    requestContextID;
+   OptionalCorsPreflightArgs   preflightArgs;
+   uint32_t                    initialRwin;
+   bool                        blockAuthPrompt;
+   bool                        suspendAfterSynthesizeResponse;
+   bool                        allowStaleCacheContent;
+   nsCString                   contentTypeHint;
++  uint32_t                    corsMode;
++  uint32_t                    redirectMode;
++  uint32_t                    fetchCacheMode;
+   uint64_t                    channelId;
+   uint64_t                    contentWindowId;
+   nsCString                   preferredAlternativeType;
+   uint64_t                    topLevelOuterContentWindowId;
+   TimeStamp                   launchServiceWorkerStart;
+   TimeStamp                   launchServiceWorkerEnd;
+   TimeStamp                   dispatchFetchEventStart;
+   TimeStamp                   dispatchFetchEventEnd;
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -2799,16 +2799,20 @@ HttpChannelChild::ContinueAsyncOpen()
+   openArgs.contentTypeHint() = mContentTypeHint;
+ 
+   nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &openArgs.loadInfo());
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   EnsureRequestContextID();
+   openArgs.requestContextID() = mRequestContextID;
+ 
++  openArgs.corsMode() = mCorsMode;
++  openArgs.redirectMode() = mRedirectMode;
++  openArgs.fetchCacheMode() = mFetchCacheMode;
++
+   openArgs.channelId() = mChannelId;
+ 
+   openArgs.contentWindowId() = contentWindowId;
+   openArgs.topLevelOuterContentWindowId() = mTopLevelOuterContentWindowId;
+ 
+   LOG(("HttpChannelChild::ContinueAsyncOpen this=%p gid=%" PRIu64 " topwinid=%" PRIx64,
+        this, mChannelId, mTopLevelOuterContentWindowId));
+ 
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -137,16 +137,17 @@ HttpChannelParent::Init(const HttpChanne
+                        a.entityID(), a.chooseApplicationCache(),
+                        a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
+                        a.tlsFlags(), a.loadInfo(), a.synthesizedResponseHead(),
+                        a.synthesizedSecurityInfoSerialization(),
+                        a.cacheKey(), a.requestContextID(), a.preflightArgs(),
+                        a.initialRwin(), a.blockAuthPrompt(),
+                        a.suspendAfterSynthesizeResponse(),
+                        a.allowStaleCacheContent(), a.contentTypeHint(),
++                       a.corsMode(), a.redirectMode(), a.fetchCacheMode(),
+                        a.channelId(), a.contentWindowId(), a.preferredAlternativeType(),
+                        a.topLevelOuterContentWindowId(),
+                        a.launchServiceWorkerStart(),
+                        a.launchServiceWorkerEnd(),
+                        a.dispatchFetchEventStart(),
+                        a.dispatchFetchEventEnd(),
+                        a.handleFetchEventStart(),
+                        a.handleFetchEventEnd(),
+@@ -475,16 +476,19 @@ HttpChannelParent::DoAsyncOpen(  const U
+                                  const uint32_t&            aCacheKey,
+                                  const uint64_t&            aRequestContextID,
+                                  const OptionalCorsPreflightArgs& aCorsPreflightArgs,
+                                  const uint32_t&            aInitialRwin,
+                                  const bool&                aBlockAuthPrompt,
+                                  const bool&                aSuspendAfterSynthesizeResponse,
+                                  const bool&                aAllowStaleCacheContent,
+                                  const nsCString&           aContentTypeHint,
++                                 const uint32_t&            aCorsMode,
++                                 const uint32_t&            aRedirectMode,
++                                 const uint32_t&            aFetchCacheMode,
+                                  const uint64_t&            aChannelId,
+                                  const uint64_t&            aContentWindowId,
+                                  const nsCString&           aPreferredAlternativeType,
+                                  const uint64_t&            aTopLevelOuterContentWindowId,
+                                  const TimeStamp&           aLaunchServiceWorkerStart,
+                                  const TimeStamp&           aLaunchServiceWorkerEnd,
+                                  const TimeStamp&           aDispatchFetchEventStart,
+                                  const TimeStamp&           aDispatchFetchEventEnd,
+@@ -531,16 +535,21 @@ HttpChannelParent::DoAsyncOpen(  const U
+     return SendFailedAsyncOpen(rv);
+   }
+ 
+   RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(channel, &rv);
+   if (NS_FAILED(rv)) {
+     return SendFailedAsyncOpen(rv);
+   }
+ 
++  // Set attributes needed to create a FetchEvent from this channel.
++  httpChannel->SetCorsMode(aCorsMode);
++  httpChannel->SetRedirectMode(aRedirectMode);
++  httpChannel->SetFetchCacheMode(aFetchCacheMode);
++
+   // Set the channelId allocated in child to the parent instance
+   httpChannel->SetChannelId(aChannelId);
+   httpChannel->SetTopLevelContentWindowId(aContentWindowId);
+   httpChannel->SetTopLevelOuterContentWindowId(aTopLevelOuterContentWindowId);
+ 
+   RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(httpChannel);
+   if (httpChannelImpl) {
+     httpChannelImpl->SetWarningReporter(this);
+diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
+--- a/netwerk/protocol/http/HttpChannelParent.h
++++ b/netwerk/protocol/http/HttpChannelParent.h
+@@ -161,16 +161,19 @@ protected:
+               const uint32_t&            aCacheKey,
+               const uint64_t&            aRequestContextID,
+               const OptionalCorsPreflightArgs& aCorsPreflightArgs,
+               const uint32_t&            aInitialRwin,
+               const bool&                aBlockAuthPrompt,
+               const bool&                aSuspendAfterSynthesizeResponse,
+               const bool&                aAllowStaleCacheContent,
+               const nsCString&           aContentTypeHint,
++              const uint32_t&            aCorsMode,
++              const uint32_t&            aRedirectMode,
++              const uint32_t&            aFetchCacheMode,
+               const uint64_t&            aChannelId,
+               const uint64_t&            aContentWindowId,
+               const nsCString&           aPreferredAlternativeType,
+               const uint64_t&            aTopLevelOuterContentWindowId,
+               const TimeStamp&           aLaunchServiceWorkerStart,
+               const TimeStamp&           aLaunchServiceWorkerEnd,
+               const TimeStamp&           aDispatchFetchEventStart,
+               const TimeStamp&           aDispatchFetchEventEnd,

+ 257 - 0
mozilla-release/patches/1431847-2-60a1.patch

@@ -0,0 +1,257 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516816036 18000
+# Node ID 9274ff8934e03db9822d34f2c2581e3eb43dd8f3
+# Parent  3fc7f12425da7bc17b658770c708c2920d8b3a62
+Bug 1431847 P2 Surface the ApplyConversion state from HttpChannelParent to HttpChannelChild. r=valentin
+
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -430,22 +430,24 @@ class StartRequestEvent : public NeckoTa
+                     const uint32_t& aCacheExpirationTime,
+                     const nsCString& aCachedCharset,
+                     const nsCString& aSecurityInfoSerialization,
+                     const NetAddr& aSelfAddr,
+                     const NetAddr& aPeerAddr,
+                     const uint32_t& aCacheKey,
+                     const nsCString& altDataType,
+                     const int64_t& altDataLen,
+-                    Maybe<ServiceWorkerDescriptor>&& aController)
++                    Maybe<ServiceWorkerDescriptor>&& aController,
++                    const bool& aApplyConversion)
+   : NeckoTargetChannelEvent<HttpChannelChild>(aChild)
+   , mChannelStatus(aChannelStatus)
+   , mResponseHead(aResponseHead)
+   , mRequestHeaders(aRequestHeaders)
+   , mUseResponseHead(aUseResponseHead)
++  , mApplyConversion(aApplyConversion)
+   , mIsFromCache(aIsFromCache)
+   , mCacheEntryAvailable(aCacheEntryAvailable)
+   , mCacheEntryId(aCacheEntryId)
+   , mCacheFetchCount(aCacheFetchCount)
+   , mCacheExpirationTime(aCacheExpirationTime)
+   , mCachedCharset(aCachedCharset)
+   , mSecurityInfoSerialization(aSecurityInfoSerialization)
+   , mSelfAddr(aSelfAddr)
+@@ -460,24 +462,25 @@ class StartRequestEvent : public NeckoTa
+   {
+     LOG(("StartRequestEvent [this=%p]\n", mChild));
+     mChild->OnStartRequest(mChannelStatus, mResponseHead, mUseResponseHead,
+                            mRequestHeaders, mIsFromCache, mCacheEntryAvailable,
+                            mCacheEntryId, mCacheFetchCount,
+                            mCacheExpirationTime, mCachedCharset,
+                            mSecurityInfoSerialization, mSelfAddr, mPeerAddr,
+                            mCacheKey, mAltDataType, mAltDataLen,
+-                           mController);
++                           mController, mApplyConversion);
+   }
+ 
+  private:
+   nsresult mChannelStatus;
+   nsHttpResponseHead mResponseHead;
+   nsHttpHeaderArray mRequestHeaders;
+   bool mUseResponseHead;
++  bool mApplyConversion;
+   bool mIsFromCache;
+   bool mCacheEntryAvailable;
+   uint64_t mCacheEntryId;
+   int32_t mCacheFetchCount;
+   uint32_t mCacheExpirationTime;
+   nsCString mCachedCharset;
+   nsCString mSecurityInfoSerialization;
+   NetAddr mSelfAddr;
+@@ -501,17 +504,18 @@ HttpChannelChild::RecvOnStartRequest(con
+                                      const nsCString& cachedCharset,
+                                      const nsCString& securityInfoSerialization,
+                                      const NetAddr& selfAddr,
+                                      const NetAddr& peerAddr,
+                                      const int16_t& redirectCount,
+                                      const uint32_t& cacheKey,
+                                      const nsCString& altDataType,
+                                      const int64_t& altDataLen,
+-                                     const OptionalIPCServiceWorkerDescriptor& aController)
++                                     const OptionalIPCServiceWorkerDescriptor& aController,
++                                     const bool& aApplyConversion)
+ {
+   LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
+   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
+   // stage, as they are set in the listener's OnStartRequest.
+   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
+     "mFlushedForDiversion should be unset before OnStartRequest!");
+   MOZ_RELEASE_ASSERT(!mDivertingToParent,
+     "mDivertingToParent should be unset before OnStartRequest!");
+@@ -527,17 +531,18 @@ HttpChannelChild::RecvOnStartRequest(con
+   mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
+                                               useResponseHead, requestHeaders,
+                                               isFromCache, cacheEntryAvailable,
+                                               cacheEntryId, cacheFetchCount,
+                                               cacheExpirationTime, cachedCharset,
+                                               securityInfoSerialization,
+                                               selfAddr, peerAddr, cacheKey,
+                                               altDataType, altDataLen,
+-                                              Move(controller)));
++                                              Move(controller),
++                                              aApplyConversion));
+ 
+   {
+     // Child's mEventQ is to control the execution order of the IPC messages
+     // from both main thread IPDL and PBackground IPDL.
+     // To guarantee the ordering, PBackground IPC messages that are sent after
+     // OnStartRequest will be throttled until OnStartRequest hits the Child's
+     // mEventQ.
+     MutexAutoLock lock(mBgChildMutex);
+@@ -568,17 +573,18 @@ HttpChannelChild::OnStartRequest(const n
+                                  const uint32_t& cacheExpirationTime,
+                                  const nsCString& cachedCharset,
+                                  const nsCString& securityInfoSerialization,
+                                  const NetAddr& selfAddr,
+                                  const NetAddr& peerAddr,
+                                  const uint32_t& cacheKey,
+                                  const nsCString& altDataType,
+                                  const int64_t& altDataLen,
+-                                 const Maybe<ServiceWorkerDescriptor>& aController)
++                                 const Maybe<ServiceWorkerDescriptor>& aController,
++                                 const bool& aApplyConversion)
+ {
+   LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
+ 
+   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
+   // stage, as they are set in the listener's OnStartRequest.
+   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
+     "mFlushedForDiversion should be unset before OnStartRequest!");
+   MOZ_RELEASE_ASSERT(!mDivertingToParent,
+@@ -606,16 +612,18 @@ HttpChannelChild::OnStartRequest(const n
+   mPeerAddr = peerAddr;
+ 
+   mAvailableCachedAltDataType = altDataType;
+   mAltDataLength = altDataLen;
+ 
+   const Maybe<ServiceWorkerDescriptor>& prevController =
+     mLoadInfo->GetController();
+ 
++  SetApplyConversion(aApplyConversion);
++
+   // If we got a service worker controller from the parent, then note
+   // it on the LoadInfo.  This may indicate that a non-subresource request
+   // was intercepted and the resulting window/worker should be controlled.
+   if (aController.isSome() && prevController.isNothing()) {
+     mLoadInfo->SetController(aController.ref());
+   }
+ 
+   // If we did not set a controller, then verify it was either because:
+diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h
+--- a/netwerk/protocol/http/HttpChannelChild.h
++++ b/netwerk/protocol/http/HttpChannelChild.h
+@@ -137,17 +137,18 @@ protected:
+                                              const nsCString& cachedCharset,
+                                              const nsCString& securityInfoSerialization,
+                                              const NetAddr& selfAddr,
+                                              const NetAddr& peerAddr,
+                                              const int16_t& redirectCount,
+                                              const uint32_t& cacheKey,
+                                              const nsCString& altDataType,
+                                              const int64_t& altDataLen,
+-                                             const OptionalIPCServiceWorkerDescriptor& aController) override;
++                                             const OptionalIPCServiceWorkerDescriptor& aController,
++                                             const bool& aApplyConversion) override;
+   mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
+   mozilla::ipc::IPCResult RecvRedirect1Begin(const uint32_t& registrarId,
+                                              const URIParams& newURI,
+                                              const uint32_t& redirectFlags,
+                                              const nsHttpResponseHead& responseHead,
+                                              const nsCString& securityInfoSerialization,
+                                              const uint64_t& channelId,
+                                              const NetAddr& oldPeerAddr) override;
+@@ -404,17 +405,18 @@ private:
+                       const uint32_t& cacheExpirationTime,
+                       const nsCString& cachedCharset,
+                       const nsCString& securityInfoSerialization,
+                       const NetAddr& selfAddr,
+                       const NetAddr& peerAddr,
+                       const uint32_t& cacheKey,
+                       const nsCString& altDataType,
+                       const int64_t& altDataLen,
+-                      const Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController);
++                      const Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
++                      const bool& aApplyConversion);
+   void MaybeDivertOnData(const nsCString& data,
+                          const uint64_t& offset,
+                          const uint32_t& count);
+   void OnTransportAndData(const nsresult& channelStatus,
+                           const nsresult& status,
+                           const uint64_t& offset,
+                           const uint32_t& count,
+                           const nsCString& data);
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -1485,19 +1485,22 @@ HttpChannelParent::OnStartRequest(nsIReq
+       if (mIPCClosed ||
+           !SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
+       {
+         return NS_ERROR_UNEXPECTED;
+       }
+     }
+   }
+ 
+-  nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
+-  if (encodedChannel)
+-    encodedChannel->SetApplyConversion(false);
++  // Propagate whether or not conversion should occur from the parent-side
++  // channel to the child-side channel.  Then disable the parent-side
++  // conversion so that it only occurs in the child.
++  bool applyConversion = true;
++  Unused << chan->GetApplyConversion(&applyConversion);
++  chan->SetApplyConversion(false);
+ 
+   // Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
+   // It could be already released by nsHttpChannel at that time.
+   nsCOMPtr<nsISupports> cacheEntry;
+   nsresult channelStatus = NS_OK;
+   uint32_t cacheKeyValue = 0;
+   nsAutoCString altDataType;
+ 
+@@ -1562,17 +1565,18 @@ HttpChannelParent::OnStartRequest(nsIReq
+                           cacheEntryId,
+                           fetchCount, expirationTime,
+                           cachedCharset, secInfoSerialization,
+                           chan->GetSelfAddr(), chan->GetPeerAddr(),
+                           redirectCount,
+                           cacheKeyValue,
+                           altDataType,
+                           altDataLen,
+-                          ipcController))
++                          ipcController,
++                          applyConversion))
+   {
+     rv = NS_ERROR_UNEXPECTED;
+   }
+   requestHead->Exit();
+ 
+   // OnStartRequest is sent to content process successfully.
+   // Notify PHttpBackgroundChannelChild that all following IPC mesasges
+   // should be run after OnStartRequest is handled.
+diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl
+--- a/netwerk/protocol/http/PHttpChannel.ipdl
++++ b/netwerk/protocol/http/PHttpChannel.ipdl
+@@ -105,17 +105,18 @@ child:
+                        nsCString           cachedCharset,
+                        nsCString           securityInfoSerialization,
+                        NetAddr             selfAddr,
+                        NetAddr             peerAddr,
+                        int16_t             redirectCount,
+                        uint32_t            cacheKey,
+                        nsCString           altDataType,
+                        int64_t             altDataLength,
+-                       OptionalIPCServiceWorkerDescriptor controller);
++                       OptionalIPCServiceWorkerDescriptor controller,
++                       bool                applyConversion);
+ 
+   // Used to cancel child channel if we hit errors during creating and
+   // AsyncOpen of nsHttpChannel on the parent.
+   async FailedAsyncOpen(nsresult status);
+ 
+   // Called to initiate content channel redirect, starts talking to sinks
+   // on the content process and reports result via Redirect2Verify above
+   async Redirect1Begin(uint32_t           registrarId,

+ 110 - 0
mozilla-release/patches/1431847-3-60a1.patch

@@ -0,0 +1,110 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516816036 18000
+# Node ID c540f53d730b090123a37d1171f2d55e94a7153c
+# Parent  a49789c77497c0fb69841e99b5ab3dad1dab5434
+Bug 1431847 P3 Add ServiceWorkerParentInterceptEnabled() method and backing pref. r=asuth
+
+diff --git a/dom/workers/ServiceWorkerUtils.cpp b/dom/workers/ServiceWorkerUtils.cpp
+new file mode 100644
+--- /dev/null
++++ b/dom/workers/ServiceWorkerUtils.cpp
+@@ -0,0 +1,36 @@
++/* -*- 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 "ServiceWorkerUtils.h"
++
++#include "mozilla/Preferences.h"
++
++namespace mozilla {
++namespace dom {
++
++bool
++ServiceWorkerParentInterceptEnabled()
++{
++  // For right now we only support main thread.  In the future we could make
++  // this use an atomic bool if we need to support worker threads.
++  MOZ_ASSERT(NS_IsMainThread());
++
++  static bool sInit = false;
++  static bool sEnabled;
++
++  if (!sInit) {
++    MOZ_ASSERT(NS_IsMainThread());
++    Preferences::AddBoolVarCache(&sEnabled,
++                                 "dom.serviceWorkers.parent_intercept",
++                                 false);
++    sInit = true;
++  }
++
++  return sEnabled;
++}
++
++} // namespace dom
++} // namespace mozilla
+diff --git a/dom/workers/ServiceWorkerUtils.h b/dom/workers/ServiceWorkerUtils.h
+new file mode 100644
+--- /dev/null
++++ b/dom/workers/ServiceWorkerUtils.h
+@@ -0,0 +1,18 @@
++/* -*- 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/. */
++#ifndef _mozilla_dom_ServiceWorkerUtils_h
++#define _mozilla_dom_ServiceWorkerUtils_h
++
++namespace mozilla {
++namespace dom {
++
++bool
++ServiceWorkerParentInterceptEnabled();
++
++} // namespace dom
++} // namespace mozilla
++
++#endif // _mozilla_dom_ServiceWorkerUtils_h
+diff --git a/dom/workers/moz.build b/dom/workers/moz.build
+--- a/dom/workers/moz.build
++++ b/dom/workers/moz.build
+@@ -13,16 +13,17 @@ EXPORTS.mozilla.dom += [
+     'ServiceWorkerCommon.h',
+     'ServiceWorkerContainer.h',
+     'ServiceWorkerDescriptor.h',
+     'ServiceWorkerEvents.h',
+     'ServiceWorkerInterceptController.h',
+     'ServiceWorkerIPCUtils.h',
+     'ServiceWorkerRegistrar.h',
+     'ServiceWorkerRegistration.h',
++    'ServiceWorkerUtils.h',
+     'WorkerLocation.h',
+     'WorkerNavigator.h',
+     'WorkerPrivate.h',
+     'WorkerRunnable.h',
+     'WorkerScope.h',
+ ]
+ 
+ EXPORTS.mozilla.dom.workers += [
+@@ -73,16 +74,17 @@ UNIFIED_SOURCES += [
+     'ServiceWorkerRegistrar.cpp',
+     'ServiceWorkerRegistration.cpp',
+     'ServiceWorkerRegistrationInfo.cpp',
+     'ServiceWorkerScriptCache.cpp',
+     'ServiceWorkerUnregisterJob.cpp',
+     'ServiceWorkerUpdateJob.cpp',
+     'ServiceWorkerUpdaterChild.cpp',
+     'ServiceWorkerUpdaterParent.cpp',
++    'ServiceWorkerUtils.cpp',
+     'SharedWorker.cpp',
+     'WorkerDebuggerManager.cpp',
+     'WorkerHolder.cpp',
+     'WorkerHolderToken.cpp',
+     'WorkerLocation.cpp',
+     'WorkerNavigator.cpp',
+     'WorkerPrivate.cpp',
+     'WorkerRunnable.cpp',

+ 48 - 0
mozilla-release/patches/1431847-4-60a1.patch

@@ -0,0 +1,48 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516816036 18000
+# Node ID f4f3e57a1de6e9fda7cc6b31e9ce46da1f2f01ee
+# Parent  197920f47c75d887d8cb109b3404e35869f5dd80
+Bug 1431847 P4 Don't require a load group when spawning the service worker thread for a FetchEvent. r=asuth
+
+diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp
+--- a/dom/workers/ServiceWorkerPrivate.cpp
++++ b/dom/workers/ServiceWorkerPrivate.cpp
+@@ -1785,29 +1785,31 @@ ServiceWorkerPrivate::SendFetchEvent(nsI
+ nsresult
+ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
+                                           nsIRunnable* aLoadFailedRunnable,
+                                           bool* aNewWorkerCreated,
+                                           nsILoadGroup* aLoadGroup)
+ {
+   AssertIsOnMainThread();
+ 
+-  // XXXcatalinb: We need to have a separate load group that's linked to
+-  // an existing tab child to pass security checks on b2g.
+-  // This should be fixed in bug 1125961, but for now we enforce updating
+-  // the overriden load group when intercepting a fetch.
+-  MOZ_ASSERT_IF(aWhy == FetchEvent, aLoadGroup);
+-
+   // Defaults to no new worker created, but if there is one, we'll set the value
+   // to true at the end of this function.
+   if (aNewWorkerCreated) {
+     *aNewWorkerCreated = false;
+   }
+ 
+   if (mWorkerPrivate) {
++    // If we have a load group here then use it to update the service worker
++    // load group.  This was added when we needed the load group's tab child
++    // to pass some security checks.  Those security checks are gone, though,
++    // and we could possibly remove this now.  For now we just do it
++    // opportunistically.  When the service worker is running in a separate
++    // process from the client that initiated the intercepted channel, then
++    // the load group will be nullptr.  UpdateOverrideLoadGroup ignores nullptr
++    // load groups.
+     mWorkerPrivate->UpdateOverridenLoadGroup(aLoadGroup);
+     RenewKeepAliveToken(aWhy);
+ 
+     return NS_OK;
+   }
+ 
+   // Sanity check: mSupportsArray should be empty if we're about to
+   // spin up a new worker.

+ 236 - 0
mozilla-release/patches/1431847-5-60a1.patch

@@ -0,0 +1,236 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516816036 18000
+# Node ID 27dc825e05aa08f9dce50a30a24476a903d97e09
+# Parent  b170b8b2d1f3e8acc432ebe473f6531c34874378
+Bug 1431847 P5 Perform service worker interception in the parent if ServiceWorkerParentInterceptEnable() returns true. r=asuth
+
+diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
+--- a/docshell/base/nsDocShell.cpp
++++ b/docshell/base/nsDocShell.cpp
+@@ -42,16 +42,17 @@
+ #include "mozilla/dom/Element.h"
+ #include "mozilla/dom/HTMLAnchorElement.h"
+ #include "mozilla/dom/PerformanceNavigation.h"
+ #include "mozilla/dom/PermissionMessageUtils.h"
+ #include "mozilla/dom/ProfileTimelineMarkerBinding.h"
+ #include "mozilla/dom/ScreenOrientation.h"
+ #include "mozilla/dom/ScriptSettings.h"
+ #include "mozilla/dom/ServiceWorkerInterceptController.h"
++#include "mozilla/dom/ServiceWorkerUtils.h"
+ #include "mozilla/dom/TabChild.h"
+ #include "mozilla/dom/TabGroup.h"
+ #include "mozilla/dom/ToJSValue.h"
+ 
+ #include "mozilla/dom/workers/ServiceWorkerManager.h"
+ 
+ #include "mozilla/net/ReferrerPolicy.h"
+ 
+@@ -459,17 +460,22 @@ nsDocShell::Init()
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   NS_ASSERTION(mLoadGroup, "Something went wrong!");
+ 
+   mContentListener = new nsDSURIContentListener(this);
+   rv = mContentListener->Init();
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+-  mInterceptController = new ServiceWorkerInterceptController();
++  // If parent intercept is not enabled then we must forward to
++  // the network controller from docshell.  We also enable if we're
++  // in the parent process in order to support non-e10s configurations.
++  if (!ServiceWorkerParentInterceptEnabled() || XRE_IsParentProcess()) {
++    mInterceptController = new ServiceWorkerInterceptController();
++  }
+ 
+   // We want to hold a strong ref to the loadgroup, so it better hold a weak
+   // ref to us...  use an InterfaceRequestorProxy to do this.
+   nsCOMPtr<nsIInterfaceRequestor> proxy =
+     new InterfaceRequestorProxy(static_cast<nsIInterfaceRequestor*>(this));
+   mLoadGroup->SetNotificationCallbacks(proxy);
+ 
+   rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this);
+@@ -524,17 +530,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
+   NS_INTERFACE_MAP_ENTRY(nsIContentViewerContainer)
+   NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor)
+   NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
+   NS_INTERFACE_MAP_ENTRY(nsILoadContext)
+   NS_INTERFACE_MAP_ENTRY(nsIWebShellServices)
+   NS_INTERFACE_MAP_ENTRY(nsILinkHandler)
+   NS_INTERFACE_MAP_ENTRY(nsIClipboardCommands)
+   NS_INTERFACE_MAP_ENTRY(nsIDOMStorageManager)
+-  NS_INTERFACE_MAP_ENTRY(nsINetworkInterceptController)
++  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsINetworkInterceptController,
++                                     mInterceptController)
+   NS_INTERFACE_MAP_ENTRY(nsIDeprecationWarner)
+ NS_INTERFACE_MAP_END_INHERITING(nsDocLoader)
+ 
+ NS_IMETHODIMP
+ nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
+ {
+   NS_PRECONDITION(aSink, "null out param");
+ 
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -7,16 +7,17 @@
+ // HttpLog.h should generally be included first
+ #include "HttpLog.h"
+ 
+ #include "mozilla/ipc/FileDescriptorSetParent.h"
+ #include "mozilla/ipc/IPCStreamUtils.h"
+ #include "mozilla/net/HttpChannelParent.h"
+ #include "mozilla/dom/ContentParent.h"
+ #include "mozilla/dom/Element.h"
++#include "mozilla/dom/ServiceWorkerUtils.h"
+ #include "mozilla/dom/TabParent.h"
+ #include "mozilla/net/NeckoParent.h"
+ #include "mozilla/IntegerPrintfMacros.h"
+ #include "mozilla/UniquePtr.h"
+ #include "mozilla/Unused.h"
+ #include "HttpBackgroundChannelParent.h"
+ #include "HttpChannelParentListener.h"
+ #include "nsHttpHandler.h"
+@@ -670,17 +671,17 @@ HttpChannelParent::DoAsyncOpen(  const U
+     httpChannelImpl->SetCouldBeSynthesized();
+ 
+     if (!aSecurityInfoSerialization.IsEmpty()) {
+       nsCOMPtr<nsISupports> secInfo;
+       NS_DeserializeObject(aSecurityInfoSerialization, getter_AddRefs(secInfo));
+       rv = httpChannel->OverrideSecurityInfo(secInfo);
+       MOZ_ASSERT(NS_SUCCEEDED(rv));
+     }
+-  } else {
++  } else if (!ServiceWorkerParentInterceptEnabled()) {
+     nsLoadFlags newLoadFlags;
+     httpChannel->GetLoadFlags(&newLoadFlags);
+     newLoadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
+     httpChannel->SetLoadFlags(newLoadFlags);
+   }
+ 
+   nsCOMPtr<nsISupportsPRUint32> cacheKey =
+     do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
+diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp
+--- a/netwerk/protocol/http/HttpChannelParentListener.cpp
++++ b/netwerk/protocol/http/HttpChannelParentListener.cpp
+@@ -3,42 +3,50 @@
+ /* 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/. */
+ 
+ // HttpLog.h should generally be included first
+ #include "HttpLog.h"
+ 
+ #include "HttpChannelParentListener.h"
++#include "mozilla/dom/ServiceWorkerInterceptController.h"
++#include "mozilla/dom/ServiceWorkerUtils.h"
+ #include "mozilla/net/HttpChannelParent.h"
+ #include "mozilla/Unused.h"
+ #include "nsIAuthPrompt.h"
+ #include "nsIAuthPrompt2.h"
+ #include "nsIHttpEventSink.h"
+ #include "nsIHttpHeaderVisitor.h"
+ #include "nsIRedirectChannelRegistrar.h"
+ #include "nsIPromptFactory.h"
+ #include "nsIWindowWatcher.h"
+ #include "nsQueryObject.h"
+ 
+ using mozilla::Unused;
++using mozilla::dom::ServiceWorkerInterceptController;
++using mozilla::dom::ServiceWorkerParentInterceptEnabled;
+ 
+ namespace mozilla {
+ namespace net {
+ 
+ HttpChannelParentListener::HttpChannelParentListener(HttpChannelParent* aInitialChannel)
+   : mNextListener(aInitialChannel)
+   , mRedirectChannelId(0)
+   , mSuspendedForDiversion(false)
+   , mShouldIntercept(false)
+   , mShouldSuspendIntercept(false)
+   , mInterceptCanceled(false)
+ {
+   LOG(("HttpChannelParentListener::HttpChannelParentListener [this=%p, next=%p]",
+        this, aInitialChannel));
++
++  if (ServiceWorkerParentInterceptEnabled()) {
++    mInterceptController = new ServiceWorkerInterceptController();
++  }
+ }
+ 
+ HttpChannelParentListener::~HttpChannelParentListener()
+ {
+ }
+ 
+ //-----------------------------------------------------------------------------
+ // HttpChannelParentListener::nsISupports
+@@ -275,16 +283,22 @@ HttpChannelParentListener::OnRedirectRes
+ // HttpChannelParentListener::nsINetworkInterceptController
+ //-----------------------------------------------------------------------------
+ 
+ NS_IMETHODIMP
+ HttpChannelParentListener::ShouldPrepareForIntercept(nsIURI* aURI,
+                                                      nsIChannel* aChannel,
+                                                      bool* aShouldIntercept)
+ {
++  // If parent-side interception is enabled just forward to the real
++  // network controler.
++  if (mInterceptController) {
++    return mInterceptController->ShouldPrepareForIntercept(aURI, aChannel,
++                                                           aShouldIntercept);
++  }
+   *aShouldIntercept = mShouldIntercept;
+   return NS_OK;
+ }
+ 
+ class HeaderVisitor final : public nsIHttpHeaderVisitor
+ {
+   nsCOMPtr<nsIInterceptedChannel> mChannel;
+   ~HeaderVisitor()
+@@ -324,16 +338,22 @@ public:
+     mChannel->FinishSynthesizedResponse();
+     return NS_OK;
+   }
+ };
+ 
+ NS_IMETHODIMP
+ HttpChannelParentListener::ChannelIntercepted(nsIInterceptedChannel* aChannel)
+ {
++  // If parent-side interception is enabled just forward to the real
++  // network controler.
++  if (mInterceptController) {
++    return mInterceptController->ChannelIntercepted(aChannel);
++  }
++
+   // Its possible for the child-side interception to complete and tear down
+   // the actor before we even get this parent-side interception notification.
+   // In this case we want to let the interception succeed, but then immediately
+   // cancel it.  If we return an error code from here then it might get
+   // propagated back to the child process where the interception did not encounter
+   // an error.  Therefore cancel the new channel asynchronously from a runnable.
+   if (mInterceptCanceled) {
+     nsCOMPtr<nsIRunnable> r =
+diff --git a/netwerk/protocol/http/HttpChannelParentListener.h b/netwerk/protocol/http/HttpChannelParentListener.h
+--- a/netwerk/protocol/http/HttpChannelParentListener.h
++++ b/netwerk/protocol/http/HttpChannelParentListener.h
+@@ -77,16 +77,20 @@ private:
+   // interception first occurs.  In this case cancelation is deferred until
+   // the interception takes place.
+   bool mInterceptCanceled;
+ 
+   nsAutoPtr<nsHttpResponseHead> mSynthesizedResponseHead;
+ 
+   // Handle to the channel wrapper if this channel has been intercepted.
+   nsCOMPtr<nsIInterceptedChannel> mInterceptedChannel;
++
++  // This will be populated with a real network controller if parent-side
++  // interception is enabled.
++  nsCOMPtr<nsINetworkInterceptController> mInterceptController;
+ };
+ 
+ NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParentListener,
+                               HTTP_CHANNEL_PARENT_LISTENER_IID)
+ 
+ } // namespace net
+ } // namespace mozilla
+ 

+ 40 - 0
mozilla-release/patches/1433044-1no2-60a1.patch

@@ -0,0 +1,40 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1516913570 28800
+# Node ID c0e6a1684ad6043aa6ad429bd0f134026872cd68
+# Parent  8ad22c16fa5c73e08725706971aa79233357fb91
+Bug 1433044 P1 Make workers keep the same null principal even if GetChannelResultPrincipal() returns different null principals. r=baku
+
+diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
+--- a/dom/workers/WorkerPrivate.cpp
++++ b/dom/workers/WorkerPrivate.cpp
+@@ -1913,16 +1913,29 @@ WorkerLoadInfo::GetPrincipalAndLoadGroup
+ 
+   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
+   MOZ_DIAGNOSTIC_ASSERT(ssm);
+ 
+   nsCOMPtr<nsIPrincipal> channelPrincipal;
+   nsresult rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(channelPrincipal));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
++  // Every time we call GetChannelResultPrincipal() it will return a different
++  // null principal for a data URL.  We don't want to change the worker's
++  // principal again, though.  Instead just keep the original null principal we
++  // first got from the channel.
++  //
++  // Note, we don't do this by setting principalToInherit on the channel's
++  // load info because we don't yet have the first null principal when we
++  // create the channel.
++  if (mPrincipal && mPrincipal->GetIsNullPrincipal() &&
++                    channelPrincipal->GetIsNullPrincipal()) {
++    channelPrincipal = mPrincipal;
++  }
++
+   nsCOMPtr<nsILoadGroup> channelLoadGroup;
+   rv = aChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
+   NS_ENSURE_SUCCESS(rv, rv);
+   MOZ_ASSERT(channelLoadGroup);
+ 
+   // If the loading principal is the system principal then the channel
+   // principal must also be the system principal (we do not allow chrome
+   // code to create workers with non-chrome scripts, and if we ever decide

+ 6 - 6
mozilla-release/patches/1434686-4-60a1.patch

@@ -3,7 +3,7 @@
 # Date 1517512874 18000
 #      Thu Feb 01 14:21:14 2018 -0500
 # Node ID a3d5547b0b7f7aa9a3e5eaed7b3151cadff42334
-# Parent  727dd8b63526d310fd1dfb753e7a78c269607ed4
+# Parent  3b69491de4314b34e1def6092f91ce7d06c98389
 Bug 1434686 part 4.  Use IgnoreErrors() in dom/.  r=mystor
 
 MozReview-Commit-ID: GwVDrTLPTOb
@@ -987,7 +987,7 @@ new file mode 100644
 diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 --- a/dom/workers/ScriptLoader.cpp
 +++ b/dom/workers/ScriptLoader.cpp
-@@ -1582,18 +1582,17 @@ CacheCreator::DeleteCache()
+@@ -1645,18 +1645,17 @@ CacheCreator::DeleteCache()
  {
    AssertIsOnMainThread();
  
@@ -1007,7 +1007,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
    FailLoaders(NS_ERROR_FAILURE);
  }
  
-@@ -1714,23 +1713,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
+@@ -1777,23 +1776,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
    rv = UNWRAP_OBJECT(Response, &obj, response);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      Fail(rv);
@@ -1037,7 +1037,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
 --- a/dom/workers/ServiceWorkerEvents.cpp
 +++ b/dom/workers/ServiceWorkerEvents.cpp
-@@ -701,17 +701,17 @@ RespondWithHandler::ResolvedCallback(JSC
+@@ -723,17 +723,17 @@ RespondWithHandler::ResolvedCallback(JSC
                                                            mScriptSpec,
                                                            responseURL,
                                                            Move(closure));
@@ -1059,8 +1059,8 @@ diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEven
 diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp
 --- a/dom/workers/ServiceWorkerScriptCache.cpp
 +++ b/dom/workers/ServiceWorkerScriptCache.cpp
-@@ -589,19 +589,18 @@ private:
-     ir->SetBody(body, aCN->Buffer().Length());
+@@ -612,19 +612,18 @@ private:
+     ir->SetURLList(aCN->URLList());
  
      ir->InitChannelInfo(aCN->GetChannelInfo());
      UniquePtr<PrincipalInfo> principalInfo = aCN->TakePrincipalInfo();

+ 128 - 0
mozilla-release/patches/1437080-2-fix-60a1.patch

@@ -0,0 +1,128 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1518211034 28800
+# Node ID 4a3044a631d79b5f0b3b5333cd9aa055be0490bf
+# Parent  55c5fddaa80bb480bccbae0a678758084ef3708a
+Bug 1437080 P2 Remove the HttpBaseChannel::mFetchCacheMode override to avoid possibility it can get out of sync with load flags. r=valentin
+
+diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh
+--- a/netwerk/ipc/NeckoChannelParams.ipdlh
++++ b/netwerk/ipc/NeckoChannelParams.ipdlh
+@@ -170,17 +170,16 @@ struct HttpChannelOpenArgs
+   OptionalCorsPreflightArgs   preflightArgs;
+   uint32_t                    initialRwin;
+   bool                        blockAuthPrompt;
+   bool                        suspendAfterSynthesizeResponse;
+   bool                        allowStaleCacheContent;
+   nsCString                   contentTypeHint;
+   uint32_t                    corsMode;
+   uint32_t                    redirectMode;
+-  uint32_t                    fetchCacheMode;
+   uint64_t                    channelId;
+   uint64_t                    contentWindowId;
+   nsCString                   preferredAlternativeType;
+   uint64_t                    topLevelOuterContentWindowId;
+   TimeStamp                   launchServiceWorkerStart;
+   TimeStamp                   launchServiceWorkerEnd;
+   TimeStamp                   dispatchFetchEventStart;
+   TimeStamp                   dispatchFetchEventEnd;
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -2810,17 +2810,16 @@ HttpChannelChild::ContinueAsyncOpen()
+   nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &openArgs.loadInfo());
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   EnsureRequestContextID();
+   openArgs.requestContextID() = mRequestContextID;
+ 
+   openArgs.corsMode() = mCorsMode;
+   openArgs.redirectMode() = mRedirectMode;
+-  openArgs.fetchCacheMode() = mFetchCacheMode;
+ 
+   openArgs.channelId() = mChannelId;
+ 
+   openArgs.contentWindowId() = contentWindowId;
+   openArgs.topLevelOuterContentWindowId() = mTopLevelOuterContentWindowId;
+ 
+   LOG(("HttpChannelChild::ContinueAsyncOpen this=%p gid=%" PRIu64 " topwinid=%" PRIx64,
+        this, mChannelId, mTopLevelOuterContentWindowId));
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -138,17 +138,17 @@ HttpChannelParent::Init(const HttpChanne
+                        a.entityID(), a.chooseApplicationCache(),
+                        a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
+                        a.tlsFlags(), a.loadInfo(), a.synthesizedResponseHead(),
+                        a.synthesizedSecurityInfoSerialization(),
+                        a.cacheKey(), a.requestContextID(), a.preflightArgs(),
+                        a.initialRwin(), a.blockAuthPrompt(),
+                        a.suspendAfterSynthesizeResponse(),
+                        a.allowStaleCacheContent(), a.contentTypeHint(),
+-                       a.corsMode(), a.redirectMode(), a.fetchCacheMode(),
++                       a.corsMode(), a.redirectMode(),
+                        a.channelId(), a.contentWindowId(), a.preferredAlternativeType(),
+                        a.topLevelOuterContentWindowId(),
+                        a.launchServiceWorkerStart(),
+                        a.launchServiceWorkerEnd(),
+                        a.dispatchFetchEventStart(),
+                        a.dispatchFetchEventEnd(),
+                        a.handleFetchEventStart(),
+                        a.handleFetchEventEnd(),
+@@ -479,17 +479,16 @@ HttpChannelParent::DoAsyncOpen(  const U
+                                  const OptionalCorsPreflightArgs& aCorsPreflightArgs,
+                                  const uint32_t&            aInitialRwin,
+                                  const bool&                aBlockAuthPrompt,
+                                  const bool&                aSuspendAfterSynthesizeResponse,
+                                  const bool&                aAllowStaleCacheContent,
+                                  const nsCString&           aContentTypeHint,
+                                  const uint32_t&            aCorsMode,
+                                  const uint32_t&            aRedirectMode,
+-                                 const uint32_t&            aFetchCacheMode,
+                                  const uint64_t&            aChannelId,
+                                  const uint64_t&            aContentWindowId,
+                                  const nsCString&           aPreferredAlternativeType,
+                                  const uint64_t&            aTopLevelOuterContentWindowId,
+                                  const TimeStamp&           aLaunchServiceWorkerStart,
+                                  const TimeStamp&           aLaunchServiceWorkerEnd,
+                                  const TimeStamp&           aDispatchFetchEventStart,
+                                  const TimeStamp&           aDispatchFetchEventEnd,
+@@ -539,17 +538,16 @@ HttpChannelParent::DoAsyncOpen(  const U
+   RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(channel, &rv);
+   if (NS_FAILED(rv)) {
+     return SendFailedAsyncOpen(rv);
+   }
+ 
+   // Set attributes needed to create a FetchEvent from this channel.
+   httpChannel->SetCorsMode(aCorsMode);
+   httpChannel->SetRedirectMode(aRedirectMode);
+-  httpChannel->SetFetchCacheMode(aFetchCacheMode);
+ 
+   // Set the channelId allocated in child to the parent instance
+   httpChannel->SetChannelId(aChannelId);
+   httpChannel->SetTopLevelContentWindowId(aContentWindowId);
+   httpChannel->SetTopLevelOuterContentWindowId(aTopLevelOuterContentWindowId);
+ 
+   RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(httpChannel);
+   if (httpChannelImpl) {
+diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
+--- a/netwerk/protocol/http/HttpChannelParent.h
++++ b/netwerk/protocol/http/HttpChannelParent.h
+@@ -163,17 +163,16 @@ protected:
+               const OptionalCorsPreflightArgs& aCorsPreflightArgs,
+               const uint32_t&            aInitialRwin,
+               const bool&                aBlockAuthPrompt,
+               const bool&                aSuspendAfterSynthesizeResponse,
+               const bool&                aAllowStaleCacheContent,
+               const nsCString&           aContentTypeHint,
+               const uint32_t&            aCorsMode,
+               const uint32_t&            aRedirectMode,
+-              const uint32_t&            aFetchCacheMode,
+               const uint64_t&            aChannelId,
+               const uint64_t&            aContentWindowId,
+               const nsCString&           aPreferredAlternativeType,
+               const uint64_t&            aTopLevelOuterContentWindowId,
+               const TimeStamp&           aLaunchServiceWorkerStart,
+               const TimeStamp&           aLaunchServiceWorkerEnd,
+               const TimeStamp&           aDispatchFetchEventStart,
+               const TimeStamp&           aDispatchFetchEventEnd,

+ 28 - 0
mozilla-release/patches/1437897-1no2-61a1.patch

@@ -0,0 +1,28 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1523425363 -7200
+# Node ID fb6547e96546f8063935adb89ddff55c3f7f50e9
+# Parent  73c6c2fa3b3dd2d016ac65b7daf310d80e938ef5
+Bug 1437897 - Remove a wrong assertion related to the size of the Performance resource entries array in Performance::InsertResourceEntry, r=bz
+
+diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp
+--- a/dom/performance/Performance.cpp
++++ b/dom/performance/Performance.cpp
+@@ -419,17 +419,16 @@ Performance::SetResourceTimingBufferSize
+ {
+   mResourceTimingBufferSize = aMaxSize;
+ }
+ 
+ void
+ Performance::InsertResourceEntry(PerformanceEntry* aEntry)
+ {
+   MOZ_ASSERT(aEntry);
+-  MOZ_ASSERT(mResourceEntries.Length() <= mResourceTimingBufferSize);
+ 
+   // We won't add an entry when 'privacy.resistFingerprint' is true.
+   if (nsContentUtils::ShouldResistFingerprinting()) {
+     return;
+   }
+ 
+   // Don't add the entry if the buffer is full
+   if (mResourceEntries.Length() >= mResourceTimingBufferSize) {

+ 119 - 0
mozilla-release/patches/1439879-60a1.patch

@@ -0,0 +1,119 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1519413325 28800
+# Node ID 481fcece2fc719f516cf542478d6be63bc89badd
+# Parent  bea6918e2e656ed430cb5f67fd32bec9d8864c73
+Bug 1439879 Add some more SW preference checks to e10s http channel code. r=asuth
+
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -8,16 +8,17 @@
+ // HttpLog.h should generally be included first
+ #include "HttpLog.h"
+ 
+ #include "nsHttp.h"
+ #include "nsICacheEntry.h"
+ #include "mozilla/Unused.h"
+ #include "mozilla/dom/ContentChild.h"
+ #include "mozilla/dom/DocGroup.h"
++#include "mozilla/dom/ServiceWorkerUtils.h"
+ #include "mozilla/dom/TabChild.h"
+ #include "mozilla/dom/TabGroup.h"
+ #include "mozilla/extensions/StreamFilterParent.h"
+ #include "mozilla/ipc/FileDescriptorSetChild.h"
+ #include "mozilla/ipc/IPCStreamUtils.h"
+ #include "mozilla/net/NeckoChild.h"
+ #include "mozilla/net/HttpChannelChild.h"
+ 
+@@ -609,36 +610,38 @@ HttpChannelChild::OnStartRequest(const n
+   mCacheExpirationTime = cacheExpirationTime;
+   mCachedCharset = cachedCharset;
+   mSelfAddr = selfAddr;
+   mPeerAddr = peerAddr;
+ 
+   mAvailableCachedAltDataType = altDataType;
+   mAltDataLength = altDataLen;
+ 
+-  const Maybe<ServiceWorkerDescriptor>& prevController =
+-    mLoadInfo->GetController();
+-
+   SetApplyConversion(aApplyConversion);
+ 
+-  // If we got a service worker controller from the parent, then note
+-  // it on the LoadInfo.  This may indicate that a non-subresource request
+-  // was intercepted and the resulting window/worker should be controlled.
+-  if (aController.isSome() && prevController.isNothing()) {
+-    mLoadInfo->SetController(aController.ref());
+-  }
+-
+-  // If we did not set a controller, then verify it was either because:
+-  //  1. Neither the parent or child know about a controlling service worker.
+-  //  2. The parent and child both have the same controlling service worker.
+-  else {
+-    MOZ_DIAGNOSTIC_ASSERT((prevController.isNothing() && aController.isNothing()) ||
+-                          (prevController.ref().Id() == aController.ref().Id() &&
+-                           prevController.ref().Scope() == aController.ref().Scope() &&
+-                           prevController.ref().PrincipalInfo() == aController.ref().PrincipalInfo()));
++  if (ServiceWorkerParentInterceptEnabled()) {
++    const Maybe<ServiceWorkerDescriptor>& prevController =
++      mLoadInfo->GetController();
++
++    // If we got a service worker controller from the parent, then note
++    // it on the LoadInfo.  This may indicate that a non-subresource request
++    // was intercepted and the resulting window/worker should be controlled.
++    if (aController.isSome() && prevController.isNothing()) {
++      mLoadInfo->SetController(aController.ref());
++    }
++
++    // If we did not set a controller, then verify it was either because:
++    //  1. Neither the parent or child know about a controlling service worker.
++    //  2. The parent and child both have the same controlling service worker.
++    else {
++      MOZ_DIAGNOSTIC_ASSERT((prevController.isNothing() && aController.isNothing()) ||
++                            (prevController.ref().Id() == aController.ref().Id() &&
++                             prevController.ref().Scope() == aController.ref().Scope() &&
++                             prevController.ref().PrincipalInfo() == aController.ref().PrincipalInfo()));
++    }
+   }
+ 
+   mAfterOnStartRequestBegun = true;
+ 
+   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
+ 
+   nsresult rv;
+   nsCOMPtr<nsISupportsPRUint32> container =
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -1539,22 +1539,24 @@ HttpChannelParent::OnStartRequest(nsIReq
+   // Maybe pass back the ServiceWorkerDescriptor controller for this channel.
+   // For subresource loads the controller is already known when the channel
+   // is first open and comes down to us via the LoadInfo.  For non-subresource
+   // loads, however, the controller is selected based on the URL by the
+   // ServiceWorkerManager.  In these cases we need to communicate the controller
+   // back to the child process so the resulting window/worker can set its
+   // navigator.serviceWorker.controller correctly immediately.
+   OptionalIPCServiceWorkerDescriptor ipcController = void_t();
+-  nsCOMPtr<nsILoadInfo> loadInfo;
+-  Unused << chan->GetLoadInfo(getter_AddRefs(loadInfo));
+-  if (loadInfo) {
+-    const Maybe<ServiceWorkerDescriptor>& controller = loadInfo->GetController();
+-    if (controller.isSome()) {
+-      ipcController = controller.ref().ToIPC();
++  if (ServiceWorkerParentInterceptEnabled()) {
++    nsCOMPtr<nsILoadInfo> loadInfo;
++    Unused << chan->GetLoadInfo(getter_AddRefs(loadInfo));
++    if (loadInfo) {
++      const Maybe<ServiceWorkerDescriptor>& controller = loadInfo->GetController();
++      if (controller.isSome()) {
++        ipcController = controller.ref().ToIPC();
++      }
+     }
+   }
+ 
+   // !!! We need to lock headers and please don't forget to unlock them !!!
+   requestHead->Enter();
+   nsresult rv = NS_OK;
+   if (mIPCClosed ||
+       !SendOnStartRequest(channelStatus,

+ 5 - 3
mozilla-release/patches/1443429-3-66a1.patch

@@ -2,7 +2,7 @@
 # User Jean-Yves Avenard <jyavenard@mozilla.com>
 # Date 1544731562 0
 # Node ID f0bd2be0b68c851510a7748ead565a5b149ce7ee
-# Parent  69c192a285b069abd014fe16e97e45ea078d6056
+# Parent  455832c052a0691e1553b428acb062f69d79590a
 Bug 1443429 - P3. Don't use WebVTTListener while in stable state. r=smaug
 
 WebVTTListener is a JS wrapper around vtt.js.
@@ -38,7 +38,7 @@ diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
  #include "nsGenericHTMLElement.h"
  #include "nsGkAtoms.h"
  #include "nsIAsyncVerifyRedirectCallback.h"
-@@ -259,28 +258,26 @@ HTMLTrackElement::SetSrc(const nsAString
+@@ -261,28 +260,26 @@ HTMLTrackElement::SetSrc(const nsAString
  
    DispatchLoadResource();
  }
@@ -72,7 +72,7 @@ diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
      return;
    }
  
-@@ -315,43 +312,54 @@ HTMLTrackElement::LoadResource()
+@@ -317,44 +314,55 @@ HTMLTrackElement::LoadResource()
      } else if (CORS_USE_CREDENTIALS == corsMode) {
        secFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
      } else {
@@ -88,6 +88,7 @@ diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
 -                     static_cast<Element*>(this),
 -                     secFlags,
 -                     nsIContentPolicy::TYPE_INTERNAL_TRACK,
+-                     nullptr, // PerformanceStorage
 -                     loadGroup,
 -                     nullptr,   // aCallbacks
 -                     nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI);
@@ -123,6 +124,7 @@ diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
 +        nsresult rv = NS_NewChannel(
 +            getter_AddRefs(channel), uri, static_cast<Element*>(self), secFlags,
 +            nsIContentPolicy::TYPE_INTERNAL_TRACK,
++            nullptr,  // PerformanceStorage
 +            loadGroup,
 +            nullptr,  // aCallbacks
 +            nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI);

+ 8 - 8
mozilla-release/patches/1465580-62a1.patch

@@ -2,20 +2,20 @@
 # User Ben Kelly <ben@wanderview.com>
 # Date 1527875818 25200
 # Node ID 7f4eeef07a85b27f3795a34030a16ad20675831a
-# Parent  60801ea7105d55aeaafdd140b24a000796e230ed
+# Parent  c1256e754652d22ec95bb0b99da7d679995eed43
 Bug 1465580 Make HttpChannelParent get the channel status when its underlying channel is an InterceptedHttpChannel. r=mayhemer
 
 diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
 --- a/netwerk/protocol/http/HttpChannelParent.cpp
 +++ b/netwerk/protocol/http/HttpChannelParent.cpp
-@@ -1480,29 +1480,29 @@ HttpChannelParent::OnStartRequest(nsIReq
-       }
-     }
-   }
+@@ -1493,29 +1493,29 @@ HttpChannelParent::OnStartRequest(nsIReq
  
-   nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
-   if (encodedChannel)
-     encodedChannel->SetApplyConversion(false);
+   // Propagate whether or not conversion should occur from the parent-side
+   // channel to the child-side channel.  Then disable the parent-side
+   // conversion so that it only occurs in the child.
+   bool applyConversion = true;
+   Unused << chan->GetApplyConversion(&applyConversion);
+   chan->SetApplyConversion(false);
  
 +  nsresult channelStatus = NS_OK;
 +  chan->GetStatus(&channelStatus);

+ 267 - 72
mozilla-release/patches/1465585-3-std-62a1.patch

@@ -2,7 +2,7 @@
 # User Emilio Cobos Alvarez <emilio@crisal.io>
 # Date 1527707735 -7200
 # Node ID b54db66223586b4e04f5cb926fccdacf8a176b91
-# Parent  311f8d558c72b391fc8107abe0b888ea1a3b99ee
+# Parent  919c7003dd683c6a68b292c50f36af6b8ae78b64
 Bug 1465585: Switch from mozilla::Move to std::move. r=froydnj
 
 This was done automatically replacing:
@@ -1280,7 +1280,7 @@ diff --git a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h b/devtools/shar
 diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
 --- a/docshell/base/nsDocShell.cpp
 +++ b/docshell/base/nsDocShell.cpp
-@@ -2870,17 +2870,17 @@ nsDocShell::MaybeCreateInitialClientSour
+@@ -2877,17 +2877,17 @@ nsDocShell::MaybeCreateInitialClientSour
  }
  
  Maybe<ClientInfo>
@@ -1299,7 +1299,7 @@ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
  
    if (!doc || !doc->IsInitialDocument()) {
      return Maybe<ClientInfo>();
-@@ -5068,17 +5068,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
+@@ -5075,17 +5075,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
      // Stack variables to ensure changes to the member variables don't affect to
      // the call.
      nsCOMPtr<nsIURI> currentURI = mCurrentURI;
@@ -1318,7 +1318,7 @@ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
                        referrerURI,
                        referrerPolicy,
                        triggeringPrincipal,
-@@ -11182,17 +11182,17 @@ nsDocShell::DoChannelLoad(nsIChannel* aC
+@@ -11190,17 +11190,17 @@ nsDocShell::DoChannelLoad(nsIChannel* aC
  
    // Since we are loading a document we need to make sure the proper reserved
    // and initial client data is stored on the nsILoadInfo.  The
@@ -1337,7 +1337,7 @@ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
    NS_ENSURE_SUCCESS(rv, rv);
  
    // We're about to load a new page and it may take time before necko
-@@ -12368,17 +12368,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
+@@ -12376,17 +12376,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
      return NS_ERROR_FAILURE;
    }
  
@@ -1356,7 +1356,7 @@ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
                      referrerURI,
                      referrerPolicy,
                      triggeringPrincipal,
-@@ -14166,17 +14166,17 @@ nsDocShell::NotifyJSRunToCompletionStart
+@@ -14174,17 +14174,17 @@ nsDocShell::NotifyJSRunToCompletionStart
                                           const uint32_t aLineNumber,
                                           JS::Handle<JS::Value> aAsyncStack,
                                           const char* aAsyncCause)
@@ -1375,7 +1375,7 @@ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
  
    mJSRunToCompletionDepth++;
  }
-@@ -14254,17 +14254,17 @@ nsDocShell::InFrameSwap()
+@@ -14262,17 +14262,17 @@ nsDocShell::InFrameSwap()
      shell = shell->GetParentDocshell();
    } while (shell);
    return false;
@@ -2523,7 +2523,7 @@ diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
 diff --git a/dom/base/EventSource.cpp b/dom/base/EventSource.cpp
 --- a/dom/base/EventSource.cpp
 +++ b/dom/base/EventSource.cpp
-@@ -1415,17 +1415,17 @@ EventSourceImpl::Freeze()
+@@ -1417,17 +1417,17 @@ EventSourceImpl::Freeze()
    return NS_OK;
  }
  
@@ -2542,7 +2542,7 @@ diff --git a/dom/base/EventSource.cpp b/dom/base/EventSource.cpp
  
    // removes the trailing LF from mData
    MOZ_ASSERT(message->mData.CharAt(message->mData.Length() - 1) == LF_CHAR,
-@@ -1811,17 +1811,17 @@ class WorkerRunnableDispatcher final : p
+@@ -1813,17 +1813,17 @@ class WorkerRunnableDispatcher final : p
    RefPtr<EventSourceImpl> mEventSourceImpl;
  
  public:
@@ -3094,7 +3094,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                       "mIdentifierMap mNameContentList");
    aCallback->NoteXPCOMChild(static_cast<nsIDOMNodeList*>(mNameContentList));
-@@ -1325,28 +1325,28 @@ nsIDocument::SelectorCache::SelectorList
+@@ -1326,28 +1326,28 @@ nsIDocument::SelectorCache::SelectorList
  
  #ifdef MOZ_OLD_STYLE
  // CacheList takes ownership of aSelectorList.
@@ -3125,7 +3125,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
    MOZ_ASSERT(NS_IsMainThread());
    MOZ_ASSERT(aSelector);
  
-@@ -3200,19 +3200,19 @@ nsIDocument::GetDocGroup() const
+@@ -3201,19 +3201,19 @@ nsIDocument::GetDocGroup() const
  }
  
  nsresult
@@ -3148,7 +3148,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
    if (mDocGroup) {
      return mDocGroup->EventTargetFor(aCategory);
    }
-@@ -5670,39 +5670,39 @@ nsIDocument::GetAnonRootIfInAnonymousCon
+@@ -5671,39 +5671,39 @@ nsIDocument::GetAnonRootIfInAnonymousCon
    return nullptr;
  }
  
@@ -3197,7 +3197,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  DocumentType*
  nsIDocument::GetDoctype() const
  {
-@@ -6623,17 +6623,17 @@ nsIDocument::CreateNodeIterator(nsINode&
+@@ -6624,17 +6624,17 @@ nsIDocument::CreateNodeIterator(nsINode&
  
  already_AddRefed<NodeIterator>
  nsIDocument::CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
@@ -3216,7 +3216,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
                               uint32_t aWhatToShow,
                               nsIDOMNodeFilter *aFilter,
                               uint8_t aOptionalArgc,
-@@ -6663,17 +6663,17 @@ nsIDocument::CreateTreeWalker(nsINode& a
+@@ -6664,17 +6664,17 @@ nsIDocument::CreateTreeWalker(nsINode& a
    return CreateTreeWalker(aRoot, aWhatToShow, NodeFilterHolder(aFilter), rv);
  }
  
@@ -3235,7 +3235,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  nsDocument::GetDefaultView(mozIDOMWindowProxy** aDefaultView)
  {
    *aDefaultView = nullptr;
-@@ -6922,17 +6922,17 @@ nsDocument::NotifyPossibleTitleChange(bo
+@@ -6923,17 +6923,17 @@ nsDocument::NotifyPossibleTitleChange(bo
  
    MOZ_RELEASE_ASSERT(NS_IsMainThread());
    RefPtr<nsRunnableMethod<nsDocument, void, false>> event =
@@ -3254,7 +3254,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  {
    mPendingTitleChangeEvent.Forget();
    mHaveFiredTitleChange = true;
-@@ -10159,17 +10159,17 @@ nsIDocument::FlushPendingLinkUpdates()
+@@ -10160,17 +10160,17 @@ nsIDocument::FlushPendingLinkUpdates()
    if (mFlushingPendingLinkUpdates) {
      return;
    }
@@ -3273,7 +3273,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
          if (element->IsInComposedDoc()) {
            element->UpdateLinkState(link->LinkState());
          }
-@@ -11098,17 +11098,17 @@ ResetFullScreen(nsIDocument* aDocument, 
+@@ -11099,17 +11099,17 @@ ResetFullScreen(nsIDocument* aDocument, 
  // Since nsIDocument::ExitFullscreenInDocTree() could be called from
  // Element::UnbindFromTree() where it is not safe to synchronously run
  // script. This runnable is the script part of that function.
@@ -3292,7 +3292,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
      // Dispatch MozDOMFullscreen:Exited to the last document in
      // the list since we want this event to follow the same path
      // MozDOMFullscreen:Entered dispatched.
-@@ -11168,17 +11168,17 @@ nsIDocument::ExitFullscreenInDocTree(nsI
+@@ -11169,17 +11169,17 @@ nsIDocument::ExitFullscreenInDocTree(nsI
  
    NS_ASSERTION(!root->GetFullscreenElement(),
      "Fullscreen root should no longer be a fullscreen doc...");
@@ -3311,7 +3311,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
    if (aDoc->IsFullscreenLeaf()) {
      nsIDocument** result = static_cast<nsIDocument**>(aData);
      *result = aDoc;
-@@ -11295,23 +11295,23 @@ nsDocument::RestorePreviousFullScreenSta
+@@ -11296,23 +11296,23 @@ nsDocument::RestorePreviousFullScreenSta
    }
  }
  
@@ -3337,7 +3337,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  
  void
  nsDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
-@@ -11319,17 +11319,17 @@ nsDocument::AsyncRequestFullScreen(Uniqu
+@@ -11320,17 +11320,17 @@ nsDocument::AsyncRequestFullScreen(Uniqu
    if (!aRequest->GetElement()) {
      MOZ_ASSERT_UNREACHABLE(
        "Must pass non-null element to nsDocument::AsyncRequestFullScreen");
@@ -3356,7 +3356,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  {
    RefPtr<AsyncEventDispatcher> asyncDispatcher =
      new AsyncEventDispatcher(this,
-@@ -11503,17 +11503,17 @@ nsresult nsDocument::RemoteFrameFullscre
+@@ -11504,17 +11504,17 @@ nsresult nsDocument::RemoteFrameFullscre
  {
    // Ensure the frame element is the fullscreen element in this document.
    // If the frame element is already the fullscreen element in this document,
@@ -3375,7 +3375,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
  {
    RestorePreviousFullScreenState();
    return NS_OK;
-@@ -11801,17 +11801,17 @@ nsDocument::RequestFullScreen(UniquePtr<
+@@ -11802,17 +11802,17 @@ nsDocument::RequestFullScreen(UniquePtr<
    }
  
    // We don't need to check element ready before this point, because
@@ -3830,7 +3830,7 @@ diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceMan
 diff --git a/dom/base/nsSyncLoadService.cpp b/dom/base/nsSyncLoadService.cpp
 --- a/dom/base/nsSyncLoadService.cpp
 +++ b/dom/base/nsSyncLoadService.cpp
-@@ -340,17 +340,17 @@ nsSyncLoadService::LoadDocument(nsIURI *
+@@ -341,17 +341,17 @@ nsSyncLoadService::LoadDocument(nsIURI *
  }
  
  /* static */
@@ -5982,7 +5982,7 @@ diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
 diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
 --- a/dom/fetch/FetchDriver.cpp
 +++ b/dom/fetch/FetchDriver.cpp
-@@ -373,17 +373,17 @@ FetchDriver::Fetch(AbortSignal* aSignal,
+@@ -378,17 +378,17 @@ FetchDriver::Fetch(AbortSignal* aSignal,
  
  
    UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo(new mozilla::ipc::PrincipalInfo());
@@ -6787,7 +6787,7 @@ diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
      if (IsCancelled()) {
        mElement->mPendingPlayPromisesRunners.RemoveElement(this);
        return NS_OK;
-@@ -3539,17 +3539,17 @@ HTMLMediaElement::AddCaptureMediaTrackTo
+@@ -3540,17 +3540,17 @@ HTMLMediaElement::AddCaptureMediaTrackTo
    // and an MSG iteration passes before the mute comes into effect.
    processedOutputSource->SetTrackEnabled(destinationTrackID,
                                           DisabledTrackMode::SILENCE_FREEZE);
@@ -6806,7 +6806,7 @@ diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
  
    LOG(LogLevel::Debug,
        ("Created %s track %p with id %d from track %p through MediaInputPort %p",
-@@ -5425,17 +5425,17 @@ void
+@@ -5426,17 +5426,17 @@ void
  HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
                                   UniquePtr<const MetadataTags> aTags)
  {
@@ -6825,7 +6825,7 @@ diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
      DispatchAsyncEvent(NS_LITERAL_STRING("resize"));
    }
    NS_ASSERTION(!HasVideo() ||
-@@ -7681,17 +7681,17 @@ HTMLMediaElement::AbstractMainThread() c
+@@ -7682,17 +7682,17 @@ HTMLMediaElement::AbstractMainThread() c
    MOZ_ASSERT(mAbstractMainThread);
  
    return mAbstractMainThread;
@@ -16551,6 +16551,201 @@ diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.c
 +  return mainTarget->Dispatch(std::move(aRunnable), nsIEventTarget::DISPATCH_NORMAL);
  }
  
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/performance/PerformanceMainThread.cpp b/dom/performance/PerformanceMainThread.cpp
+--- a/dom/performance/PerformanceMainThread.cpp
++++ b/dom/performance/PerformanceMainThread.cpp
+@@ -126,17 +126,17 @@ PerformanceMainThread::AddEntry(nsIHttpC
+                                   entryName));
+   if (!performanceTimingData) {
+     return;
+   }
+ 
+   // The PerformanceResourceTiming object will use the PerformanceTimingData
+   // object to get all the required timings.
+   RefPtr<PerformanceResourceTiming> performanceEntry =
+-    new PerformanceResourceTiming(Move(performanceTimingData), this,
++    new PerformanceResourceTiming(std::move(performanceTimingData), this,
+                                   entryName);
+ 
+   performanceEntry->SetInitiatorType(initiatorType);
+   InsertResourceEntry(performanceEntry);
+ }
+ 
+ // To be removed once bug 1124165 lands
+ bool
+@@ -288,17 +288,17 @@ PerformanceMainThread::EnsureDocEntry()
+     UniquePtr<PerformanceTimingData> timing(
+       new PerformanceTimingData(mChannel, nullptr, 0));
+ 
+     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
+     if (httpChannel) {
+       timing->SetPropertiesFromHttpChannel(httpChannel);
+     }
+ 
+-    mDocEntry = new PerformanceNavigationTiming(Move(timing), this);
++    mDocEntry = new PerformanceNavigationTiming(std::move(timing), this);
+   }
+ }
+ 
+ 
+ void
+ PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
+ {
+   // We return an empty list when 'privacy.resistFingerprinting' is on.
+diff --git a/dom/performance/PerformanceNavigationTiming.h b/dom/performance/PerformanceNavigationTiming.h
+--- a/dom/performance/PerformanceNavigationTiming.h
++++ b/dom/performance/PerformanceNavigationTiming.h
+@@ -26,17 +26,17 @@ public:
+   NS_DECL_ISUPPORTS_INHERITED
+ 
+   // Note that aPerformanceTiming must be initalized with zeroTime = 0
+   // so that timestamps are relative to startTime, as opposed to the
+   // performance.timing object for which timestamps are absolute and has a
+   // zeroTime initialized to navigationStart
+   PerformanceNavigationTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
+                               Performance* aPerformance)
+-    : PerformanceResourceTiming(Move(aPerformanceTiming), aPerformance,
++    : PerformanceResourceTiming(std::move(aPerformanceTiming), aPerformance,
+                                 NS_LITERAL_STRING("document")) {
+       SetEntryType(NS_LITERAL_STRING("navigation"));
+       SetInitiatorType(NS_LITERAL_STRING("navigation"));
+     }
+ 
+   DOMHighResTimeStamp Duration() const override
+   {
+     return nsRFPService::ReduceTimePrecisionAsMSecs(LoadEventEnd() - StartTime());
+diff --git a/dom/performance/PerformanceResourceTiming.cpp b/dom/performance/PerformanceResourceTiming.cpp
+--- a/dom/performance/PerformanceResourceTiming.cpp
++++ b/dom/performance/PerformanceResourceTiming.cpp
+@@ -22,17 +22,17 @@ NS_INTERFACE_MAP_END_INHERITING(Performa
+ 
+ NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
+ NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
+ 
+ PerformanceResourceTiming::PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
+                                                      Performance* aPerformance,
+                                                      const nsAString& aName)
+   : PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource"))
+-  , mTimingData(Move(aPerformanceTiming))
++  , mTimingData(std::move(aPerformanceTiming))
+   , mPerformance(aPerformance)
+ {
+   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
+ }
+ 
+ PerformanceResourceTiming::~PerformanceResourceTiming()
+ {
+ }
+diff --git a/dom/performance/PerformanceStorageWorker.cpp b/dom/performance/PerformanceStorageWorker.cpp
+--- a/dom/performance/PerformanceStorageWorker.cpp
++++ b/dom/performance/PerformanceStorageWorker.cpp
+@@ -14,17 +14,17 @@ namespace dom {
+ using namespace workers;
+ 
+ class PerformanceProxyData
+ {
+ public:
+   PerformanceProxyData(UniquePtr<PerformanceTimingData>&& aData,
+                        const nsAString& aInitiatorType,
+                        const nsAString& aEntryName)
+-    : mData(Move(aData))
++    : mData(std::move(aData))
+     , mInitiatorType(aInitiatorType)
+     , mEntryName(aEntryName)
+   {}
+ 
+   UniquePtr<PerformanceTimingData> mData;
+   nsString mInitiatorType;
+   nsString mEntryName;
+ };
+@@ -77,23 +77,23 @@ public:
+ class PerformanceEntryAdder final : public WorkerControlRunnable
+ {
+ public:
+   PerformanceEntryAdder(WorkerPrivate* aWorkerPrivate,
+                         PerformanceStorageWorker* aStorage,
+                         UniquePtr<PerformanceProxyData>&& aData)
+     : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
+     , mStorage(aStorage)
+-    , mData(Move(aData))
++    , mData(std::move(aData))
+   {}
+ 
+   bool
+   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
+   {
+-    mStorage->AddEntryOnWorker(Move(mData));
++    mStorage->AddEntryOnWorker(std::move(mData));
+     return true;
+   }
+ 
+   nsresult
+   Cancel() override
+   {
+     mStorage->ShutdownOnWorker();
+     return WorkerRunnable::Cancel();
+@@ -184,21 +184,21 @@ PerformanceStorageWorker::AddEntry(nsIHt
+   UniquePtr<PerformanceTimingData> performanceTimingData(
+     PerformanceTimingData::Create(aTimedChannel, aChannel, 0, initiatorType,
+                                   entryName));
+   if (!performanceTimingData) {
+     return;
+   }
+ 
+   UniquePtr<PerformanceProxyData> data(
+-    new PerformanceProxyData(Move(performanceTimingData), initiatorType,
++    new PerformanceProxyData(std::move(performanceTimingData), initiatorType,
+                              entryName));
+ 
+   RefPtr<PerformanceEntryAdder> r =
+-    new PerformanceEntryAdder(mWorkerPrivate, this, Move(data));
++    new PerformanceEntryAdder(mWorkerPrivate, this, std::move(data));
+   Unused << NS_WARN_IF(!r->Dispatch());
+ }
+ 
+ void
+ PerformanceStorageWorker::InitializeOnWorker()
+ {
+   MutexAutoLock lock(mMutex);
+   MOZ_ASSERT(mState == eInitializing);
+@@ -232,17 +232,17 @@ PerformanceStorageWorker::ShutdownOnWork
+   mWorkerHolder = nullptr;
+   mWorkerPrivate = nullptr;
+ }
+ 
+ void
+ PerformanceStorageWorker::AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData)
+ {
+   RefPtr<Performance> performance;
+-  UniquePtr<PerformanceProxyData> data = Move(aData);
++  UniquePtr<PerformanceProxyData> data = std::move(aData);
+ 
+   {
+     MutexAutoLock lock(mMutex);
+ 
+     if (mState == eTerminated) {
+       return;
+     }
+ 
+@@ -255,17 +255,17 @@ PerformanceStorageWorker::AddEntryOnWork
+     performance = scope->GetPerformance();
+   }
+ 
+   if (NS_WARN_IF(!performance)) {
+     return;
+   }
+ 
+   RefPtr<PerformanceResourceTiming> performanceEntry =
+-    new PerformanceResourceTiming(Move(data->mData), performance,
++    new PerformanceResourceTiming(std::move(data->mData), performance,
+                                  data->mEntryName);
+   performanceEntry->SetInitiatorType(data->mInitiatorType);
+ 
+   performance->InsertResourceEntry(performanceEntry);
+ }
+ 
  } // namespace dom
  } // namespace mozilla
 diff --git a/dom/push/PushManager.cpp b/dom/push/PushManager.cpp
@@ -16883,7 +17078,7 @@ diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp
 diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
 --- a/dom/script/ScriptLoader.cpp
 +++ b/dom/script/ScriptLoader.cpp
-@@ -1357,17 +1357,17 @@ ScriptLoader::ProcessExternalScript(nsIS
+@@ -1358,17 +1358,17 @@ ScriptLoader::ProcessExternalScript(nsIS
      if (!principal) {
        principal = aScriptContent->NodePrincipal();
      }
@@ -17685,7 +17880,7 @@ diff --git a/dom/webbrowserpersist/WebBrowserPersistSerializeChild.cpp b/dom/web
 diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
 --- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
 +++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
-@@ -1810,17 +1810,17 @@ nsWebBrowserPersist::FinishSaveDocumentI
+@@ -1811,17 +1811,17 @@ nsWebBrowserPersist::FinishSaveDocumentI
          mWalkStack.TruncateLength(mWalkStack.Length() - 1);
          // Bounce this off the event loop to avoid stack overflow.
          typedef StoreCopyPassByRRef<decltype(toWalk)> WalkStorage;
@@ -17704,7 +17899,7 @@ diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersi
  }
  
  void nsWebBrowserPersist::Cleanup()
-@@ -2717,17 +2717,17 @@ nsWebBrowserPersist::SaveSubframeContent
+@@ -2718,17 +2718,17 @@ nsWebBrowserPersist::SaveSubframeContent
  
      // We shouldn't use SaveDocumentInternal for the contents
      // of frames that are not documents, e.g. images.
@@ -17792,7 +17987,7 @@ diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
 diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 --- a/dom/workers/ScriptLoader.cpp
 +++ b/dom/workers/ScriptLoader.cpp
-@@ -739,17 +739,17 @@ private:
+@@ -749,17 +749,17 @@ private:
  
      UniquePtr<PrincipalInfo> principalInfo(new PrincipalInfo());
      rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get());
@@ -17811,7 +18006,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
      mozilla::dom::RequestOrUSVString request;
  
      MOZ_ASSERT(!loadInfo.mFullURL.IsEmpty());
-@@ -1014,17 +1014,17 @@ private:
+@@ -1025,17 +1025,17 @@ private:
      rv = NS_NewStreamLoader(getter_AddRefs(loader), listener);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
@@ -17830,7 +18025,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
      }
  
      if (loadInfo.mCacheStatus != ScriptLoadInfo::ToBeCached) {
-@@ -1783,17 +1783,17 @@ CacheScriptLoader::ResolvedCallback(JSCo
+@@ -1794,17 +1794,17 @@ CacheScriptLoader::ResolvedCallback(JSCo
    const UniquePtr<PrincipalInfo>& pInfo = response->GetPrincipalInfo();
    if (pInfo) {
      mPrincipalInfo = mozilla::MakeUnique<PrincipalInfo>(*pInfo);
@@ -17849,7 +18044,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
    MOZ_ASSERT(!mPump);
    rv = NS_NewInputStreamPump(getter_AddRefs(mPump),
                               inputStream.forget(),
-@@ -1850,17 +1850,17 @@ CacheScriptLoader::OnStreamComplete(nsIS
+@@ -1861,17 +1861,17 @@ CacheScriptLoader::OnStreamComplete(nsIS
      return NS_OK;
    }
  
@@ -18139,7 +18334,7 @@ diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorke
      RefPtr<Response> response =
        new Response(aCache->GetGlobalObject(), ir, nullptr);
  
-@@ -913,17 +913,17 @@ CompareNetwork::SetPrincipalInfo(nsIChan
+@@ -916,17 +916,17 @@ CompareNetwork::SetPrincipalInfo(nsIChan
  
    UniquePtr<PrincipalInfo> principalInfo = MakeUnique<PrincipalInfo>();
    rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get());
@@ -18161,7 +18356,7 @@ diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorke
 diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
 --- a/dom/workers/WorkerPrivate.cpp
 +++ b/dom/workers/WorkerPrivate.cpp
-@@ -4702,17 +4702,17 @@ WorkerPrivate::Constructor(JSContext* aC
+@@ -4716,17 +4716,17 @@ WorkerPrivate::Constructor(JSContext* aC
    // WorkerThreadPrimaryRunnable::Run for workers just before running worker
    // code), so this is never SpiderMonkey's builtin default locale.
    JS::UniqueChars defaultLocale = JS_GetDefaultLocale(aCx);
@@ -18180,7 +18375,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
  
    worker->EnableDebugger();
  
-@@ -5259,17 +5259,17 @@ WorkerPrivate::DispatchToMainThread(nsIR
+@@ -5273,17 +5273,17 @@ WorkerPrivate::DispatchToMainThread(nsIR
    nsCOMPtr<nsIRunnable> r = aRunnable;
    return DispatchToMainThread(r.forget(), aFlags);
  }
@@ -18199,7 +18394,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
    return mWorkerControlEventTarget;
  }
  
-@@ -5347,17 +5347,17 @@ WorkerPrivate::GetClientInfo() const
+@@ -5361,17 +5361,17 @@ WorkerPrivate::GetClientInfo() const
  
  const ClientState
  WorkerPrivate::GetClientState() const
@@ -18218,7 +18413,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
    AssertIsOnWorkerThread();
    MOZ_DIAGNOSTIC_ASSERT(mClientSource);
    return mClientSource->GetController();
-@@ -7118,17 +7118,17 @@ WorkerPrivate::GetOrCreateGlobalScope(JS
+@@ -7132,17 +7132,17 @@ WorkerPrivate::GetOrCreateGlobalScope(JS
  
      JS::Rooted<JSObject*> global(aCx);
      NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
@@ -18237,7 +18432,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
  
      JS_FireOnNewGlobalObject(aCx, global);
    }
-@@ -7149,17 +7149,17 @@ WorkerPrivate::CreateDebuggerGlobalScope
+@@ -7163,17 +7163,17 @@ WorkerPrivate::CreateDebuggerGlobalScope
    JS::Rooted<JSObject*> global(aCx);
    NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
  
@@ -18259,7 +18454,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
 diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
 --- a/dom/workers/WorkerPrivate.h
 +++ b/dom/workers/WorkerPrivate.h
-@@ -321,17 +321,17 @@ public:
+@@ -322,17 +322,17 @@ public:
      AssertIsOnParentThread();
      MOZ_ASSERT(mSelfRef);
      mSelfRef = nullptr;
@@ -18278,7 +18473,7 @@ diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
    nsresult
    DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable> aDebuggerRunnable);
  
-@@ -1182,17 +1182,17 @@ public:
+@@ -1185,17 +1185,17 @@ public:
    }
  
    JS::UniqueChars
@@ -18498,7 +18693,7 @@ diff --git a/dom/xbl/nsXBLWindowKeyHandler.cpp b/dom/xbl/nsXBLWindowKeyHandler.c
 diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
 --- a/dom/xhr/XMLHttpRequestMainThread.cpp
 +++ b/dom/xhr/XMLHttpRequestMainThread.cpp
-@@ -2568,17 +2568,17 @@ XMLHttpRequestMainThread::MaybeLowerChan
+@@ -2571,17 +2571,17 @@ XMLHttpRequestMainThread::MaybeLowerChan
  }
  
  nsresult
@@ -18517,7 +18712,7 @@ diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainTh
    if (HasListenersFor(nsGkAtoms::onprogress) ||
        (mUpload && mUpload->HasListenersFor(nsGkAtoms::onprogress))) {
      nsLoadFlags loadFlags;
-@@ -3268,20 +3268,20 @@ XMLHttpRequestMainThread::SetTimerEventT
+@@ -3271,20 +3271,20 @@ XMLHttpRequestMainThread::SetTimerEventT
  
  nsresult
  XMLHttpRequestMainThread::DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable)
@@ -27692,7 +27887,7 @@ diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp
  NS_IMPL_ISUPPORTS(nsProgressNotificationProxy,
                    nsIProgressEventSink,
                    nsIChannelEventSink,
-@@ -1045,17 +1045,17 @@ imgCacheQueue::Remove(imgCacheEntry* ent
+@@ -1047,17 +1047,17 @@ imgCacheQueue::Remove(imgCacheEntry* ent
  }
  
  void
@@ -27711,7 +27906,7 @@ diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp
  }
  
  already_AddRefed<imgCacheEntry>
-@@ -2969,17 +2969,17 @@ imgCacheValidator::UpdateProxies(bool aC
+@@ -2971,17 +2971,17 @@ imgCacheValidator::UpdateProxies(bool aC
    }
  
    // We have finished validating the request, so we can safely take ownership
@@ -39899,7 +40094,7 @@ diff --git a/js/xpconnect/loader/URLPreloader.cpp b/js/xpconnect/loader/URLPrelo
 diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp
 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp
 +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
-@@ -279,17 +279,17 @@ ReportOnCallerUTF8(JSCLContextHelper& he
+@@ -280,17 +280,17 @@ ReportOnCallerUTF8(JSCLContextHelper& he
      nsCString location;
      MOZ_TRY(info.GetLocation(location));
  
@@ -39918,7 +40113,7 @@ diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/
  #undef ENSURE_DEP
  
  mozJSComponentLoader::~mozJSComponentLoader()
-@@ -1427,10 +1427,10 @@ JSCLContextHelper::~JSCLContextHelper()
+@@ -1428,10 +1428,10 @@ JSCLContextHelper::~JSCLContextHelper()
          JS_ReportErrorUTF8(mContext, "%s", mBuf.get());
      }
  }
@@ -41508,7 +41703,7 @@ diff --git a/layout/style/CounterStyleManager.cpp b/layout/style/CounterStyleMan
 diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp
 --- a/layout/style/FontFaceSet.cpp
 +++ b/layout/style/FontFaceSet.cpp
-@@ -1782,21 +1782,21 @@ FontFaceSet::CheckLoadingFinished()
+@@ -1783,21 +1783,21 @@ FontFaceSet::CheckLoadingFinished()
        mNonRuleFaces[i].mLoadEventShouldFire = false;
      } else if (f->Status() == FontFaceLoadStatus::Error) {
        failed.AppendElement(*f);
@@ -46447,7 +46642,7 @@ diff --git a/mfbt/tests/TestVector.cpp b/mfbt/tests/TestVector.cpp
 diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp
 --- a/modules/libjar/nsJARChannel.cpp
 +++ b/modules/libjar/nsJARChannel.cpp
-@@ -1055,17 +1055,17 @@ nsJARChannel::OnDownloadComplete(MemoryD
+@@ -1056,17 +1056,17 @@ nsJARChannel::OnDownloadComplete(MemoryD
          // Refuse to unpack view-source: jars even if open-unsafe-types is set.
          nsCOMPtr<nsIViewSourceChannel> viewSource = do_QueryInterface(channel);
          if (viewSource) {
@@ -46804,7 +46999,7 @@ diff --git a/mozglue/misc/interceptor/VMSharingPolicies.h b/mozglue/misc/interce
 diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
 --- a/netwerk/base/LoadInfo.cpp
 +++ b/netwerk/base/LoadInfo.cpp
-@@ -421,17 +421,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
+@@ -423,17 +423,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
    , mParentOuterWindowID(aParentOuterWindowID)
    , mTopOuterWindowID(aTopOuterWindowID)
    , mFrameOuterWindowID(aFrameOuterWindowID)
@@ -46823,7 +47018,7 @@ diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
    , mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized)
  {
    // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
-@@ -1184,29 +1184,29 @@ LoadInfo::GetClientInfo()
+@@ -1186,29 +1186,29 @@ LoadInfo::GetClientInfo()
  {
    return mClientInfo;
  }
@@ -47035,7 +47230,7 @@ diff --git a/netwerk/base/nsMIMEInputStream.cpp b/netwerk/base/nsMIMEInputStream
 diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
 --- a/netwerk/base/nsNetUtil.cpp
 +++ b/netwerk/base/nsNetUtil.cpp
-@@ -688,17 +688,17 @@ NS_NewInputStreamChannelInternal(nsIChan
+@@ -719,17 +719,17 @@ NS_NewInputStreamChannelInternal(nsIChan
  {
    nsresult rv;
    nsCOMPtr<nsIInputStreamChannel> isc =
@@ -47054,7 +47249,7 @@ diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
  
    if (!aContentType.IsEmpty()) {
      rv = channel->SetContentType(aContentType);
-@@ -739,17 +739,17 @@ NS_NewInputStreamChannelInternal(nsIChan
+@@ -770,17 +770,17 @@ NS_NewInputStreamChannelInternal(nsIChan
                            aTriggeringPrincipal,
                            aLoadingNode,
                            aSecurityFlags,
@@ -47073,7 +47268,7 @@ diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
                                            aContentCharset,
                                            loadInfo);
  }
-@@ -857,17 +857,17 @@ NS_NewInputStreamChannel(nsIChannel     
+@@ -888,17 +888,17 @@ NS_NewInputStreamChannel(nsIChannel     
  nsresult
  NS_NewInputStreamPump(nsIInputStreamPump** aResult,
                        already_AddRefed<nsIInputStream> aStream,
@@ -47092,7 +47287,7 @@ diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
          rv = pump->Init(stream, aSegsize, aSegcount, aCloseWhenDone,
                          aMainThreadTarget);
          if (NS_SUCCEEDED(rv)) {
-@@ -1463,17 +1463,17 @@ NS_NewLocalFileStream(nsIFileStream **re
+@@ -1495,17 +1495,17 @@ NS_NewLocalFileStream(nsIFileStream **re
      return rv;
  }
  
@@ -47111,7 +47306,7 @@ diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp
          rv = out->Init(outputStream, aBufferSize);
          if (NS_SUCCEEDED(rv)) {
              out.forget(aResult);
-@@ -1482,17 +1482,17 @@ NS_NewBufferedOutputStream(nsIOutputStre
+@@ -1514,17 +1514,17 @@ NS_NewBufferedOutputStream(nsIOutputStre
      return rv;
  }
  
@@ -47341,7 +47536,7 @@ diff --git a/netwerk/ipc/NeckoTargetHolder.cpp b/netwerk/ipc/NeckoTargetHolder.c
 diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
 --- a/netwerk/protocol/http/HttpBaseChannel.cpp
 +++ b/netwerk/protocol/http/HttpBaseChannel.cpp
-@@ -299,17 +299,17 @@ HttpBaseChannel::ReleaseMainThreadOnlyRe
+@@ -300,17 +300,17 @@ HttpBaseChannel::ReleaseMainThreadOnlyRe
    if (mAddedAsNonTailRequest) {
      // RemoveNonTailRequest() on our request context must be called on the main thread
      MOZ_RELEASE_ASSERT(mRequestContext, "Someone released rc or set flags w/o having it?");
@@ -47360,7 +47555,7 @@ diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/H
    LOG(("HttpBaseChannel::SetIsTrackingResource %p", this));
    mIsTrackingResource = true;
  }
-@@ -2528,17 +2528,17 @@ HttpBaseChannel::AddSecurityMessage(cons
+@@ -2529,17 +2529,17 @@ HttpBaseChannel::AddSecurityMessage(cons
    MOZ_ASSERT(NS_IsMainThread());
  
    nsresult rv;
@@ -47404,7 +47599,7 @@ diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/Htt
 diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
 --- a/netwerk/protocol/http/HttpChannelChild.cpp
 +++ b/netwerk/protocol/http/HttpChannelChild.cpp
-@@ -230,17 +230,17 @@ HttpChannelChild::ReleaseMainThreadOnlyR
+@@ -231,17 +231,17 @@ HttpChannelChild::ReleaseMainThreadOnlyR
  
    // To solve multiple inheritence of nsISupports in InterceptStreamListener
    nsCOMPtr<nsIStreamListener> listener = mInterceptListener.forget();
@@ -47423,7 +47618,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
  NS_IMPL_ADDREF(HttpChannelChild)
  
  NS_IMETHODIMP_(MozExternalRefCountType) HttpChannelChild::Release()
-@@ -448,17 +448,17 @@ class StartRequestEvent : public NeckoTa
+@@ -451,17 +451,17 @@ class StartRequestEvent : public NeckoTa
    , mCacheExpirationTime(aCacheExpirationTime)
    , mCachedCharset(aCachedCharset)
    , mSecurityInfoSerialization(aSecurityInfoSerialization)
@@ -47442,7 +47637,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
      mChild->OnStartRequest(mChannelStatus, mResponseHead, mUseResponseHead,
                             mRequestHeaders, mIsFromCache, mCacheEntryAvailable,
                             mCacheEntryId, mCacheFetchCount,
-@@ -527,17 +527,17 @@ HttpChannelChild::RecvOnStartRequest(con
+@@ -532,17 +532,17 @@ HttpChannelChild::RecvOnStartRequest(con
    mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
                                                useResponseHead, requestHeaders,
                                                isFromCache, cacheEntryAvailable,
@@ -47451,8 +47646,9 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
                                                securityInfoSerialization,
                                                selfAddr, peerAddr, cacheKey,
                                                altDataType, altDataLen,
--                                              Move(controller)));
-+                                              std::move(controller)));
+-                                              Move(controller),
++                                              std::move(controller),
+                                               aApplyConversion));
  
    {
      // Child's mEventQ is to control the execution order of the IPC messages
@@ -47460,8 +47656,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
      // To guarantee the ordering, PBackground IPC messages that are sent after
      // OnStartRequest will be throttled until OnStartRequest hits the Child's
      // mEventQ.
-     MutexAutoLock lock(mBgChildMutex);
-@@ -2176,17 +2176,17 @@ HttpChannelChild::ConnectParent(uint32_t
+@@ -2188,17 +2188,17 @@ HttpChannelChild::ConnectParent(uint32_t
  
      MOZ_RELEASE_ASSERT(gSocketTransportService);
  
@@ -47480,7 +47675,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
  
      mBgChild = bgChild.forget();
    }
-@@ -3965,17 +3965,17 @@ HttpChannelChild::RecvSetPriority(const 
+@@ -3980,17 +3980,17 @@ HttpChannelChild::RecvSetPriority(const 
  {
    mPriority = aPriority;
    return IPC_OK();
@@ -47543,7 +47738,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
                      nsProxyInfo *proxyInfo,
                      uint32_t proxyResolveFlags,
                      nsIURI *proxyURI,
-@@ -3176,17 +3176,17 @@ nsHttpChannel::ProcessPartialContent()
+@@ -3177,17 +3177,17 @@ nsHttpChannel::ProcessPartialContent()
  
      // update the cached response head
      nsAutoCString head;
@@ -47562,7 +47757,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
  
      // notify observers interested in looking at a response that has been
      // merged with any cached headers (http-on-examine-merged-response).
-@@ -3323,17 +3323,17 @@ nsHttpChannel::ProcessNotModified()
+@@ -3324,17 +3324,17 @@ nsHttpChannel::ProcessNotModified()
  
      // update the cached response head
      nsAutoCString head;
@@ -47581,7 +47776,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
  
      rv = AddCacheEntryHeaders(mCacheEntry);
      if (NS_FAILED(rv)) return rv;
-@@ -4713,17 +4713,17 @@ nsHttpChannel::ReadFromCache(bool alread
+@@ -4714,17 +4714,17 @@ nsHttpChannel::ReadFromCache(bool alread
          } else {
              MOZ_ASSERT(mFirstResponseSource == RESPONSE_FROM_NETWORK);
              LOG(("Skipping read from cache because first response was from network\n"));
@@ -47600,7 +47795,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
      // from the cache, or 2) this may be due to a 304 not modified response,
      // in which case we could have security info from a socket transport.
      if (!mSecurityInfo)
-@@ -6290,20 +6290,20 @@ nsHttpChannel::ProcessId()
+@@ -6292,20 +6292,20 @@ nsHttpChannel::ProcessId()
  bool
  nsHttpChannel::AttachStreamFilter(ipc::Endpoint<extensions::PStreamFilterParent>&& aEndpoint)
  
@@ -47623,7 +47818,7 @@ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsH
  //-----------------------------------------------------------------------------
  
  NS_IMETHODIMP
-@@ -7116,17 +7116,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
+@@ -7118,17 +7118,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
              if (size == int64_t(-1)) {
                  // mayhemer TODO - we have to restart read from cache here at the size offset
                  MOZ_ASSERT(false);

+ 19 - 12
mozilla-release/patches/1467852-62a1.patch

@@ -2,13 +2,13 @@
 # User Ben Kelly <ben@wanderview.com>
 # Date 1528681478 25200
 # Node ID 29598a3b4cc09aef566178a33b3c5d7dbd36da17
-# Parent  405e41836ee9f375adb4345965965ab9253d294a
+# Parent  147b150e8683e08f9c8e39c4e878832612c17a84
 Bug 1467852 Align LoadInfo::mServiceWorkerTaintingSynthesized handling with other service worker fields. r=valentin
 
 diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
 --- a/netwerk/base/LoadInfo.cpp
 +++ b/netwerk/base/LoadInfo.cpp
-@@ -332,17 +332,18 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
+@@ -357,17 +357,18 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
        rhs.mRedirectChainIncludingInternalRedirects)
    , mRedirectChain(rhs.mRedirectChain)
    , mAncestorPrincipals(rhs.mAncestorPrincipals)
@@ -31,7 +31,7 @@ diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
 diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
 --- a/netwerk/base/LoadInfo.h
 +++ b/netwerk/base/LoadInfo.h
-@@ -73,24 +73,16 @@ public:
+@@ -78,24 +78,16 @@ public:
    // nsBaseChannel::Redirect()
    already_AddRefed<nsILoadInfo>
    CloneWithNewSecFlags(nsSecurityFlags aSecurityFlags) const;
@@ -59,8 +59,7 @@ diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
 diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
 --- a/netwerk/base/nsILoadInfo.idl
 +++ b/netwerk/base/nsILoadInfo.idl
-@@ -37,16 +37,17 @@ native OriginAttributes(mozilla::OriginA
- [ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
+@@ -39,16 +39,17 @@ native OriginAttributes(mozilla::OriginA
  [ref] native PrincipalArrayRef(const nsTArray<nsCOMPtr<nsIPrincipal>>);
  [ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo);
        native UniqueClientSource(mozilla::UniquePtr<mozilla::dom::ClientSource>);
@@ -68,6 +67,7 @@ diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
  [ref] native const_MaybeClientInfoRef(const mozilla::Maybe<mozilla::dom::ClientInfo>);
  [ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor);
  [ref] native const_MaybeServiceWorkerDescriptorRef(const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>);
+ [ptr] native PerformanceStoragePtr(mozilla::dom::PerformanceStorage);
 +      native LoadTainting(mozilla::LoadTainting);
  
  typedef unsigned long nsSecurityFlags;
@@ -77,8 +77,7 @@ diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
   * was started, and how we plan on using the resulting response.
   * If a network request is redirected, the new channel will receive a new
   * LoadInfo object. The new object will contain mostly the same
-@@ -929,9 +930,19 @@ interface nsILoadInfo : nsISupports
-   void ClearController();
+@@ -941,16 +942,26 @@ interface nsILoadInfo : nsISupports
  
    /**
     * Get the service worker controlling this network request, if one has
@@ -86,7 +85,7 @@ diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
     */
    [noscript, nostdcall, notxpcom]
    const_MaybeServiceWorkerDescriptorRef GetController();
-+
+ 
 +  /* The service worker and fetch specifications require returning the
 +   * exact tainting level of the Response passed to FetchEvent.respondWith().
 +   * This method allows us to override the tainting level in that case.
@@ -96,11 +95,19 @@ diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
 +   */
 +  [noscript, nostdcall, notxpcom]
 +  void SynthesizeServiceWorkerTainting(in LoadTainting aTainting);
- };
++
+   /**
+    * Set a custom performance storage. This is meant to be executed only for
+    * workers. If a PerformanceStorage is not set, the loadingDocument->Window
+    * Performance object will be used instead.
+    */
+   [noscript, nostdcall, notxpcom]
+   void SetPerformanceStorage(in PerformanceStoragePtr aPerformanceStorage);
+ 
 diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
 --- a/netwerk/protocol/http/HttpChannelChild.cpp
 +++ b/netwerk/protocol/http/HttpChannelChild.cpp
-@@ -1826,16 +1826,20 @@ HttpChannelChild::Redirect1Begin(const u
+@@ -1880,16 +1880,20 @@ HttpChannelChild::Redirect1Begin(const u
  
  void
  HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
@@ -121,7 +128,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
                          : nsIChannelEventSink::REDIRECT_INTERNAL;
  
  
-@@ -1851,16 +1855,30 @@ HttpChannelChild::BeginNonIPCRedirect(ns
+@@ -1905,16 +1909,30 @@ HttpChannelChild::BeginNonIPCRedirect(ns
      // is a synthesized response that has its own security info, the pre-redirect channel
      // has already received it and it must be propagated to the post-redirect channel.
      nsCOMPtr<nsIHttpChannelChild> channelChild = do_QueryInterface(newChannel);
@@ -155,7 +162,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
 diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
 --- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
 +++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
-@@ -265,16 +265,27 @@ InterceptedHttpChannel::RedirectForRespo
+@@ -267,16 +267,27 @@ InterceptedHttpChannel::RedirectForRespo
    uint32_t flags = aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
                                         : nsIChannelEventSink::REDIRECT_INTERNAL;
  

+ 34 - 0
mozilla-release/patches/1485197-63a1.patch

@@ -0,0 +1,34 @@
+# HG changeset patch
+# User Boris Chiou <boris.chiou@gmail.com>
+# Date 1534894851 0
+# Node ID bdf392eff10efe64f35c8b7c524f07b91950777f
+# Parent  ec687f6d2dd825323d1f49885aeb7c1266d49b0a
+Bug 1485197 - Bump cbindgen to 0.6.2. r=heycam
+
+In order to support operator==() for tagged enum, we have to bump the version to
+0.6.2.
+
+Differential Revision: https://phabricator.services.mozilla.com/D3932
+
+diff --git a/build/moz.configure/rust.configure b/build/moz.configure/rust.configure
+--- a/build/moz.configure/rust.configure
++++ b/build/moz.configure/rust.configure
+@@ -290,17 +290,17 @@ cbindgen = check_prog('CBINDGEN', add_ru
+                       when=depends(build_project)
+                       (lambda build_project: build_project != 'js'))
+ 
+ 
+ @depends_if(cbindgen)
+ @checking('cbindgen version')
+ @imports(_from='textwrap', _import='dedent')
+ def cbindgen_version(cbindgen):
+-    cbindgen_min_version = Version('0.6.1')
++    cbindgen_min_version = Version('0.6.2')
+ 
+     # cbindgen x.y.z
+     version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])
+ 
+     if version < cbindgen_min_version:
+         die(dedent('''\
+         cbindgen version {} is too old. At least version {} is required.
+ 

+ 3 - 3
mozilla-release/patches/1515021-66a1.patch

@@ -2,7 +2,7 @@
 # User Jean-Yves Avenard <jyavenard@mozilla.com>
 # Date 1545251155 0
 # Node ID b77b6244ebc95356c4bb552ba4524531967f9838
-# Parent  3041fcb96a843a18f47ca9c2835fa0ea9e91f0ed
+# Parent  d9adfdaefcd87658c1f61de33645330970903e5f
 Bug 1515021 - Interrupt steps if shutdown. r=smaug
 
 Differential Revision: https://phabricator.services.mozilla.com/D15008
@@ -10,7 +10,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D15008
 diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
 --- a/dom/html/HTMLTrackElement.cpp
 +++ b/dom/html/HTMLTrackElement.cpp
-@@ -326,16 +326,20 @@ void HTMLTrackElement::LoadResource(RefP
+@@ -328,16 +328,20 @@ void HTMLTrackElement::LoadResource(RefP
    if (!doc) {
      return;
    }
@@ -29,5 +29,5 @@ diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
          nsresult rv = NS_NewChannel(
              getter_AddRefs(channel), uri, static_cast<Element*>(self), secFlags,
              nsIContentPolicy::TYPE_INTERNAL_TRACK,
+             nullptr,  // PerformanceStorage
              loadGroup,
-             nullptr,  // aCallbacks

+ 3 - 3
mozilla-release/patches/1519319-2-66a1.patch

@@ -3,7 +3,7 @@
 # Date 1547221327 0
 #      Fri Jan 11 15:42:07 2019 +0000
 # Node ID 027d42f23d2dc4979d6f9fde3b5883fe4c14bd43
-# Parent  239c32d69b0662b5d5d8ff39abca5fb7003c935b
+# Parent  592fb63b3acfeec5d435e9d31a8ee2bee7ee6dad
 Bug 1519319 - Move cbindgen check to bindgen.configure. r=froydnj
 
 Depends on D16292
@@ -30,7 +30,7 @@ diff --git a/build/moz.configure/bindgen.configure b/build/moz.configure/bindgen
 +@checking('cbindgen version')
 +@imports(_from='textwrap', _import='dedent')
 +def cbindgen_version(cbindgen):
-+    cbindgen_min_version = Version('0.6.1')
++    cbindgen_min_version = Version('0.6.2')
 +
 +    # cbindgen x.y.z
 +    version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])
@@ -84,7 +84,7 @@ diff --git a/build/moz.configure/rust.configure b/build/moz.configure/rust.confi
 -@checking('cbindgen version')
 -@imports(_from='textwrap', _import='dedent')
 -def cbindgen_version(cbindgen):
--    cbindgen_min_version = Version('0.6.1')
+-    cbindgen_min_version = Version('0.6.2')
 -
 -    # cbindgen x.y.z
 -    version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])

+ 2 - 2
mozilla-release/patches/1542878-68a1.patch

@@ -2,7 +2,7 @@
 # User Emilio Cobos Alvarez <emilio@crisal.io>
 # Date 1555511479 0
 # Node ID 30271e4881e7a27c75e5490f99908d2e764e8fa4
-# Parent  99ca10d3009a8a94ef2fb0b6b4ba39b3a10fe1e3
+# Parent  d2ec3222ba6d9e1e902dd4fb9fa6e99b2f16ac65
 Bug 1542878 - Check all the cbindgen executables before failing configure. r=froydnj
 
 Before this patch, we first find an executable, then check the version. So if
@@ -42,7 +42,7 @@ diff --git a/build/moz.configure/bindgen.configure b/build/moz.configure/bindgen
 +def check_cbindgen_version(cbindgen, fatal=False):
 +    log.debug("trying cbindgen: %s" % cbindgen)
 +
-     cbindgen_min_version = Version('0.6.1')
+     cbindgen_min_version = Version('0.6.2')
  
      # cbindgen x.y.z
      version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])

+ 22 - 22
mozilla-release/patches/1750902-916.patch

@@ -2,7 +2,7 @@
 # User Kelsey Gilbert <jgilbert@mozilla.com>
 # Date 1642718813 0
 # Node ID 362cfd416ae98aea091bebb1b0576a42b834e9ab
-# Parent  2ccb38e81fca20c6c26674fb1e886b0a408bf9ee
+# Parent  92442f94e04efde423dc02e6e9c139142772319b
 Bug 1750902 - Disable dom.vr.enabled by default. r=jrmuizel,jmathies,emilio a=RyanVM
 
 Preserve testing, just disable the pref by default.
@@ -26,45 +26,45 @@ diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochites
 +// (You can request review on Phabricator via r=#webidl)
 +var interfaceNamesInGlobalScope = [
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "AbortController",
+     {name: "AbortController", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "AbortSignal",
+     {name: "AbortSignal", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "AnalyserNode",
+     {name: "AnalyserNode", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     {name: "Animation"},
+     {name: "Animation", insecureContext: true},
 @@ -1114,32 +1114,16 @@ var interfaceNamesInGlobalScope =
-     "UserProximityEvent",
+     {name: "UserProximityEvent", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "ValidityState",
+     {name: "ValidityState", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "VideoPlaybackQuality",
+     {name: "VideoPlaybackQuality", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "VideoStreamTrack",
+     {name: "VideoStreamTrack", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRDisplay", releaseNonWindows: false},
+-    {name: "VRDisplay", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRDisplayCapabilities", releaseNonWindows: false},
+-    {name: "VRDisplayCapabilities", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRDisplayEvent", releaseNonWindows: false},
+-    {name: "VRDisplayEvent", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VREyeParameters", releaseNonWindows: false},
+-    {name: "VREyeParameters", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRFieldOfView", releaseNonWindows: false},
+-    {name: "VRFieldOfView", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRFrameData", releaseNonWindows: false},
+-    {name: "VRFrameData", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRPose", releaseNonWindows: false},
+-    {name: "VRPose", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
--    {name: "VRStageParameters", releaseNonWindows: false},
+-    {name: "VRStageParameters", insecureContext: true, releaseNonWindows: false},
 -// IMPORTANT: Do not change this list without review from a DOM peer!
-     "VTTCue",
+     {name: "VTTCue", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "VTTRegion",
+     {name: "VTTRegion", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     "WaveShaperNode",
+     {name: "WaveShaperNode", insecureContext: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
-     {name: "WebAuthnAssertion", disabled: true},
+     {name: "WebAuthnAssertion", insecureContext: true, disabled: true},
  // IMPORTANT: Do not change this list without review from a DOM peer!
 diff --git a/dom/vr/test/crashtests/crashtests.list.1750902.later b/dom/vr/test/crashtests/crashtests.list.1750902.later
 new file mode 100644
@@ -110,7 +110,7 @@ diff --git a/dom/vr/test/reftest/reftest.list b/dom/vr/test/reftest/reftest.list
 diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
 --- a/modules/libpref/init/all.js
 +++ b/modules/libpref/init/all.js
-@@ -5459,23 +5459,20 @@ pref("jsloader.shareGlobal", false);
+@@ -5522,23 +5522,20 @@ pref("jsloader.shareGlobal", false);
  
  // When we're asked to take a screenshot, don't wait more than 2000ms for the
  // event loop to become idle before actually taking the screenshot.

+ 4 - 3
mozilla-release/patches/833098-1-62a1.patch

@@ -2,7 +2,7 @@
 # User Kris Maglione <maglione.k@gmail.com>
 # Date 1524976083 25200
 # Node ID 4cf33b7e542827c80c494eeea10c10c2721bf2d6
-# Parent  fcb5d99b3982b897363d4281c5e62cb7b8f60008
+# Parent  04f7c148b662981fc542e86781c79857c8d6b1ea
 Bug 833098: Part 1 - Remove dead code in xpfe directory viewer. r=Mossop
 
 Most of this module is dead code, intended to convert directory listings into
@@ -37,7 +37,7 @@ diff --git a/browser/installer/package-manifest.in b/browser/installer/package-m
 diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
 --- a/modules/libpref/init/all.js
 +++ b/modules/libpref/init/all.js
-@@ -2159,22 +2159,16 @@ pref("network.standard-url.max-length", 
+@@ -2167,22 +2167,16 @@ pref("network.standard-url.max-length", 
  
  // Whether nsIURI.host/.hostname/.spec should return a punycode string
  // If set to false we will revert to previous behaviour and return a unicode string.
@@ -261,7 +261,7 @@ diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/d
 deleted file mode 100644
 --- a/xpfe/components/directory/nsDirectoryViewer.cpp
 +++ /dev/null
-@@ -1,1375 +0,0 @@
+@@ -1,1376 +0,0 @@
 -/* -*- Mode: C++; tab-width: 8; 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
@@ -1545,6 +1545,7 @@ deleted file mode 100644
 -                       nsContentUtils::GetSystemPrincipal(),
 -                       nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
 -                       nsIContentPolicy::TYPE_OTHER,
+-                       nullptr, // PerformanceStorage
 -                       aLoadGroup);
 -    if (NS_FAILED(rv)) return rv;
 -

+ 19 - 0
mozilla-release/patches/series

@@ -915,6 +915,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1427006-59a1.patch
 1428685-59a1.patch
 1429908-59a1.patch
+1429014-59a1.patch
 1430799-59a1.patch
 1427718-59a1.patch
 1421213-1-59a1.patch
@@ -1170,6 +1171,11 @@ servo-19850-60a1.patch
 1432516-3-60a1.patch
 1431866-60a1.patch
 1432640-60a1.patch
+1431847-1-60a1.patch
+1431847-2-60a1.patch
+1431847-3-60a1.patch
+1431847-4-60a1.patch
+1431847-5-60a1.patch
 1432553-60a1.patch
 1431864-60a1.patch
 1431025-60a1.patch
@@ -1195,6 +1201,15 @@ servo-19850-60a1.patch
 1431173-60a1.patch
 1432956-1-60a1.patch
 1398149-60a1.patch
+1433044-1no2-60a1.patch
+1425458-0-60a1.patch
+1425458-1-60a1.patch
+1425458-2-60a1.patch
+1425458-3-60a1.patch
+1425458-4-60a1.patch
+1425458-5-60a1.patch
+1425458-6-60a1.patch
+1425458-7no8or9-60a1.patch
 1255378-1-60a1.patch
 1255378-2-60a1.patch
 1432541-1-60a1.patch
@@ -1862,6 +1877,7 @@ servo-20004-60a1.patch
 1429768-60a1.patch
 1415443-60a1.patch
 1436742-60a1.patch
+1437080-2-fix-60a1.patch
 servo-20011-60a1.patch
 servo-20010-60a1.patch
 1435139-60a1.patch
@@ -2346,6 +2362,7 @@ servo-20104-60a1.patch
 1438846-1only-60a1.patch
 1440043-60a1.patch
 1428433-60a1.patch
+1439879-60a1.patch
 1440118-1-60a1.patch
 1440118-2-60a1.patch
 1440164-1-60a1.patch
@@ -3517,6 +3534,7 @@ servo-20592-61a1.patch
 1452827-1-61a1.patch
 1452827-2-61a1.patch
 1452307-1-61a1.patch
+1437897-1no2-61a1.patch
 1453090-61a1.patch
 1447273-1-61a1.patch
 1447273-2-61a1.patch
@@ -4389,6 +4407,7 @@ NOBUG-20180505-lint-61a1.patch
 1479420-63a1.patch
 1483566-63a1.patch
 1484846-63a1.patch
+1485197-63a1.patch
 1485072-63a1.patch
 1484888-63a1.patch
 1483778-63a1.patch