Merge mozilla-central to autoland. r=merge a=merge on a CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Tue, 21 Nov 2017 00:24:13 +0200
changeset 437320 5f6fb7f92a7cf07c18a02c0f3ca12d65d8a40bcd
parent 437319 ff6ab6ec5d185be0a27a7779dbf82e991fe4de59 (current diff)
parent 437284 081c06e175b2b4431b7af5ea594ff0373e97b70a (diff)
child 437321 03490b29ea3467281d639004d998b16392ac2ec9
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersmerge, merge
milestone59.0a1
Merge mozilla-central to autoland. r=merge a=merge on a CLOSED TREE
testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini
--- a/accessible/base/RoleMap.h
+++ b/accessible/base/RoleMap.h
@@ -858,17 +858,17 @@ ROLE(DOCUMENT_FRAME,
      eNoNameRule)
 
 ROLE(HEADING,
      "heading",
      ATK_ROLE_HEADING,
      @"AXHeading",
      USE_ROLE_STRING,
      IA2_ROLE_HEADING,
-     eNameFromSubtreeIfReqRule)
+     eNameFromSubtreeRule)
 
 ROLE(PAGE,
      "page",
      ATK_ROLE_PAGE,
      NSAccessibilityGroupRole,
      USE_ROLE_STRING,
      IA2_ROLE_PAGE,
      eNoNameRule)
--- a/accessible/jsat/OutputGenerator.jsm
+++ b/accessible/jsat/OutputGenerator.jsm
@@ -172,20 +172,23 @@ var OutputGenerator = {
     }
 
     let description = aAccessible.description;
     if (description) {
       // Compare against the calculated name unconditionally, regardless of name rule,
       // so we can make sure we don't speak duplicated descriptions
       let tmpName = name || aAccessible.name;
       if (tmpName && (description !== tmpName)) {
-        name = name || "";
-        name = this.outputOrder === OUTPUT_DESC_FIRST ?
-          description + " - " + name :
-          name + " - " + description;
+        if (name) {
+          name = this.outputOrder === OUTPUT_DESC_FIRST ?
+            description + " - " + name :
+            name + " - " + description;
+        } else {
+          name = description;
+        }
       }
     }
 
     if (!name || !name.trim()) {
       return;
     }
     aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"](name);
   },
--- a/accessible/tests/mochitest/jsat/test_output.html
+++ b/accessible/tests/mochitest/jsat/test_output.html
@@ -25,20 +25,20 @@ https://bugzilla.mozilla.org/show_bug.cg
         var tests = [{
           accOrElmOrID: "anchor",
           expectedUtterance: [[{"string": "link"}, "title"],
             ["title", {"string": "link"}]],
           expectedBraille: [[{"string": "linkAbbr"}, "title"],
             ["title", {"string": "linkAbbr"}]]
         }, {
           accOrElmOrID: "anchor_titleandtext",
-          expectedUtterance: [[{"string": "link"}, "goes to the tests -",
-            "Tests"], ["Tests", "- goes to the tests", {"string": "link"}]],
-          expectedBraille:   [[{"string": "linkAbbr"}, "goes to the tests -",
-            "Tests"], ["Tests", "- goes to the tests", {"string": "linkAbbr"}]],
+          expectedUtterance: [[{"string": "link"}, "goes to the tests",
+            "Tests"], ["Tests", "goes to the tests", {"string": "link"}]],
+          expectedBraille:   [[{"string": "linkAbbr"}, "goes to the tests",
+            "Tests"], ["Tests", "goes to the tests", {"string": "linkAbbr"}]],
         }, {
           accOrElmOrID: "anchor_duplicatedtitleandtext",
           expectedUtterance: [[{"string": "link"}, "Tests"],
             ["Tests", {"string": "link"}]],
           expectedBraille: [[{"string": "linkAbbr"}, "Tests"],
             ["Tests", {"string": "linkAbbr"}]]
         }, {
           accOrElmOrID: "anchor_arialabelandtext",
--- a/accessible/tests/mochitest/name/test_general.html
+++ b/accessible/tests/mochitest/name/test_general.html
@@ -143,16 +143,19 @@
       testName("tablemenuitem", "menuitem 1");
 
       // Get the name from child acronym title attribute rather than from
       // acronym content.
       testName("label_with_acronym", "O A T F World Wide Web");
 
       testName("testArticle", "Test article");
 
+      testName("h1", "heading");
+      testName("aria_heading", "aria_heading");
+
       // ////////////////////////////////////////////////////////////////////////
       // title attribute
 
       // If nothing is left. Let's try title attribute.
       testName("btn_title", "title");
 
       // ////////////////////////////////////////////////////////////////////////
       // textarea name
@@ -483,16 +486,19 @@
     <acronym title="O A T F">OATF</acronym>
     <abbr title="World Wide Web">WWW</abbr>
   </label>
 
   <div id="testArticle" role="article" title="Test article">
     <p>This is a paragraph inside the article.</p>
   </div>
 
+  <h1 id="h1" title="oops">heading</h1>
+  <div role="heading" id="aria_heading">aria_heading</div>
+
   <!-- name from title attribute -->
   <span id="btn_title" role="group" title="title">15</span>
 
   <!-- A textarea nested in a label with a text child (bug #453371). -->
   <form>
     <label>Story
       <textarea id="textareawithchild" name="name">Foo</textarea>
       is ended.
--- a/browser/base/content/test/alerts/browser.ini
+++ b/browser/base/content/test/alerts/browser.ini
@@ -3,11 +3,12 @@ support-files =
   head.js
   file_dom_notifications.html
 
 [browser_notification_close.js]
 skip-if = os == 'win' # Bug 1227785
 [browser_notification_do_not_disturb.js]
 skip-if = os == 'win' # Bug 1352791
 [browser_notification_open_settings.js]
+skip-if = os == 'win' # Bug 1411118
 [browser_notification_remove_permission.js]
 [browser_notification_replace.js]
 [browser_notification_tab_switching.js]
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -23,21 +23,16 @@ WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_
 RETRIEVE_WINDOWS_INSTALLER = 1
 
 MOZ_LANGPACK_EID=langpack-$(AB_CD)@firefox.mozilla.org
 # For Nightly, we know where to get the builds from to do local repacks
 ifdef NIGHTLY_BUILD
 export EN_US_BINARY_URL ?= https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central
 endif
 
-L10N_PREF_JS_EXPORTS = $(call MERGE_FILE,firefox-l10n.js)
-L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
-L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
-PP_TARGETS += L10N_PREF_JS_EXPORTS
-
 ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
 MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore
 MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png
 MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns
 MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ '
 endif
 
 MOZ_SFX_PACKAGE=$(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
@@ -180,23 +175,16 @@ ifeq ($(OS_ARCH),WINNT)
 else
 	cat $< | \
 	  sed -e 's/^InfoText=/Info=/' -e 's/^TitleText=/Title=/' | \
 	  sed -e 's/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/' > \
 	  $(FINAL_TARGET)/../updater.ini
 endif
 endif
 
-ifndef IS_LANGPACK
-ifdef MOZ_CRASHREPORTER
-libs:: $(call MERGE_FILE,crashreporter/crashreporter-override.ini)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
-endif
-endif
-
 ident:
 	@printf 'fx_revision '
 	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
 	    $(STAGEDIST)/application.ini App SourceStamp
 	@printf 'buildid '
 	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
 	    $(STAGEDIST)/application.ini App BuildID
 
--- a/browser/locales/moz.build
+++ b/browser/locales/moz.build
@@ -1,16 +1,22 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 JAR_MANIFESTS += ['jar.mn']
 
+# If DIST_SUBDIR ever gets unset in browser this path might be wrong due to PREF_DIR changing.
+LOCALIZED_PP_FILES.defaults.preferences += ['en-US/firefox-l10n.js']
+
+if CONFIG['MOZ_CRASHREPORTER']:
+    LOCALIZED_FILES += ['en-US/crashreporter/crashreporter-override.ini']
+
 with Files("**"):
     BUG_COMPONENT = ("Toolkit", "Build Config")
 
 with Files("all-locales"):
     BUG_COMPONENT = ("Core", "Localization")
 
 with Files("en-US/**"):
     BUG_COMPONENT = ("Core", "Localization")
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -10,17 +10,16 @@
 // We intentionally shadow non-virtual methods, but gcc gets confused.
 #ifdef __GNUC__
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
 #endif
 
 #include <stdint.h>
 #include "jspubtd.h"
-#include "js/GCAPI.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMDOMException.h"
 #include "nsWrapperCache.h"
 #include "xpcexception.h"
 #include "nsString.h"
 #include "mozilla/dom/BindingDeclarations.h"
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -85,18 +85,16 @@
 #include "nsTextFragment.h"
 #include "nsContentCID.h"
 
 #include "nsIDOMEventListener.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
 #include "nsIWidget.h"
 
-#include "js/GCAPI.h"
-
 #include "nsNodeInfoManager.h"
 #include "nsICategoryManager.h"
 #include "nsGenericHTMLElement.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIControllers.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -7,17 +7,16 @@
 #ifndef nsIScriptContext_h__
 #define nsIScriptContext_h__
 
 #include "nscore.h"
 #include "nsStringGlue.h"
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
 #include "jspubtd.h"
-#include "js/GCAPI.h"
 
 class nsIScriptGlobalObject;
 
 #define NS_ISCRIPTCONTEXT_IID \
 { 0x54cbe9cf, 0x7282, 0x421a, \
  { 0x91, 0x6f, 0xd0, 0x70, 0x73, 0xde, 0xb8, 0xc0 } }
 
 class nsIOffThreadScriptReceiver;
--- a/dom/base/nsWrapperCacheInlines.h
+++ b/dom/base/nsWrapperCacheInlines.h
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWrapperCacheInline_h___
 #define nsWrapperCacheInline_h___
 
 #include "nsWrapperCache.h"
-#include "js/GCAPI.h"
 #include "js/TracingAPI.h"
 
 inline JSObject*
 nsWrapperCache::GetWrapperPreserveColor() const
 {
   JSObject* obj = mWrapper;
   if (obj && js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
     // The object has been found to be dead and is in the process of being
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -312,17 +312,16 @@ DOMInterfaces = {
 
 'EventTarget': {
     # When we get rid of hasXPConnectImpls, we can get rid of the
     # couldBeDOMBinding stuff in GetOrCreateDOMReflector.
     #
     # We can also get rid of the UnwrapArg bits in
     # the dom QueryInterface (in BindingUtils.cpp) at that point.
     'hasXPConnectImpls': True,
-    'concrete': False,
     'jsImplParent': 'mozilla::DOMEventTargetHelper',
 },
 
 'Exception': {
     'headerFile': 'mozilla/dom/DOMException.h',
     'binaryNames': {
         'message': 'messageMoz',
     },
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2376,32 +2376,21 @@ class MethodDefiner(PropertyDefiner):
                     raise TypeError("Legacy queryInterface member shouldn't be static")
                 signatures = m.signatures()
 
                 def argTypeIsIID(arg):
                     return arg.type.inner.isExternal() and arg.type.inner.identifier.name == 'IID'
                 if len(signatures) > 1 or len(signatures[0][1]) > 1 or not argTypeIsIID(signatures[0][1][0]):
                     raise TypeError("There should be only one queryInterface method with 1 argument of type IID")
 
-                # Make sure to not stick QueryInterface on abstract interfaces that
-                # have hasXPConnectImpls (like EventTarget).  So only put it on
-                # interfaces that are concrete and all of whose ancestors are abstract.
-                def allAncestorsAbstract(iface):
-                    if not iface.parent:
-                        return True
-                    desc = self.descriptor.getDescriptor(iface.parent.identifier.name)
-                    if desc.concrete:
-                        return False
-                    return allAncestorsAbstract(iface.parent)
+                # Make sure to not stick QueryInterface on abstract interfaces.
                 if (not self.descriptor.interface.hasInterfacePrototypeObject() or
-                    not self.descriptor.concrete or
-                    not allAncestorsAbstract(self.descriptor.interface)):
+                    not self.descriptor.concrete):
                     raise TypeError("QueryInterface is only supported on "
-                                    "interfaces that are concrete and all "
-                                    "of whose ancestors are abstract: " +
+                                    "interfaces that are concrete: " +
                                     self.descriptor.name)
                 condition = "WantsQueryInterface<%s>::Enabled" % descriptor.nativeType
                 self.regular.append({
                     "name": 'QueryInterface',
                     "methodInfo": False,
                     "length": 1,
                     "flags": "0",
                     "condition": MemberCondition(func=condition)
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/Exceptions.h"
 
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "jsapi.h"
 #include "jsprf.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsPIDOMWindow.h"
--- a/dom/canvas/ImageData.h
+++ b/dom/canvas/ImageData.h
@@ -11,17 +11,17 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/TypedArray.h"
 #include <stdint.h>
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 
 namespace mozilla {
 namespace dom {
 
 class ImageData final : public nsISupports
 {
   ~ImageData()
   {
new file mode 100644
--- /dev/null
+++ b/dom/events/ConstructibleEventTarget.cpp
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/ConstructibleEventTarget.h"
+#include "mozilla/dom/EventTargetBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+JSObject*
+ConstructibleEventTarget::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
+{
+  return EventTargetBinding::Wrap(cx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/events/ConstructibleEventTarget.h
@@ -0,0 +1,35 @@
+/* -*- 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_ConstructibleEventTarget_h_
+#define mozilla_dom_ConstructibleEventTarget_h_
+
+#include "mozilla/DOMEventTargetHelper.h"
+#include "js/RootingAPI.h"
+
+namespace mozilla {
+namespace dom {
+
+class ConstructibleEventTarget : public DOMEventTargetHelper
+{
+public:
+  // Not worrying about isupports and cycle collection here.  This does mean
+  // ConstructibleEventTarget will show up in CC and refcount logs as a
+  // DOMEventTargetHelper, but that's probably OK.
+
+  explicit ConstructibleEventTarget(nsIGlobalObject* aGlobalObject)
+    : DOMEventTargetHelper(aGlobalObject)
+  {
+  }
+
+  virtual JSObject* WrapObject(JSContext* cx,
+			       JS::Handle<JSObject*> aGivenProto) override;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ConstructibleEventTarget_h_
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -138,20 +138,17 @@ public:
   nsPIDOMWindowInner* GetWindowIfCurrent() const;
   // Returns the document associated with this event target, if that document is
   // the current document of its browsing context.  Will return null otherwise.
   nsIDocument* GetDocumentIfCurrent() const;
   void BindToOwner(nsIGlobalObject* aOwner);
   void BindToOwner(nsPIDOMWindowInner* aOwner);
   void BindToOwner(DOMEventTargetHelper* aOther);
   virtual void DisconnectFromOwner();
-  nsIGlobalObject* GetParentObject() const
-  {
-    return GetOwnerGlobal();
-  }
+  using EventTarget::GetParentObject;
   virtual nsIGlobalObject* GetOwnerGlobal() const override
   {
     nsCOMPtr<nsIGlobalObject> parentObject = do_QueryReferent(mParentObject);
     return parentObject;
   }
   bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
 
   virtual void EventListenerAdded(nsAtom* aType) override;
--- a/dom/events/EventTarget.cpp
+++ b/dom/events/EventTarget.cpp
@@ -2,21 +2,36 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/EventTargetBinding.h"
+#include "mozilla/dom/ConstructibleEventTarget.h"
+#include "nsIGlobalObject.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace dom {
 
+/* static */
+already_AddRefed<EventTarget>
+EventTarget::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
+{
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!global) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return nullptr;
+  }
+  RefPtr<EventTarget> target = new ConstructibleEventTarget(global);
+  return target.forget();
+}
+
 void
 EventTarget::RemoveEventListener(const nsAString& aType,
                                  EventListener* aListener,
                                  const EventListenerOptionsOrBoolean& aOptions,
                                  ErrorResult& aRv)
 {
   EventListenerManager* elm = GetExistingListenerManager();
   if (elm) {
--- a/dom/events/EventTarget.h
+++ b/dom/events/EventTarget.h
@@ -23,45 +23,53 @@ class EventListenerManager;
 
 namespace dom {
 
 class AddEventListenerOptionsOrBoolean;
 class Event;
 class EventListener;
 class EventListenerOptionsOrBoolean;
 class EventHandlerNonNull;
+class GlobalObject;
 
 template <class T> struct Nullable;
 
 // IID for the dom::EventTarget interface
 #define NS_EVENTTARGET_IID \
 { 0xde651c36, 0x0053, 0x4c67, \
   { 0xb1, 0x3d, 0x67, 0xb9, 0x40, 0xfc, 0x82, 0xe4 } }
 
 class EventTarget : public nsIDOMEventTarget,
                     public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_EVENTTARGET_IID)
 
   // WebIDL API
+  static already_AddRefed<EventTarget> Constructor(const GlobalObject& aGlobal,
+                                                   ErrorResult& aRv);
   using nsIDOMEventTarget::AddEventListener;
   using nsIDOMEventTarget::RemoveEventListener;
   using nsIDOMEventTarget::DispatchEvent;
   virtual void AddEventListener(const nsAString& aType,
                                 EventListener* aCallback,
                                 const AddEventListenerOptionsOrBoolean& aOptions,
                                 const Nullable<bool>& aWantsUntrusted,
                                 ErrorResult& aRv) = 0;
   virtual void RemoveEventListener(const nsAString& aType,
                                    EventListener* aCallback,
                                    const EventListenerOptionsOrBoolean& aOptions,
                                    ErrorResult& aRv);
   bool DispatchEvent(Event& aEvent, CallerType aCallerType, ErrorResult& aRv);
 
+  nsIGlobalObject* GetParentObject() const
+  {
+    return GetOwnerGlobal();
+  }
+
   // Note, this takes the type in onfoo form!
   EventHandlerNonNull* GetEventHandler(const nsAString& aType)
   {
     RefPtr<nsAtom> type = NS_Atomize(aType);
     return GetEventHandler(type, EmptyString());
   }
 
   // Note, this takes the type in onfoo form!
--- a/dom/events/moz.build
+++ b/dom/events/moz.build
@@ -40,16 +40,17 @@ EXPORTS.mozilla += [
 ]
 
 EXPORTS.mozilla.dom += [
     'AnimationEvent.h',
     'BeforeUnloadEvent.h',
     'ClipboardEvent.h',
     'CommandEvent.h',
     'CompositionEvent.h',
+    'ConstructibleEventTarget.h',
     'CustomEvent.h',
     'DataTransfer.h',
     'DataTransferItem.h',
     'DataTransferItemList.h',
     'DeviceMotionEvent.h',
     'DragEvent.h',
     'Event.h',
     'EventTarget.h',
@@ -82,16 +83,17 @@ if CONFIG['MOZ_WEBSPEECH']:
 
 UNIFIED_SOURCES += [
     'AnimationEvent.cpp',
     'AsyncEventDispatcher.cpp',
     'BeforeUnloadEvent.cpp',
     'ClipboardEvent.cpp',
     'CommandEvent.cpp',
     'CompositionEvent.cpp',
+    'ConstructibleEventTarget.cpp',
     'ContentEventHandler.cpp',
     'CustomEvent.cpp',
     'DataTransfer.cpp',
     'DataTransferItem.cpp',
     'DataTransferItemList.cpp',
     'DeviceMotionEvent.cpp',
     'DOMEventTargetHelper.cpp',
     'DragEvent.cpp',
--- a/dom/flyweb/FlyWebServerEvents.cpp
+++ b/dom/flyweb/FlyWebServerEvents.cpp
@@ -8,18 +8,16 @@
 #include "mozilla/dom/FlyWebFetchEventBinding.h"
 #include "mozilla/dom/FlyWebPublishedServer.h"
 #include "mozilla/dom/FlyWebServerEvents.h"
 #include "mozilla/dom/FlyWebWebSocketEventBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/Response.h"
 
-#include "js/GCAPI.h"
-
 namespace mozilla {
 namespace dom {
 
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(FlyWebFetchEvent)
 
 NS_IMPL_ADDREF_INHERITED(FlyWebFetchEvent, Event)
 NS_IMPL_RELEASE_INHERITED(FlyWebFetchEvent, Event)
--- a/dom/html/nsIHTMLCollection.h
+++ b/dom/html/nsIHTMLCollection.h
@@ -6,17 +6,17 @@
 
 #ifndef nsIHTMLCollection_h___
 #define nsIHTMLCollection_h___
 
 #include "nsISupports.h"
 #include "nsStringFwd.h"
 #include "nsTArrayForwardDeclare.h"
 #include "nsWrapperCache.h"
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 
 class nsINode;
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/ProcessHangMonitorIPC.h"
 
 #include "jsapi.h"
-#include "js/GCAPI.h"
 
 #include "mozilla/Atomics.h"
 #include "mozilla/BackgroundHangMonitor.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabParent.h"
--- a/dom/media/eme/MediaKeyMessageEvent.cpp
+++ b/dom/media/eme/MediaKeyMessageEvent.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/MediaKeyMessageEvent.h"
 #include "mozilla/dom/MediaKeyMessageEventBinding.h"
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 #include "jsfriendapi.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PrimitiveConversions.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/dom/TypedArray.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/MediaKeys.h"
 
--- a/dom/vr/VRDisplayEvent.cpp
+++ b/dom/vr/VRDisplayEvent.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VRDisplayEvent.h"
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PrimitiveConversions.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/webauthn/u2f-hid-rs/src/lib.rs
+++ b/dom/webauthn/u2f-hid-rs/src/lib.rs
@@ -22,17 +22,17 @@ pub mod platform;
 #[cfg(any(target_os = "windows"))]
 #[path = "windows/mod.rs"]
 pub mod platform;
 
 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
 #[path = "stub/mod.rs"]
 pub mod platform;
 
-#[cfg(not(any(target_os = "macos")))]
+#[cfg(target_os = "windows")]
 mod khmatcher;
 
 #[macro_use]
 extern crate log;
 extern crate rand;
 extern crate libc;
 extern crate boxfnonce;
 extern crate runloop;
--- a/dom/webauthn/u2f-hid-rs/src/linux/mod.rs
+++ b/dom/webauthn/u2f-hid-rs/src/linux/mod.rs
@@ -1,172 +1,149 @@
 /* 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/. */
 
 use std::time::Duration;
 use std::thread;
 
 mod device;
-mod devicemap;
 mod hidraw;
 mod monitor;
+mod transaction;
 
 use consts::PARAMETER_SIZE;
-use khmatcher::KeyHandleMatcher;
-use runloop::RunLoop;
+use platform::device::Device;
+use platform::transaction::Transaction;
 use util::{io_err, OnceCallback};
-use u2fprotocol::{u2f_is_keyhandle_valid, u2f_register, u2f_sign};
+use u2fprotocol::{u2f_init_device, u2f_is_keyhandle_valid, u2f_register, u2f_sign};
 
-use self::devicemap::DeviceMap;
-use self::monitor::Monitor;
-
+#[derive(Default)]
 pub struct PlatformManager {
-    // Handle to the thread loop.
-    thread: Option<RunLoop>,
+    transaction: Option<Transaction>,
 }
 
 impl PlatformManager {
     pub fn new() -> Self {
-        Self { thread: None }
+        Default::default()
     }
 
     pub fn register(
         &mut self,
         timeout: u64,
         challenge: Vec<u8>,
         application: Vec<u8>,
         key_handles: Vec<Vec<u8>>,
         callback: OnceCallback<Vec<u8>>,
     ) {
         // Abort any prior register/sign calls.
         self.cancel();
 
         let cbc = callback.clone();
 
-        let thread = RunLoop::new_with_timeout(
-            move |alive| {
-                let mut devices = DeviceMap::new();
-                let monitor = try_or!(Monitor::new(), |e| callback.call(Err(e)));
-                let mut matches = KeyHandleMatcher::new(&key_handles);
+        let transaction = Transaction::new(timeout, cbc.clone(), move |path, alive| {
+            // Create a new device.
+            let dev = &mut match Device::new(path) {
+                Ok(dev) => dev,
+                _ => return,
+            };
 
-                while alive() && monitor.alive() {
-                    // Add/remove devices.
-                    for event in monitor.events() {
-                        devices.process_event(event);
-                    }
+            // Try initializing it.
+            if !dev.is_u2f() || !u2f_init_device(dev) {
+                return;
+            }
 
-                    // Query newly added devices.
-                    matches.update(devices.iter_mut(), |device, key_handle| {
-                        u2f_is_keyhandle_valid(device, &challenge, &application, key_handle)
-                            .unwrap_or(false /* no match on failure */)
-                    });
+            // Iterate the exclude list and see if there are any matches.
+            // Abort the state machine if we found a valid key handle.
+            if key_handles.iter().any(|key_handle| {
+                u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle)
+                    .unwrap_or(false) /* no match on failure */
+            })
+            {
+                return;
+            }
 
-                    // Iterate all devices that don't match any of the handles
-                    // in the exclusion list and try to register.
-                    for (path, device) in devices.iter_mut() {
-                        if matches.get(path).is_empty() {
-                            if let Ok(bytes) = u2f_register(device, &challenge, &application) {
-                                callback.call(Ok(bytes));
-                                return;
-                            }
-                        }
-                    }
-
-                    // Wait a little before trying again.
-                    thread::sleep(Duration::from_millis(100));
+            while alive() {
+                if let Ok(bytes) = u2f_register(dev, &challenge, &application) {
+                    callback.call(Ok(bytes));
+                    break;
                 }
 
-                callback.call(Err(io_err("aborted or timed out")));
-            },
-            timeout,
-        );
+                // Sleep a bit before trying again.
+                thread::sleep(Duration::from_millis(100));
+            }
+        });
 
-        self.thread = Some(try_or!(
-            thread,
-            |_| cbc.call(Err(io_err("couldn't create runloop")))
-        ));
+        self.transaction = Some(try_or!(transaction, |_| {
+            cbc.call(Err(io_err("couldn't create transaction")))
+        }));
     }
 
     pub fn sign(
         &mut self,
         timeout: u64,
         challenge: Vec<u8>,
         application: Vec<u8>,
         key_handles: Vec<Vec<u8>>,
         callback: OnceCallback<(Vec<u8>, Vec<u8>)>,
     ) {
         // Abort any prior register/sign calls.
         self.cancel();
 
         let cbc = callback.clone();
 
-        let thread = RunLoop::new_with_timeout(
-            move |alive| {
-                let mut devices = DeviceMap::new();
-                let monitor = try_or!(Monitor::new(), |e| callback.call(Err(e)));
-                let mut matches = KeyHandleMatcher::new(&key_handles);
+        let transaction = Transaction::new(timeout, cbc.clone(), move |path, alive| {
+            // Create a new device.
+            let dev = &mut match Device::new(path) {
+                Ok(dev) => dev,
+                _ => return,
+            };
 
-                while alive() && monitor.alive() {
-                    // Add/remove devices.
-                    for event in monitor.events() {
-                        devices.process_event(event);
-                    }
-
-                    // Query newly added devices.
-                    matches.update(devices.iter_mut(), |device, key_handle| {
-                        u2f_is_keyhandle_valid(device, &challenge, &application, key_handle)
-                            .unwrap_or(false /* no match on failure */)
-                    });
-
-                    // Iterate all devices.
-                    for (path, device) in devices.iter_mut() {
-                        let key_handles = matches.get(path);
+            // Try initializing it.
+            if !dev.is_u2f() || !u2f_init_device(dev) {
+                return;
+            }
 
-                        // If the device matches none of the given key handles
-                        // then just make it blink with bogus data.
-                        if key_handles.is_empty() {
-                            let blank = vec![0u8; PARAMETER_SIZE];
-                            if let Ok(_) = u2f_register(device, &blank, &blank) {
-                                callback.call(Err(io_err("invalid key")));
-                                return;
-                            }
-
-                            continue;
-                        }
+            // Find all matching key handles.
+            let key_handles = key_handles
+                .iter()
+                .filter(|key_handle| {
+                    u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle)
+                        .unwrap_or(false) /* no match on failure */
+                })
+                .collect::<Vec<_>>();
 
-                        // Otherwise, try to sign.
-                        for key_handle in key_handles {
-                            if let Ok(bytes) = u2f_sign(
-                                device,
-                                &challenge,
-                                &application,
-                                key_handle,
-                            )
-                            {
-                                callback.call(Ok((key_handle.to_vec(), bytes)));
-                                return;
-                            }
+            while alive() {
+                // If the device matches none of the given key handles
+                // then just make it blink with bogus data.
+                if key_handles.is_empty() {
+                    let blank = vec![0u8; PARAMETER_SIZE];
+                    if let Ok(_) = u2f_register(dev, &blank, &blank) {
+                        callback.call(Err(io_err("invalid key")));
+                        break;
+                    }
+                } else {
+                    // Otherwise, try to sign.
+                    for key_handle in &key_handles {
+                        if let Ok(bytes) = u2f_sign(dev, &challenge, &application, key_handle) {
+                            callback.call(Ok((key_handle.to_vec(), bytes)));
+                            break;
                         }
                     }
-
-                    // Wait a little before trying again.
-                    thread::sleep(Duration::from_millis(100));
                 }
 
-                callback.call(Err(io_err("aborted or timed out")));
-            },
-            timeout,
-        );
+                // Sleep a bit before trying again.
+                thread::sleep(Duration::from_millis(100));
+            }
+        });
 
-        self.thread = Some(try_or!(
-            thread,
-            |_| cbc.call(Err(io_err("couldn't create runloop")))
-        ));
+        self.transaction = Some(try_or!(transaction, |_| {
+            cbc.call(Err(io_err("couldn't create transaction")))
+        }));
     }
 
     // This blocks.
     pub fn cancel(&mut self) {
-        if let Some(thread) = self.thread.take() {
-            thread.cancel();
+        if let Some(mut transaction) = self.transaction.take() {
+            transaction.cancel();
         }
     }
 }
--- a/dom/webauthn/u2f-hid-rs/src/linux/monitor.rs
+++ b/dom/webauthn/u2f-hid-rs/src/linux/monitor.rs
@@ -1,24 +1,21 @@
 /* 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/. */
 
+use libc::{c_int, c_short, c_ulong};
 use libudev;
 use libudev::EventType;
-
-use libc::{c_int, c_short, c_ulong};
-
+use runloop::RunLoop;
+use std::collections::HashMap;
 use std::ffi::OsString;
 use std::io;
 use std::os::unix::io::AsRawFd;
-use std::sync::mpsc::{channel, Receiver, TryIter};
-
-use runloop::RunLoop;
-use util::to_io_err;
+use std::sync::Arc;
 
 const UDEV_SUBSYSTEM: &'static str = "hidraw";
 const POLLIN: c_short = 0x0001;
 const POLL_TIMEOUT: c_int = 100;
 
 fn poll(fds: &mut Vec<::libc::pollfd>) -> io::Result<()> {
     let nfds = fds.len() as c_ulong;
 
@@ -26,95 +23,110 @@ fn poll(fds: &mut Vec<::libc::pollfd>) -
 
     if rv < 0 {
         Err(io::Error::from_raw_os_error(rv))
     } else {
         Ok(())
     }
 }
 
-pub enum Event {
-    Add(OsString),
-    Remove(OsString),
+pub struct Monitor<F>
+where
+    F: Fn(OsString, &Fn() -> bool) + Sync,
+{
+    runloops: HashMap<OsString, RunLoop>,
+    new_device_cb: Arc<F>,
 }
 
-impl Event {
-    fn from_udev(event: libudev::Event) -> Option<Self> {
+impl<F> Monitor<F>
+where
+    F: Fn(OsString, &Fn() -> bool) + Send + Sync + 'static,
+{
+    pub fn new(new_device_cb: F) -> Self {
+        Self {
+            runloops: HashMap::new(),
+            new_device_cb: Arc::new(new_device_cb),
+        }
+    }
+
+    pub fn run(&mut self, alive: &Fn() -> bool) -> io::Result<()> {
+        let ctx = libudev::Context::new()?;
+
+        let mut enumerator = libudev::Enumerator::new(&ctx)?;
+        enumerator.match_subsystem(UDEV_SUBSYSTEM)?;
+
+        // Iterate all existing devices.
+        for dev in enumerator.scan_devices()? {
+            if let Some(path) = dev.devnode().map(|p| p.to_owned().into_os_string()) {
+                self.add_device(path);
+            }
+        }
+
+        let mut monitor = libudev::Monitor::new(&ctx)?;
+        monitor.match_subsystem(UDEV_SUBSYSTEM)?;
+
+        // Start listening for new devices.
+        let mut socket = monitor.listen()?;
+        let mut fds = vec![
+            ::libc::pollfd {
+                fd: socket.as_raw_fd(),
+                events: POLLIN,
+                revents: 0,
+            },
+        ];
+
+        while alive() {
+            // Wait for new events, break on failure.
+            poll(&mut fds)?;
+
+            if let Some(event) = socket.receive_event() {
+                self.process_event(event);
+            }
+        }
+
+        // Remove all tracked devices.
+        self.remove_all_devices();
+
+        Ok(())
+    }
+
+    fn process_event(&mut self, event: libudev::Event) {
         let path = event.device().devnode().map(
             |dn| dn.to_owned().into_os_string(),
         );
 
         match (event.event_type(), path) {
-            (EventType::Add, Some(path)) => Some(Event::Add(path)),
-            (EventType::Remove, Some(path)) => Some(Event::Remove(path)),
-            _ => None,
+            (EventType::Add, Some(path)) => {
+                self.add_device(path);
+            }
+            (EventType::Remove, Some(path)) => {
+                self.remove_device(path);
+            }
+            _ => { /* ignore other types and failures */ }
+        }
+    }
+
+    fn add_device(&mut self, path: OsString) {
+        let f = self.new_device_cb.clone();
+        let key = path.clone();
+
+        let runloop = RunLoop::new(move |alive| if alive() {
+            f(path, alive);
+        });
+
+        if let Ok(runloop) = runloop {
+            self.runloops.insert(key, runloop);
+        }
+    }
+
+    fn remove_device(&mut self, path: OsString) {
+        if let Some(runloop) = self.runloops.remove(&path) {
+            runloop.cancel();
+        }
+    }
+
+    fn remove_all_devices(&mut self) {
+        while !self.runloops.is_empty() {
+            let path = self.runloops.keys().next().unwrap().clone();
+            self.remove_device(path);
         }
     }
 }
-
-pub struct Monitor {
-    // Receive events from the thread.
-    rx: Receiver<Event>,
-    // Handle to the thread loop.
-    thread: RunLoop,
-}
-
-impl Monitor {
-    pub fn new() -> io::Result<Self> {
-        let (tx, rx) = channel();
-
-        let thread = RunLoop::new(move |alive| -> io::Result<()> {
-            let ctx = libudev::Context::new()?;
-            let mut enumerator = libudev::Enumerator::new(&ctx)?;
-            enumerator.match_subsystem(UDEV_SUBSYSTEM)?;
-
-            // Iterate all existing devices.
-            for dev in enumerator.scan_devices()? {
-                if let Some(path) = dev.devnode().map(|p| p.to_owned().into_os_string()) {
-                    tx.send(Event::Add(path)).map_err(to_io_err)?;
-                }
-            }
-
-            let mut monitor = libudev::Monitor::new(&ctx)?;
-            monitor.match_subsystem(UDEV_SUBSYSTEM)?;
-
-            // Start listening for new devices.
-            let mut socket = monitor.listen()?;
-            let mut fds = vec![
-                ::libc::pollfd {
-                    fd: socket.as_raw_fd(),
-                    events: POLLIN,
-                    revents: 0,
-                },
-            ];
-
-            // Loop until we're stopped by the controlling thread, or fail.
-            while alive() {
-                // Wait for new events, break on failure.
-                poll(&mut fds)?;
-
-                // Send the event over.
-                let udev_event = socket.receive_event();
-                if let Some(event) = udev_event.and_then(Event::from_udev) {
-                    tx.send(event).map_err(to_io_err)?;
-                }
-            }
-
-            Ok(())
-        })?;
-
-        Ok(Self { rx, thread })
-    }
-
-    pub fn events<'a>(&'a self) -> TryIter<'a, Event> {
-        self.rx.try_iter()
-    }
-
-    pub fn alive(&self) -> bool {
-        self.thread.alive()
-    }
-}
-
-impl Drop for Monitor {
-    fn drop(&mut self) {
-        self.thread.cancel();
-    }
-}
new file mode 100644
--- /dev/null
+++ b/dom/webauthn/u2f-hid-rs/src/linux/transaction.rs
@@ -0,0 +1,43 @@
+/* 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/. */
+
+use platform::monitor::Monitor;
+use runloop::RunLoop;
+use std::ffi::OsString;
+use std::io;
+use util::{io_err, OnceCallback};
+
+pub struct Transaction {
+    // Handle to the thread loop.
+    thread: Option<RunLoop>,
+}
+
+impl Transaction {
+    pub fn new<F, T>(timeout: u64, callback: OnceCallback<T>, new_device_cb: F) -> io::Result<Self>
+    where
+        F: Fn(OsString, &Fn() -> bool) + Sync + Send + 'static,
+        T: 'static,
+    {
+        let thread = RunLoop::new_with_timeout(
+            move |alive| {
+                // Create a new device monitor.
+                let mut monitor = Monitor::new(new_device_cb);
+
+                // Start polling for new devices.
+                try_or!(monitor.run(alive), |e| callback.call(Err(e)));
+
+                // Send an error, if the callback wasn't called already.
+                callback.call(Err(io_err("aborted or timed out")));
+            },
+            timeout,
+        )?;
+
+        Ok(Self { thread: Some(thread) })
+    }
+
+    pub fn cancel(&mut self) {
+        // This must never be None.
+        self.thread.take().unwrap().cancel();
+    }
+}
--- a/dom/webauthn/u2f-hid-rs/src/macos/mod.rs
+++ b/dom/webauthn/u2f-hid-rs/src/macos/mod.rs
@@ -45,17 +45,17 @@ impl PlatformManager {
             // Create a new device.
             let dev = &mut Device::new(device_ref, rx);
 
             // Try initializing it.
             if !u2f_init_device(dev) {
                 return;
             }
 
-            // Iterate the exlude list and see if there are any matches.
+            // Iterate the exclude list and see if there are any matches.
             // Abort the state machine if we found a valid key handle.
             if key_handles.iter().any(|key_handle| {
                 u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle)
                     .unwrap_or(false) /* no match on failure */
             })
             {
                 return;
             }
@@ -102,17 +102,17 @@ impl PlatformManager {
 
             // Find all matching key handles.
             let key_handles = key_handles
                 .iter()
                 .filter(|key_handle| {
                     u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle)
                         .unwrap_or(false) /* no match on failure */
                 })
-                .collect::<Vec<&Vec<u8>>>();
+                .collect::<Vec<_>>();
 
             while alive() {
                 // If the device matches none of the given key handles
                 // then just make it blink with bogus data.
                 if key_handles.is_empty() {
                     let blank = vec![0u8; PARAMETER_SIZE];
                     if let Ok(_) = u2f_register(dev, &blank, &blank) {
                         callback.call(Err(io_err("invalid key")));
--- a/dom/webidl/EventTarget.webidl
+++ b/dom/webidl/EventTarget.webidl
@@ -18,17 +18,18 @@ dictionary EventListenerOptions {
   boolean mozSystemGroup = false;
 };
 
 dictionary AddEventListenerOptions : EventListenerOptions {
   boolean passive = false;
   boolean once = false;
 };
 
-[Exposed=(Window,Worker,WorkerDebugger,System)]
+[Constructor,
+ Exposed=(Window,Worker,WorkerDebugger,System)]
 interface EventTarget {
   /* Passing null for wantsUntrusted means "default behavior", which
      differs in content and chrome.  In content that default boolean
      value is true, while in chrome the default boolean value is
      false. */
   [Throws]
   void addEventListener(DOMString type,
                         EventListener? listener,
--- a/dom/webidl/U2F.webidl
+++ b/dom/webidl/U2F.webidl
@@ -1,18 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is a combination of the FIDO U2F Raw Message Formats:
- * https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-raw-message-formats.html
- * and the U2F JavaScript API v1.1, not yet published. While v1.1 is not published,
- * v1.0, is located here:
- * https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-javascript-api.html
+ * https://www.fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
+ * and the U2F JavaScript API v1.1:
+ * https://www.fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-javascript-api-v1.1-id-20160915.html
  */
 
 [NoInterfaceObject]
 interface GlobalU2F {
   [Throws, Pref="security.webauth.u2f"]
   readonly attribute U2F u2f;
 };
 
--- a/dom/xbl/nsXBLMaybeCompiled.h
+++ b/dom/xbl/nsXBLMaybeCompiled.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXBLMaybeCompiled_h__
 #define nsXBLMaybeCompiled_h__
 
-#include "js/GCAPI.h"
+#include "js/RootingAPI.h"
 
 /*
  * A union containing either a pointer representing uncompiled source or a
  * JSObject* representing the compiled result.  The class is templated on the
  * source object type.
  *
  * The purpose of abstracting this as a separate class is to allow it to be
  * wrapped in a JS::Heap<T> to correctly handle post-barriering of the JSObject
--- a/gfx/layers/PaintThread.cpp
+++ b/gfx/layers/PaintThread.cpp
@@ -41,46 +41,62 @@ bool
 CapturedBufferState::Unrotate::UnrotateBuffer()
 {
   return mBuffer->UnrotateBufferTo(mParameters);
 }
 
 bool
 CapturedBufferState::PrepareBuffer()
 {
-  return (!mBufferCopy || mBufferCopy->CopyBuffer()) &&
-         (!mBufferUnrotate || mBufferUnrotate->UnrotateBuffer());
+  return (!mBufferFinalize || mBufferFinalize->CopyBuffer()) &&
+         (!mBufferUnrotate || mBufferUnrotate->UnrotateBuffer()) &&
+         (!mBufferInitialize || mBufferInitialize->CopyBuffer());
 }
 
 void
 CapturedBufferState::GetTextureClients(nsTArray<RefPtr<TextureClient>>& aTextureClients)
 {
-  if (mBufferCopy) {
-    if (TextureClient* source = mBufferCopy->mSource->GetClient()) {
+  if (mBufferFinalize) {
+    if (TextureClient* source = mBufferFinalize->mSource->GetClient()) {
       aTextureClients.AppendElement(source);
     }
-    if (TextureClient* sourceOnWhite = mBufferCopy->mSource->GetClientOnWhite()) {
+    if (TextureClient* sourceOnWhite = mBufferFinalize->mSource->GetClientOnWhite()) {
       aTextureClients.AppendElement(sourceOnWhite);
     }
-    if (TextureClient* destination = mBufferCopy->mDestination->GetClient()) {
+    if (TextureClient* destination = mBufferFinalize->mDestination->GetClient()) {
       aTextureClients.AppendElement(destination);
     }
-    if (TextureClient* destinationOnWhite = mBufferCopy->mDestination->GetClientOnWhite()) {
+    if (TextureClient* destinationOnWhite = mBufferFinalize->mDestination->GetClientOnWhite()) {
       aTextureClients.AppendElement(destinationOnWhite);
     }
   }
 
   if (mBufferUnrotate) {
     if (TextureClient* client = mBufferUnrotate->mBuffer->GetClient()) {
       aTextureClients.AppendElement(client);
     }
     if (TextureClient* clientOnWhite = mBufferUnrotate->mBuffer->GetClientOnWhite()) {
       aTextureClients.AppendElement(clientOnWhite);
     }
   }
+
+  if (mBufferInitialize) {
+    if (TextureClient* source = mBufferInitialize->mSource->GetClient()) {
+      aTextureClients.AppendElement(source);
+    }
+    if (TextureClient* sourceOnWhite = mBufferInitialize->mSource->GetClientOnWhite()) {
+      aTextureClients.AppendElement(sourceOnWhite);
+    }
+    if (TextureClient* destination = mBufferInitialize->mDestination->GetClient()) {
+      aTextureClients.AppendElement(destination);
+    }
+    if (TextureClient* destinationOnWhite = mBufferInitialize->mDestination->GetClientOnWhite()) {
+      aTextureClients.AppendElement(destinationOnWhite);
+    }
+  }
 }
 
 StaticAutoPtr<PaintThread> PaintThread::sSingleton;
 StaticRefPtr<nsIThread> PaintThread::sThread;
 PlatformThreadId PaintThread::sThreadId;
 
 // RAII make sure we clean up and restore our draw targets
 // when we paint async.
--- a/gfx/layers/PaintThread.h
+++ b/gfx/layers/PaintThread.h
@@ -97,18 +97,19 @@ public:
    * Prepares the rotated buffers for painting by copying a previous frame
    * into the buffer and/or unrotating the pixels and returns whether the
    * operations were successful. If this fails a new buffer should be created
    * for the frame.
    */
   bool PrepareBuffer();
   void GetTextureClients(nsTArray<RefPtr<TextureClient>>& aTextureClients);
 
-  Maybe<Copy> mBufferCopy;
+  Maybe<Copy> mBufferFinalize;
   Maybe<Unrotate> mBufferUnrotate;
+  Maybe<Copy> mBufferInitialize;
 
 protected:
   ~CapturedBufferState() {}
 };
 
 typedef bool (*PrepDrawTargetForPaintingCallback)(CapturedPaintState* aPaintState);
 
 class CompositorBridgeChild;
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -155,72 +155,84 @@ ContentClient::BeginPaint(PaintedLayer* 
                          !(aLayer->Manager()->AsWebRenderLayerManager());
   bool canDrawRotated = aFlags & PAINT_CAN_DRAW_ROTATED;
   bool asyncPaint = (aFlags & PAINT_ASYNC);
 
   IntRect drawBounds = result.mRegionToDraw.GetBounds();
   OpenMode lockMode = asyncPaint ? OpenMode::OPEN_READ_ASYNC_WRITE
                                  : OpenMode::OPEN_READ_WRITE;
 
+  if (asyncPaint) {
+    result.mBufferState = new CapturedBufferState();
+  }
+
+  if (mBuffer) {
+    if (mBuffer->Lock(lockMode)) {
+      // Do not modify result.mRegionToDraw or result.mContentType after this call.
+      Maybe<CapturedBufferState::Copy> bufferFinalize =
+        FinalizeFrame(result.mRegionToDraw);
+
+      if (asyncPaint) {
+        result.mBufferState->mBufferFinalize = Move(bufferFinalize);
+      } else if (bufferFinalize) {
+        bufferFinalize->CopyBuffer();
+      }
+    } else {
+      result.mRegionToDraw = dest.mNeededRegion;
+      dest.mCanReuseBuffer = false;
+      Clear();
+    }
+  }
+
   if (dest.mCanReuseBuffer) {
     MOZ_ASSERT(mBuffer);
 
     bool canReuseBuffer = false;
 
-    if (mBuffer->Lock(lockMode)) {
-      RefPtr<CapturedBufferState> bufferState = new CapturedBufferState();
-
-      // Do not modify result.mRegionToDraw or result.mContentType after this call.
-      FinalizeFrame(result.mRegionToDraw, bufferState);
-
-      auto newParameters = mBuffer->AdjustedParameters(dest.mBufferRect);
+    auto newParameters = mBuffer->AdjustedParameters(dest.mBufferRect);
+    Maybe<CapturedBufferState::Unrotate> bufferUnrotate = Nothing();
 
-      if ((!canHaveRotation && newParameters.IsRotated()) ||
-          (!canDrawRotated && newParameters.RectWrapsBuffer(drawBounds))) {
-        bufferState->mBufferUnrotate = Some(CapturedBufferState::Unrotate {
-          newParameters,
-          mBuffer->ShallowCopy(),
-        });
-      }
+    if ((!canHaveRotation && newParameters.IsRotated()) ||
+        (!canDrawRotated && newParameters.RectWrapsBuffer(drawBounds))) {
+      bufferUnrotate = Some(CapturedBufferState::Unrotate {
+        newParameters,
+        mBuffer->ShallowCopy(),
+      });
+    }
 
-      // If we're async painting then return the buffer state to
-      // be dispatched to the paint thread, otherwise do it now
-      if (asyncPaint) {
-        // We cannot do a buffer unrotate if the buffer is already rotated
-        // and we're async painting as that may fail
-        if (!bufferState->mBufferUnrotate ||
-            mBuffer->BufferRotation() == IntPoint(0,0)) {
-          result.mBufferState = bufferState;
+    // If we're async painting then return the buffer state to
+    // be dispatched to the paint thread, otherwise do it now
+    if (asyncPaint) {
+      // We cannot do a buffer unrotate if the buffer is already rotated
+      // and we're async painting as that may fail
+      if (!bufferUnrotate ||
+          mBuffer->BufferRotation() == IntPoint(0,0)) {
+        result.mBufferState->mBufferUnrotate = Move(bufferUnrotate);
 
-          // We can then assume that preparing the buffer will always
-          // succeed and update our parameters unconditionally
-          if (bufferState->mBufferUnrotate) {
-            newParameters.SetUnrotated();
-          }
-          mBuffer->SetParameters(newParameters);
-          canReuseBuffer = true;
+        // We can then assume that preparing the buffer will always
+        // succeed and update our parameters unconditionally
+        if (result.mBufferState->mBufferUnrotate) {
+          newParameters.SetUnrotated();
         }
-      } else {
-        if (bufferState->PrepareBuffer()) {
-          if (bufferState->mBufferUnrotate) {
-            newParameters.SetUnrotated();
-          }
-          mBuffer->SetParameters(newParameters);
-          canReuseBuffer = true;
+        mBuffer->SetParameters(newParameters);
+        canReuseBuffer = true;
+      }
+    } else {
+      if (!bufferUnrotate || bufferUnrotate->UnrotateBuffer()) {
+        if (bufferUnrotate) {
+          newParameters.SetUnrotated();
         }
+        mBuffer->SetParameters(newParameters);
+        canReuseBuffer = true;
       }
     }
 
     if (!canReuseBuffer) {
-      if (mBuffer->IsLocked()) {
-        mBuffer->Unlock();
-      }
       dest.mBufferRect = ComputeBufferRect(dest.mNeededRegion.GetBounds());
       dest.mCanReuseBuffer = false;
-      dest.mMustRemoveFrontBuffer = true;
     }
   }
 
   NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || dest.mBufferRect == dest.mNeededRegion.GetBounds(),
                "If we're resampling, we need to validate the entire buffer");
 
   // We never had a buffer, the buffer wasn't big enough, the content changed
   // types, or we failed to unrotate the buffer when requested. In any case,
@@ -238,56 +250,56 @@ ContentClient::BeginPaint(PaintedLayer* 
     if (!newBuffer) {
       if (Factory::ReasonableSurfaceSize(IntSize(dest.mBufferRect.Width(), dest.mBufferRect.Height()))) {
         gfxCriticalNote << "Failed buffer for "
                         << dest.mBufferRect.x << ", "
                         << dest.mBufferRect.y << ", "
                         << dest.mBufferRect.Width() << ", "
                         << dest.mBufferRect.Height();
       }
+      Clear();
       return result;
     }
 
     if (!newBuffer->Lock(lockMode)) {
       gfxCriticalNote << "Failed to lock new back buffer.";
+      Clear();
       return result;
     }
 
     // If we have an existing front buffer, copy it into the new back buffer
-    if (RefPtr<RotatedBuffer> frontBuffer = GetFrontBuffer()) {
+    if (mBuffer) {
+      if (mBuffer->IsLocked()) {
+        mBuffer->Unlock();
+      }
+
       nsIntRegion updateRegion = newBuffer->BufferRect();
       updateRegion.Sub(updateRegion, result.mRegionToDraw);
 
       if (!updateRegion.IsEmpty()) {
-        RefPtr<CapturedBufferState> bufferState = new CapturedBufferState();
-
-        bufferState->mBufferCopy = Some(CapturedBufferState::Copy {
-          frontBuffer->ShallowCopy(),
+        auto bufferInitialize = CapturedBufferState::Copy {
+          mBuffer->ShallowCopy(),
           newBuffer->ShallowCopy(),
           updateRegion.GetBounds(),
-        });
+        };
 
         // If we're async painting then return the buffer state to
         // be dispatched to the paint thread, otherwise do it now
         if (asyncPaint) {
-          MOZ_ASSERT(!result.mBufferState);
-          result.mBufferState = bufferState;
+          result.mBufferState->mBufferInitialize = Some(Move(bufferInitialize));
         } else {
-          if (!bufferState->PrepareBuffer()) {
+          if (!bufferInitialize.CopyBuffer()) {
             gfxCriticalNote << "Failed to copy front buffer to back buffer.";
             return result;
           }
         }
       }
-
-      if (dest.mMustRemoveFrontBuffer) {
-        Clear();
-      }
     }
 
+    Clear();
     mBuffer = newBuffer;
   }
 
   NS_ASSERTION(canHaveRotation || mBuffer->BufferRotation() == IntPoint(0,0),
                "Rotation disabled, but we have nonzero rotation?");
 
   nsIntRegion invalidate;
   invalidate.Sub(aLayer->GetValidRegion(), dest.mBufferRect);
@@ -414,27 +426,24 @@ ContentClient::PrepareDrawTargetForPaint
 ContentClient::BufferDecision
 ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
                                        uint32_t aFlags)
 {
   gfxContentType layerContentType =
     aLayer->CanUseOpaqueSurface() ? gfxContentType::COLOR :
                                     gfxContentType::COLOR_ALPHA;
 
-  RefPtr<RotatedBuffer> frontBuffer = GetFrontBuffer();
-
   SurfaceMode mode;
   gfxContentType contentType;
   IntRect destBufferRect;
   nsIntRegion neededRegion;
   nsIntRegion validRegion = aLayer->GetValidRegion();
 
   bool canReuseBuffer = !!mBuffer;
   bool canKeepBufferContents = true;
-  bool mustRemoveFrontBuffer = false;
 
   while (true) {
     mode = aLayer->GetSurfaceMode();
     neededRegion = aLayer->GetVisibleRegion().ToUnknownRegion();
     canReuseBuffer = canReuseBuffer && ValidBufferSize(mBufferSizePolicy,
                                                        mBuffer->BufferRect().Size(),
                                                        neededRegion.GetBounds().Size());
     contentType = layerContentType;
@@ -446,32 +455,17 @@ ContentClient::CalculateBufferForPaint(P
       } else if (neededRegion.GetBounds().Size() <= mBuffer->BufferRect().Size()) {
         // The buffer's big enough but doesn't contain everything that's
         // going to be visible. We'll move it.
         destBufferRect = IntRect(neededRegion.GetBounds().TopLeft(), mBuffer->BufferRect().Size());
       } else {
         destBufferRect = neededRegion.GetBounds();
       }
     } else {
-      // We won't be reusing the buffer. Compute a new rect.
-      if (frontBuffer) {
-        // We must create a buffer that is the same size as the front buffer,
-        // or else we need to remove the front buffer
-        if (ValidBufferSize(mBufferSizePolicy,
-                            frontBuffer->BufferRect().Size(),
-                            neededRegion.GetBounds().Size())) {
-          destBufferRect = frontBuffer->BufferRect();
-          destBufferRect.MoveTo(neededRegion.GetBounds().TopLeft());
-        } else {
-          destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
-          mustRemoveFrontBuffer = true;
-        }
-      } else {
-        destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
-      }
+      destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
     }
 
     if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
 #if defined(MOZ_GFX_OPTIMIZE_MOBILE)
       mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
 #else
       if (!aLayer->GetParent() ||
           !aLayer->GetParent()->SupportsComponentAlphaChildren() ||
@@ -501,67 +495,49 @@ ContentClient::CalculateBufferForPaint(P
 
     // If we have an existing buffer, but the content type has changed or we
     // have transitioned into/out of component alpha, then we need to recreate it.
     bool needsComponentAlpha = (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA);
     bool backBufferChangedSurface = mBuffer &&
                                     (contentType != mBuffer->GetContentType() ||
                                      needsComponentAlpha != mBuffer->HaveBufferOnWhite());
     if (canKeepBufferContents && backBufferChangedSurface) {
-      // We cannot reuse the back buffer if the surface type or content type
-      // changed. We may have to also invalidate, but only if the front buffer
-      // also changed.
-      canReuseBuffer = false;
-    }
-    bool frontBufferChangedSurface = frontBuffer &&
-                                     (contentType != frontBuffer->GetContentType() ||
-                                      needsComponentAlpha != frontBuffer->HaveBufferOnWhite());
-    if (canKeepBufferContents && frontBufferChangedSurface) {
       // Restart the decision process; we won't re-enter since we guard on
       // being able to keep the buffer contents.
       canReuseBuffer = false;
       canKeepBufferContents = false;
       validRegion.SetEmpty();
-      continue;
     }
-
     break;
   }
 
   NS_ASSERTION(destBufferRect.Contains(neededRegion.GetBounds()),
                "Destination rect doesn't contain what we need to paint");
 
   BufferDecision dest;
   dest.mNeededRegion = Move(neededRegion);
   dest.mValidRegion = Move(validRegion);
   dest.mBufferRect = destBufferRect;
   dest.mBufferMode = mode;
   dest.mBufferContentType = contentType;
   dest.mCanReuseBuffer = canReuseBuffer;
   dest.mCanKeepBufferContents = canKeepBufferContents;
-  dest.mMustRemoveFrontBuffer = mustRemoveFrontBuffer;
   return dest;
 }
 
 bool
 ContentClient::ValidBufferSize(BufferSizePolicy aPolicy,
                                const gfx::IntSize& aBufferSize,
                                const gfx::IntSize& aVisibleBoundsSize)
 {
   return (aVisibleBoundsSize == aBufferSize ||
           (SizedToVisibleBounds != aPolicy &&
            aVisibleBoundsSize < aBufferSize));
 }
 
-RefPtr<RotatedBuffer>
-ContentClient::GetFrontBuffer() const
-{
-  return mBuffer;
-}
-
 void
 ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("ContentClient (0x%p)", this).get();
 }
 
 // We pass a null pointer for the ContentClient Forwarder argument, which means
@@ -914,85 +890,96 @@ ContentClientDoubleBuffered::SwapBuffers
 
   mFrontAndBackBufferDiffer = true;
 }
 
 ContentClient::PaintState
 ContentClientDoubleBuffered::BeginPaint(PaintedLayer* aLayer,
                                         uint32_t aFlags)
 {
+  EnsureBackBufferIfFrontBuffer();
+
   mIsNewBuffer = false;
+
   if (!mFrontBuffer || !mBuffer) {
     mFrontAndBackBufferDiffer = false;
   }
 
-  return ContentClient::BeginPaint(aLayer, aFlags);
-}
+  if (mFrontAndBackBufferDiffer) {
+    if (mFrontBuffer->DidSelfCopy()) {
+      // We can't easily draw our front buffer into us, since we're going to be
+      // copying stuff around anyway it's easiest if we just move our situation
+      // to non-rotated while we're at it. If this situation occurs we'll have
+      // hit a self-copy path in PaintThebes before as well anyway.
+      gfx::IntRect backBufferRect = mBuffer->BufferRect();
+      backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
 
-RefPtr<RotatedBuffer>
-ContentClientDoubleBuffered::GetFrontBuffer() const
-{
-  return mFrontBuffer;
+      mBuffer->SetBufferRect(backBufferRect);
+      mBuffer->SetBufferRotation(IntPoint(0,0));
+    } else {
+      mBuffer->SetBufferRect(mFrontBuffer->BufferRect());
+      mBuffer->SetBufferRotation(mFrontBuffer->BufferRotation());
+    }
+  }
+
+  return ContentClient::BeginPaint(aLayer, aFlags);
 }
 
 // Sync front/back buffers content
 // After executing, the new back buffer has the same (interesting) pixels as
 // the new front buffer, and mValidRegion et al. are correct wrt the new
 // back buffer (i.e. as they were for the old back buffer)
-void
-ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw,
-                                           CapturedBufferState* aPrepareState)
+Maybe<CapturedBufferState::Copy>
+ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
 {
   if (!mFrontAndBackBufferDiffer) {
     MOZ_ASSERT(!mFrontBuffer || !mFrontBuffer->DidSelfCopy(),
                "If the front buffer did a self copy then our front and back buffer must be different.");
-    return;
+    return Nothing();
   }
 
   MOZ_ASSERT(mFrontBuffer && mBuffer);
   if (!mFrontBuffer || !mBuffer) {
-    return;
+    return Nothing();
   }
 
   MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>",
                   this,
                   mFrontUpdatedRegion.GetBounds().x,
                   mFrontUpdatedRegion.GetBounds().y,
                   mFrontUpdatedRegion.GetBounds().Width(),
                   mFrontUpdatedRegion.GetBounds().Height()));
 
   mFrontAndBackBufferDiffer = false;
 
-  // Move the back buffer rect and rotation to the front buffer rect and rotation
-  // so that we can update the pixels that changed between frames
-  gfx::IntRect backBufferRect = mBuffer->BufferRect();
-  backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
-  mBuffer->SetBufferRect(backBufferRect);
-  mBuffer->SetBufferRotation(mFrontBuffer->BufferRotation());
-
-  // Calculate the region to update
   nsIntRegion updateRegion = mFrontUpdatedRegion;
   if (mFrontBuffer->DidSelfCopy()) {
-    // If we did an unrotate operation on the front buffer we might as well
-    // unrotate as well because we will be reading back the whole front buffer
-    mBuffer->SetBufferRotation(IntPoint(0,0));
-
     mFrontBuffer->ClearDidSelfCopy();
     updateRegion = mBuffer->BufferRect();
   }
 
   // No point in sync'ing what we are going to draw over anyway. And if there is
   // nothing to sync at all, there is nothing to do and we can go home early.
   updateRegion.Sub(updateRegion, aRegionToDraw);
   if (updateRegion.IsEmpty()) {
-    return;
+    return Nothing();
   }
 
-  MOZ_ASSERT(!aPrepareState->mBufferCopy);
-  aPrepareState->mBufferCopy = Some(CapturedBufferState::Copy {
+  return Some(CapturedBufferState::Copy {
     mFrontBuffer->ShallowCopy(),
     mBuffer->ShallowCopy(),
     updateRegion.GetBounds(),
   });
 }
 
+void
+ContentClientDoubleBuffered::EnsureBackBufferIfFrontBuffer()
+{
+  if (!mBuffer && mFrontBuffer) {
+    mBuffer = CreateBufferInternal(mFrontBuffer->BufferRect(),
+                                   mFrontBuffer->GetFormat(),
+                                   mTextureFlags);
+    MOZ_ASSERT(mBuffer);
+  }
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -193,42 +193,40 @@ protected:
   struct BufferDecision {
     nsIntRegion mNeededRegion;
     nsIntRegion mValidRegion;
     gfx::IntRect mBufferRect;
     SurfaceMode mBufferMode;
     gfxContentType mBufferContentType;
     bool mCanReuseBuffer;
     bool mCanKeepBufferContents;
-    bool mMustRemoveFrontBuffer;
   };
 
   /**
    * Decide whether we can keep our current buffer and its contents,
    * and return a struct containing the regions to paint, invalidate,
    * the new buffer rect, surface mode, and content type.
    */
   BufferDecision CalculateBufferForPaint(PaintedLayer* aLayer,
                                          uint32_t aFlags);
 
   static bool ValidBufferSize(BufferSizePolicy aPolicy,
                               const gfx::IntSize& aBufferSize,
                               const gfx::IntSize& aVisibleBoundsSize);
 
-  virtual RefPtr<RotatedBuffer> GetFrontBuffer() const;
-
   /**
    * Any actions that should be performed at the last moment before we begin
    * rendering the next frame. I.e., after we calculate what we will draw,
    * but before we rotate the buffer and possibly create new buffers.
    * aRegionToDraw is the region which is guaranteed to be overwritten when
    * drawing the next frame.
    */
-  virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw,
-                             CapturedBufferState* aState) {}
+  virtual Maybe<CapturedBufferState::Copy> FinalizeFrame(const nsIntRegion& aRegionToDraw) {
+    return Nothing();
+  }
 
   /**
    * Create a new rotated buffer for the specified content type, buffer rect,
    * and buffer flags.
    */
   virtual RefPtr<RotatedBuffer> CreateBuffer(gfxContentType aType,
                                              const gfx::IntRect& aRect,
                                              uint32_t aFlags) = 0;
@@ -361,27 +359,26 @@ public:
                     TextureDumpMode aCompress=TextureDumpMode::Compress) override;
 
   virtual void Clear() override;
 
   virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) override;
 
   virtual PaintState BeginPaint(PaintedLayer* aLayer, uint32_t aFlags) override;
 
-  virtual RefPtr<RotatedBuffer> GetFrontBuffer() const override;
-
-  virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw,
-                             CapturedBufferState* aState) override;
+  virtual Maybe<CapturedBufferState::Copy> FinalizeFrame(const nsIntRegion& aRegionToDraw) override;
 
   virtual TextureInfo GetTextureInfo() const override
   {
     return TextureInfo(CompositableType::CONTENT_DOUBLE, mTextureFlags);
   }
 
 private:
+  void EnsureBackBufferIfFrontBuffer();
+
   RefPtr<RemoteRotatedBuffer> mFrontBuffer;
   nsIntRegion mFrontUpdatedRegion;
   bool mFrontAndBackBufferDiffer;
 };
 
 /**
  * A single buffered ContentClientRemoteBuffer. We have a single
  * TextureClient/Host which we update and then send a message to the
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -480,18 +480,21 @@ WebRenderCommandBuilder::GenerateFallbac
 
   RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
 
   bool snap;
   nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
 
   // Blob images will only draw the visible area of the blob so we don't need to clip
   // them here and can just rely on the webrender clipping.
+  // TODO We also don't clip native themed widget to avoid over-invalidation during scrolling.
+  // it would be better to support a sort of straming/tiling scheme for large ones but the hope
+  // is that we should not have large native themed items.
   nsRect paintBounds = itemBounds;
-  if (useBlobImage) {
+  if (useBlobImage || aItem->MustPaintOnContentSide()) {
     paintBounds = itemBounds;
   } else {
     paintBounds = aItem->GetClippedBounds(aDisplayListBuilder);
   }
 
   // nsDisplayItem::Paint() may refer the variables that come from ComputeVisibility().
   // So we should call ComputeVisibility() before painting. e.g.: nsDisplayBoxShadowInner
   // uses mVisibleRegion in Paint() and mVisibleRegion is computed in
--- a/gfx/webrender_bindings/Moz2DImageRenderer.cpp
+++ b/gfx/webrender_bindings/Moz2DImageRenderer.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxUtils.h"
+#include "mozilla/Mutex.h"
 #include "mozilla/Range.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/InlineTranslator.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/RecordedEvent.h"
 #include "WebRenderTypes.h"
 #include "webrender_ffi.h"
 
@@ -46,34 +47,37 @@ namespace wr {
 struct FontTemplate {
   const uint8_t *mData;
   size_t mSize;
   uint32_t mIndex;
   const VecU8 *mVec;
   RefPtr<UnscaledFont> mUnscaledFont;
 };
 
+StaticMutex sFontDataTableLock;
 std::unordered_map<FontKey, FontTemplate> sFontDataTable;
 
 extern "C" {
 void
 AddFontData(WrFontKey aKey, const uint8_t *aData, size_t aSize, uint32_t aIndex, const ArcVecU8 *aVec) {
+  StaticMutexAutoLock lock(sFontDataTableLock);
   auto i = sFontDataTable.find(aKey);
   if (i == sFontDataTable.end()) {
     FontTemplate font;
     font.mData = aData;
     font.mSize = aSize;
     font.mIndex = aIndex;
     font.mVec = wr_add_ref_arc(aVec);
     sFontDataTable[aKey] = font;
   }
 }
 
 void
 AddNativeFontHandle(WrFontKey aKey, void* aHandle, uint32_t aIndex) {
+  StaticMutexAutoLock lock(sFontDataTableLock);
   auto i = sFontDataTable.find(aKey);
   if (i == sFontDataTable.end()) {
     FontTemplate font;
     font.mData = nullptr;
     font.mSize = 0;
     font.mIndex = 0;
     font.mVec = nullptr;
 #ifdef XP_MACOSX
@@ -86,30 +90,36 @@ AddNativeFontHandle(WrFontKey aKey, void
     font.mUnscaledFont = new UnscaledFontFontconfig(reinterpret_cast<const char*>(aHandle), aIndex);
 #endif
     sFontDataTable[aKey] = font;
   }
 }
 
 void
 DeleteFontData(WrFontKey aKey) {
+  StaticMutexAutoLock lock(sFontDataTableLock);
   auto i = sFontDataTable.find(aKey);
   if (i != sFontDataTable.end()) {
     if (i->second.mVec) {
       wr_dec_ref_arc(i->second.mVec);
     }
     sFontDataTable.erase(i);
   }
 }
 }
 
 RefPtr<UnscaledFont>
 GetUnscaledFont(Translator *aTranslator, wr::FontKey key) {
-  MOZ_ASSERT(sFontDataTable.find(key) != sFontDataTable.end());
-  auto &data = sFontDataTable[key];
+  StaticMutexAutoLock lock(sFontDataTableLock);
+  auto i = sFontDataTable.find(key);
+  if (i == sFontDataTable.end()) {
+    gfxDevCrash(LogReason::UnscaledFontNotFound) << "Failed to get UnscaledFont entry for FontKey " << key.mHandle;
+    return nullptr;
+  }
+  auto &data = i->second;
   if (data.mUnscaledFont) {
     return data.mUnscaledFont;
   }
   MOZ_ASSERT(data.mData);
   FontType type =
 #ifdef XP_MACOSX
     FontType::MAC;
 #elif defined(XP_WIN)
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -467,24 +467,16 @@ typedef bool
  * Finalize obj, which the garbage collector has determined to be unreachable
  * from other live objects or from GC roots.  Obviously, finalizers must never
  * store a reference to obj.
  */
 typedef void
 (* JSFinalizeOp)(JSFreeOp* fop, JSObject* obj);
 
 /**
- * Finalizes external strings created by JS_NewExternalString. The finalizer
- * can be called off the main thread.
- */
-struct JSStringFinalizer {
-    void (*finalize)(const JSStringFinalizer* fin, char16_t* chars);
-};
-
-/**
  * Check whether v is an instance of obj.  Return false on error or exception,
  * true on success with true in *bp if v is an instance of obj, false in
  * *bp otherwise.
  */
 typedef bool
 (* JSHasInstanceOp)(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp,
                     bool* bp);
 
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -1,25 +1,46 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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/. */
 
+/*
+ * High-level interface to the JS garbage collector.
+ */
+
 #ifndef js_GCAPI_h
 #define js_GCAPI_h
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Vector.h"
 
 #include "js/GCAnnotations.h"
-#include "js/HeapAPI.h"
 #include "js/UniquePtr.h"
 #include "js/Utility.h"
 
+struct JSCompartment;
+struct JSContext;
+struct JSFreeOp;
+class JSObject;
+struct JSRuntime;
+class JSString;
+
+#ifdef JS_BROKEN_GCC_ATTRIBUTE_WARNING
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif // JS_BROKEN_GCC_ATTRIBUTE_WARNING
+
+class JS_PUBLIC_API(JSTracer);
+
+#ifdef JS_BROKEN_GCC_ATTRIBUTE_WARNING
+#pragma GCC diagnostic pop
+#endif // JS_BROKEN_GCC_ATTRIBUTE_WARNING
+
 namespace js {
 namespace gc {
 class GCRuntime;
 } // namespace gc
 namespace gcstats {
 struct Statistics;
 } // namespace gcstats
 } // namespace js
@@ -44,18 +65,282 @@ typedef enum JSGCMode {
 typedef enum JSGCInvocationKind {
     /* Normal invocation. */
     GC_NORMAL = 0,
 
     /* Minimize GC triggers and release empty GC chunks right away. */
     GC_SHRINK = 1
 } JSGCInvocationKind;
 
+typedef enum JSGCParamKey {
+    /**
+     * Maximum nominal heap before last ditch GC.
+     *
+     * Soft limit on the number of bytes we are allowed to allocate in the GC
+     * heap. Attempts to allocate gcthings over this limit will return null and
+     * subsequently invoke the standard OOM machinery, independent of available
+     * physical memory.
+     *
+     * Pref: javascript.options.mem.max
+     * Default: 0xffffffff
+     */
+    JSGC_MAX_BYTES          = 0,
+
+    /**
+     * Initial value for the malloc bytes threshold.
+     *
+     * Pref: javascript.options.mem.high_water_mark
+     * Default: TuningDefaults::MaxMallocBytes
+     */
+    JSGC_MAX_MALLOC_BYTES   = 1,
+
+    /**
+     * Maximum size of the generational GC nurseries.
+     *
+     * Pref: javascript.options.mem.nursery.max_kb
+     * Default: JS::DefaultNurseryBytes
+     */
+    JSGC_MAX_NURSERY_BYTES  = 2,
+
+    /** Amount of bytes allocated by the GC. */
+    JSGC_BYTES = 3,
+
+    /** Number of times GC has been invoked. Includes both major and minor GC. */
+    JSGC_NUMBER = 4,
+
+    /**
+     * Select GC mode.
+     *
+     * See: JSGCMode in GCAPI.h
+     * prefs: javascript.options.mem.gc_per_zone and
+     *   javascript.options.mem.gc_incremental.
+     * Default: JSGC_MODE_INCREMENTAL
+     */
+    JSGC_MODE = 6,
+
+    /** Number of cached empty GC chunks. */
+    JSGC_UNUSED_CHUNKS = 7,
+
+    /** Total number of allocated GC chunks. */
+    JSGC_TOTAL_CHUNKS = 8,
+
+    /**
+     * Max milliseconds to spend in an incremental GC slice.
+     *
+     * Pref: javascript.options.mem.gc_incremental_slice_ms
+     * Default: DefaultTimeBudget.
+     */
+    JSGC_SLICE_TIME_BUDGET = 9,
+
+    /**
+     * Maximum size the GC mark stack can grow to.
+     *
+     * Pref: none
+     * Default: MarkStack::DefaultCapacity
+     */
+    JSGC_MARK_STACK_LIMIT = 10,
+
+    /**
+     * GCs less than this far apart in time will be considered 'high-frequency
+     * GCs'.
+     *
+     * See setGCLastBytes in jsgc.cpp.
+     *
+     * Pref: javascript.options.mem.gc_high_frequency_time_limit_ms
+     * Default: HighFrequencyThresholdUsec
+     */
+    JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
+
+    /**
+     * Start of dynamic heap growth.
+     *
+     * Pref: javascript.options.mem.gc_high_frequency_low_limit_mb
+     * Default: HighFrequencyLowLimitBytes
+     */
+    JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
+
+    /**
+     * End of dynamic heap growth.
+     *
+     * Pref: javascript.options.mem.gc_high_frequency_high_limit_mb
+     * Default: HighFrequencyHighLimitBytes
+     */
+    JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
+
+    /**
+     * Upper bound of heap growth.
+     *
+     * Pref: javascript.options.mem.gc_high_frequency_heap_growth_max
+     * Default: HighFrequencyHeapGrowthMax
+     */
+    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
+
+    /**
+     * Lower bound of heap growth.
+     *
+     * Pref: javascript.options.mem.gc_high_frequency_heap_growth_min
+     * Default: HighFrequencyHeapGrowthMin
+     */
+    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
+
+    /**
+     * Heap growth for low frequency GCs.
+     *
+     * Pref: javascript.options.mem.gc_low_frequency_heap_growth
+     * Default: LowFrequencyHeapGrowth
+     */
+    JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
+
+    /**
+     * If false, the heap growth factor is fixed at 3. If true, it is determined
+     * based on whether GCs are high- or low- frequency.
+     *
+     * Pref: javascript.options.mem.gc_dynamic_heap_growth
+     * Default: DynamicHeapGrowthEnabled
+     */
+    JSGC_DYNAMIC_HEAP_GROWTH = 17,
+
+    /**
+     * If true, high-frequency GCs will use a longer mark slice.
+     *
+     * Pref: javascript.options.mem.gc_dynamic_mark_slice
+     * Default: DynamicMarkSliceEnabled
+     */
+    JSGC_DYNAMIC_MARK_SLICE = 18,
+
+    /**
+     * Lower limit after which we limit the heap growth.
+     *
+     * The base value used to compute zone->threshold.gcTriggerBytes(). When
+     * usage.gcBytes() surpasses threshold.gcTriggerBytes() for a zone, the
+     * zone may be scheduled for a GC, depending on the exact circumstances.
+     *
+     * Pref: javascript.options.mem.gc_allocation_threshold_mb
+     * Default GCZoneAllocThresholdBase
+     */
+    JSGC_ALLOCATION_THRESHOLD = 19,
+
+    /**
+     * We try to keep at least this many unused chunks in the free chunk pool at
+     * all times, even after a shrinking GC.
+     *
+     * Pref: javascript.options.mem.gc_min_empty_chunk_count
+     * Default: MinEmptyChunkCount
+     */
+    JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
+
+    /**
+     * We never keep more than this many unused chunks in the free chunk
+     * pool.
+     *
+     * Pref: javascript.options.mem.gc_min_empty_chunk_count
+     * Default: MinEmptyChunkCount
+     */
+    JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
+
+    /**
+     * Whether compacting GC is enabled.
+     *
+     * Pref: javascript.options.mem.gc_compacting
+     * Default: CompactingEnabled
+     */
+    JSGC_COMPACTING_ENABLED = 23,
+
+    /**
+     * If true, painting can trigger IGC slices.
+     *
+     * Pref: javascript.options.mem.gc_refresh_frame_slices_enabled
+     * Default: RefreshFrameSlicesEnabled
+     */
+    JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
+
+    /**
+     * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD
+     *
+     * Default: ZoneAllocThresholdFactorDefault
+     * Pref: None
+     */
+    JSGC_ALLOCATION_THRESHOLD_FACTOR = 25,
+
+    /**
+     * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD.
+     * Used if another GC (in different zones) is already running.
+     *
+     * Default: ZoneAllocThresholdFactorAvoidInterruptDefault
+     * Pref: None
+     */
+    JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT = 26,
+} JSGCParamKey;
+
+/*
+ * Generic trace operation that calls JS::TraceEdge on each traceable thing's
+ * location reachable from data.
+ */
+typedef void
+(* JSTraceDataOp)(JSTracer* trc, void* data);
+
+typedef enum JSGCStatus {
+    JSGC_BEGIN,
+    JSGC_END
+} JSGCStatus;
+
+typedef void
+(* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data);
+
+typedef void
+(* JSObjectsTenuredCallback)(JSContext* cx, void* data);
+
+typedef enum JSFinalizeStatus {
+    /**
+     * Called when preparing to sweep a group of zones, before anything has been
+     * swept.  The collector will not yield to the mutator before calling the
+     * callback with JSFINALIZE_GROUP_START status.
+     */
+    JSFINALIZE_GROUP_PREPARE,
+
+    /**
+     * Called after preparing to sweep a group of zones. Weak references to
+     * unmarked things have been removed at this point, but no GC things have
+     * been swept. The collector may yield to the mutator after this point.
+     */
+    JSFINALIZE_GROUP_START,
+
+    /**
+     * Called after sweeping a group of zones. All dead GC things have been
+     * swept at this point.
+     */
+    JSFINALIZE_GROUP_END,
+
+    /**
+     * Called at the end of collection when everything has been swept.
+     */
+    JSFINALIZE_COLLECTION_END
+} JSFinalizeStatus;
+
+typedef void
+(* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, void* data);
+
+typedef void
+(* JSWeakPointerZonesCallback)(JSContext* cx, void* data);
+
+typedef void
+(* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data);
+
+/**
+ * Finalizes external strings created by JS_NewExternalString. The finalizer
+ * can be called off the main thread.
+ */
+struct JSStringFinalizer {
+    void (*finalize)(const JSStringFinalizer* fin, char16_t* chars);
+};
+
 namespace JS {
 
+struct Zone;
+
 #define GCREASONS(D)                            \
     /* Reasons internal to the JS engine */     \
     D(API)                                      \
     D(EAGER_ALLOC_TRIGGER)                      \
     D(DESTROY_RUNTIME)                          \
     D(ROOTS_REMOVED)                            \
     D(LAST_DITCH)                               \
     D(TOO_MUCH_MALLOC)                          \
@@ -437,39 +722,16 @@ IsIncrementalGCInProgress(JSContext* cx)
 
 /**
  * Returns true while an incremental GC is ongoing, both when actively
  * collecting and between slices.
  */
 extern JS_PUBLIC_API(bool)
 IsIncrementalGCInProgress(JSRuntime* rt);
 
-/*
- * Returns true when writes to GC thing pointers (and reads from weak pointers)
- * must call an incremental barrier. This is generally only true when running
- * mutator code in-between GC slices. At other times, the barrier may be elided
- * for performance.
- */
-extern JS_PUBLIC_API(bool)
-IsIncrementalBarrierNeeded(JSContext* cx);
-
-/*
- * Notify the GC that a reference to a JSObject is about to be overwritten.
- * This method must be called if IsIncrementalBarrierNeeded.
- */
-extern JS_PUBLIC_API(void)
-IncrementalPreWriteBarrier(JSObject* obj);
-
-/*
- * Notify the GC that a weak reference to a GC thing has been read.
- * This method must be called if IsIncrementalBarrierNeeded.
- */
-extern JS_PUBLIC_API(void)
-IncrementalReadBarrier(GCCellPtr thing);
-
 /**
  * Returns true if the most recent GC ran incrementally.
  */
 extern JS_PUBLIC_API(bool)
 WasIncrementalGC(JSRuntime* rt);
 
 /*
  * Generational GC:
@@ -608,105 +870,181 @@ class JS_PUBLIC_API(AutoCheckCannotGC) :
 #else
 class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC
 {
   public:
     explicit AutoCheckCannotGC(JSContext* cx = nullptr) {}
 } JS_HAZ_GC_INVALIDATED;
 #endif
 
-/**
- * Unsets the gray bit for anything reachable from |thing|. |kind| should not be
- * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates
- * if anything was unmarked.
- */
-extern JS_FRIEND_API(bool)
-UnmarkGrayGCThingRecursively(GCCellPtr thing);
-
-} /* namespace JS */
-
-namespace js {
-namespace gc {
-
-static MOZ_ALWAYS_INLINE void
-ExposeGCThingToActiveJS(JS::GCCellPtr thing)
-{
-    // GC things residing in the nursery cannot be gray: they have no mark bits.
-    // All live objects in the nursery are moved to tenured at the beginning of
-    // each GC slice, so the gray marker never sees nursery things.
-    if (IsInsideNursery(thing.asCell()))
-        return;
-
-    // There's nothing to do for permanent GC things that might be owned by
-    // another runtime.
-    if (thing.mayBeOwnedByOtherRuntime())
-        return;
-
-    if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
-        JS::IncrementalReadBarrier(thing);
-    else if (js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()))
-        JS::UnmarkGrayGCThingRecursively(thing);
-
-    MOZ_ASSERT(!js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()));
-}
-
-template <typename T>
-extern JS_PUBLIC_API(bool)
-EdgeNeedsSweepUnbarrieredSlow(T* thingp);
-
-static MOZ_ALWAYS_INLINE bool
-EdgeNeedsSweepUnbarriered(JSObject** objp)
-{
-    // This function does not handle updating nursery pointers. Raw JSObject
-    // pointers should be updated separately or replaced with
-    // JS::Heap<JSObject*> which handles this automatically.
-    MOZ_ASSERT(!JS::CurrentThreadIsHeapMinorCollecting());
-    if (IsInsideNursery(reinterpret_cast<Cell*>(*objp)))
-        return false;
-
-    auto zone = JS::shadow::Zone::asShadowZone(detail::GetGCThingZone(uintptr_t(*objp)));
-    if (!zone->isGCSweepingOrCompacting())
-        return false;
-
-    return EdgeNeedsSweepUnbarrieredSlow(objp);
-}
-
-} /* namespace gc */
-} /* namespace js */
-
-namespace JS {
-
-/*
- * This should be called when an object that is marked gray is exposed to the JS
- * engine (by handing it to running JS code or writing it into live JS
- * data). During incremental GC, since the gray bits haven't been computed yet,
- * we conservatively mark the object black.
- */
-static MOZ_ALWAYS_INLINE void
-ExposeObjectToActiveJS(JSObject* obj)
-{
-    MOZ_ASSERT(obj);
-    MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&obj));
-    js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj));
-}
-
-static MOZ_ALWAYS_INLINE void
-ExposeScriptToActiveJS(JSScript* script)
-{
-    MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&script));
-    js::gc::ExposeGCThingToActiveJS(GCCellPtr(script));
-}
-
 /*
  * Internal to Firefox.
  */
 extern JS_FRIEND_API(void)
 NotifyGCRootsRemoved(JSContext* cx);
 
 /*
  * Internal to Firefox.
  */
 extern JS_FRIEND_API(void)
 NotifyDidPaint(JSContext* cx);
 
 } /* namespace JS */
 
+/**
+ * Register externally maintained GC roots.
+ *
+ * traceOp: the trace operation. For each root the implementation should call
+ *          JS::TraceEdge whenever the root contains a traceable thing.
+ * data:    the data argument to pass to each invocation of traceOp.
+ */
+extern JS_PUBLIC_API(bool)
+JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
+
+/** Undo a call to JS_AddExtraGCRootsTracer. */
+extern JS_PUBLIC_API(void)
+JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
+
+extern JS_PUBLIC_API(void)
+JS_GC(JSContext* cx);
+
+extern JS_PUBLIC_API(void)
+JS_MaybeGC(JSContext* cx);
+
+extern JS_PUBLIC_API(void)
+JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data);
+
+extern JS_PUBLIC_API(void)
+JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb,
+                             void* data);
+
+extern JS_PUBLIC_API(bool)
+JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data);
+
+extern JS_PUBLIC_API(void)
+JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb);
+
+/*
+ * Weak pointers and garbage collection
+ *
+ * Weak pointers are by their nature not marked as part of garbage collection,
+ * but they may need to be updated in two cases after a GC:
+ *
+ *  1) Their referent was found not to be live and is about to be finalized
+ *  2) Their referent has been moved by a compacting GC
+ *
+ * To handle this, any part of the system that maintain weak pointers to
+ * JavaScript GC things must register a callback with
+ * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
+ * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
+ * about.
+ *
+ * Since sweeping is incremental, we have several callbacks to avoid repeatedly
+ * having to visit all embedder structures. The WeakPointerZonesCallback is
+ * called once for each strongly connected group of zones, whereas the
+ * WeakPointerCompartmentCallback is called once for each compartment that is
+ * visited while sweeping. Structures that cannot contain references in more
+ * than one compartment should sweep the relevant per-compartment structures
+ * using the latter callback to minimizer per-slice overhead.
+ *
+ * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
+ * referent is about to be finalized the pointer will be set to null. If the
+ * referent has been moved then the pointer will be updated to point to the new
+ * location.
+ *
+ * Callers of this method are responsible for updating any state that is
+ * dependent on the object's address. For example, if the object's address is
+ * used as a key in a hashtable, then the object must be removed and
+ * re-inserted with the correct hash.
+ */
+
+extern JS_PUBLIC_API(bool)
+JS_AddWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb, void* data);
+
+extern JS_PUBLIC_API(void)
+JS_RemoveWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb);
+
+extern JS_PUBLIC_API(bool)
+JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb,
+                                     void* data);
+
+extern JS_PUBLIC_API(void)
+JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb);
+
+namespace JS {
+template <typename T> class Heap;
+}
+
+extern JS_PUBLIC_API(void)
+JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
+
+extern JS_PUBLIC_API(void)
+JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
+
+extern JS_PUBLIC_API(void)
+JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
+
+extern JS_PUBLIC_API(void)
+JS_ResetGCParameter(JSContext* cx, JSGCParamKey key);
+
+extern JS_PUBLIC_API(uint32_t)
+JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
+
+extern JS_PUBLIC_API(void)
+JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem);
+
+/**
+ * Create a new JSString whose chars member refers to external memory, i.e.,
+ * memory requiring application-specific finalization.
+ */
+extern JS_PUBLIC_API(JSString*)
+JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
+                     const JSStringFinalizer* fin);
+
+/**
+ * Create a new JSString whose chars member may refer to external memory.
+ * If a new external string is allocated, |*allocatedExternal| is set to true.
+ * Otherwise the returned string is either not an external string or an
+ * external string allocated by a previous call and |*allocatedExternal| is set
+ * to false. If |*allocatedExternal| is false, |fin| won't be called.
+ */
+extern JS_PUBLIC_API(JSString*)
+JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
+                          const JSStringFinalizer* fin, bool* allocatedExternal);
+
+/**
+ * Return whether 'str' was created with JS_NewExternalString or
+ * JS_NewExternalStringWithClosure.
+ */
+extern JS_PUBLIC_API(bool)
+JS_IsExternalString(JSString* str);
+
+/**
+ * Return the 'fin' arg passed to JS_NewExternalString.
+ */
+extern JS_PUBLIC_API(const JSStringFinalizer*)
+JS_GetExternalStringFinalizer(JSString* str);
+
+namespace JS {
+
+extern JS_PUBLIC_API(bool)
+IsIdleGCTaskNeeded(JSRuntime* rt);
+
+extern JS_PUBLIC_API(void)
+RunIdleTimeGCTask(JSRuntime* rt);
+
+} // namespace JS
+
+namespace js {
+namespace gc {
+
+/**
+ * Create an object providing access to the garbage collector's internal notion
+ * of the current state of memory (both GC heap memory and GCthing-controlled
+ * malloc memory.
+ */
+extern JS_PUBLIC_API(JSObject*)
+NewMemoryInfoObject(JSContext* cx);
+
+} /* namespace gc */
+} /* namespace js */
+
 #endif /* js_GCAPI_h */
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -103,17 +103,29 @@ AssertGCThingHasType(js::gc::Cell* cell,
 #endif
 
 MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell);
 
 } /* namespace gc */
 } /* namespace js */
 
 namespace JS {
-struct Zone;
+
+/*
+ * This list enumerates the different types of conceptual stacks we have in
+ * SpiderMonkey. In reality, they all share the C stack, but we allow different
+ * stack limits depending on the type of code running.
+ */
+enum StackKind
+{
+    StackForSystemCode,      // C++, such as the GC, running on behalf of the VM.
+    StackForTrustedScript,   // Script running with trusted principals.
+    StackForUntrustedScript, // Script running with untrusted principals.
+    StackKindCount
+};
 
 /*
  * Default size for the generational nursery in bytes.
  * This is the initial nursery size, when running in the browser this is
  * updated by JS_SetGCParameter().
  */
 const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize;
 
@@ -462,17 +474,48 @@ GCThingIsMarkedGray(GCCellPtr thing)
     if (thing.mayBeOwnedByOtherRuntime())
         return false;
     return js::gc::detail::CellIsMarkedGrayIfKnown(thing.asCell());
 }
 
 extern JS_PUBLIC_API(JS::TraceKind)
 GCThingTraceKind(void* thing);
 
-} /* namespace JS */
+/*
+ * Returns true when writes to GC thing pointers (and reads from weak pointers)
+ * must call an incremental barrier. This is generally only true when running
+ * mutator code in-between GC slices. At other times, the barrier may be elided
+ * for performance.
+ */
+extern JS_PUBLIC_API(bool)
+IsIncrementalBarrierNeeded(JSContext* cx);
+
+/*
+ * Notify the GC that a reference to a JSObject is about to be overwritten.
+ * This method must be called if IsIncrementalBarrierNeeded.
+ */
+extern JS_PUBLIC_API(void)
+IncrementalPreWriteBarrier(JSObject* obj);
+
+/*
+ * Notify the GC that a weak reference to a GC thing has been read.
+ * This method must be called if IsIncrementalBarrierNeeded.
+ */
+extern JS_PUBLIC_API(void)
+IncrementalReadBarrier(GCCellPtr thing);
+
+/**
+ * Unsets the gray bit for anything reachable from |thing|. |kind| should not be
+ * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates
+ * if anything was unmarked.
+ */
+extern JS_FRIEND_API(bool)
+UnmarkGrayGCThingRecursively(GCCellPtr thing);
+
+} // namespace JS
 
 namespace js {
 namespace gc {
 
 static MOZ_ALWAYS_INLINE bool
 IsIncrementalBarrierNeededOnTenuredGCThing(const JS::GCCellPtr thing)
 {
     MOZ_ASSERT(thing);
@@ -482,20 +525,80 @@ IsIncrementalBarrierNeededOnTenuredGCThi
     // called while we are tracing the heap, e.g. during memory reporting
     // (see bug 1313318).
     MOZ_ASSERT(!JS::CurrentThreadIsHeapCollecting());
 
     JS::Zone* zone = JS::GetTenuredGCThingZone(thing);
     return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier();
 }
 
-/**
- * Create an object providing access to the garbage collector's internal notion
- * of the current state of memory (both GC heap memory and GCthing-controlled
- * malloc memory.
+static MOZ_ALWAYS_INLINE void
+ExposeGCThingToActiveJS(JS::GCCellPtr thing)
+{
+    // GC things residing in the nursery cannot be gray: they have no mark bits.
+    // All live objects in the nursery are moved to tenured at the beginning of
+    // each GC slice, so the gray marker never sees nursery things.
+    if (IsInsideNursery(thing.asCell()))
+        return;
+
+    // There's nothing to do for permanent GC things that might be owned by
+    // another runtime.
+    if (thing.mayBeOwnedByOtherRuntime())
+        return;
+
+    if (IsIncrementalBarrierNeededOnTenuredGCThing(thing))
+        JS::IncrementalReadBarrier(thing);
+    else if (js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()))
+        JS::UnmarkGrayGCThingRecursively(thing);
+
+    MOZ_ASSERT(!js::gc::detail::TenuredCellIsMarkedGray(thing.asCell()));
+}
+
+template <typename T>
+extern JS_PUBLIC_API(bool)
+EdgeNeedsSweepUnbarrieredSlow(T* thingp);
+
+static MOZ_ALWAYS_INLINE bool
+EdgeNeedsSweepUnbarriered(JSObject** objp)
+{
+    // This function does not handle updating nursery pointers. Raw JSObject
+    // pointers should be updated separately or replaced with
+    // JS::Heap<JSObject*> which handles this automatically.
+    MOZ_ASSERT(!JS::CurrentThreadIsHeapMinorCollecting());
+    if (IsInsideNursery(reinterpret_cast<Cell*>(*objp)))
+        return false;
+
+    auto zone = JS::shadow::Zone::asShadowZone(detail::GetGCThingZone(uintptr_t(*objp)));
+    if (!zone->isGCSweepingOrCompacting())
+        return false;
+
+    return EdgeNeedsSweepUnbarrieredSlow(objp);
+}
+
+} // namespace gc
+} // namesapce js
+
+namespace JS {
+
+/*
+ * This should be called when an object that is marked gray is exposed to the JS
+ * engine (by handing it to running JS code or writing it into live JS
+ * data). During incremental GC, since the gray bits haven't been computed yet,
+ * we conservatively mark the object black.
  */
-extern JS_PUBLIC_API(JSObject*)
-NewMemoryInfoObject(JSContext* cx);
+static MOZ_ALWAYS_INLINE void
+ExposeObjectToActiveJS(JSObject* obj)
+{
+    MOZ_ASSERT(obj);
+    MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&obj));
+    js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj));
+}
 
-} /* namespace gc */
-} /* namespace js */
+static MOZ_ALWAYS_INLINE void
+ExposeScriptToActiveJS(JSScript* script)
+{
+    MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&script));
+    js::gc::ExposeGCThingToActiveJS(GCCellPtr(script));
+}
+
+} /* namespace JS */
 
 #endif /* js_HeapAPI_h */
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -14,17 +14,16 @@
 #include "mozilla/Move.h"
 #include "mozilla/TypeTraits.h"
 
 #include <type_traits>
 
 #include "jspubtd.h"
 
 #include "js/GCAnnotations.h"
-#include "js/GCAPI.h"
 #include "js/GCPolicyAPI.h"
 #include "js/HeapAPI.h"
 #include "js/TypeDecls.h"
 #include "js/UniquePtr.h"
 #include "js/Utility.h"
 
 /*
  * Moving GC Stack Rooting
@@ -766,16 +765,134 @@ class alignas(8) DispatchWrapper
         wrapper->tracer(trc, &wrapper->storage, name);
     }
 };
 
 } /* namespace js */
 
 namespace JS {
 
+class JS_PUBLIC_API(AutoGCRooter);
+
+// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
+// instantiation of MapTypeToRootKind.
+template <>
+struct MapTypeToRootKind<void*> {
+    static const RootKind kind = RootKind::Traceable;
+};
+
+using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
+                                                 Rooted<void*>*>;
+
+// Superclass of JSContext which can be used for rooting data in use by the
+// current thread but that does not provide all the functions of a JSContext.
+class RootingContext
+{
+    // Stack GC roots for Rooted GC heap pointers.
+    RootedListHeads stackRoots_;
+    template <typename T> friend class JS::Rooted;
+
+    // Stack GC roots for AutoFooRooter classes.
+    JS::AutoGCRooter* autoGCRooters_;
+    friend class JS::AutoGCRooter;
+
+  public:
+    RootingContext();
+
+    void traceStackRoots(JSTracer* trc);
+    void checkNoGCRooters();
+
+  protected:
+    // The remaining members in this class should only be accessed through
+    // JSContext pointers. They are unrelated to rooting and are in place so
+    // that inlined API functions can directly access the data.
+
+    /* The current compartment. */
+    JSCompartment*      compartment_;
+
+    /* The current zone. */
+    JS::Zone*           zone_;
+
+  public:
+    /* Limit pointer for checking native stack consumption. */
+    uintptr_t nativeStackLimit[StackKindCount];
+
+    static const RootingContext* get(const JSContext* cx) {
+        return reinterpret_cast<const RootingContext*>(cx);
+    }
+
+    static RootingContext* get(JSContext* cx) {
+        return reinterpret_cast<RootingContext*>(cx);
+    }
+
+    friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
+    friend JS::Zone* js::GetContextZone(const JSContext* cx);
+};
+
+class JS_PUBLIC_API(AutoGCRooter)
+{
+  public:
+    AutoGCRooter(JSContext* cx, ptrdiff_t tag)
+      : AutoGCRooter(JS::RootingContext::get(cx), tag)
+    {}
+    AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
+      : down(cx->autoGCRooters_),
+        tag_(tag),
+        stackTop(&cx->autoGCRooters_)
+    {
+        MOZ_ASSERT(this != *stackTop);
+        *stackTop = this;
+    }
+
+    ~AutoGCRooter() {
+        MOZ_ASSERT(this == *stackTop);
+        *stackTop = down;
+    }
+
+    /* Implemented in gc/RootMarking.cpp. */
+    inline void trace(JSTracer* trc);
+    static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
+    static void traceAllWrappers(const js::CooperatingContext& target, JSTracer* trc);
+
+  protected:
+    AutoGCRooter * const down;
+
+    /*
+     * Discriminates actual subclass of this being used.  If non-negative, the
+     * subclass roots an array of values of the length stored in this field.
+     * If negative, meaning is indicated by the corresponding value in the enum
+     * below.  Any other negative value indicates some deeper problem such as
+     * memory corruption.
+     */
+    ptrdiff_t tag_;
+
+    enum {
+        VALARRAY =     -2, /* js::AutoValueArray */
+        PARSER =       -3, /* js::frontend::Parser */
+        VALVECTOR =   -10, /* js::AutoValueVector */
+        IDVECTOR =    -11, /* js::AutoIdVector */
+        OBJVECTOR =   -14, /* js::AutoObjectVector */
+        IONMASM =     -19, /* js::jit::MacroAssembler */
+        WRAPVECTOR =  -20, /* js::AutoWrapperVector */
+        WRAPPER =     -21, /* js::AutoWrapperRooter */
+        CUSTOM =      -26  /* js::CustomAutoRooter */
+    };
+
+    static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
+    static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
+    static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
+
+  private:
+    AutoGCRooter ** const stackTop;
+
+    /* No copy or assignment semantics. */
+    AutoGCRooter(AutoGCRooter& ida) = delete;
+    void operator=(AutoGCRooter& ida) = delete;
+};
+
 namespace detail {
 
 /*
  * For pointer types, the TraceKind for tracing is based on the list it is
  * in (selected via MapTypeToRootKind), so no additional storage is
  * required here. Non-pointer types, however, share the same list, so the
  * function to call for tracing is stored adjacent to the struct. Since C++
  * cannot templatize on storage class, this is implemented via the wrapper
@@ -869,16 +986,38 @@ class MOZ_RAII Rooted : public js::Roote
 
     Rooted(const Rooted&) = delete;
 } JS_HAZ_ROOTED;
 
 } /* namespace JS */
 
 namespace js {
 
+/*
+ * Inlinable accessors for JSContext.
+ *
+ * - These must not be available on the more restricted superclasses of
+ *   JSContext, so we can't simply define them on RootingContext.
+ *
+ * - They're perfectly ordinary JSContext functionality, so ought to be
+ *   usable without resorting to jsfriendapi.h, and when JSContext is an
+ *   incomplete type.
+ */
+inline JSCompartment*
+GetContextCompartment(const JSContext* cx)
+{
+    return JS::RootingContext::get(cx)->compartment_;
+}
+
+inline JS::Zone*
+GetContextZone(const JSContext* cx)
+{
+    return JS::RootingContext::get(cx)->zone_;
+}
+
 /**
  * Augment the generic Rooted<T> interface when T = JSObject* with
  * class-querying and downcasting operations.
  *
  * Given a Rooted<JSObject*> obj, one can view
  *   Handle<StringObject*> h = obj.as<StringObject*>();
  * as an optimization of
  *   Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
--- a/js/src/builtin/Intl.h
+++ b/js/src/builtin/Intl.h
@@ -10,17 +10,16 @@
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "jsalloc.h"
 #include "NamespaceImports.h"
 
 #include "builtin/SelfHostingDefines.h"
 #include "js/Class.h"
-#include "js/GCAPI.h"
 #include "js/GCHashTable.h"
 #include "vm/NativeObject.h"
 
 class JSLinearString;
 
 /*
  * The Intl module specified by standard ECMA-402,
  * ECMAScript Internationalization API Specification.
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -21,17 +21,16 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jsnum.h"
 #include "jsprf.h"
 
 #include "builtin/TypedObject.h"
 #include "jit/AtomicOperations.h"
 #include "jit/InlinableNatives.h"
-#include "js/GCAPI.h"
 #include "js/Value.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 
 using mozilla::ArrayLength;
 using mozilla::IsFinite;
--- a/js/src/gc/ArenaList.h
+++ b/js/src/gc/ArenaList.h
@@ -7,17 +7,16 @@
 /*
  * GC-internal definitions of ArenaList and associated heap data structures.
  */
 
 #ifndef gc_ArenaList_h
 #define gc_ArenaList_h
 
 #include "gc/AllocKind.h"
-#include "js/GCAPI.h"
 #include "js/SliceBudget.h"
 #include "threading/ProtectedData.h"
 
 namespace JS {
 
 struct Zone;
 
 } /* namespace JS */
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -10,18 +10,16 @@
 
 #ifndef gc_GCInternals_h
 #define gc_GCInternals_h
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/PodOperations.h"
 
-#include "jscntxt.h"
-
 #include "gc/RelocationOverlay.h"
 #include "gc/Zone.h"
 #include "vm/HelperThreads.h"
 #include "vm/Runtime.h"
 
 namespace js {
 namespace gc {
 
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -6,17 +6,16 @@
 
 #ifndef gc_GCRuntime_h
 #define gc_GCRuntime_h
 
 #include "mozilla/Atomics.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/Maybe.h"
 
-#include "jsapi.h"
 #include "jsatom.h"
 
 #include "gc/ArenaList.h"
 #include "gc/AtomMarking.h"
 #include "gc/GCHelperState.h"
 #include "gc/GCMarker.h"
 #include "gc/GCParallelTask.h"
 #include "gc/Nursery.h"
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -20,17 +20,16 @@
 #include "jspubtd.h"
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "ds/BitArray.h"
 #include "gc/AllocKind.h"
 #include "gc/GCEnum.h"
 #include "gc/Memory.h"
-#include "js/GCAPI.h"
 #include "js/HeapAPI.h"
 #include "js/RootingAPI.h"
 #include "js/TracingAPI.h"
 
 #include "vm/Printer.h"
 
 struct JSRuntime;
 
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -8,17 +8,16 @@
 #include "gc/Nursery-inl.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Move.h"
 #include "mozilla/Unused.h"
 
 #include "jscompartment.h"
-#include "jsfriendapi.h"
 #include "jsutil.h"
 
 #include "gc/GCInternals.h"
 #include "gc/Memory.h"
 #include "jit/JitFrames.h"
 #include "vm/ArrayObject.h"
 #include "vm/Debugger.h"
 #if defined(DEBUG)
@@ -546,18 +545,21 @@ js::Nursery::renderProfileJSON(JSONPrint
     json.beginObject();
 
     json.property("status", "complete");
 
     json.property("reason", JS::gcreason::ExplainReason(previousGC.reason));
     json.property("bytes_tenured", previousGC.tenuredBytes);
     json.property("bytes_used", previousGC.nurseryUsedBytes);
     json.property("cur_capacity", previousGC.nurseryCapacity);
-    json.property("new_capacity", spaceToEnd());
-    json.property("lazy_capacity", allocatedChunkCount() * ChunkSize);
+    const size_t newCapacity = spaceToEnd(maxChunkCount());
+    if (newCapacity != previousGC.nurseryCapacity)
+        json.property("new_capacity", newCapacity);
+    if (previousGC.nurseryLazyCapacity != previousGC.nurseryCapacity)
+        json.property("lazy_capacity", previousGC.nurseryLazyCapacity);
     if (!timeInChunkAlloc_.IsZero())
         json.property("chunk_alloc_us", timeInChunkAlloc_, json.MICROSECONDS);
 
     json.beginObjectProperty("phase_times");
 
 #define EXTRACT_NAME(name, text) #name,
     static const char* names[] = {
 FOR_EACH_NURSERY_PROFILE_TIME(EXTRACT_NAME)
@@ -670,17 +672,18 @@ js::Nursery::collect(JS::gcreason::Reaso
     JS::AutoSuppressGCAnalysis nogc;
 
     TenureCountCache tenureCounts;
     previousGC.reason = JS::gcreason::NO_REASON;
     if (!isEmpty()) {
         doCollection(reason, tenureCounts);
     } else {
         previousGC.nurseryUsedBytes = 0;
-        previousGC.nurseryCapacity = spaceToEnd();
+        previousGC.nurseryCapacity = spaceToEnd(maxChunkCount());
+        previousGC.nurseryLazyCapacity = spaceToEnd(allocatedChunkCount());
         previousGC.tenuredBytes = 0;
     }
 
     // Resize the nursery.
     maybeResizeNursery(reason);
 
     // If we are promoting the nursery, or exhausted the store buffer with
     // pointers to nursery things, which will force a collection well before
@@ -759,17 +762,17 @@ js::Nursery::doCollection(JS::gcreason::
 {
     JSRuntime* rt = runtime();
     AutoTraceSession session(rt, JS::HeapState::MinorCollecting);
     AutoSetThreadIsPerformingGC performingGC;
     AutoStopVerifyingBarriers av(rt, false);
     AutoDisableProxyCheck disableStrictProxyChecking;
     mozilla::DebugOnly<AutoEnterOOMUnsafeRegion> oomUnsafeRegion;
 
-    const size_t initialNurseryCapacity = spaceToEnd();
+    const size_t initialNurseryCapacity = spaceToEnd(maxChunkCount());
     const size_t initialNurseryUsedBytes = initialNurseryCapacity - freeSpace();
 
     // Move objects pointed to by roots from the nursery to the major heap.
     TenuringTracer mover(rt, this);
 
     // Mark the store buffer. This must happen first.
     StoreBuffer& sb = runtime()->gc.storeBuffer();
 
@@ -858,16 +861,17 @@ js::Nursery::doCollection(JS::gcreason::
 #ifdef JS_GC_ZEAL
     if (rt->hasZealMode(ZealMode::CheckHashTablesOnMinorGC))
         CheckHashTablesAfterMovingGC(rt);
 #endif
     endProfile(ProfileKey::CheckHashTables);
 
     previousGC.reason = reason;
     previousGC.nurseryCapacity = initialNurseryCapacity;
+    previousGC.nurseryLazyCapacity = spaceToEnd(allocatedChunkCount());
     previousGC.nurseryUsedBytes = initialNurseryUsedBytes;
     previousGC.tenuredBytes = mover.tenuredSize;
 }
 
 void
 js::Nursery::FreeMallocedBuffersTask::transferBuffersToFree(MallocedBuffersSet& buffersToFree,
                                                             const AutoLockHelperThreadState& lock)
 {
@@ -961,19 +965,19 @@ js::Nursery::clear()
         setCurrentChunk(0);
     }
 
     /* Set current start position for isEmpty checks. */
     setStartPosition();
 }
 
 size_t
-js::Nursery::spaceToEnd() const
+js::Nursery::spaceToEnd(unsigned chunkCount) const
 {
-    unsigned lastChunk = maxChunkCount() - 1;
+    unsigned lastChunk = chunkCount - 1;
 
     MOZ_ASSERT(lastChunk >= currentStartChunk_);
     MOZ_ASSERT(currentStartPosition_ - chunk(currentStartChunk_).start() <= NurseryChunkUsableSize);
 
     size_t bytes = (chunk(currentStartChunk_).end() - currentStartPosition_) +
                    ((lastChunk - currentStartChunk_) * NurseryChunkUsableSize);
 
     MOZ_ASSERT(bytes <= maxChunkCount() * NurseryChunkUsableSize);
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -248,17 +248,20 @@ class Nursery
         size_t total = 0;
         for (MallocedBuffersSet::Range r = mallocedBuffers.all(); !r.empty(); r.popFront())
             total += mallocSizeOf(r.front());
         total += mallocedBuffers.sizeOfExcludingThis(mallocSizeOf);
         return total;
     }
 
     // The number of bytes from the start position to the end of the nursery.
-    size_t spaceToEnd() const;
+    // pass maxChunkCount(), allocatedChunkCount() or chunkCountLimit()
+    // to calculate the nursery size, current lazy-allocated size or nursery
+    // limit respectively.
+    size_t spaceToEnd(unsigned chunkCount) const;
 
     // Free space remaining, not counting chunk trailers.
     MOZ_ALWAYS_INLINE size_t freeSpace() const {
         MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize);
         return (currentEnd_ - position_) +
                (maxChunkCount() - currentChunk_ - 1) * NurseryChunkUsableSize;
     }
 
@@ -372,16 +375,17 @@ class Nursery
 
     /*
      * This data is initialised only if the nursery is enabled and after at
      * least one call to Nursery::collect()
      */
     struct {
         JS::gcreason::Reason reason;
         size_t nurseryCapacity;
+        size_t nurseryLazyCapacity;
         size_t nurseryUsedBytes;
         size_t tenuredBytes;
     } previousGC;
 
     /*
      * Calculate the promotion rate of the most recent minor GC.
      * The valid_for_tenuring parameter is used to return whether this
      * promotion rate is accurate enough (the nursery was full enough) to be
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -588,74 +588,91 @@ Statistics::renderJsonMessage(uint64_t t
     json.endObject();
 
     return UniqueChars(printer.release());
 }
 
 void
 Statistics::formatJsonDescription(uint64_t timestamp, JSONPrinter& json) const
 {
+    // If you change JSON properties here, please update:
+    // Telemetry ping code: toolkit/components/telemetry/GCTelemetry.jsm
+    // Telemetry documentation: toolkit/components/telemetry/docs/data/main-ping.rst
+    // Telemetry tests: toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js
+    // Perf.html: https://github.com/devtools-html/perf.html
+
     json.property("timestamp", timestamp);
 
     TimeDuration total, longest;
     gcDuration(&total, &longest);
     json.property("max_pause", longest, JSONPrinter::MILLISECONDS);
     json.property("total_time", total, JSONPrinter::MILLISECONDS);
-
+    // We might be able to omit reason if perf.html was able to retrive it
+    // from the first slice.  But it doesn't do this yet.
     json.property("reason", ExplainReason(slices_[0].reason));
     json.property("zones_collected", zoneStats.collectedZoneCount);
     json.property("total_zones", zoneStats.zoneCount);
     json.property("total_compartments", zoneStats.compartmentCount);
-    json.property("minor_gcs", counts[STAT_MINOR_GC]);
-    json.property("store_buffer_overflows", counts[STAT_STOREBUFFER_OVERFLOW]);
+    json.property("minor_gcs", getCount(STAT_MINOR_GC));
+    uint32_t storebufferOverflows = getCount(STAT_STOREBUFFER_OVERFLOW);
+    if (storebufferOverflows)
+        json.property("store_buffer_overflows", storebufferOverflows);
     json.property("slices", slices_.length());
 
     const double mmu20 = computeMMU(TimeDuration::FromMilliseconds(20));
     const double mmu50 = computeMMU(TimeDuration::FromMilliseconds(50));
     json.property("mmu_20ms", int(mmu20 * 100));
     json.property("mmu_50ms", int(mmu50 * 100));
 
     TimeDuration sccTotal, sccLongest;
     sccDurations(&sccTotal, &sccLongest);
     json.property("scc_sweep_total", sccTotal, JSONPrinter::MILLISECONDS);
     json.property("scc_sweep_max_pause", sccLongest, JSONPrinter::MILLISECONDS);
 
-    json.property("nonincremental_reason", ExplainAbortReason(nonincrementalReason_));
-    json.property("allocated", uint64_t(preBytes)/1024/1024);
+    if (nonincrementalReason_ != AbortReason::None)
+        json.property("nonincremental_reason", ExplainAbortReason(nonincrementalReason_));
     json.property("allocated_bytes", preBytes);
-    json.property("added_chunks", getCount(STAT_NEW_CHUNK));
-    json.property("removed_chunks", getCount(STAT_DESTROY_CHUNK));
+    uint32_t addedChunks = getCount(STAT_NEW_CHUNK);
+    if (addedChunks)
+        json.property("added_chunks", addedChunks);
+    uint32_t removedChunks = getCount(STAT_DESTROY_CHUNK);
+    if (removedChunks)
+        json.property("removed_chunks", removedChunks);
     json.property("major_gc_number", startingMajorGCNumber);
     json.property("minor_gc_number", startingMinorGCNumber);
     json.property("slice_number", startingSliceNumber);
 }
 
 void
 Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice, JSONPrinter& json) const
 {
-    TimeDuration when = slice.start - slices_[0].start;
+    // If you change JSON properties here, please update:
+    // Telemetry ping code: toolkit/components/telemetry/GCTelemetry.jsm
+    // Telemetry documentation: toolkit/components/telemetry/docs/data/main-ping.rst
+    // Telemetry tests: toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js
+    // Perf.html: https://github.com/devtools-html/perf.html
     char budgetDescription[200];
     slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
     TimeStamp originTime = TimeStamp::ProcessCreation();
 
     json.property("slice", i);
     json.property("pause", slice.duration(), JSONPrinter::MILLISECONDS);
-    json.property("when", when, JSONPrinter::MILLISECONDS);
     json.property("reason", ExplainReason(slice.reason));
     json.property("initial_state", gc::StateName(slice.initialState));
     json.property("final_state", gc::StateName(slice.finalState));
     json.property("budget", budgetDescription);
     json.property("major_gc_number", startingMajorGCNumber);
     if (thresholdTriggered) {
         json.floatProperty("trigger_amount", triggerAmount, 0);
         json.floatProperty("trigger_threshold", triggerThreshold, 0);
     }
-    json.property("page_faults", int64_t(slice.endFaults - slice.startFaults));
+    int64_t numFaults = slice.endFaults - slice.startFaults;
+    if (numFaults != 0)
+        json.property("page_faults", numFaults);
     json.property("start_timestamp", slice.start - originTime, JSONPrinter::SECONDS);
-    json.property("end_timestamp", slice.end - originTime, JSONPrinter::SECONDS);
 }
 
 void
 Statistics::formatJsonPhaseTimes(const PhaseTimeTable& phaseTimes, JSONPrinter& json) const
 {
     for (auto phase : AllPhases()) {
         TimeDuration ownTime = phaseTimes[phase];
         if (!ownTime.IsZero())
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -14,17 +14,16 @@
 #include "mozilla/Maybe.h"
 #include "mozilla/PodOperations.h"
 
 #include "jsalloc.h"
 #include "jspubtd.h"
 #include "NamespaceImports.h"
 
 #include "gc/GCEnum.h"
-#include "js/GCAPI.h"
 #include "js/SliceBudget.h"
 #include "js/UniquePtr.h"
 #include "js/Vector.h"
 #include "vm/JSONPrinter.h"
 
 using mozilla::Maybe;
 
 namespace js {
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gc/Tracer.h"
 
 #include "mozilla/DebugOnly.h"
 
-#include "jsapi.h"
 #include "jsfun.h"
 #include "jsprf.h"
 #include "jsscript.h"
 #include "jsutil.h"
 #include "NamespaceImports.h"
 
 #include "gc/GCInternals.h"
 #include "gc/Marking.h"
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -12,17 +12,16 @@
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Sprintf.h"
 
 #include "jscntxt.h"
 #include "jsprf.h"
 
 #include "gc/GCInternals.h"
 #include "gc/Zone.h"
-#include "js/GCAPI.h"
 #include "js/HashTable.h"
 
 #include "jscntxtinlines.h"
 #include "jsgcinlines.h"
 
 #include "gc/Marking-inl.h"
 
 using namespace js;
--- a/js/src/jit-test/tests/coverage/simple.js
+++ b/js/src/jit-test/tests/coverage/simple.js
@@ -96,73 +96,88 @@ checkLcov(function () { //FN:$,top-level
   }
   f();              //DA:$,1
   //FNF:2
   //FNH:2
   //LF:2
   //LH:2
 });
 
+checkLcov(function () { ','.split(','); //FN:$,top-level //FNDA:1,% //DA:$,1
+  //FNF:1
+  //FNH:1
+  //LF:1
+  //LH:1
+});
+
+checkLcov(function () { function f() { ','.split(','); } //FN:$,top-level //FNDA:1,% //FN:$,f //FNDA:1,f //DA:$,1
+  f(); //DA:$,1
+  //FNF:2
+  //FNH:2
+  //LF:2
+  //LH:2
+});
+
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  if (l.length == 3)      //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,-
+  if (l.length == 3)      //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0
     l.push('');           //DA:$,0
   l.pop();                //DA:$,1
   //FNF:1
   //FNH:1
   //LF:4
   //LH:3
   //BRF:2
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
     l.push('');           //DA:$,1
   l.pop();                //DA:$,1
   //FNF:1
   //FNH:1
   //LF:4
   //LH:4
   //BRF:2
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  if (l.length == 3)      //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,-
+  if (l.length == 3)      //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0
     l.push('');           //DA:$,0
   else
     l.pop();              //DA:$,1
   //FNF:1
   //FNH:1
   //LF:4
   //LH:3
   //BRF:2
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
     l.push('');           //DA:$,1
   else
     l.pop();              //DA:$,0
   //FNF:1
   //FNH:1
   //LF:4
   //LH:3
   //BRF:2
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+  if (l.length == 2)      //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
     l.push('');           //DA:$,1
   else {
     if (l.length == 1)    //DA:$,0 //BRDA:$,1,0,- //BRDA:$,1,1,-
       l.pop();            //DA:$,0
   }
   //FNF:1
   //FNH:1
   //LF:5
@@ -188,17 +203,17 @@ checkLcov(function () { //FN:$,top-level
   f(5);           //DA:$,1
   //FNF:2
   //FNH:2
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   try {                     //DA:$,1
     var l = ",".split(','); //DA:$,1
-    if (l.length == 2) {    //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+    if (l.length == 2) {    //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
       l.push('');           //DA:$,1
       throw l;              //DA:$,1
     }
     l.pop();                //DA:$,0
   } catch (x) {             //DA:$,1
     x.pop();                //DA:$,1
   }
   //FNF:1
@@ -208,17 +223,17 @@ checkLcov(function () { //FN:$,top-level
   //BRF:2
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(',');   //DA:$,1
   try {                     //DA:$,1
     try {                   //DA:$,1
-      if (l.length == 2) {  //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+      if (l.length == 2) {  //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
         l.push('');         //DA:$,1
         throw l;            //DA:$,1
       }
       l.pop();              //DA:$,0
     } finally {             //DA:$,1
       l.pop();              //DA:$,1
     }
   } catch (x) {             //DA:$,1
@@ -248,17 +263,17 @@ checkLcov(function () { //FN:$,top-level
   //LH:5
   //BRF:0
   //BRH:0
 });
 
 // Test TableSwitch opcode
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,- //BRDA:$,0,4,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 //BRDA:$,0,4,0
     case 0:
       l.push('0');        //DA:$,0
       break;
     case 1:
       l.push('1');        //DA:$,0
       break;
     case 2:
       l.push('2');        //DA:$,1
@@ -273,17 +288,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:4
   //BRF:5
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,- //BRDA:$,0,4,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 //BRDA:$,0,4,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
     case 3:
       l.push('3');        //DA:$,1
@@ -295,17 +310,17 @@ checkLcov(function () { //FN:$,top-level
   //LH:5
   //BRF:5
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
                           // Branches are ordered, and starting at 0
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,- //BRDA:$,0,2,- //BRDA:$,0,3,- //BRDA:$,0,4,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0 //BRDA:$,0,2,0 //BRDA:$,0,3,0 //BRDA:$,0,4,0
     case 5:
       l.push('5');        //DA:$,0
     case 4:
       l.push('4');        //DA:$,0
     case 3:
       l.push('3');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
@@ -316,34 +331,34 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:4
   //BRF:5
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,- //BRDA:$,0,2,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0 //BRDA:$,0,2,0
     case 2:
       l.push('2');        //DA:$,1
     case 5:
       l.push('5');        //DA:$,1
   }
   l.pop();                //DA:$,1
   //FNF:1
   //FNH:1
   //LF:5
   //LH:5
   //BRF:3
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1
     case 3:
       l.push('1');        //DA:$,0
     case 5:
       l.push('5');        //DA:$,0
   }
   l.pop();                //DA:$,1
   //FNF:1
   //FNH:1
@@ -356,33 +371,33 @@ checkLcov(function () { //FN:$,top-level
 // Unfortunately the differences between switch implementations leaks in the
 // code coverage reports.
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   function f(a) {         //FN:$,f //FNDA:2,%
     return a;             //DA:$,2
   }
   var l = ",".split(','); //DA:$,1
   switch (l.length) {     //DA:$,1
-    case f(-42):          //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1
+    case f(-42):          //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1
       l.push('1');        //DA:$,0
-    case f(51):           //DA:$,1 //BRDA:$,1,0,- //BRDA:$,1,1,1
+    case f(51):           //DA:$,1 //BRDA:$,1,0,0 //BRDA:$,1,1,1
       l.push('5');        //DA:$,0
   }
   l.pop();                //DA:$,1
   //FNF:2
   //FNH:2
   //LF:8
   //LH:6
   //BRF:4
   //BRH:2
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1 //BRDA:$,0,2,- //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1 //BRDA:$,0,2,0 //BRDA:$,0,3,0
     case 0:
     case 1:
       l.push('0');        //DA:$,0
       l.push('1');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
     case 3:
       l.push('3');        //DA:$,1
@@ -393,17 +408,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     case 2:
     case 3:
       l.push('2');        //DA:$,1
       l.push('3');        //DA:$,1
@@ -414,17 +429,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
     default:
       l.push('1');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
     case 3:
@@ -436,17 +451,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
     case 2:
       l.push('2');        //DA:$,1
     case 3:
@@ -458,17 +473,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,- //BRDA:$,0,4,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 //BRDA:$,0,4,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
       l.push('default');  //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
@@ -481,17 +496,17 @@ checkLcov(function () { //FN:$,top-level
   //LF:8
   //LH:5
   //BRF:5
   //BRH:1
 });
 
 checkLcov(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,- //BRDA:$,0,3,1
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,0 //BRDA:$,0,3,1
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
       l.push('2');        //DA:$,1
     case 3:
       l.push('3');        //DA:$,1
@@ -500,10 +515,29 @@ checkLcov(function () { //FN:$,top-level
   //FNF:1
   //FNH:1
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
+checkLcov(function () { //FN:$,top-level //FNDA:1,%
+  var l = ','.split(','); //DA:$,1
+  if (l.length === 45) {  //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0
+    switch (l[0]) {       //DA:$,0 //BRDA:$,1,0,- //BRDA:$,1,1,-
+      case ',':
+        l.push('0');      //DA:$,0
+      default:
+        l.push('1');      //DA:$,0
+    }
+  }
+  l.pop();                //DA:$,1
+  //FNF:1
+  //FNH:1
+  //LF:6
+  //LH:3
+  //BRF:4
+  //BRH:1
+});
+
 // If you add a test case here, do the same in
 // jit-test/tests/debug/Script-getOffsetsCoverage-01.js
--- a/js/src/jit-test/tests/debug/Script-getOffsetsCoverage-01.js
+++ b/js/src/jit-test/tests/debug/Script-getOffsetsCoverage-01.js
@@ -149,16 +149,23 @@ checkGetOffsetsCoverage(function () { //
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level
   function f() {    //FN:$,f
     ",".split(','); //DA:$,1
   }
   f();              //DA:$,1
 });
 
+checkGetOffsetsCoverage(function () { ','.split(','); //FN:$,top-level //DA:$,1
+});
+
+checkGetOffsetsCoverage(function () { function f() { ','.split(','); } //FN:$,top-level //FN:$,f //DA:$,1
+  f(); //DA:$,1
+});
+
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
   if (l.length == 3)      //DA:$,1
     l.push('');           //DA:$,0
   l.pop();                //DA:$,1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
@@ -338,17 +345,17 @@ checkGetOffsetsCoverage(function () { //
       l.push('5');        //DA:$,0
   }
   l.pop();                //DA:$,1
 });
 
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,1 //BRDA:$,0,2,- //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1 //BRDA:$,0,2,0 //BRDA:$,0,3,0
     case 0:
     case 1:
       l.push('0');        //DA:$,0
       l.push('1');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
     case 3:
       l.push('3');        //DA:$,1
@@ -359,17 +366,17 @@ checkGetOffsetsCoverage(function () { //
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     case 2:
     case 3:
       l.push('2');        //DA:$,1
       l.push('3');        //DA:$,1
@@ -380,17 +387,17 @@ checkGetOffsetsCoverage(function () { //
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
     default:
       l.push('1');        //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
     case 3:
@@ -402,17 +409,17 @@ checkGetOffsetsCoverage(function () { //
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
     case 2:
       l.push('2');        //DA:$,1
     case 3:
@@ -424,17 +431,17 @@ checkGetOffsetsCoverage(function () { //
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,1 //BRDA:$,0,3,- //BRDA:$,0,4,-
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 //BRDA:$,0,4,0
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
       l.push('default');  //DA:$,0
     case 2:
       l.push('2');        //DA:$,1
@@ -447,17 +454,17 @@ checkGetOffsetsCoverage(function () { //
   //LF:8
   //LH:5
   //BRF:5
   //BRH:1
 });
 
 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
   var l = ",".split(','); //DA:$,1
-  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,- //BRDA:$,0,1,- //BRDA:$,0,2,- //BRDA:$,0,3,1
+  switch (l.length) {     //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,0 //BRDA:$,0,3,1
     case 0:
       l.push('0');        //DA:$,0
     case 1:
       l.push('1');        //DA:$,0
     default:
       l.push('2');        //DA:$,1
     case 3:
       l.push('3');        //DA:$,1
@@ -466,10 +473,29 @@ checkGetOffsetsCoverage(function () { //
   //FNF:1
   //FNH:1
   //LF:7
   //LH:5
   //BRF:4
   //BRH:1
 });
 
+checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,%
+  var l = ','.split(','); //DA:$,1
+  if (l.length === 45) {  //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0
+    switch (l[0]) {       //DA:$,0 //BRDA:$,1,0,- //BRDA:$,1,1,-
+      case ',':
+        l.push('0');      //DA:$,0
+      default:
+        l.push('1');      //DA:$,0
+    }
+  }
+  l.pop();                //DA:$,1
+  //FNF:1
+  //FNH:1
+  //LF:6
+  //LH:3
+  //BRF:4
+  //BRH:1
+});
+
 // If you add a test case here, do the same in
 // jit-test/tests/coverage/simple.js
--- a/js/src/jit-test/tests/ion/recover-arrays.js
+++ b/js/src/jit-test/tests/ion/recover-arrays.js
@@ -270,18 +270,17 @@ function build(l) { var arr = []; for (v
 var uceFault_arrayAlloc3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arrayAlloc3'));
 function arrayAlloc3(i) {
     var a = [0,1,2,3];
     if (uceFault_arrayAlloc3(i) || uceFault_arrayAlloc3(i)) {
         assertEq(a[0], 0);
         assertEq(a[3], 3);
         return a.length;
     }
-    // TODO: Does not support NewArrayCopyOnWrite yet.
-    assertRecoveredOnBailout(a, false);
+    assertRecoveredOnBailout(a, true);
     return 0;
 };
 
 // Prevent compilation of the top-level
 eval(uneval(resumeHere));
 
 for (var i = 0; i < 100; i++) {
     array0Length(i);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/recover-cow-arrays.js
@@ -0,0 +1,218 @@
+// Ion eager fails the test below because we have not yet created any
+// template object in baseline before running the content of the top-level
+// function.
+if (getJitCompilerOptions()["ion.warmup.trigger"] <= 100)
+    setJitCompilerOption("ion.warmup.trigger", 100);
+
+// This test checks that we are able to remove the getelem & setelem with scalar
+// replacement, so we should not force inline caches, as this would skip the
+// generation of getelem & setelem instructions.
+if (getJitCompilerOptions()["ion.forceinlineCaches"])
+    setJitCompilerOption("ion.forceinlineCaches", 0);
+
+// This function is used to force a bailout when it is inlined, and to recover
+// the frame of the function in which this function is inlined.
+var resumeHere = function (i) { if (i >= 99) bailout(); };
+
+// This function is used to cause an invalidation after having removed a branch
+// after DCE.  This is made to check if we correctly recover an array
+// allocation.
+var uceFault = function (i) {
+    if (i > 98)
+        uceFault = function (i) { return true; };
+    return false;
+};
+
+// This function is used to ensure that we do escape the array, and thus prevent
+// any escape analysis.
+var global_arr;
+function escape(arr) { global_arr = arr; }
+
+// Check Array length defined by the literal.
+function array0Length(i) {
+    var a = [];
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array0LengthBail(i) {
+    var a = [];
+    resumeHere(i);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array1Length(i) {
+    var a = [1];
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array1LengthBail(i) {
+    var a = [1];
+    resumeHere(i);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2Length(i) {
+    var a = [1, 2];
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2LengthBail(i) {
+    var a = [1, 2];
+    resumeHere(i);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+
+// Check Array content
+function array1Content(i) {
+    var a = [42];
+    assertEq(a[0], 42);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+function array1ContentBail0(i) {
+    var a = [42];
+    resumeHere(i);
+    assertEq(a[0], 42);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+function array1ContentBail1(i) {
+    var a = [42];
+    assertEq(a[0], 42);
+    resumeHere(i);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2Content(i) {
+    var a = [1, 2];
+    assertEq(a[0], 1);
+    assertEq(a[1], 2);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2ContentBail0(i) {
+    var a = [1, 2];
+    resumeHere(i);
+    assertEq(a[0], 1);
+    assertEq(a[1], 2);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2ContentBail1(i) {
+    var a = [1, 2];
+    assertEq(a[0], 1);
+    resumeHere(i);
+    assertEq(a[1], 2);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+function array2ContentBail2(i) {
+    var a = [1, 2];
+    assertEq(a[0], 1);
+    assertEq(a[1], 2);
+    resumeHere(i);
+    assertRecoveredOnBailout(a, true);
+    return a.length;
+}
+
+// We don't handle COW array writes
+function arrayWrite1(i) {
+    var a = [1, 2];
+    a[0] = 42;
+    assertEq(a[0], 42);
+    assertEq(a[1], 2);
+    assertRecoveredOnBailout(a, false);
+    return a.length;
+}
+
+function arrayWrite2(i) {
+    var a = [1, 2];
+    a.length = 1;
+    assertEq(a[0], 1);
+    assertEq(a[1], undefined);
+    assertRecoveredOnBailout(a, false);
+    return a.length;
+}
+
+// Check escape analysis in case of holes.
+function arrayHole0(i) {
+    var a = [1,,3];
+    assertEq(a[0], 1);
+    assertEq(a[1], undefined);
+    assertEq(a[2], 3);
+    // need to check for holes.
+    assertRecoveredOnBailout(a, false);
+    return a.length;
+}
+
+// Same test as the previous one, but the Array.prototype is changed to return
+// "100" when we request for the element "1".
+function arrayHole1(i) {
+    var a = [1,,3];
+    assertEq(a[0], 1);
+    assertEq(a[1], 100);
+    assertEq(a[2], 3);
+    // need to check for holes.
+    assertRecoveredOnBailout(a, false);
+    return a.length;
+}
+
+function build(l) { var arr = []; for (var i = 0; i < l; i++) arr.push(i); return arr }
+var uceFault_arrayAlloc3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arrayAlloc3'));
+function arrayAlloc(i) {
+    var a = [0,1,2,3];
+    if (uceFault_arrayAlloc3(i) || uceFault_arrayAlloc3(i)) {
+        assertEq(a[0], 0);
+        assertEq(a[3], 3);
+        return a.length;
+    }
+    assertRecoveredOnBailout(a, true);
+    return 0;
+};
+
+// Prevent compilation of the top-level
+eval(uneval(resumeHere));
+
+for (var i = 0; i < 100; i++) {
+    array0Length(i);
+    array0LengthBail(i);
+    array1Length(i);
+    array1LengthBail(i);
+    array2Length(i);
+    array2LengthBail(i);
+    array1Content(i);
+    array1ContentBail0(i);
+    array1ContentBail1(i);
+    array2Content(i);
+    array2ContentBail0(i);
+    array2ContentBail1(i);
+    array2ContentBail2(i);
+    arrayWrite1(i);
+    arrayWrite2(i);
+    arrayHole0(i);
+    arrayAlloc(i);
+}
+
+// If arr[1] is not defined, then we fallback on the prototype which instead of
+// returning undefined, returns "0".
+Object.defineProperty(Array.prototype, 1, {
+  value: 100,
+  configurable: true,
+  enumerable: true,
+  writable: true
+});
+
+for (var i = 0; i < 100; i++) {
+    arrayHole1(i);
+}
--- a/js/src/jit/ExecutableAllocator.h
+++ b/js/src/jit/ExecutableAllocator.h
@@ -41,17 +41,16 @@
 #endif
 #include "jit/arm/Simulator-arm.h"
 #if defined(JS_CODEGEN_ARM64)
 #include "jit/arm64/vixl/Cpu-vixl.h"
 #endif
 #include "jit/mips32/Simulator-mips32.h"
 #include "jit/mips64/Simulator-mips64.h"
 #include "jit/ProcessExecutableMemory.h"
-#include "js/GCAPI.h"
 #include "js/HashTable.h"
 #include "js/Vector.h"
 
 #if defined(__sparc__)
 #ifdef __linux__  // bugzilla 502369
 static void sync_instruction_memory(caddr_t v, u_int len)
 {
     caddr_t end = v + len;
@@ -71,16 +70,18 @@ extern  "C" void sync_instruction_memory
      (!defined(JS_SIMULATOR_MIPS32) && !defined(JS_SIMULATOR_MIPS64))
 #include <sys/cachectl.h>
 #endif
 
 #if defined(JS_CODEGEN_ARM) && defined(XP_IOS)
 #include <libkern/OSCacheControl.h>
 #endif
 
+struct JSRuntime;
+
 namespace JS {
     struct CodeSizes;
 } // namespace JS
 
 namespace js {
 namespace jit {
 
 enum CodeKind { ION_CODE = 0, BASELINE_CODE, REGEXP_CODE, OTHER_CODE };
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6117,18 +6117,22 @@ IonBuilder::jsop_newarray_copyonwrite()
 
     // The baseline compiler should have ensured the template object has a type
     // with the copy on write flag set already. During the arguments usage
     // analysis the baseline compiler hasn't run yet, however, though in this
     // case the template object's type doesn't matter.
     MOZ_ASSERT_IF(info().analysisMode() != Analysis_ArgumentsUsage,
                   templateObject->group()->hasAnyFlags(OBJECT_FLAG_COPY_ON_WRITE));
 
+
+    MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
+    current->add(templateConst);
+
     MNewArrayCopyOnWrite* ins =
-        MNewArrayCopyOnWrite::New(alloc(), constraints(), templateObject,
+        MNewArrayCopyOnWrite::New(alloc(), constraints(), templateConst,
                                   templateObject->group()->initialHeap(constraints()));
 
     current->add(ins);
     current->push(ins);
 
     return Ok();
 }
 
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -9,17 +9,16 @@
 
 #include "mozilla/HashFunctions.h"
 
 #include <algorithm>
 
 #include "jsfriendapi.h"
 #include "jstypes.h"
 
-#include "js/GCAPI.h"
 #include "js/Value.h"
 #include "vm/String.h"
 
 namespace js {
 namespace jit {
 
 typedef uint32_t RecoverOffset;
 typedef uint32_t SnapshotOffset;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -5084,17 +5084,17 @@ MObjectState::initFromTemplateObject(Tem
     // uninitialized-lexical magic value of call objects.
     if (templateObject->is<UnboxedPlainObject>()) {
         UnboxedPlainObject& unboxedObject = templateObject->as<UnboxedPlainObject>();
         const UnboxedLayout& layout = unboxedObject.layoutDontCheckGeneration();
         const UnboxedLayout::PropertyVector& properties = layout.properties();
 
         for (size_t i = 0; i < properties.length(); i++) {
             Value val = unboxedObject.getValue(properties[i], /* maybeUninitialized = */ true);
-            MDefinition *def = undefinedVal;
+            MDefinition* def = undefinedVal;
             if (!val.isUndefined()) {
                 MConstant* ins = val.isObject() ?
                     MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
                     MConstant::New(alloc, val);
                 block()->insertBefore(this, ins);
                 def = ins;
             }
             initSlot(i, def);
@@ -5150,40 +5150,70 @@ MObjectState::Copy(TempAllocator& alloc,
 }
 
 MArrayState::MArrayState(MDefinition* arr)
   : MVariadicInstruction(classOpcode)
 {
     // This instruction is only used as a summary for bailout paths.
     setResultType(MIRType::Object);
     setRecoveredOnBailout();
-    numElements_ = arr->toNewArray()->length();
+    numElements_ = arr->isNewArray() ? arr->toNewArray()->length()
+                   : arr->toNewArrayCopyOnWrite()->length();
 }
 
 bool
 MArrayState::init(TempAllocator& alloc, MDefinition* obj, MDefinition* len)
 {
     if (!MVariadicInstruction::init(alloc, numElements() + 2))
         return false;
     // +1, for the Array object.
     initOperand(0, obj);
     // +1, for the length value of the array.
     initOperand(1, len);
     return true;
 }
 
+bool
+MArrayState::initFromTemplateObject(TempAllocator& alloc, MDefinition* undefinedVal)
+{
+    if (!array()->isNewArrayCopyOnWrite()) {
+        for (size_t i = 0; i < numElements(); i++)
+            initElement(i, undefinedVal);
+
+        return true;
+    }
+
+    ArrayObject* obj = array()->toNewArrayCopyOnWrite()->templateObject();
+    MOZ_ASSERT(obj->length() == numElements());
+
+    // Initialize all the elements of the object state with the value contained in
+    // the template object.
+    for (size_t i = 0; i < numElements(); i++) {
+        Value val = obj->getDenseElement(i);
+        MDefinition* def = undefinedVal;
+        if (!val.isUndefined()) {
+            MConstant* ins = val.isObject() ?
+                MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
+                MConstant::New(alloc, val);
+            block()->insertBefore(this, ins);
+            def = ins;
+        }
+        initElement(i, def);
+    }
+
+    return true;
+}
+
 MArrayState*
 MArrayState::New(TempAllocator& alloc, MDefinition* arr, MDefinition* undefinedVal,
                  MDefinition* initLength)
 {
     MArrayState* res = new(alloc) MArrayState(arr);
     if (!res || !res->init(alloc, arr, initLength))
         return nullptr;
-    for (size_t i = 0; i < res->numElements(); i++)
-        res->initElement(i, undefinedVal);
     return res;
 }
 
 MArrayState*
 MArrayState::Copy(TempAllocator& alloc, MArrayState* state)
 {
     MDefinition* arr = state->array();
     MDefinition* len = state->initializedLength();
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3366,50 +3366,55 @@ class MNewArray
     MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
     bool canRecoverOnBailout() const override {
         // The template object can safely be used in the recover instruction
         // because it can never be mutated by any other function execution.
         return templateObject() != nullptr;
     }
 };
 
-class MNewArrayCopyOnWrite : public MNullaryInstruction
-{
-    CompilerGCPointer<ArrayObject*> templateObject_;
+class MNewArrayCopyOnWrite
+  : public MUnaryInstruction,
+    public NoTypePolicy::Data
+{
     gc::InitialHeap initialHeap_;
 
     MNewArrayCopyOnWrite(TempAllocator& alloc, CompilerConstraintList* constraints,
-                         ArrayObject* templateObject, gc::InitialHeap initialHeap)
-      : MNullaryInstruction(classOpcode),
-        templateObject_(templateObject),
+                         MConstant* templateConst, gc::InitialHeap initialHeap)
+      : MUnaryInstruction(classOpcode, templateConst),
         initialHeap_(initialHeap)
     {
-        MOZ_ASSERT(!templateObject->isSingleton());
+        MOZ_ASSERT(!templateObject()->isSingleton());
         setResultType(MIRType::Object);
-        setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, templateObject));
+        setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, templateObject()));
     }
 
   public:
     INSTRUCTION_HEADER(NewArrayCopyOnWrite)
     TRIVIAL_NEW_WRAPPERS_WITH_ALLOC
 
+    uint32_t length() const {
+      return templateObject()->length();
+    }
+
     ArrayObject* templateObject() const {
-        return templateObject_;
+        return &getOperand(0)->toConstant()->toObject().as<ArrayObject>();
     }
 
     gc::InitialHeap initialHeap() const {
         return initialHeap_;
     }
 
     virtual AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
 
-    bool appendRoots(MRootList& roots) const override {
-        return roots.append(templateObject_);
+    MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
+    bool canRecoverOnBailout() const override {
+        return true;
     }
 };
 
 class MNewArrayDynamicLength
   : public MUnaryInstruction,
     public IntPolicy<0>::Data
 {
     CompilerObject templateObject_;
@@ -3997,21 +4002,23 @@ class MArrayState
   public:
     INSTRUCTION_HEADER(ArrayState)
     NAMED_OPERANDS((0, array), (1, initializedLength))
 
     static MArrayState* New(TempAllocator& alloc, MDefinition* arr, MDefinition* undefinedVal,
                             MDefinition* initLength);
     static MArrayState* Copy(TempAllocator& alloc, MArrayState* state);
 
+    // Initialize values from CopyOnWrite arrays.
+    MOZ_MUST_USE bool initFromTemplateObject(TempAllocator& alloc, MDefinition* undefinedVal);
+
     void setInitializedLength(MDefinition* def) {
         replaceOperand(1, def);
     }
 
-
     size_t numElements() const {
         return numElements_;
     }
 
     MDefinition* getElement(uint32_t index) const {
         return getOperand(index + 2);
     }
     void setElement(uint32_t index, MDefinition* def) {
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -16,17 +16,16 @@
 #include "jit/AtomicOp.h"
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/Lowering.h"
 #include "jit/MIR.h"
 #include "js/Conversions.h"
-#include "js/GCAPI.h"
 #include "vm/TraceLogging.h"
 
 #include "jsobjinlines.h"
 
 #include "gc/Nursery-inl.h"
 #include "jit/shared/Lowering-shared-inl.h"
 #include "vm/Interpreter-inl.h"
 
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -1397,16 +1397,45 @@ RNewArray::recover(JSContext* cx, Snapsh
         return false;
 
     result.setObject(*resultObject);
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
+MNewArrayCopyOnWrite::writeRecoverData(CompactBufferWriter& writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_NewArrayCopyOnWrite));
+    writer.writeByte(initialHeap());
+    return true;
+}
+
+RNewArrayCopyOnWrite::RNewArrayCopyOnWrite(CompactBufferReader& reader)
+{
+    initialHeap_ = gc::InitialHeap(reader.readByte());
+}
+
+bool
+RNewArrayCopyOnWrite::recover(JSContext* cx, SnapshotIterator& iter) const
+{
+    RootedArrayObject templateObject(cx, &iter.read().toObject().as<ArrayObject>());
+    RootedValue result(cx);
+
+    ArrayObject* resultObject = NewDenseCopyOnWriteArray(cx, templateObject, initialHeap_);
+    if (!resultObject)
+        return false;
+
+    result.setObject(*resultObject);
+    iter.storeInstructionResult(result);
+    return true;
+}
+
+bool
 MNewIterator::writeRecoverData(CompactBufferWriter& writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_NewIterator));
     writer.writeByte(type_);
     return true;
 }
 
@@ -1727,26 +1756,36 @@ RArrayState::RArrayState(CompactBufferRe
 
 bool
 RArrayState::recover(JSContext* cx, SnapshotIterator& iter) const
 {
     RootedValue result(cx);
     ArrayObject* object = &iter.read().toObject().as<ArrayObject>();
     uint32_t initLength = iter.read().toInt32();
 
-    object->setDenseInitializedLength(initLength);
-    for (size_t index = 0; index < numElements(); index++) {
-        Value val = iter.read();
+    if (!object->denseElementsAreCopyOnWrite()) {
+        object->setDenseInitializedLength(initLength);
+        for (size_t index = 0; index < numElements(); index++) {
+            Value val = iter.read();
+
+            if (index >= initLength) {
+                MOZ_ASSERT(val.isUndefined());
+                continue;
+            }
 
-        if (index >= initLength) {
-            MOZ_ASSERT(val.isUndefined());
-            continue;
+            object->initDenseElement(index, val);
         }
+    } else {
+        MOZ_ASSERT(object->getDenseInitializedLength() == numElements());
+        MOZ_ASSERT(initLength == numElements());
 
-        object->initDenseElement(index, val);
+        for (size_t index = 0; index < numElements(); index++) {
+            Value val = iter.read();
+            MOZ_RELEASE_ASSERT(object->getDenseElement(index) == val);
+        }
     }
 
     result.setObject(*object);
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -98,16 +98,17 @@ namespace jit {
     _(StringReplace)                            \
     _(TypeOf)                                   \
     _(ToDouble)                                 \
     _(ToFloat32)                                \
     _(TruncateToInt32)                          \
     _(NewObject)                                \
     _(NewTypedArray)                            \
     _(NewArray)                                 \
+    _(NewArrayCopyOnWrite)                      \
     _(NewIterator)                              \
     _(NewDerivedTypedObject)                    \
     _(NewCallObject)                            \
     _(CreateThisWithTemplate)                   \
     _(Lambda)                                   \
     _(LambdaArrow)                              \
     _(SimdBox)                                  \
     _(ObjectState)                              \
@@ -604,16 +605,27 @@ class RNewArray final : public RInstruct
     uint32_t count_;
 
   public:
     RINSTRUCTION_HEADER_NUM_OP_(NewArray, 1)
 
     MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
 };
 
+class RNewArrayCopyOnWrite final : public RInstruction
+{
+  private:
+    gc::InitialHeap initialHeap_;
+
+  public:
+    RINSTRUCTION_HEADER_NUM_OP_(NewArrayCopyOnWrite, 1)
+
+    MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
+};
+
 class RNewIterator final : public RInstruction
 {
   private:
     uint8_t type_;
 
   public:
     RINSTRUCTION_HEADER_NUM_OP_(NewIterator, 1)
 
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -870,17 +870,17 @@ IndexOf(MDefinition* ins, int32_t* res)
         return false;
     *res = indexDefConst->toInt32();
     return true;
 }
 
 // Returns False if the elements is not escaped and if it is optimizable by
 // ScalarReplacementOfArray.
 static bool
-IsElementEscaped(MElements* def, uint32_t arraySize)
+IsElementEscaped(MElements* def, uint32_t arraySize, bool copyOnWrite)
 {
     JitSpewDef(JitSpew_Escape, "Check elements\n", def);
     JitSpewIndent spewIndent(JitSpew_Escape);
 
     for (MUseIterator i(def->usesBegin()); i != def->usesEnd(); i++) {
         // The MIRType::Elements cannot be captured in a resume point as
         // it does not represent a value allocation.
         MDefinition* access = (*i)->consumer()->toDefinition();
@@ -914,16 +914,21 @@ IsElementEscaped(MElements* def, uint32_
                 return true;
             }
             break;
           }
 
           case MDefinition::Opcode::StoreElement: {
             MOZ_ASSERT(access->toStoreElement()->elements() == def);
 
+            if (copyOnWrite) {
+                JitSpewDef(JitSpew_Escape, "write to COW\n", access);
+                return true;
+            }
+
             // If we need hole checks, then the array cannot be escaped
             // as the array might refer to the prototype chain to look
             // for properties, thus it might do additional side-effects
             // which are not reflected by the alias set, is we are
             // bailing on holes.
             if (access->toStoreElement()->needsHoleCheck()) {
                 JitSpewDef(JitSpew_Escape,
                            "has a store element with a hole check\n", access);
@@ -946,16 +951,21 @@ IsElementEscaped(MElements* def, uint32_
             if (access->toStoreElement()->value()->type() == MIRType::MagicHole) {
                 JitSpewDef(JitSpew_Escape, "has a store element with an magic-hole constant\n", access);
                 return true;
             }
             break;
           }
 
           case MDefinition::Opcode::SetInitializedLength:
+            if (copyOnWrite) {
+                JitSpewDef(JitSpew_Escape, "write to COW\n", access);
+                return true;
+            }
+
             MOZ_ASSERT(access->toSetInitializedLength()->elements() == def);
             break;
 
           case MDefinition::Opcode::InitializedLength:
             MOZ_ASSERT(access->toInitializedLength()->elements() == def);
             break;
 
           case MDefinition::Opcode::ArrayLength:
@@ -966,35 +976,46 @@ IsElementEscaped(MElements* def, uint32_
             JitSpewDef(JitSpew_Escape, "is escaped by\n", access);
             return true;
         }
     }
     JitSpew(JitSpew_Escape, "Elements is not escaped");
     return false;
 }
 
+static inline bool
+IsOptimizableArrayInstruction(MInstruction* ins)
+{
+    return ins->isNewArray() || ins->isNewArrayCopyOnWrite();
+}
+
 // Returns False if the array is not escaped and if it is optimizable by
 // ScalarReplacementOfArray.
 //
 // For the moment, this code is dumb as it only supports arrays which are not
 // changing length, with only access with known constants.
 static bool
 IsArrayEscaped(MInstruction* ins)
 {
     MOZ_ASSERT(ins->type() == MIRType::Object);
-    MOZ_ASSERT(ins->isNewArray());
-    uint32_t length = ins->toNewArray()->length();
+    MOZ_ASSERT(IsOptimizableArrayInstruction(ins));
 
     JitSpewDef(JitSpew_Escape, "Check array\n", ins);
     JitSpewIndent spewIndent(JitSpew_Escape);
 
-    JSObject* obj = ins->toNewArray()->templateObject();
-    if (!obj) {
-        JitSpew(JitSpew_Escape, "No template object defined.");
-        return true;
+    uint32_t length;
+    if (ins->isNewArray()) {
+        if (!ins->toNewArray()->templateObject()) {
+            JitSpew(JitSpew_Escape, "No template object defined.");
+            return true;
+        }
+
+        length = ins->toNewArray()->length();
+    } else {
+        length = ins->toNewArrayCopyOnWrite()->templateObject()->length();
     }
 
     if (length >= 16) {
         JitSpew(JitSpew_Escape, "Array has too many elements");
         return true;
     }
 
     // Check if the object is escaped. If the object is not the first argument
@@ -1011,17 +1032,17 @@ IsArrayEscaped(MInstruction* ins)
             continue;
         }
 
         MDefinition* def = consumer->toDefinition();
         switch (def->op()) {
           case MDefinition::Opcode::Elements: {
             MElements *elem = def->toElements();
             MOZ_ASSERT(elem->object() == ins);
-            if (IsElementEscaped(elem, length)) {
+            if (IsElementEscaped(elem, length, ins->isNewArrayCopyOnWrite())) {
                 JitSpewDef(JitSpew_Escape, "is indirectly escaped by\n", elem);
                 return true;
             }
 
             break;
           }
 
           // This instruction is a no-op used to verify that scalar replacement
@@ -1121,27 +1142,33 @@ ArrayMemoryView::startingBlock()
     return startBlock_;
 }
 
 bool
 ArrayMemoryView::initStartingState(BlockState** pState)
 {
     // Uninitialized elements have an "undefined" value.
     undefinedVal_ = MConstant::New(alloc_, UndefinedValue());
-    MConstant* initLength = MConstant::New(alloc_, Int32Value(0));
+    MConstant* initLength = MConstant::New(alloc_, Int32Value(arr_->isNewArrayCopyOnWrite()
+                                                              ? arr_->toNewArrayCopyOnWrite()->length()
+                                                              : 0));
     arr_->block()->insertBefore(arr_, undefinedVal_);
     arr_->block()->insertBefore(arr_, initLength);
 
     // Create a new block state and insert at it at the location of the new array.
     BlockState* state = BlockState::New(alloc_, arr_, undefinedVal_, initLength);
     if (!state)
         return false;
 
     startBlock_->insertAfter(arr_, state);
 
+    // Initialize the elements of the array state.
+    if (!state->initFromTemplateObject(alloc_, undefinedVal_))
+        return false;
+
     // Hold out of resume point until it is visited.
     state->setInWorklist();
 
     *pState = state;
     return true;
 }
 
 void
@@ -1396,17 +1423,17 @@ ScalarReplacement(MIRGenerator* mir, MIR
                 ObjectMemoryView view(graph.alloc(), *ins);
                 if (!replaceObject.run(view))
                     return false;
                 view.assertSuccess();
                 addedPhi = true;
                 continue;
             }
 
-            if (ins->isNewArray() && !IsArrayEscaped(*ins)) {
+            if (IsOptimizableArrayInstruction(*ins) && !IsArrayEscaped(*ins)) {
                 ArrayMemoryView view(graph.alloc(), *ins);
                 if (!replaceArray.run(view))
                     return false;
                 view.assertSuccess();
                 addedPhi = true;
                 continue;
             }
         }
--- a/js/src/jsapi-tests/testGCHooks.cpp
+++ b/js/src/jsapi-tests/testGCHooks.cpp
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/UniquePtr.h"
 
-#include "js/GCAPI.h"
-
 #include "jsapi-tests/tests.h"
 
 static unsigned gSliceCallbackCount = 0;
 
 static void
 NonIncrementalGCSliceCallback(JSContext* cx, JS::GCProgress progress, const JS::GCDescription& desc)
 {
     using namespace JS;
--- a/js/src/jsapi-tests/testIntTypesABI.cpp
+++ b/js/src/jsapi-tests/testIntTypesABI.cpp
@@ -14,17 +14,16 @@
 #include "jstypes.h"
 
 #include "js/CallArgs.h"
 #include "js/CallNonGenericMethod.h"
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/Date.h"
 #include "js/Debug.h"
-#include "js/GCAPI.h"
 #include "js/HashTable.h"
 #include "js/HeapAPI.h"
 #include "js/Id.h"
 /* LegacyIntTypes.h is deliberately exempted from this requirement */
 #include "js/MemoryMetrics.h"
 #include "js/ProfilingStack.h"
 #include "js/RefCounted.h"
 #include "js/RequiredDefines.h"
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -544,63 +544,16 @@ struct JSFreeOp {
         return runtime_;
     }
 };
 
 /* Callbacks and their arguments. */
 
 /************************************************************************/
 
-typedef enum JSGCStatus {
-    JSGC_BEGIN,
-    JSGC_END
-} JSGCStatus;
-
-typedef void
-(* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data);
-
-typedef void
-(* JSObjectsTenuredCallback)(JSContext* cx, void* data);
-
-typedef enum JSFinalizeStatus {
-    /**
-     * Called when preparing to sweep a group of zones, before anything has been
-     * swept.  The collector will not yield to the mutator before calling the
-     * callback with JSFINALIZE_GROUP_START status.
-     */
-    JSFINALIZE_GROUP_PREPARE,
-
-    /**
-     * Called after preparing to sweep a group of zones. Weak references to
-     * unmarked things have been removed at this point, but no GC things have
-     * been swept. The collector may yield to the mutator after this point.
-     */
-    JSFINALIZE_GROUP_START,
-
-    /**
-     * Called after sweeping a group of zones. All dead GC things have been
-     * swept at this point.
-     */
-    JSFINALIZE_GROUP_END,
-
-    /**
-     * Called at the end of collection when everything has been swept.
-     */
-    JSFINALIZE_COLLECTION_END
-} JSFinalizeStatus;
-
-typedef void
-(* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, void* data);
-
-typedef void
-(* JSWeakPointerZonesCallback)(JSContext* cx, void* data);
-
-typedef void
-(* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data);
-
 typedef bool
 (* JSInterruptCallback)(JSContext* cx);
 
 typedef JSObject*
 (* JSGetIncumbentGlobalCallback)(JSContext* cx);
 
 typedef bool
 (* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job,
@@ -1724,359 +1677,16 @@ JS_freeop(JSFreeOp* fop, void* p);
 
 extern JS_PUBLIC_API(void)
 JS_updateMallocCounter(JSContext* cx, size_t nbytes);
 
 extern JS_PUBLIC_API(char*)
 JS_strdup(JSContext* cx, const char* s);
 
 /**
- * Register externally maintained GC roots.
- *
- * traceOp: the trace operation. For each root the implementation should call
- *          JS::TraceEdge whenever the root contains a traceable thing.
- * data:    the data argument to pass to each invocation of traceOp.
- */
-extern JS_PUBLIC_API(bool)
-JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
-
-/** Undo a call to JS_AddExtraGCRootsTracer. */
-extern JS_PUBLIC_API(void)
-JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
-
-/*
- * Garbage collector API.
- */
-namespace JS {
-
-extern JS_PUBLIC_API(bool)
-IsIdleGCTaskNeeded(JSRuntime* rt);
-
-extern JS_PUBLIC_API(void)
-RunIdleTimeGCTask(JSRuntime* rt);
-
-} // namespace JS
-
-extern JS_PUBLIC_API(void)
-JS_GC(JSContext* cx);
-
-extern JS_PUBLIC_API(void)
-JS_MaybeGC(JSContext* cx);
-
-extern JS_PUBLIC_API(void)
-JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data);
-
-extern JS_PUBLIC_API(void)
-JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb,
-                             void* data);
-
-extern JS_PUBLIC_API(bool)
-JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data);
-
-extern JS_PUBLIC_API(void)
-JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb);
-
-/*
- * Weak pointers and garbage collection
- *
- * Weak pointers are by their nature not marked as part of garbage collection,
- * but they may need to be updated in two cases after a GC:
- *
- *  1) Their referent was found not to be live and is about to be finalized
- *  2) Their referent has been moved by a compacting GC
- *
- * To handle this, any part of the system that maintain weak pointers to
- * JavaScript GC things must register a callback with
- * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
- * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
- * about.
- *
- * Since sweeping is incremental, we have several callbacks to avoid repeatedly
- * having to visit all embedder structures. The WeakPointerZonesCallback is
- * called once for each strongly connected group of zones, whereas the
- * WeakPointerCompartmentCallback is called once for each compartment that is
- * visited while sweeping. Structures that cannot contain references in more
- * than one compartment should sweep the relevant per-compartment structures
- * using the latter callback to minimizer per-slice overhead.
- *
- * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
- * referent is about to be finalized the pointer will be set to null. If the
- * referent has been moved then the pointer will be updated to point to the new
- * location.
- *
- * Callers of this method are responsible for updating any state that is
- * dependent on the object's address. For example, if the object's address is
- * used as a key in a hashtable, then the object must be removed and
- * re-inserted with the correct hash.
- */
-
-extern JS_PUBLIC_API(bool)
-JS_AddWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb, void* data);
-
-extern JS_PUBLIC_API(void)
-JS_RemoveWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb);
-
-extern JS_PUBLIC_API(bool)
-JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb,
-                                     void* data);
-
-extern JS_PUBLIC_API(void)
-JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb);
-
-extern JS_PUBLIC_API(void)
-JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
-
-extern JS_PUBLIC_API(void)
-JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
-
-typedef enum JSGCParamKey {
-    /**
-     * Maximum nominal heap before last ditch GC.
-     *
-     * Soft limit on the number of bytes we are allowed to allocate in the GC
-     * heap. Attempts to allocate gcthings over this limit will return null and
-     * subsequently invoke the standard OOM machinery, independent of available
-     * physical memory.
-     *
-     * Pref: javascript.options.mem.max
-     * Default: 0xffffffff
-     */
-    JSGC_MAX_BYTES          = 0,
-
-    /**
-     * Initial value for the malloc bytes threshold.
-     *
-     * Pref: javascript.options.mem.high_water_mark
-     * Default: TuningDefaults::MaxMallocBytes
-     */
-    JSGC_MAX_MALLOC_BYTES   = 1,
-
-    /**
-     * Maximum size of the generational GC nurseries.
-     *
-     * Pref: javascript.options.mem.nursery.max_kb
-     * Default: JS::DefaultNurseryBytes
-     */
-    JSGC_MAX_NURSERY_BYTES  = 2,
-
-    /** Amount of bytes allocated by the GC. */
-    JSGC_BYTES = 3,
-
-    /** Number of times GC has been invoked. Includes both major and minor GC. */
-    JSGC_NUMBER = 4,
-
-    /**
-     * Select GC mode.
-     *
-     * See: JSGCMode in GCAPI.h
-     * prefs: javascript.options.mem.gc_per_zone and
-     *   javascript.options.mem.gc_incremental.
-     * Default: JSGC_MODE_INCREMENTAL
-     */
-    JSGC_MODE = 6,
-
-    /** Number of cached empty GC chunks. */
-    JSGC_UNUSED_CHUNKS = 7,
-
-    /** Total number of allocated GC chunks. */
-    JSGC_TOTAL_CHUNKS = 8,
-
-    /**
-     * Max milliseconds to spend in an incremental GC slice.
-     *
-     * Pref: javascript.options.mem.gc_incremental_slice_ms
-     * Default: DefaultTimeBudget.
-     */
-    JSGC_SLICE_TIME_BUDGET = 9,
-
-    /**
-     * Maximum size the GC mark stack can grow to.
-     *
-     * Pref: none
-     * Default: MarkStack::DefaultCapacity
-     */
-    JSGC_MARK_STACK_LIMIT = 10,
-
-    /**
-     * GCs less than this far apart in time will be considered 'high-frequency
-     * GCs'.
-     *
-     * See setGCLastBytes in jsgc.cpp.
-     *
-     * Pref: javascript.options.mem.gc_high_frequency_time_limit_ms
-     * Default: HighFrequencyThresholdUsec
-     */
-    JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
-
-    /**
-     * Start of dynamic heap growth.
-     *
-     * Pref: javascript.options.mem.gc_high_frequency_low_limit_mb
-     * Default: HighFrequencyLowLimitBytes
-     */
-    JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
-
-    /**
-     * End of dynamic heap growth.
-     *
-     * Pref: javascript.options.mem.gc_high_frequency_high_limit_mb
-     * Default: HighFrequencyHighLimitBytes
-     */
-    JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
-
-    /**
-     * Upper bound of heap growth.
-     *
-     * Pref: javascript.options.mem.gc_high_frequency_heap_growth_max
-     * Default: HighFrequencyHeapGrowthMax
-     */
-    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
-
-    /**
-     * Lower bound of heap growth.
-     *
-     * Pref: javascript.options.mem.gc_high_frequency_heap_growth_min
-     * Default: HighFrequencyHeapGrowthMin
-     */
-    JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
-
-    /**
-     * Heap growth for low frequency GCs.
-     *
-     * Pref: javascript.options.mem.gc_low_frequency_heap_growth
-     * Default: LowFrequencyHeapGrowth
-     */
-    JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
-
-    /**
-     * If false, the heap growth factor is fixed at 3. If true, it is determined
-     * based on whether GCs are high- or low- frequency.
-     *
-     * Pref: javascript.options.mem.gc_dynamic_heap_growth
-     * Default: DynamicHeapGrowthEnabled
-     */
-    JSGC_DYNAMIC_HEAP_GROWTH = 17,
-
-    /**
-     * If true, high-frequency GCs will use a longer mark slice.
-     *
-     * Pref: javascript.options.mem.gc_dynamic_mark_slice
-     * Default: DynamicMarkSliceEnabled
-     */
-    JSGC_DYNAMIC_MARK_SLICE = 18,
-
-    /**
-     * Lower limit after which we limit the heap growth.
-     *
-     * The base value used to compute zone->threshold.gcTriggerBytes(). When
-     * usage.gcBytes() surpasses threshold.gcTriggerBytes() for a zone, the
-     * zone may be scheduled for a GC, depending on the exact circumstances.
-     *
-     * Pref: javascript.options.mem.gc_allocation_threshold_mb
-     * Default GCZoneAllocThresholdBase
-     */
-    JSGC_ALLOCATION_THRESHOLD = 19,
-
-    /**
-     * We try to keep at least this many unused chunks in the free chunk pool at
-     * all times, even after a shrinking GC.
-     *
-     * Pref: javascript.options.mem.gc_min_empty_chunk_count
-     * Default: MinEmptyChunkCount
-     */
-    JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
-
-    /**
-     * We never keep more than this many unused chunks in the free chunk
-     * pool.
-     *
-     * Pref: javascript.options.mem.gc_min_empty_chunk_count
-     * Default: MinEmptyChunkCount
-     */
-    JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
-
-    /**
-     * Whether compacting GC is enabled.
-     *
-     * Pref: javascript.options.mem.gc_compacting
-     * Default: CompactingEnabled
-     */
-    JSGC_COMPACTING_ENABLED = 23,
-
-    /**
-     * If true, painting can trigger IGC slices.
-     *
-     * Pref: javascript.options.mem.gc_refresh_frame_slices_enabled
-     * Default: RefreshFrameSlicesEnabled
-     */
-    JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
-
-    /**
-     * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD
-     *
-     * Default: ZoneAllocThresholdFactorDefault
-     * Pref: None
-     */
-    JSGC_ALLOCATION_THRESHOLD_FACTOR = 25,
-
-    /**
-     * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD.
-     * Used if another GC (in different zones) is already running.
-     *
-     * Default: ZoneAllocThresholdFactorAvoidInterruptDefault
-     * Pref: None
-     */
-    JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT = 26,
-} JSGCParamKey;
-
-extern JS_PUBLIC_API(void)
-JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
-
-extern JS_PUBLIC_API(void)
-JS_ResetGCParameter(JSContext* cx, JSGCParamKey key);
-
-extern JS_PUBLIC_API(uint32_t)
-JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
-
-extern JS_PUBLIC_API(void)
-JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem);
-
-/**
- * Create a new JSString whose chars member refers to external memory, i.e.,
- * memory requiring application-specific finalization.
- */
-extern JS_PUBLIC_API(JSString*)
-JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
-                     const JSStringFinalizer* fin);
-
-/**
- * Create a new JSString whose chars member may refer to external memory.
- * If a new external string is allocated, |*allocatedExternal| is set to true.
- * Otherwise the returned string is either not an external string or an
- * external string allocated by a previous call and |*allocatedExternal| is set
- * to false. If |*allocatedExternal| is false, |fin| won't be called.
- */
-extern JS_PUBLIC_API(JSString*)
-JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
-                          const JSStringFinalizer* fin, bool* allocatedExternal);
-
-/**
- * Return whether 'str' was created with JS_NewExternalString or
- * JS_NewExternalStringWithClosure.
- */
-extern JS_PUBLIC_API(bool)
-JS_IsExternalString(JSString* str);
-
-/**
- * Return the 'fin' arg passed to JS_NewExternalString.
- */
-extern JS_PUBLIC_API(const JSStringFinalizer*)
-JS_GetExternalStringFinalizer(JSString* str);
-
-/**
  * Set the size of the native stack that should not be exceed. To disable
  * stack size checking pass 0.
  *
  * SpiderMonkey allows for a distinction between system code (such as GCs, which
  * may incidentally be triggered by script but are not strictly performed on
  * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
  * and untrusted script. Each kind of code may have a different stack quota,
  * allowing embedders to keep higher-priority machinery running in the face of
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -66,43 +66,18 @@ class AtomStateEntry
     bool needsSweep() {
         JSAtom* atom = asPtrUnbarriered();
         return gc::IsAboutToBeFinalizedUnbarriered(&atom);
     }
 };
 
 struct AtomHasher
 {
-    struct Lookup
-    {
-        union {
-            const JS::Latin1Char* latin1Chars;
-            const char16_t* twoByteChars;
-        };
-        bool isLatin1;
-        size_t length;
-        const JSAtom* atom; /* Optional. */
-        JS::AutoCheckCannotGC nogc;
-
-        HashNumber hash;
-
-        MOZ_ALWAYS_INLINE Lookup(const char16_t* chars, size_t length)
-          : twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
-        {
-            hash = mozilla::HashString(chars, length);
-        }
-        MOZ_ALWAYS_INLINE Lookup(const JS::Latin1Char* chars, size_t length)
-          : latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
-        {
-            hash = mozilla::HashString(chars, length);
-        }
-        inline explicit Lookup(const JSAtom* atom);
-    };
-
-    static HashNumber hash(const Lookup& l) { return l.hash; }
+    struct Lookup;
+    static inline HashNumber hash(const Lookup& l);
     static MOZ_ALWAYS_INLINE bool match(const AtomStateEntry& entry, const Lookup& lookup);
     static void rekey(AtomStateEntry& k, const AtomStateEntry& newKey) { k = newKey; }
 };
 
 using AtomSet = JS::GCHashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy>;
 
 // This class is a wrapper for AtomSet that is used to ensure the AtomSet is
 // not modified. It should only expose read-only methods from AtomSet.
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -30,16 +30,48 @@ inline JSAtom*
 js::AtomStateEntry::asPtrUnbarriered() const
 {
     MOZ_ASSERT(bits != 0);
     return reinterpret_cast<JSAtom*>(bits & NO_TAG_MASK);
 }
 
 namespace js {
 
+struct AtomHasher::Lookup
+{
+    union {
+        const JS::Latin1Char* latin1Chars;
+        const char16_t* twoByteChars;
+    };
+    bool isLatin1;
+    size_t length;
+    const JSAtom* atom; /* Optional. */
+    JS::AutoCheckCannotGC nogc;
+
+    HashNumber hash;
+
+    MOZ_ALWAYS_INLINE Lookup(const char16_t* chars, size_t length)
+      : twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
+        {
+            hash = mozilla::HashString(chars, length);
+        }
+    MOZ_ALWAYS_INLINE Lookup(const JS::Latin1Char* chars, size_t length)
+      : latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
+        {
+            hash = mozilla::HashString(chars, length);
+        }
+    inline explicit Lookup(const JSAtom* atom);
+};
+
+inline HashNumber
+AtomHasher::hash(const Lookup& l)
+{
+    return l.hash;
+}
+
 inline jsid
 AtomToId(JSAtom* atom)
 {
     JS_STATIC_ASSERT(JSID_INT_MIN == 0);
 
     uint32_t index;
     if (atom->isIndex(&index) && index <= JSID_INT_MAX)
         return INT_TO_JSID(int32_t(index));
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -15,17 +15,16 @@
  * values, called slots.  The map/slot pointer pair is GC'ed, while the map
  * is reference counted and the slot vector is malloc'ed.
  */
 
 #include "mozilla/MemoryReporting.h"
 
 #include "gc/Barrier.h"
 #include "js/Conversions.h"
-#include "js/GCAPI.h"
 #include "js/GCVector.h"
 #include "js/HeapAPI.h"
 #include "vm/Printer.h"
 #include "vm/Shape.h"
 #include "vm/String.h"
 #include "vm/Xdr.h"
 
 namespace JS {
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -102,23 +102,16 @@ class JS_PUBLIC_API(JSTracer);
 class JSFlatString;
 
 typedef bool                    (*JSInitCallback)(void);
 
 template<typename T> struct JSConstScalarSpec;
 typedef JSConstScalarSpec<double> JSConstDoubleSpec;
 typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
 
-/*
- * Generic trace operation that calls JS::TraceEdge on each traceable thing's
- * location reachable from data.
- */
-typedef void
-(* JSTraceDataOp)(JSTracer* trc, void* data);
-
 namespace js {
 namespace gc {
 class AutoTraceSession;
 class StoreBuffer;
 } // namespace gc
 
 class CooperatingContext;
 
@@ -203,177 +196,18 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(Auto
     ~AutoEnterCycleCollection();
 #else
   public:
     explicit AutoEnterCycleCollection(JSRuntime* rt) {}
     ~AutoEnterCycleCollection() {}
 #endif
 };
 
-class RootingContext;
-
-// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
-// instantiation of MapTypeToRootKind.
-template <>
-struct MapTypeToRootKind<void*> {
-    static const RootKind kind = RootKind::Traceable;
-};
-
-using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
-                                                 Rooted<void*>*>;
-
-/*
- * This list enumerates the different types of conceptual stacks we have in
- * SpiderMonkey. In reality, they all share the C stack, but we allow different
- * stack limits depending on the type of code running.
- */
-enum StackKind
-{
-    StackForSystemCode,      // C++, such as the GC, running on behalf of the VM.
-    StackForTrustedScript,   // Script running with trusted principals.
-    StackForUntrustedScript, // Script running with untrusted principals.
-    StackKindCount
-};
-
-class JS_PUBLIC_API(AutoGCRooter);
-
-// Superclass of JSContext which can be used for rooting data in use by the
-// current thread but that does not provide all the functions of a JSContext.
-class RootingContext
-{
-    // Stack GC roots for Rooted GC heap pointers.
-    RootedListHeads stackRoots_;
-    template <typename T> friend class JS::Rooted;
-
-    // Stack GC roots for AutoFooRooter classes.
-    JS::AutoGCRooter* autoGCRooters_;
-    friend class JS::AutoGCRooter;
-
-  public:
-    RootingContext();
-
-    void traceStackRoots(JSTracer* trc);
-    void checkNoGCRooters();
-
-  protected:
-    // The remaining members in this class should only be accessed through
-    // JSContext pointers. They are unrelated to rooting and are in place so
-    // that inlined API functions can directly access the data.
-
-    /* The current compartment. */
-    JSCompartment*      compartment_;
-
-    /* The current zone. */
-    JS::Zone*           zone_;
-
-  public:
-    /* Limit pointer for checking native stack consumption. */
-    uintptr_t nativeStackLimit[StackKindCount];
-
-    static const RootingContext* get(const JSContext* cx) {
-        return reinterpret_cast<const RootingContext*>(cx);
-    }
-
-    static RootingContext* get(JSContext* cx) {
-        return reinterpret_cast<RootingContext*>(cx);
-    }
-
-    friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
-    friend JS::Zone* js::GetContextZone(const JSContext* cx);
-};
-
-class JS_PUBLIC_API(AutoGCRooter)
-{
-  public:
-    AutoGCRooter(JSContext* cx, ptrdiff_t tag)
-      : AutoGCRooter(JS::RootingContext::get(cx), tag)
-    {}
-    AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
-      : down(cx->autoGCRooters_),
-        tag_(tag),
-        stackTop(&cx->autoGCRooters_)
-    {
-        MOZ_ASSERT(this != *stackTop);
-        *stackTop = this;
-    }
-
-    ~AutoGCRooter() {
-        MOZ_ASSERT(this == *stackTop);
-        *stackTop = down;
-    }
-
-    /* Implemented in gc/RootMarking.cpp. */
-    inline void trace(JSTracer* trc);
-    static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
-    static void traceAllWrappers(const js::CooperatingContext& target, JSTracer* trc);
-
-  protected:
-    AutoGCRooter * const down;
-
-    /*
-     * Discriminates actual subclass of this being used.  If non-negative, the
-     * subclass roots an array of values of the length stored in this field.
-     * If negative, meaning is indicated by the corresponding value in the enum
-     * below.  Any other negative value indicates some deeper problem such as
-     * memory corruption.
-     */
-    ptrdiff_t tag_;
-
-    enum {
-        VALARRAY =     -2, /* js::AutoValueArray */
-        PARSER =       -3, /* js::frontend::Parser */
-        VALVECTOR =   -10, /* js::AutoValueVector */
-        IDVECTOR =    -11, /* js::AutoIdVector */
-        OBJVECTOR =   -14, /* js::AutoObjectVector */
-        IONMASM =     -19, /* js::jit::MacroAssembler */
-        WRAPVECTOR =  -20, /* js::AutoWrapperVector */
-        WRAPPER =     -21, /* js::AutoWrapperRooter */
-        CUSTOM =      -26  /* js::CustomAutoRooter */
-    };
-
-    static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
-    static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
-    static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
-
-  private:
-    AutoGCRooter ** const stackTop;
-
-    /* No copy or assignment semantics. */
-    AutoGCRooter(AutoGCRooter& ida) = delete;
-    void operator=(AutoGCRooter& ida) = delete;
-};
-
 } /* namespace JS */
 
-namespace js {
-
-/*
- * Inlinable accessors for JSContext.
- *
- * - These must not be available on the more restricted superclasses of
- *   JSContext, so we can't simply define them on RootingContext.
- *
- * - They're perfectly ordinary JSContext functionality, so ought to be
- *   usable without resorting to jsfriendapi.h, and when JSContext is an
- *   incomplete type.
- */
-inline JSCompartment*
-GetContextCompartment(const JSContext* cx)
-{
-    return JS::RootingContext::get(cx)->compartment_;
-}
-
-inline JS::Zone*
-GetContextZone(const JSContext* cx)
-{
-    return JS::RootingContext::get(cx)->zone_;
-}
-
-} /* namespace js */
-
 MOZ_BEGIN_EXTERN_C
 
 // Defined in NSPR prio.h.
 typedef struct PRFileDesc PRFileDesc;
 
 MOZ_END_EXTERN_C
 
 #endif /* jspubtd_h */
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -9,17 +9,16 @@
 #include <string.h>
 
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsfriendapi.h"
 #include "jsobj.h"
 #include "jswrapper.h"
 
-#include "js/GCAPI.h"
 #include "vm/GlobalObject.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 WeakMapBase::WeakMapBase(JSObject* memOf, Zone* zone)
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -70,17 +70,16 @@
 #include "frontend/Parser.h"
 #include "gc/GCInternals.h"
 #include "jit/arm/Simulator-arm.h"
 #include "jit/InlinableNatives.h"
 #include "jit/Ion.h"
 #include "jit/JitcodeMap.h"
 #include "jit/OptimizationTracking.h"
 #include "js/Debug.h"
-#include "js/GCAPI.h"
 #include "js/GCVector.h"
 #include "js/Initialization.h"
 #include "js/StructuredClone.h"
 #include "js/SweepingAPI.h"
 #include "js/TrackedOptimizationInfo.h"
 #include "perf/jsperf.h"
 #include "shell/jsoptparse.h"
 #include "shell/jsshell.h"
--- a/js/src/vm/CodeCoverage.cpp
+++ b/js/src/vm/CodeCoverage.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "vm/CodeCoverage.h"
 
 #include "mozilla/Atomics.h"
 #include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/Move.h"
 
 #include <stdio.h>
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #endif
@@ -67,35 +68,36 @@ LCovSource::LCovSource(LifoAlloc* alloc,
   : name_(name),
     outFN_(alloc),
     outFNDA_(alloc),
     numFunctionsFound_(0),
     numFunctionsHit_(0),
     outBRDA_(alloc),
     numBranchesFound_(0),
     numBranchesHit_(0),
-    outDA_(alloc),
     numLinesInstrumented_(0),
     numLinesHit_(0),
+    maxLineHit_(0),
     hasTopLevelScript_(false)
 {
 }
 
 LCovSource::LCovSource(LCovSource&& src)
   : name_(src.name_),
     outFN_(src.outFN_),
     outFNDA_(src.outFNDA_),
     numFunctionsFound_(src.numFunctionsFound_),
     numFunctionsHit_(src.numFunctionsHit_),
     outBRDA_(src.outBRDA_),
     numBranchesFound_(src.numBranchesFound_),
     numBranchesHit_(src.numBranchesHit_),
-    outDA_(src.outDA_),
+    linesHit_(Move(src.linesHit_)),
     numLinesInstrumented_(src.numLinesInstrumented_),
     numLinesHit_(src.numLinesHit_),
+    maxLineHit_(src.maxLineHit_),
     hasTopLevelScript_(src.hasTopLevelScript_)
 {
     src.name_ = nullptr;
 }
 
 LCovSource::~LCovSource()
 {
     js_delete(name_);
@@ -114,17 +116,23 @@ LCovSource::exportInto(GenericPrinter& o
     outFNDA_.exportInto(out);
     out.printf("FNF:%zu\n", numFunctionsFound_);
     out.printf("FNH:%zu\n", numFunctionsHit_);
 
     outBRDA_.exportInto(out);
     out.printf("BRF:%zu\n", numBranchesFound_);
     out.printf("BRH:%zu\n", numBranchesHit_);
 
-    outDA_.exportInto(out);
+    if (linesHit_.initialized()) {
+        for (size_t lineno = 1; lineno <= maxLineHit_; ++lineno) {
+            if (auto p = linesHit_.lookup(lineno))
+                out.printf("DA:%zu,%" PRIu64 "\n", lineno, p->value());
+        }
+    }
+
     out.printf("LF:%zu\n", numLinesInstrumented_);
     out.printf("LH:%zu\n", numLinesHit_);
 
     out.put("end_of_record\n");
 }
 
 bool
 LCovSource::writeScriptName(LSprinter& out, JSScript* script)
@@ -134,16 +142,19 @@ LCovSource::writeScriptName(LSprinter& o
         return EscapedStringPrinter(out, fun->displayAtom(), 0);
     out.printf("top-level");
     return true;
 }
 
 bool
 LCovSource::writeScript(JSScript* script)
 {
+    if (!linesHit_.initialized() && !linesHit_.init())
+        return false;
+
     numFunctionsFound_++;
     outFN_.printf("FN:%zu,", script->lineno());
     if (!writeScriptName(outFN_, script))
         return false;
     outFN_.put("\n", 1);
 
     uint64_t hits = 0;
     ScriptCounts* sc = nullptr;
@@ -165,16 +176,17 @@ LCovSource::writeScript(JSScript* script
     jssrcnote* sn = script->notes();
     if (!SN_IS_TERMINATOR(sn))
         snpc += SN_DELTA(sn);
 
     size_t lineno = script->lineno();
     jsbytecode* end = script->codeEnd();
     size_t branchId = 0;
     size_t tableswitchExitOffset = 0;
+    bool firstLineHasBeenWritten = false;
     for (jsbytecode* pc = script->code(); pc != end; pc = GetNextPc(pc)) {
         MOZ_ASSERT(script->code() <= pc && pc < end);
         JSOp op = JSOp(*pc);
         bool jump = IsJumpOpcode(op) || op == JSOP_TABLESWITCH;
         bool fallsthrough = BytecodeFallsThrough(op) && op != JSOP_GOSUB;
 
         // If the current script & pc has a hit-count report, then update the
         // current number of hits.
@@ -183,33 +195,44 @@ LCovSource::writeScript(JSScript* script
             if (counts)
                 hits = counts->numExec();
         }
 
         // If we have additional source notes, walk all the source notes of the
         // current pc.
         if (snpc <= pc) {
             size_t oldLine = lineno;
+            // Without this check, we'll never write the script's first line
+            if (lineno == script->lineno() && !firstLineHasBeenWritten)
+                oldLine = 0;
             while (!SN_IS_TERMINATOR(sn) && snpc <= pc) {
                 SrcNoteType type = SN_TYPE(sn);
                 if (type == SRC_SETLINE)
                     lineno = size_t(GetSrcNoteOffset(sn, 0));
                 else if (type == SRC_NEWLINE)
                     lineno++;
                 else if (type == SRC_TABLESWITCH)
                     tableswitchExitOffset = GetSrcNoteOffset(sn, 0);
 
                 sn = SN_NEXT(sn);
                 snpc += SN_DELTA(sn);
             }
 
             if (oldLine != lineno && fallsthrough) {
-                outDA_.printf("DA:%zu,%" PRIu64 "\n", lineno, hits);
+                auto p = linesHit_.lookupForAdd(lineno);
+                if (!p) {
+                    if (!linesHit_.add(p, lineno, hits))
+                        return false;
+                } else {
+                    p->value() += hits;
+                }
 
                 // Count the number of lines instrumented & hit.
+                firstLineHasBeenWritten = true;
+                maxLineHit_ = std::max(lineno, maxLineHit_);
                 numLinesInstrumented_++;
                 if (hits)
                     numLinesHit_++;
             }
         }
 
         // If the current instruction has thrown, then decrement the hit counts
         // with the number of throws.
@@ -227,23 +250,23 @@ LCovSource::writeScript(JSScript* script
             if (sc) {
                 const PCCounts* counts = sc->maybeGetPCCounts(script->pcToOffset(fallthroughTarget));
                 if (counts)
                     fallthroughHits = counts->numExec();
             }
 
             uint64_t taken = hits - fallthroughHits;
             outBRDA_.printf("BRDA:%zu,%zu,0,", lineno, branchId);
-            if (taken)
+            if (hits)
                 outBRDA_.printf("%" PRIu64 "\n", taken);
             else
                 outBRDA_.put("-\n", 2);
 
             outBRDA_.printf("BRDA:%zu,%zu,1,", lineno, branchId);
-            if (fallthroughHits)
+            if (hits)
                 outBRDA_.printf("%" PRIu64 "\n", fallthroughHits);
             else
                 outBRDA_.put("-\n", 2);
 
             // Count the number of branches, and the number of branches hit.
             numBranchesFound_ += 2;
             if (hits)
                 numBranchesHit_ += !!taken + !!fallthroughHits;
@@ -331,17 +354,17 @@ LCovSource::writeScript(JSScript* script
                                 fallsThroughHits = script->getHitCount(endpc);
                         }
 
                         caseHits -= fallsThroughHits;
                     }
 
                     outBRDA_.printf("BRDA:%zu,%zu,%zu,",
                                     lineno, branchId, caseId);
-                    if (caseHits)
+                    if (hits)
                         outBRDA_.printf("%" PRIu64 "\n", caseHits);
                     else
                         outBRDA_.put("-\n", 2);
 
                     numBranchesFound_++;
                     numBranchesHit_ += !!caseHits;
                     defaultHits -= caseHits;
                     caseId++;
@@ -396,35 +419,34 @@ LCovSource::writeScript(JSScript* script
                         defaultHits = counts->numExec();
                 }
                 defaultHits -= fallsThroughHits;
             }
 
             if (defaultHasOwnClause) {
                 outBRDA_.printf("BRDA:%zu,%zu,%zu,",
                                 lineno, branchId, caseId);
-                if (defaultHits)
+                if (hits)
                     outBRDA_.printf("%" PRIu64 "\n", defaultHits);
                 else
                     outBRDA_.put("-\n", 2);
                 numBranchesFound_++;
                 numBranchesHit_ += !!defaultHits;
             }
 
             // Increment the branch identifier, and go to the next instruction.
             branchId++;
             tableswitchExitOffset = 0;
         }
     }
 
     // Report any new OOM.
     if (outFN_.hadOutOfMemory() ||
         outFNDA_.hadOutOfMemory() ||
-        outBRDA_.hadOutOfMemory() ||
-        outDA_.hadOutOfMemory())
+        outBRDA_.hadOutOfMemory())
     {
         return false;
     }
 
     // If this script is the top-level script, then record it such that we can
     // assume that the code coverage report is complete, as this script has
     // references on all inner scripts.
     if (script->isTopLevel())
--- a/js/src/vm/CodeCoverage.h
+++ b/js/src/vm/CodeCoverage.h
@@ -6,16 +6,18 @@
 
 #ifndef vm_CodeCoverage_h
 #define vm_CodeCoverage_h
 
 #include "mozilla/Vector.h"
 
 #include "ds/LifoAlloc.h"
 
+#include "js/HashTable.h"
+
 #include "vm/Printer.h"
 
 struct JSCompartment;
 class JSScript;
 class JSObject;
 
 namespace js {
 
@@ -65,20 +67,24 @@ class LCovSource
     size_t numFunctionsFound_;
     size_t numFunctionsHit_;
 
     // LifoAlloc string which hold branches statistics.
     LSprinter outBRDA_;
     size_t numBranchesFound_;
     size_t numBranchesHit_;
 
-    // LifoAlloc string which hold lines statistics.
-    LSprinter outDA_;
+    // Holds lines statistics. When processing a line hit count, the hit count
+    // is added to any hit count already in the hash map so that we handle
+    // lines that belong to more than one JSScript or function in the same
+    // source file.
+    HashMap<size_t, uint64_t, DefaultHasher<size_t>, SystemAllocPolicy> linesHit_;
     size_t numLinesInstrumented_;
     size_t numLinesHit_;
+    size_t maxLineHit_;
 
     // Status flags.
     bool hasTopLevelScript_ : 1;
 };
 
 class LCovCompartment
 {
   public:
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -22,17 +22,16 @@
 
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/Parser.h"
 #include "gc/Marking.h"
 #include "gc/Policy.h"
 #include "jit/BaselineDebugModeOSR.h"
 #include "jit/BaselineJIT.h"
 #include "js/Date.h"
-#include "js/GCAPI.h"
 #include "js/UbiNodeBreadthFirst.h"
 #include "js/Vector.h"
 #include "proxy/ScriptedProxyHandler.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
 #include "vm/DebuggerMemory.h"
 #include "vm/GeckoProfiler.h"
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/PodOperations.h"
 
 #include "jscntxt.h"
 
 #include "gc/Marking.h"
 #include "jit/BaselineFrame.h"
 #include "jit/JitcodeMap.h"
 #include "jit/JitCompartment.h"
-#include "js/GCAPI.h"
 #include "vm/Debugger.h"
 #include "vm/Opcodes.h"
 
 #include "jit/JSJitFrameIter-inl.h"
 #include "vm/EnvironmentObject-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/Probes-inl.h"
 
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/RangedPtr.h"
 #include "mozilla/TypeTraits.h"
 #include "mozilla/Unused.h"
 
 #include "gc/Marking.h"
-#include "js/GCAPI.h"
 #include "js/UbiNode.h"
 #include "vm/GeckoProfiler.h"
 
 #include "jscntxtinlines.h"
 #include "jscompartmentinlines.h"
 
 #include "vm/GeckoProfiler-inl.h"
 
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -14,17 +14,16 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jsstr.h"
 
 #include "gc/Barrier.h"
 #include "gc/Heap.h"
 #include "gc/Rooting.h"
 #include "js/CharacterEncoding.h"
-#include "js/GCAPI.h"
 #include "js/RootingAPI.h"
 
 #include "vm/Printer.h"
 
 class JSDependentString;
 class JSExtensibleString;
 class JSExternalString;
 class JSInlineString;
--- a/layout/reftests/css-invalid/select/reftest.list
+++ b/layout/reftests/css-invalid/select/reftest.list
@@ -2,11 +2,11 @@ needs-focus == select-valid.html select-
 fuzzy-if(skiaContent,1,3) needs-focus == select-invalid.html select-ref.html
 fuzzy-if(skiaContent,2,6) needs-focus == select-disabled.html select-disabled-ref.html
 fuzzy-if(skiaContent,2,6) needs-focus == select-dyn-disabled.html select-disabled-ref.html
 fuzzy-if(skiaContent,1,3) needs-focus == select-dyn-not-disabled.html select-ref.html
 needs-focus == select-required-invalid.html select-required-ref.html
 needs-focus == select-required-valid.html select-required-ref.html
 needs-focus == select-required-multiple-still-valid.html select-required-multiple-ref.html
 fuzzy-if(skiaContent,1,250) needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html
-fuzzy-if(skiaContent&&!Android,1,3) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html
+fuzzy-if(skiaContent&&!Android,1,3) skip-if(Android) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html
 fuzzy-if(skiaContent&&!Android,2,3) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html
 fuzzy-if(skiaContent,2,5) needs-focus == select-fieldset-legend.html select-fieldset-legend-ref.html
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -4142,17 +4142,17 @@ public class BrowserApp extends GeckoApp
         showTabQueuePromptIfApplicable(intent);
 
         // GeckoApp will wrap this unsafe external intent in a SafeIntent.
         super.onNewIntent(externalIntent);
 
         if (AppConstants.MOZ_ANDROID_BEAM && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
             final GeckoBundle data = new GeckoBundle(2);
             data.putString("uri", intent.getDataString());
-            data.putInt("flags", LOAD_NEW_TAB);
+            data.putString("flags", "OPEN_NEWTAB");
             getAppEventDispatcher().dispatch("Tab:OpenUri", data);
         }
 
         // Only solicit feedback when the app has been launched from the icon shortcut.
         if (GuestSession.NOTIFICATION_INTENT.equals(action)) {
             GuestSession.onNotificationIntentReceived(this);
         }
 
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -156,20 +156,16 @@ public abstract class GeckoApp extends G
     // Delay before running one-time "cleanup" tasks that may be needed
     // after a version upgrade.
     private static final int CLEANUP_DEFERRAL_SECONDS = 15;
 
     // Length of time in ms during which crashes are classified as startup crashes
     // for crash loop detection purposes.
     private static final int STARTUP_PHASE_DURATION_MS = 30 * 1000;
 
-    protected static final int LOAD_DEFAULT = 0;
-    protected static final int LOAD_NEW_TAB = 1;
-    protected static final int LOAD_SWITCH_TAB = 2;
-
     private static boolean sAlreadyLoaded;
 
     protected RelativeLayout mRootLayout;
     protected RelativeLayout mMainLayout;
 
     protected RelativeLayout mGeckoLayout;
     private OrientationEventListener mCameraOrientationEventListener;
     protected MenuPanel mMenuPanel;
@@ -1792,22 +1788,22 @@ public abstract class GeckoApp extends G
                         flags |= Tabs.LOADURL_FIRST_AFTER_ACTIVITY_UNHIDDEN;
                     }
                     Tabs.getInstance().loadUrlWithIntentExtras(url, intent, flags);
                 }
             });
         } else if (ACTION_HOMESCREEN_SHORTCUT.equals(action)) {
             final GeckoBundle data = new GeckoBundle(2);
             data.putString("uri", uri);
-            data.putInt("flags", LOAD_SWITCH_TAB);
+            data.putString("flags", "OPEN_SWITCHTAB");
             getAppEventDispatcher().dispatch("Tab:OpenUri", data);
         } else if (Intent.ACTION_SEARCH.equals(action)) {
             final GeckoBundle data = new GeckoBundle(2);
             data.putString("uri", uri);
-            data.putInt("flags", LOAD_NEW_TAB);
+            data.putString("flags", "OPEN_NEWTAB");
             getAppEventDispatcher().dispatch("Tab:OpenUri", data);
         } else if (NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) {
             NotificationHelper.getInstance(getApplicationContext()).handleNotificationIntent(intent);
         } else if (ACTION_LAUNCH_SETTINGS.equals(action)) {
             // Check if launched from data reporting notification.
             Intent settingsIntent = new Intent(GeckoApp.this, GeckoPreferences.class);
             // Copy extras.
             settingsIntent.putExtras(intent.getUnsafe());
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1926,17 +1926,18 @@ var BrowserApp = {
           }
           this.loadURI(url, browser, params);
         }
         break;
       }
 
       case "Tab:OpenUri":
         window.browserDOMWindow.openURI(Services.io.newURI(data.uri),
-                                        /* opener */ null, data.flags,
+                                        /* opener */ null,
+                                        Ci.nsIBrowserDOMWindow[data.flags],
                                         Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL,
                                         /* triggeringPrincipal */ null);
         break;
 
       case "Tab:Selected":
         this._handleTabSelected(this.getTabForId(data.id));
         break;
 
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -1426,17 +1426,17 @@ public:
     BufferWriter(nsIInputStream* aInputStream,
                  void* aBuffer, int64_t aCount)
         : Runnable("BufferWriterRunnable")
         , mMonitor("BufferWriter.mMonitor")
         , mInputStream(aInputStream)
         , mBuffer(aBuffer)
         , mCount(aCount)
         , mWrittenData(0)
-        , mBufferType(mBuffer ? eExternal : eInternal)
+        , mBufferType(aBuffer ? eExternal : eInternal)
         , mAsyncResult(NS_OK)
         , mBufferSize(0)
     {
         MOZ_ASSERT(aInputStream);
         MOZ_ASSERT(aCount == -1 || aCount > 0);
         MOZ_ASSERT_IF(mBuffer, aCount > 0);
     }
 
@@ -1472,18 +1472,22 @@ public:
         return mWrittenData;
     }
 
     void*
     StealBuffer()
     {
         MOZ_ASSERT(mBufferType == eInternal);
 
+        MonitorAutoLock lock(mMonitor);
+
         void* buffer = mBuffer;
+
         mBuffer = nullptr;
+        mBufferSize = 0;
 
         return buffer;
     }
 
 private:
     ~BufferWriter()
     {
         if (mBuffer && mBufferType == eInternal) {
@@ -1546,105 +1550,106 @@ private:
         mTaskQueue = new TaskQueue(target.forget());
 
         MonitorAutoLock lock(mMonitor);
 
         nsCOMPtr<nsIRunnable> runnable = this;
         nsresult rv = mTaskQueue->Dispatch(runnable.forget());
         NS_ENSURE_SUCCESS(rv, rv);
 
-        lock.Wait();
+        rv = lock.Wait();
+        NS_ENSURE_SUCCESS(rv, rv);
 
         return mAsyncResult;
     }
 
     // This method runs on the I/O Thread when the owning thread is blocked by
     // the mMonitor. It is called multiple times until mCount is greater than 0
     // or until there is something to read in the stream.
     NS_IMETHOD
     Run() override
     {
         MOZ_ASSERT(mAsyncInputStream);
         MOZ_ASSERT(!mInputStream);
 
+        MonitorAutoLock lock(mMonitor);
+
         if (mCount == 0) {
-            OperationCompleted(NS_OK);
+            OperationCompleted(lock, NS_OK);
             return NS_OK;
         }
 
         if (mCount == -1 && !MaybeExpandBufferSize()) {
-            OperationCompleted(NS_ERROR_OUT_OF_MEMORY);
+            OperationCompleted(lock, NS_ERROR_OUT_OF_MEMORY);
             return NS_OK;
         }
 
         uint64_t offset = mWrittenData;
         uint64_t length = mCount == -1 ? BUFFER_SIZE : mCount;
 
         // Let's try to read it directly.
         uint32_t writtenData;
         nsresult rv = mAsyncInputStream->ReadSegments(NS_CopySegmentToBuffer,
                                                      static_cast<char*>(mBuffer) + offset,
                                                      length, &writtenData);
 
         // Operation completed.
         if (NS_SUCCEEDED(rv) && writtenData == 0) {
-            OperationCompleted(NS_OK);
+            OperationCompleted(lock, NS_OK);
             return NS_OK;
         }
 
         // If we succeeded, let's try to read again.
         if (NS_SUCCEEDED(rv)) {
             mWrittenData += writtenData;
             if (mCount != -1) {
                 MOZ_ASSERT(mCount >= writtenData);
                 mCount -= writtenData;
             }
 
             nsCOMPtr<nsIRunnable> runnable = this;
             rv = mTaskQueue->Dispatch(runnable.forget());
             if (NS_WARN_IF(NS_FAILED(rv))) {
-                OperationCompleted(rv);
+                OperationCompleted(lock, rv);
             }
         
             return NS_OK;
         }
 
         // Async wait...
         if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
             rv = mAsyncInputStream->AsyncWait(this, 0, length, mTaskQueue);
             if (NS_WARN_IF(NS_FAILED(rv))) {
-                OperationCompleted(rv);
+                OperationCompleted(lock, rv);
             }
             return NS_OK;
         }
 
         // Error.
-        OperationCompleted(rv);
+        OperationCompleted(lock, rv);
         return NS_OK;
     }
 
     NS_IMETHOD
     OnInputStreamReady(nsIAsyncInputStream* aStream) override
     {
         MOZ_ASSERT(aStream == mAsyncInputStream);
         // The stream is ready, let's read it again.
         return Run();
     }
 
     // This function is called from the I/O thread and it will unblock the
     // owning thread.
     void
-    OperationCompleted(nsresult aRv)
+    OperationCompleted(MonitorAutoLock& aLock, nsresult aRv)
     {
-        MonitorAutoLock lock(mMonitor);
-
         mAsyncResult = aRv;
 
         // This will unlock the owning thread.
-        lock.Notify();
+        aLock.Notify();
     }
 
     bool
     MaybeExpandBufferSize()
     {
         MOZ_ASSERT(mCount == -1);
 
         if (mBufferSize >= mWrittenData + BUFFER_SIZE) {
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -54,16 +54,18 @@ from ..frontend.data import (
     HostSimpleProgram,
     HostSources,
     InstallationTarget,
     JARManifest,
     JavaJarData,
     Library,
     Linkable,
     LocalInclude,
+    LocalizedFiles,
+    LocalizedPreprocessedFiles,
     ObjdirFiles,
     ObjdirPreprocessedFiles,
     PerSourceFlag,
     Program,
     RustLibrary,
     HostRustLibrary,
     RustProgram,
     RustTest,
@@ -640,16 +642,22 @@ class RecursiveMakeBackend(CommonBackend
             self._process_linked_libraries(obj, backend_file)
 
         elif isinstance(obj, ObjdirFiles):
             self._process_objdir_files(obj, obj.files, backend_file)
 
         elif isinstance(obj, ObjdirPreprocessedFiles):
             self._process_final_target_pp_files(obj, obj.files, backend_file, 'OBJDIR_PP_FILES')
 
+        elif isinstance(obj, LocalizedFiles):
+            self._process_localized_files(obj, obj.files, backend_file)
+
+        elif isinstance(obj, LocalizedPreprocessedFiles):
+            self._process_localized_pp_files(obj, obj.files, backend_file)
+
         elif isinstance(obj, FinalTargetFiles):
             self._process_final_target_files(obj, obj.files, backend_file)
 
         elif isinstance(obj, FinalTargetPreprocessedFiles):
             self._process_final_target_pp_files(obj, obj.files, backend_file, 'DIST_FILES')
 
         elif isinstance(obj, AndroidResDirs):
             # Order matters.
@@ -1448,16 +1456,64 @@ class RecursiveMakeBackend(CommonBackend
             for f in files:
                 backend_file.write('%s += %s\n' % (
                     var, self._pretty_path(f, backend_file)))
             backend_file.write('%s_PATH := $(DEPTH)/%s\n'
                                % (var, mozpath.join(obj.install_target, path)))
             backend_file.write('%s_TARGET := misc\n' % var)
             backend_file.write('PP_TARGETS += %s\n' % var)
 
+    def _write_localized_files_files(self, files, name, backend_file):
+        for f in files:
+            # The emitter asserts that all files start with `en-US/`
+            e, f = f.split('en-US/')
+            assert(not e)
+            if '*' in f:
+                # We can't use MERGE_FILE for wildcards because it takes
+                # only the first match internally. This is only used
+                # in one place in the tree currently so we'll hardcode
+                # that specific behavior for now.
+                backend_file.write('%s += $(wildcard $(LOCALE_SRCDIR)/%s)\n' % (name, f))
+            else:
+                backend_file.write('%s += $(call MERGE_FILE,%s)\n' % (name, f))
+
+    def _process_localized_files(self, obj, files, backend_file):
+        target = obj.install_target
+        path = mozpath.basedir(target, ('dist/bin', ))
+        if not path:
+            raise Exception('Cannot install localized files to ' + target)
+        for i, (path, files) in enumerate(files.walk()):
+            name = 'LOCALIZED_FILES_%d' % i
+            self._no_skip['libs'].add(backend_file.relobjdir)
+            self._write_localized_files_files(files, name + '_FILES', backend_file)
+            # Use FINAL_TARGET here because some l10n repack rules set
+            # XPI_NAME to generate langpacks.
+            backend_file.write('%s_DEST = $(FINAL_TARGET)/%s\n' % (name, path))
+            backend_file.write('%s_TARGET := libs\n' % name)
+            backend_file.write('INSTALL_TARGETS += %s\n' % name)
+
+    def _process_localized_pp_files(self, obj, files, backend_file):
+        target = obj.install_target
+        path = mozpath.basedir(target, ('dist/bin', ))
+        if not path:
+            raise Exception('Cannot install localized files to ' + target)
+        for i, (path, files) in enumerate(files.walk()):
+            name = 'LOCALIZED_PP_FILES_%d' % i
+            self._no_skip['libs'].add(backend_file.relobjdir)
+            self._write_localized_files_files(files, name, backend_file)
+            # Use FINAL_TARGET here because some l10n repack rules set
+            # XPI_NAME to generate langpacks.
+            backend_file.write('%s_PATH = $(FINAL_TARGET)/%s\n' % (name, path))
+            backend_file.write('%s_TARGET := libs\n' % name)
+            # Localized files will have different content in different
+            # localizations, and some preprocessed files may not have
+            # any preprocessor directives.
+            backend_file.write('%s_FLAGS := --silence-missing-directive-warnings\n' % name)
+            backend_file.write('PP_TARGETS += %s\n' % name)
+
     def _process_objdir_files(self, obj, files, backend_file):
         # We can't use an install manifest for the root of the objdir, since it
         # would delete all the other files that get put there by the build
         # system.
         for i, (path, files) in enumerate(files.walk()):
             self._no_skip['misc'].add(backend_file.relobjdir)
             for f in files:
                 backend_file.write('OBJDIR_%d_FILES += %s\n' % (
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1410,16 +1410,63 @@ VARIABLES = {
            FINAL_TARGET_FILES += ['foo.png']
            FINAL_TARGET_FILES.images['do-not-use'] += ['bar.svg']
         """),
 
     'FINAL_TARGET_PP_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list,
         """Like ``FINAL_TARGET_FILES``, with preprocessing.
         """),
 
+    'LOCALIZED_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list,
+        """List of locale-dependent files to be installed into the application
+        directory.
+
+        This functions similarly to ``FINAL_TARGET_FILES``, but the files are
+        sourced from the locale directory and will vary per localization.
+        For an en-US build, this is functionally equivalent to
+        ``FINAL_TARGET_FILES``. For a build with ``--enable-ui-locale``,
+        the file will be taken from ``$LOCALE_SRCDIR``, with the leading
+        ``en-US`` removed. For a l10n repack of an en-US build, the file
+        will be taken from the first location where it exists from:
+        * the merged locale directory if it exists
+        * ``$LOCALE_SRCDIR`` with the leading ``en-US`` removed
+        * the in-tree en-US location
+
+        Paths specified here must be relative to the source directory and must
+        include a leading ``en-US``. Wildcards are allowed, and will be
+        expanded at the time of locale packaging to match files in the
+        locale directory.
+
+        Files that are missing from a locale will typically have the en-US
+        version used, but for wildcard expansions only files from the
+        locale directory will be used, even if that means no files will
+        be copied.
+
+        Example::
+
+           LOCALIZED_FILES.foo += [
+             'en-US/foo.js',
+             'en-US/things/*.ini',
+           ]
+
+        If this was placed in ``toolkit/locales/moz.build``, it would copy
+        ``toolkit/locales/en-US/foo.js`` and
+        ``toolkit/locales/en-US/things/*.ini`` to ``$(DIST)/bin/foo`` in an
+        en-US build, and in a build of a different locale (or a repack),
+        it would copy ``$(LOCALE_SRCDIR)/toolkit/foo.js`` and
+        ``$(LOCALE_SRCDIR)/toolkit/things/*.ini``.
+        """),
+
+    'LOCALIZED_PP_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list,
+        """Like ``LOCALIZED_FILES``, with preprocessing.
+
+        Note that the ``AB_CD`` define is available and expands to the current
+        locale being packaged, as with preprocessed entries in jar manifests.
+        """),
+
     'OBJDIR_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list,
         """List of files to be installed anywhere in the objdir. Use sparingly.
 
         ``OBJDIR_FILES`` is similar to FINAL_TARGET_FILES, but it allows copying
         anywhere in the object directory. This is intended for various one-off
         cases, not for general use. If you wish to add entries to OBJDIR_FILES,
         please consult a build peer.
         """),
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -975,16 +975,29 @@ class FinalTargetPreprocessedFiles(Conte
     FINAL_TARGET_PP_FILES.
     """
     __slots__ = ('files')
 
     def __init__(self, sandbox, files):
         ContextDerived.__init__(self, sandbox)
         self.files = files
 
+class LocalizedFiles(FinalTargetFiles):
+    """Sandbox container object for LOCALIZED_FILES, which is a
+    HierarchicalStringList.
+    """
+    pass
+
+
+class LocalizedPreprocessedFiles(FinalTargetPreprocessedFiles):
+    """Sandbox container object for LOCALIZED_PP_FILES, which is a
+    HierarchicalStringList.
+    """
+    pass
+
 
 class ObjdirFiles(FinalTargetFiles):
     """Sandbox container object for OBJDIR_FILES, which is a
     HierarchicalStringList.
     """
     @property
     def install_target(self):
         return ''
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -52,16 +52,18 @@ from .data import (
     HostSimpleProgram,
     HostSources,
     InstallationTarget,
     IPDLFile,
     JARManifest,
     Library,
     Linkable,
     LocalInclude,
+    LocalizedFiles,
+    LocalizedPreprocessedFiles,
     ObjdirFiles,
     ObjdirPreprocessedFiles,
     PerSourceFlag,
     PreprocessedTestWebIDLFile,
     PreprocessedWebIDLFile,
     Program,
     RustLibrary,
     HostRustLibrary,
@@ -1074,16 +1076,18 @@ class TreeMetadataEmitter(LoggingMixin):
         generated_files.update(['%s%s' % (k, self.config.substs.get('BIN_SUFFIX', '')) for k in self._binaries.keys()])
 
         components = []
         for var, cls in (
             ('BRANDING_FILES', BrandingFiles),
             ('EXPORTS', Exports),
             ('FINAL_TARGET_FILES', FinalTargetFiles),
             ('FINAL_TARGET_PP_FILES', FinalTargetPreprocessedFiles),
+            ('LOCALIZED_FILES', LocalizedFiles),
+            ('LOCALIZED_PP_FILES', LocalizedPreprocessedFiles),
             ('OBJDIR_FILES', ObjdirFiles),
             ('OBJDIR_PP_FILES', ObjdirPreprocessedFiles),
             ('TEST_HARNESS_FILES', TestHarnessFiles),
         ):
             all_files = context.get(var)
             if not all_files:
                 continue
             if dist_install is False and var != 'TEST_HARNESS_FILES':
@@ -1098,23 +1102,29 @@ class TreeMetadataEmitter(LoggingMixin):
                         'Cannot install files to the root of TEST_HARNESS_FILES', context)
                 if base == 'components':
                     components.extend(files)
                 if base == 'defaults/pref':
                     has_prefs = True
                 if mozpath.split(base)[0] == 'res':
                     has_resources = True
                 for f in files:
-                    if ((var == 'FINAL_TARGET_PP_FILES' or
-                         var == 'OBJDIR_PP_FILES') and
+                    if (var in ('FINAL_TARGET_PP_FILES',
+                                'OBJDIR_PP_FILES',
+                                'LOCALIZED_FILES',
+                                'LOCALIZED_PP_FILES') and
                         not isinstance(f, SourcePath)):
                         raise SandboxValidationError(
                                 ('Only source directory paths allowed in ' +
                                  '%s: %s')
                                 % (var, f,), context)
+                    if var.startswith('LOCALIZED_') and not f.startswith('en-US/'):
+                        raise SandboxValidationError(
+                                '%s paths must start with `en-US/`: %s'
+                                % (var, f,), context)
                     if not isinstance(f, ObjDirPath):
                         path = f.full_path
                         if '*' not in path and not os.path.exists(path):
                             raise SandboxValidationError(
                                 'File listed in %s does not exist: %s'
                                 % (var, path), context)
                     else:
                         # TODO: Bug 1254682 - The '/' check is to allow
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-files/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_FILES += [
+    'en-US/abc/*.abc',
+    'en-US/bar.ini',
+    'en-US/foo.js',
+]
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_PP_FILES += [
+    'en-US/bar.ini',
+    'en-US/foo.js',
+]
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -839,16 +839,54 @@ class TestRecursiveMakeBackend(BackendTe
             'DIST_FILES_0_PATH := $(DEPTH)/dist/bin/',
             'DIST_FILES_0_TARGET := misc',
             'PP_TARGETS += DIST_FILES_0',
         ]
 
         found = [str for str in lines if 'DIST_FILES' in str]
         self.assertEqual(found, expected)
 
+    def test_localized_files(self):
+        """Test that LOCALIZED_FILES is written to backend.mk correctly."""
+        env = self._consume('localized-files', RecursiveMakeBackend)
+
+        backend_path = mozpath.join(env.topobjdir, 'backend.mk')
+        lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
+
+        expected = [
+            'LOCALIZED_FILES_0_FILES += $(wildcard $(LOCALE_SRCDIR)/abc/*.abc)',
+            'LOCALIZED_FILES_0_FILES += $(call MERGE_FILE,bar.ini)',
+            'LOCALIZED_FILES_0_FILES += $(call MERGE_FILE,foo.js)',
+            'LOCALIZED_FILES_0_DEST = $(FINAL_TARGET)/',
+            'LOCALIZED_FILES_0_TARGET := libs',
+            'INSTALL_TARGETS += LOCALIZED_FILES_0',
+        ]
+
+        found = [str for str in lines if 'LOCALIZED_FILES' in str]
+        self.assertEqual(found, expected)
+
+    def test_localized_pp_files(self):
+        """Test that LOCALIZED_PP_FILES is written to backend.mk correctly."""
+        env = self._consume('localized-pp-files', RecursiveMakeBackend)
+
+        backend_path = mozpath.join(env.topobjdir, 'backend.mk')
+        lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
+
+        expected = [
+            'LOCALIZED_PP_FILES_0 += $(call MERGE_FILE,bar.ini)',
+            'LOCALIZED_PP_FILES_0 += $(call MERGE_FILE,foo.js)',
+            'LOCALIZED_PP_FILES_0_PATH = $(FINAL_TARGET)/',
+            'LOCALIZED_PP_FILES_0_TARGET := libs',
+            'LOCALIZED_PP_FILES_0_FLAGS := --silence-missing-directive-warnings',
+            'PP_TARGETS += LOCALIZED_PP_FILES_0',
+        ]
+
+        found = [str for str in lines if 'LOCALIZED_PP_FILES' in str]
+        self.assertEqual(found, expected)
+
     def test_config(self):
         """Test that CONFIGURE_SUBST_FILES are properly handled."""
         env = self._consume('test_config', RecursiveMakeBackend)
 
         self.assertEqual(
             open(os.path.join(env.topobjdir, 'file'), 'r').readlines(), [
                 '#ifdef foo\n',
                 'bar baz\n',
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/localized-files-no-en-us/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_FILES.foo += [
+    'en-US/bar.ini',
+    'foo.js',
+]
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/localized-files/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_FILES.foo += [
+    'en-US/bar.ini',
+    'en-US/code/*.js',
+    'en-US/foo.js',
+]
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/localized-pp-files/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_PP_FILES.foo += [
+    'en-US/bar.ini',
+    'en-US/foo.js',
+]
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -28,16 +28,18 @@ from mozbuild.frontend.data import (
     HostDefines,
     HostRustLibrary,
     HostRustProgram,
     HostSources,
     IPDLFile,
     JARManifest,
     LinkageMultipleRustLibrariesError,
     LocalInclude,
+    LocalizedFiles,
+    LocalizedPreprocessedFiles,
     Program,
     RustLibrary,
     RustProgram,
     SharedLibrary,
     SimpleProgram,
     Sources,
     StaticLibrary,
     TestHarnessFiles,
@@ -1230,16 +1232,56 @@ class TestEmitterBasic(unittest.TestCase
 
     def test_final_target_pp_files_non_srcdir(self):
         '''Test that non-srcdir paths in FINAL_TARGET_PP_FILES throws errors.'''
         reader = self.reader('final-target-pp-files-non-srcdir')
         with self.assertRaisesRegexp(SandboxValidationError,
              'Only source directory paths allowed in FINAL_TARGET_PP_FILES:'):
             self.read_topsrcdir(reader)
 
+    def test_localized_files(self):
+        """Test that LOCALIZED_FILES works properly."""
+        reader = self.reader('localized-files')
+        objs = self.read_topsrcdir(reader)
+
+        self.assertEqual(len(objs), 1)
+        self.assertIsInstance(objs[0], LocalizedFiles)
+
+        for path, files in objs[0].files.walk():
+            self.assertEqual(path, 'foo')
+            self.assertEqual(len(files), 3)
+
+            expected = {'en-US/bar.ini', 'en-US/code/*.js', 'en-US/foo.js'}
+            for f in files:
+                self.assertTrue(unicode(f) in expected)
+
+    def test_localized_files_no_en_us(self):
+        """Test that LOCALIZED_FILES errors if a path does not start with
+        `en-US/`."""
+        reader = self.reader('localized-files-no-en-us')
+        with self.assertRaisesRegexp(SandboxValidationError,
+             'LOCALIZED_FILES paths must start with `en-US/`:'):
+            objs = self.read_topsrcdir(reader)
+
+    def test_localized_pp_files(self):
+        """Test that LOCALIZED_PP_FILES works properly."""
+        reader = self.reader('localized-pp-files')
+        objs = self.read_topsrcdir(reader)
+
+        self.assertEqual(len(objs), 1)
+        self.assertIsInstance(objs[0], LocalizedPreprocessedFiles)
+
+        for path, files in objs[0].files.walk():
+            self.assertEqual(path, 'foo')
+            self.assertEqual(len(files), 2)
+
+            expected = {'en-US/bar.ini', 'en-US/foo.js'}
+            for f in files:
+                self.assertTrue(unicode(f) in expected)
+
     def test_rust_library_no_cargo_toml(self):
         '''Test that defining a RustLibrary without a Cargo.toml fails.'''
         reader = self.reader('rust-library-no-cargo-toml')
         with self.assertRaisesRegexp(SandboxValidationError,
              'No Cargo.toml file found'):
             self.read_topsrcdir(reader)
 
     def test_rust_library_name_mismatch(self):
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1154,9 +1154,9 @@ static const TransportSecurityPreload kP
   { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
   { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
 };
 
 // Pinning Preload List Length = 481;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1519587456099000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1519673646480000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -19,33 +19,33 @@ 8ack.de: could not connect to host
 8ballbombom.uk: could not connect to host
 8t88.biz: could not connect to host
 91-freedom.com: could not connect to host
 9ss6.com: could not connect to host
 aaronmcguire.me: could not connect to host
 abloop.com: could not connect to host
 abolition.co: could not connect to host
 accwing.com: could not connect to host
+ackis.duckdns.org: could not connect to host
 acrossgw.com: could not connect to host
 adamgold.net: could not connect to host
 aevpn.org: could not connect to host
 affily.io: could not connect to host
+ajetaci.cz: could not connect to host
 akiba-server.info: could not connect to host
 akita-stream.com: could not connect to host
 akoww.de: could not connect to host
 akul.co.in: could not connect to host
 al-f.net: could not connect to host
-alamgir.works: could not connect to host
 alasta.info: could not connect to host
 alauda-home.de: could not connect to host
 alexey-shamara.ru: could not connect to host
 alexhaydock.co.uk: could not connect to host
 alexmol.tk: could not connect to host
 alexperry.io: could not connect to host
-almstrom.org: could not connect to host
 alphie.me: could not connect to host
 altahrim.net: could not connect to host
 ameho.me: could not connect to host
 americandistribuidora.com: could not connect to host
 amua.fr: could not connect to host
 anastasia-shamara.ru: could not connect to host
 andreas-kluge.eu: could not connect to host
 andreaskluge.eu: could not connect to host
@@ -61,31 +61,35 @@ apothes.is: could not connect to host
 apparels24.com: could not connect to host
 appdrinks.com: could not connect to host
 apple.ax: could not connect to host
 arawaza.biz: could not connect to host
 arawaza.info: could not connect to host
 arcadiaeng.com: could not connect to host
 arent.kz: could not connect to host
 arksan.com.tr: could not connect to host
+arne-petersen.net: could not connect to host
 artisense.de: could not connect to host
 artyland.ru: could not connect to host
 aseith.com: could not connect to host
 askmagicconch.com: could not connect to host
+asphaltfruehling.de: could not connect to host
 assdecoeur.org: could not connect to host
 asthon.cn: could not connect to host
 at1.co: could not connect to host
 athi.pl: could not connect to host
 ausec.ch: could not connect to host
 austinsutphin.com: could not connect to host
 australiancattle.dog: could not connect to host
 autostop-occasions.be: could not connect to host
 autozane.com: could not connect to host
+avi9526.pp.ua: could not connect to host
 awan.tech: could not connect to host
 awf0.xyz: could not connect to host
+axolsoft.com: could not connect to host
 b8a.me: could not connect to host
 badbee.cc: could not connect to host
 baka.network: could not connect to host
 baka.org.cn: could not connect to host
 balonmano.co: could not connect to host
 bandally.net: could not connect to host
 bandarifamily.com: could not connect to host
 bannisbierblog.de: could not connect to host
@@ -106,38 +110,38 @@ billdestler.com: could not connect to ho
 bingcheung.com: could not connect to host
 binimo.com: could not connect to host
 bip.gov.sa: could not connect to host
 bitmessage.ch: could not connect to host
 bizeau.ch: could not connect to host
 bjtxl.cn: could not connect to host
 blackdiam.net: could not connect to host
 blackgamelp.de: could not connect to host
-blackonion.com: could not connect to host
 blackscytheconsulting.com: could not connect to host
 blinkenlight.co.uk: could not connect to host
 blinkenlight.com.au: could not connect to host
+blinkspeed.eu: could not connect to host
 blog.gparent.org: could not connect to host
+blueperil.de: could not connect to host
 blumen-garage.de: could not connect to host
 bm-i.ch: could not connect to host
 bodrumfarm.com: could not connect to host
 bolwerk.com.br: could not connect to host
 bonesserver.com: could not connect to host
 bookluk.com: could not connect to host
 boomsaki.com: could not connect to host
 boomsakis.com: could not connect to host
 borisbesemer.com: could not connect to host
 botserver.de: could not connect to host
 boyfriendhusband.men: could not connect to host
 brage.info: could not connect to host
 braintensive.com: could not connect to host
 brettabel.com: could not connect to host
 brookframework.org: could not connect to host
 bsagan.fr: could not connect to host
-bsdfreak.dk: could not connect to host
 bsktweetup.info: could not connect to host
 bsuess.de: could not connect to host
 buka.jp: could not connect to host
 burlesquemakeup.com: could not connect to host
 businessfurs.info: could not connect to host
 businessmodeler.se: could not connect to host
 buyingsellingflorida.com: could not connect to host
 buyshoe.org: could not connect to host
@@ -151,17 +155,16 @@ calculatoaresecondhand.xyz: could not co
 callabs.net: could not connect to host
 callsigns.ca: could not connect to host
 cancelmyprofile.com: could not connect to host
 carlandfaith.com: could not connect to host
 carloshmm.stream: could not connect to host
 carringtonrealtygroup.com: could not connect to host
 casinoreal.com: could not connect to host
 catcontent.cloud: could not connect to host
-catgirl.pics: could not connect to host
 caughtredhanded.co.nz: could not connect to host
 cctld.com: could not connect to host
 cee.io: could not connect to host
 cencalvia.org: could not connect to host
 centos.pub: could not connect to host
 challengeskins.com: could not connect to host
 chaouby.com: could not connect to host
 charmyadesara.com: could not connect to host
@@ -224,31 +227,29 @@ davidscherzer.at: could not connect to h
 davros.eu: could not connect to host
 davros.ru: could not connect to host
 dawnsonb.com: could not connect to host
 days.one: could not connect to host
 dbcom.ru: could not connect to host
 dbox.ga: could not connect to host
 de-servers.de: could not connect to host
 decoyrouting.com: could not connect to host
-def-pos.ru: could not connect to host
 deloittequant.com: could not connect to host
 demotivatorbi.ru: could not connect to host
 derchris.me: could not connect to host
 derivativeshub.pro: could not connect to host
 dermacarecomplex.com: could not connect to host
 detecte-fuite.ch: could not connect to host
 detecte.ch: could not connect to host
 detectefuite.ch: could not connect to host
 dev-talk.eu: could not connect to host
 devafterdark.com: could not connect to host
 devkid.net: could not connect to host
 devops.moe: could not connect to host
 devpsy.info: could not connect to host
-dhub.xyz: could not connect to host
 dick.red: could not connect to host
 digioccumss.ddns.net: could not connect to host
 digiworks.se: could not connect to host
 diguass.us: could not connect to host
 dijks.com: could not connect to host
 dirtycat.ru: could not connect to host
 disadattamentolavorativo.it: could not connect to host
 disco-crazy-world.de: could not connect to host
@@ -256,17 +257,16 @@ ditch.ch: could not connect to host
 djangogolf.com: could not connect to host
 dlyl888.com: could not connect to host
 dmdre.com: could not connect to host
 dojifish.space: could not connect to host
 dolphin-hosting.com: could not connect to host
 domengrad.ru: could not connect to host
 dostavkakurierom.ru: could not connect to host
 doyoulyft.com: could not connect to host
-doze-cloud.tech: could not connect to host
 dreamaholic.club: could not connect to host
 dreaming.solutions: could not connect to host
 drighes.com: could not connect to host
 drizz.com.br: could not connect to host
 drlazarina.net: could not connect to host
 dronexpertos.com: could not connect to host
 droomhuis-in-zuid-holland-kopen.nl: could not connect to host
 dubrovskiy.net: could not connect to host
@@ -275,27 +275,23 @@ duch.cloud: could not connect to host
 duelsow.eu: could not connect to host
 duks.com.br: could not connect to host
 duo.money: could not connect to host
 e-wishlist.net: could not connect to host
 eagleridgecampground.com: could not connect to host
 eatfitoutlet.com.br: could not connect to host
 ebonyriddle.com: could not connect to host
 eeb98.com: could not connect to host
-egbert.net: could not connect to host
 ehuber.info: could not connect to host
 elaxy-online.de: could not connect to host
-elefantevoador.com: could not connect to host
-elia.cloud: could not connect to host
 elisabeth-strunz.de: could not connect to host
 elonbase.com: could not connect to host
 elsword.moe: could not connect to host
 endspamwith.us: could not connect to host
 engg.ca: could not connect to host
-enginx.net: could not connect to host
 er-music.com: could not connect to host
 erspro.net: could not connect to host
 estan.cn: could not connect to host
 etzi.myds.me: could not connect to host
 eurostrategy.vn.ua: could not connect to host
 ev-zertifikate.de: could not connect to host
 eveshaiwu.com: could not connect to host
 exceed.global: could not connect to host
@@ -308,74 +304,75 @@ facilitrak.com: could not connect to hos
 faithwatch.org: could not connect to host
 falkus.net: could not connect to host
 farm24.co.uk: could not connect to host
 feedstringer.com: could not connect to host
 feirlane.org: could not connect to host
 fernangp.com: could not connect to host
 festival.house: could not connect to host
 findmybottleshop.com.au: could not connect to host
+finstererlebnis.de: could not connect to host
 firebaseio.com: could not connect to host
 firexarxa.de: could not connect to host
 first-time-offender.com: could not connect to host
 firstchoicecandy.com: could not connect to host
 fixmyglitch.com: could not connect to host
 florian-schlachter.de: could not connect to host
 flow.su: could not connect to host
 flugplatz-edvc.de: could not connect to host
 flygpost.com: could not connect to host
-flyss.net: could not connect to host
 foodserve.in: could not connect to host
 forcamp.ga: could not connect to host
 forglemmigej.net: could not connect to host
 fortuna-loessnitz.de: could not connect to host
 foshanshequ.com: could not connect to host
 fossewayflowers.co.uk: could not connect to host
 fossewayflowers.com: could not connect to host
 foudufafa.de: could not connect to host
 foxmay.co.uk: could not connect to host
 fr0zenbits.io: could not connect to host
 fragnic.com: could not connect to host
 franckyz.com: could not connect to host
 fransallen.com: could not connect to host
-freaksites.dk: could not connect to host
 fredliang.cn: could not connect to host
 fredtec.ru: could not connect to host
 freeassangenow.org: could not connect to host
 freelansir.com: could not connect to host
 freezion.com: could not connect to host
 freshcode.nl: could not connect to host
 frodriguez.xyz: could not connect to host
 frolov.net: could not connect to host
 fromlemaytoz.com: could not connect to host
 frosty-gaming.xyz: could not connect to host
+frusky.net: could not connect to host
 fsfi.is: could not connect to host
+fsradio.eu: could not connect to host
 fugle.de: could not connect to host
 fuitedeau.ch: could not connect to host
 fukuko.biz: could not connect to host
 fukuko.xyz: could not connect to host
-fukuoka-cityliner.jp: could not connect to host
 funfunmstdn.tokyo: could not connect to host
 funksteckdosen24.de: could not connect to host
 futbolvivo.tv: could not connect to host
 futos.de: could not connect to host
 g4w.co: could not connect to host
 gabriele-kluge.de: could not connect to host
 gaiserik.com: could not connect to host
 gala.kiev.ua: could not connect to host
 gam3rs.de: could not connect to host
 game-gentle.com: could not connect to host
-gamepad.com.br: could not connect to host
 gamishou.fr: could not connect to host
 gasbarkenora.com: could not connect to host
 gasnews.net: could not connect to host
+gasser-daniel.ch: could not connect to host
 gayforgenji.com: could not connect to host
 gaygeeks.de: could not connect to host
 gdevpenze.ru: could not connect to host
 gdhzcgs.com: could not connect to host
+ge1.me: could not connect to host
 geeks.berlin: could not connect to host
 gehrke.nrw: could not connect to host
 generationnext.pl: could not connect to host
 geneve.guide: could not connect to host
 georgescarryout.com: could not connect to host
 getgeek.dk: could not connect to host
 getgeek.ee: could not connect to host
 getgeek.es: could not connect to host
@@ -384,16 +381,17 @@ getgeek.fr: could not connect to host
 getgeek.io: could not connect to host
 getgeek.no: could not connect to host
 getgeek.nu: could not connect to host
 getgeek.pl: could not connect to host
 getwarden.net: could not connect to host
 gevaulug.fr: could not connect to host
 gfoss.gr: could not connect to host
 ggx.us: could not connect to host
+gina-architektur.design: could not connect to host
 girlsgonesporty.com: could not connect to host
 glasner.photo: could not connect to host
 glbg.eu: could not connect to host
 gmantra.org: could not connect to host
 gnom.me: could not connect to host
 godrive.ga: could not connect to host
 goiaspropaganda.com.br: could not connect to host
 google: could not connect to host
@@ -416,74 +414,76 @@ grizzlys.com: could not connect to host
 grossberger-ge.org: could not connect to host
 gugaltika-ipb.org: could not connect to host
 gvt2.com: could not connect to host
 gvt3.com: could not connect to host
 hackerchai.com: could not connect to host
 halcyonsbastion.com: could not connect to host
 hasabig.wang: could not connect to host
 hasalittle.wang: could not connect to host
-hashi.dk: could not connect to host
 haze.network: could not connect to host
 hdy.nz: could not connect to host
 hearty.ink: could not connect to host
 heisenberg.co: could not connect to host
 hellomouse.tk: could not connect to host
 helsingfors.guide: could not connect to host
 henriknoerr.com: could not connect to host
 hentaimaster.net: could not connect to host
 here.ml: could not connect to host
 heroin.org.uk: could not connect to host
 hexobind.com: could not connect to host
 hg881.com: could not connect to host
 hintermeier-rae.at: could not connect to host
 hiraku.me: could not connect to host
 hirte-digital.de: could not connect to host
 hjes.com.ve: could not connect to host
+hloe0xff.ru: could not connect to host
 hobaugh.social: could not connect to host
+hohm.in: could not connect to host
 hoodoo.io: could not connect to host
 hoodoo.tech: could not connect to host
 hopesb.org: could not connect to host
 horvathd.eu: could not connect to host
 hr98.tk: could not connect to host
 hserver.top: could not connect to host
 hudingyuan.cn: could not connect to host
 hukkatavara.com: could not connect to host
 huwjones.me: could not connect to host
 hydra.zone: could not connect to host
 hydrante.ch: could not connect to host
 ibase.com: could not connect to host
-icarlos.net: could not connect to host
 ictpro.info: could not connect to host
 idcrane.com: could not connect to host
-ideaweb.de: could not connect to host
 idid.tk: could not connect to host
 ifoss.me: could not connect to host
 ifxnet.com: could not connect to host
+ignace72.eu: could not connect to host
 ikenmeyer.com: could not connect to host
 ikenmeyer.eu: could not connect to host
 ileat.com: could not connect to host
+iltec-prom.ru: could not connect to host
 imlinan.cn: could not connect to host
 imlinan.com: could not connect to host
 imlinan.info: could not connect to host
 imlinan.net: could not connect to host
 imperdintechnologies.com: could not connect to host
 inexpensivecomputers.net: could not connect to host
 informatik.zone: could not connect to host
+injust.eu.org: could not connect to host
 injust.me: could not connect to host
 inondation.ch: could not connect to host
 inscript.pl: could not connect to host
 installgentoo.net: could not connect to host
 investorloanshub.com: could not connect to host
+irvinepa.org: could not connect to host
 is-sw.net: could not connect to host
 isamiok.com: could not connect to host
-isistomie.com: could not connect to host
-issuesofconcern.in: could not connect to host
 itpro-mg.de: could not connect to host
 itproject.guru: could not connect to host
+its-schindler.de: could not connect to host
 ivanpolchenko.com: could not connect to host
 jaaxypro.com: could not connect to host
 jakincode.army: could not connect to host
 japan4you.org: could not connect to host
 jaredfraser.com: could not connect to host
 javascriptlab.fr: could not connect to host
 jbrowndesign.me: could not connect to host
 jccrew.org: could not connect to host
@@ -497,34 +497,36 @@ jobmedic.com: could not connect to host
 joecod.es: could not connect to host
 jonathansanchez.pro: could not connect to host
 joostbovee.nl: could not connect to host
 jorovik.com: could not connect to host
 juliawebber.co.za: could not connect to host
 just-pools.co.za: could not connect to host
 justmy.website: could not connect to host
 juventusmania1897.com: could not connect to host
+kabus.org: could not connect to host
 kaika-facilitymanagement.de: could not connect to host
 kamikaichimaru.com: could not connect to host
 kapo.info: could not connect to host
 karanlyons.com: could not connect to host
 karuneshjohri.com: could not connect to host
 kawaiiku.com: could not connect to host
 kawaiiku.de: could not connect to host
-kelm.me: could not connect to host
+kbb-ev.de: could not connect to host
 kenrogers.co: could not connect to host
 kenvix.com: could not connect to host
+keys.fedoraproject.org: could not connect to host
+kheshtar.pl: could not connect to host
 kieranweightman.me: could not connect to host
 kikuzuki.org: could not connect to host
 kinepolis-studio.ga: could not connect to host
 kitchenaccessories.pro: could not connect to host
 kj1396.net: could not connect to host
 kjchernov.info: could not connect to host
 kjoglum.me: could not connect to host
-klausbrinch.dk: could not connect to host
 kngk-azs.ru: could not connect to host
 knownsec.cf: could not connect to host
 koketteriet.se: could not connect to host
 kollawat.me: could not connect to host
 konicaprinterdriver.com: could not connect to host
 konventseliten.se: could not connect to host
 kopfsalat.eu: could not connect to host
 kousaku.jp: could not connect to host
@@ -537,32 +539,31 @@ laboutiquemarocaineduconvoyeur.ma: could
 lacasa.fr: could not connect to host
 lachawoj.de: could not connect to host
 ladylikeit.com: could not connect to host
 lanonfire.com: could not connect to host
 lathamlabs.com: could not connect to host
 lathamlabs.net: could not connect to host
 lathamlabs.org: could not connect to host
 lavapot.com: could not connect to host
+lawformt.com: could not connect to host
 lazulu.com: could not connect to host
-lcht.ch: could not connect to host
 lcti.biz: could not connect to host
 ldcraft.pw: could not connect to host
 lebal.se: could not connect to host
 leedev.org: could not connect to host
 legaltip.eu: could not connect to host
 legitaxi.com: could not connect to host
 leifdreizler.com: could not connect to host
 leninalbertop.com.ve: could not connect to host
 leonardcamacho.me: could not connect to host
 leticiagomeztagle.com: could not connect to host
 leveredge.net: could not connect to host
 lezdomsm.com: could not connect to host
 lheinrich.org: could not connect to host
-lianwen.kim: could not connect to host
 lianye1.cc: could not connect to host
 lianye2.cc: could not connect to host
 lianye3.cc: could not connect to host
 lianye4.cc: could not connect to host
 lianye5.cc: could not connect to host
 lianye6.cc: could not connect to host
 libertas-tech.com: could not connect to host
 lifenexto.com: could not connect to host
@@ -570,65 +571,61 @@ likenosis.com: could not connect to host
 lingerieonline.com.br: could not connect to host
 linksanitizer.com: could not connect to host
 linksextremist.at: could not connect to host
 linuxcommand.ru: could not connect to host
 linuxwebservertips.in: could not connect to host
 linvx.org: could not connect to host
 lissabon.guide: could not connect to host
 littleservice.cn: could not connect to host
-litvideoserver.de: could not connect to host
 litz.ca: could not connect to host
 litzenberger.ca: could not connect to host
 liukang.tech: could not connect to host
 livnev.me: could not connect to host
-liyinjia.com: could not connect to host
 lobosdomain.no-ip.info: could not connect to host
 locker3.com: could not connect to host
 logcat.info: could not connect to host
 logic8.ml: could not connect to host
 lovelytimes.net: could not connect to host
 luav.org: could not connect to host
-lubot.net: could not connect to host
 lukasunger.cz: could not connect to host
 lukasunger.net: could not connect to host
 luxonetwork.com: could not connect to host
 m4g.ru: could not connect to host
 maartenterpstra.xyz: could not connect to host
 macedopesca.com.br: could not connect to host
 madrants.net: could not connect to host
 magnacumlaude.co: could not connect to host
 mail4geek.com: could not connect to host
 malgraph.net: could not connect to host
+malikussa.id: could not connect to host
 manavgabhawala.com: could not connect to host
 mare92.cz: could not connect to host
 marketingdesignu.cz: could not connect to host
 martin-mattel.com: could not connect to host
 marxist.party: could not connect to host
 mastd.me: could not connect to host
-mastodon.host: could not connect to host
 mastodon.my: could not connect to host
 mathijskingma.nl: could not connect to host
 mattwb65.com: could not connect to host
 maxhoechtl.at: could not connect to host
 maynardnetworks.com: could not connect to host
 mbdrogenbos-usedcars.be: could not connect to host
+mbwemmel-usedcars.be: could not connect to host
 mcdanieldevelopmentservices.com: could not connect to host
 mcsnovatamabayan.com: could not connect to host
 me-dc.com: could not connect to host
 meanevo.com: could not connect to host
 meathealth.com: could not connect to host
 mecanicadom.com: could not connect to host
 mediadandy.com: could not connect to host
-medtankers.management: could not connect to host
 melhorproduto.com.br: could not connect to host
 melonstudios.net: could not connect to host
 menchez.me: could not connect to host
 mentax.net: could not connect to host
-mes10doigts.ovh: could not connect to host
 metachris.com: could not connect to host
 metrix-money-ptc.com: could not connect to host
 metrobriefs.com: could not connect to host
 mhjuma.com: could not connect to host
 michaelsulzer.com: could not connect to host
 michaelsulzer.eu: could not connect to host
 migueldominguez.ch: could not connect to host
 mikek.work: could not connect to host
@@ -657,85 +654,86 @@ mrliu.me: could not connect to host
 mtn.cc: could not connect to host
 munduch.cz: could not connect to host
 muslimbanter.co.za: could not connect to host
 mybeautyjobs.de: could not connect to host
 mycustomwriting.com: could not connect to host
 myfappening.org: could not connect to host
 mygeneral.org: could not connect to host
 mytravelblog.de: could not connect to host
+naano.org: could not connect to host
 naphex.rocks: could not connect to host
 narodsovety.ru: could not connect to host
 nba2k.cn: could not connect to host
 nba2k.com.cn: could not connect to host
 nbalive.cn: could not connect to host
 ncdesigns-studio.com: could not connect to host
 nedcf.org.uk: could not connect to host
 neer.io: could not connect to host
 nephy.jp: could not connect to host
 netica.fr: could not connect to host
-netscaler.expert: could not connect to host
 netulo.com: could not connect to host
 nevadafiber.net: could not connect to host
 nexuscorporation.in: could not connect to host
 nfluence.org: could not connect to host
 nico.st: could not connect to host
 nienfun.com: could not connect to host
 nikksno.io: could not connect to host
 nikolasbradshaw.com: could not connect to host
-ninux.ch: could not connect to host
 niouininon.eu: could not connect to host
 nirada.info: could not connect to host
 nishikino-maki.com: could not connect to host
 niva.synology.me: could not connect to host
 nkb.in.th: could not connect to host
 nodefoo.com: could not connect to host
-noodleyum.com: could not connect to host
 notesforpebble.com: could not connect to host
 novascan.net: could not connect to host
 novelabs.eu: could not connect to host
 nowremindme.com: could not connect to host
 nsdev.cn: could not connect to host
 nsmail.cn: could not connect to host
 nup.pw: could not connect to host
 nyanpasu.tv: could not connect to host
 obdolbacca.ru: could not connect to host
 oberhof.co: could not connect to host
-octal.es: could not connect to host
 off-the-clock.us: could not connect to host
 offgames.pro: could not connect to host
 office-ruru.com: could not connect to host
+ohlmeier.com: could not connect to host
+ohlmeier.net: could not connect to host
+ohlmeier.org: could not connect to host
 oliverspringer.eu: could not connect to host
 onewebdev.info: could not connect to host
+online-scene.com: could not connect to host
 onstud.com: could not connect to host
 onwie.fr: could not connect to host
 opengg.me: could not connect to host
 openspace.xxx: could not connect to host
 oscsdp.cz: could not connect to host
 otinane.eu: could not connect to host
 ourchoice2016.com: could not connect to host
 outdooradventures.pro: could not connect to host
 outetc.com: could not connect to host
 oxygaming.com: could not connect to host
 oxymc.com: could not connect to host
 oyesunn.com: could not connect to host
 p4chivtac.com: could not connect to host
 pammbook.com: could not connect to host
+panicparts.com: could not connect to host
 panj.ws: could not connect to host
 pardnoy.com: could not connect to host
 passrhce.com: could not connect to host
 passrhcsa.com: could not connect to host
 pasta-factory.co.il: could not connect to host
 patrickbusch.net: could not connect to host
 patrickneuro.de: could not connect to host
 paulshir.com: could not connect to host
 paulshir.is: could not connect to host
 pbytes.com: could not connect to host
 pcvirusclear.com: could not connect to host
-pdfconvert.me: could not connect to host
 pear2pear.de: could not connect to host
 pearbloom.com: could not connect to host
 perkbrian.com: could not connect to host
 persjrp.ca: could not connect to host
 persoform.ch: could not connect to host
 peykezamin.ir: could not connect to host
 pgmann.cf: could not connect to host
 pgpmail.cc: could not connect to host
@@ -751,16 +749,17 @@ plussizereviews.com: could not connect t
 pnsc.is: could not connect to host
 pointagri.com: could not connect to host
 pokalsocial.de: could not connect to host
 polit.im: could not connect to host
 poolinstallers.co.za: could not connect to host
 pouets.ovh: could not connect to host
 powerentertainment.tv: could not connect to host
 privcloud.org: could not connect to host
+productpeo.pl: could not connect to host
 projectasterk.com: could not connect to host
 projekt-umbriel.de: could not connect to host
 prokop.ovh: could not connect to host
 provitacare.com: could not connect to host
 proxydesk.eu: could not connect to host
 proxyweb.us: could not connect to host
 psncardplus.be: could not connect to host
 psncardplus.com: could not connect to host
@@ -775,120 +774,123 @@ qixi.biz: could not connect to host
 qoqo.us: could not connect to host
 qrforex.com: could not connect to host
 qscloud.de: could not connect to host
 qto.net: could not connect to host
 r0t.co: could not connect to host
 rainbin.com: could not connect to host
 rcoliveira.com: could not connect to host
 readityourself.net: could not connect to host
+reaganlibrary.gov: could not connect to host
 reaiaer.com: could not connect to host
 real-compare.com: could not connect to host
 realraghavgupta.com: could not connect to host
 realwoo.com: could not connect to host
 regendevices.eu: could not connect to host
 reignsphere.net: could not connect to host
 reismil.ch: could not connect to host
-relaybox.io: could not connect to host
 relsak.cz: could not connect to host
+repaik.com: could not connect to host
 report-to.io: could not connect to host
 report-url.com: could not connect to host
 report-url.io: could not connect to host
 reporturi.com: could not connect to host
 reporturi.io: could not connect to host
 reporturl.com: could not connect to host
 reporturl.io: could not connect to host
 reqognize.com: could not connect to host
 ressl.ch: could not connect to host
 retcor.net: could not connect to host
 reth.ch: could not connect to host
 retube.ga: could not connect to host
 reykjavik.guide: could not connect to host
 ribopierre.fr: could not connect to host
 richeza.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
-robomonkey.org: could not connect to host
 robust.ga: could not connect to host
+rodehutskors.net: could not connect to host
 roguesignal.net: could not connect to host
 rohanbassett.com: could not connect to host
 rool.me: could not connect to host
 roolevoi.ru: could not connect to host
+rotozen.com: could not connect to host
 rs-devdemo.host: could not connect to host
 rsldb.com: could not connect to host
 rubyist.today: could not connect to host
 ruhr3.de: could not connect to host
+ruht.ro: could not connect to host
 runcarina.com: could not connect to host
 rundumcolumn.xyz: could not connect to host
 runementors.com: could not connect to host
 ruudkoot.nl: could not connect to host
 sa.net: could not connect to host
 saferedirectlink.com: could not connect to host
 sallysubs.com: could not connect to host
 salzamt.tk: could not connect to host
 samaritan.tech: could not connect to host
 sanandreasstories.com: could not connect to host
 sanatrans.com: could not connect to host
-santojuken.co.jp: could not connect to host
 sarndipity.com: could not connect to host
+savenet.org: could not connect to host
 sbiewald.de: could not connect to host
 sciencemonster.co.uk: could not connect to host
 scm-2017.org: could not connect to host
-scorobudem.ru: could not connect to host
+score-savers.com: could not connect to host
 sctm.at: could not connect to host
 seanstrout.com: could not connect to host
 seaplayhomes.com: could not connect to host
 secitem.de: could not connect to host
 sectest.ml: could not connect to host
 security.xn--q9jyb4c: could not connect to host
 securitysoapbox.com: could not connect to host
 securon.io: could not connect to host
 securoswiss.ch: could not connect to host
+secutrans.com: could not connect to host
 seleondar.ru: could not connect to host
 sellmoretires.com: could not connect to host
 server-essentials.com: could not connect to host
 servfefe.com: could not connect to host
 sesha.co.za: could not connect to host
 shadex.net: could not connect to host
 shadowplus.net: could not connect to host
 shadowrocket.net: could not connect to host
 sharevari.com: could not connect to host
-sharperedgecomputers.com: could not connect to host
 shavingks.com: could not connect to host
-shellday.cc: could not connect to host
 sheratan.web.id: could not connect to host
 sheying.tm: could not connect to host
 shirakaba-cc.com: could not connect to host
 shopifycloud.com: could not connect to host
 shoppingreview.org: could not connect to host
 shred.ch: could not connect to host
 shredoptics.ch: could not connect to host
 sigsegv.run: could not connect to host
+siku.pro: could not connect to host
 simbolo.co.uk: could not connect to host
 simplerses.com: could not connect to host
 siqi.wang: could not connect to host
 skarox.com: could not connect to host
 skarox.net: could not connect to host
 skarox.ru: could not connect to host
+skolem.de: could not connect to host
 sky-aroma.com: could not connect to host
 skylocker.net: could not connect to host
 skylocker.nl: could not connect to host
 sl1pkn07.wtf: could not connect to host
-slimmerbouwen.be: could not connect to host
 slovoice.org: could not connect to host
 slytech.ch: could not connect to host
 smartrade.tech: could not connect to host
 smith.is: could not connect to host
 sml.lc: could not connect to host
 socialworkout.com: could not connect to host
 socialworkout.net: could not connect to host
 socialworkout.org: could not connect to host
 socialworkout.tv: could not connect to host
 socketize.com: could not connect to host
 sojingle.net: could not connect to host
-solariiknight.org: could not connect to host
 solos.im: could not connect to host
+somali-derp.com: could not connect to host
 soundhunter.xyz: could not connect to host
 sowingseasons.com: could not connect to host
 spicywombat.com: could not connect to host
 split.is: could not connect to host
 sportsmanadvisor.com: could not connect to host
 square-gaming.org: could not connect to host
 srvonfire.com: could not connect to host
 sss3s.com: could not connect to host
@@ -908,78 +910,75 @@ stylle.me: could not connect to host
 sudo.im: could not connect to host
 sulek.eu: could not connect to host
 suneilpatel.com: could not connect to host
 sunjaydhama.com: could not connect to host
 superpase.com: could not connect to host
 suspiciousdarknet.xyz: could not connect to host
 sussexwebdesigns.com: could not connect to host
 swuosa.org: could not connect to host
-sysdb.io: could not connect to host
-systemreboot.net: could not connect to host
 t3rror.net: could not connect to host
 tacticalsquare.com: could not connect to host
+tadu.de: could not connect to host
 takusan.ru: could not connect to host
 talktwincities.com: could not connect to host
 tangzhao.net: could not connect to host
-tcpweb.net: could not connect to host
 tdelmas.eu: could not connect to host
 tdelmas.ovh: could not connect to host
 tdsb.cf: could not connect to host
 tdsbhack.tk: could not connect to host
 techask.it: could not connect to host
-techpit.us: could not connect to host
 telekollektiv.org: could not connect to host
 telugu4u.net: could not connect to host
 tenispopular.com: could not connect to host
-tequilazor.com: could not connect to host
 terra-x.net: could not connect to host
 terrax.net: could not connect to host
 tetsai.com: could not connect to host
-teulon.eu: could not connect to host
 thefox.co: could not connect to host
 theprivacysolution.com: could not connect to host
 thermique.ch: could not connect to host
 thesehighsandlows.com: could not connect to host
 thinkcash.nl: could not connect to host
 timysewyn.be: could not connect to host
 todosrv.com: could not connect to host
 tokaido.com: could not connect to host
-tokkee.org: could not connect to host
 topdetoxcleanse.com: could not connect to host
 topnotchendings.com: could not connect to host
 totallynotaserver.com: could not connect to host
 totch.de: could not connect to host
 totot.net: could not connect to host
 touch-up-net.com: could not connect to host
 touha.me: could not connect to host
 toxicip.com: could not connect to host
 tpolemis.com: could not connect to host
 tradingbhavishya.com: could not connect to host
 transcendmotor.sg: could not connect to host
 travotion.com: could not connect to host
 treker.us: could not connect to host
 triddi.com: could not connect to host
 tsaro.io: could not connect to host
+tsurezurematome.ga: could not connect to host
+ttchan.org: could not connect to host
 tucidi.net: could not connect to host
 tumelum.de: could not connect to host
 turn-sticks.com: could not connect to host
 tuxhound.org: could not connect to host
 twiri.net: could not connect to host
 twitter.ax: could not connect to host
 twotube.ie: could not connect to host
 tyil.work: could not connect to host
 tykoon.com: could not connect to host
 ubicv.com: could not connect to host
 udo-luetkemeier.de: could not connect to host
 umsapi.com: could not connect to host
 unefuite.ch: could not connect to host
 unhu.fr: could not connect to host
 unicorn.li: could not connect to host
 unirenter.ru: could not connect to host
+unite-ka.de: could not connect to host
 unmonito.red: could not connect to host
 urbackups.com: could not connect to host
 urcentral.org: could not connect to host
 usportsgo.com: could not connect to host
 uwesander.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
 vadik.me: could not connect to host
 vanderstraeten.dynv6.net: could not connect to host
 vapehour.com: could not connect to host
@@ -987,89 +986,94 @@ varela-electricite.fr: could not connect
 venmos.com: could not connect to host
 versfin.net: could not connect to host
 vgatest.nl: could not connect to host
 vieaw.com: could not connect to host
 vimeosucks.nyc: could not connect to host
 vinetalk.net: could not connect to host
 visionthroughknowledge.com: could not connect to host
 visiontree.eu: could not connect to host
-visudira.com: could not connect to host
-vkino.com: could not connect to host
 vlogge.com: could not connect to host
 vmug.pl: could not connect to host
 votresiteweb.ch: could not connect to host
 vrtouring.org: could not connect to host
 vsx.ch: could not connect to host
 vumetric.com: could not connect to host
 vxapps.com: could not connect to host
 w4.no: could not connect to host
+wahhoi.net: could not connect to host
 waixingrenfuli.vip: could not connect to host
 wanashi.com: could not connect to host
+wanda76.com: could not connect to host
+wanda78.com: could not connect to host
+wanda79.com: could not connect to host
+wanda96.com: could not connect to host
+wanda97.com: could not connect to host
+wanda98.com: could not connect to host
 warlions.info: could not connect to host
 watchweasel.com: could not connect to host
 we.serveftp.net: could not connect to host
 weareincognito.org: could not connect to host
-web-wave.jp: could not connect to host
 webart-factory.de: could not connect to host
 webcatechism.com: could not connect to host
 webdesigneauclaire.com: could not connect to host
 webfox.com.br: could not connect to host
 webhackspro.com: could not connect to host
 webtech.com.br: could not connect to host
 webthings.com.br: could not connect to host
 wecanvisit.com: could not connect to host
-weed.ren: could not connect to host
 weiler.xyz: could not connect to host
 welby.cat: could not connect to host
 werhatunsverraten.eu: could not connect to host
 werkkrew.xyz: could not connect to host
 wessner.org: could not connect to host
 wetthost.com: could not connect to host
 whereisjason.com: could not connect to host
 whereismyorigin.cf: could not connect to host
 whilsttraveling.com: could not connect to host
 wilhelm-nathan.de: could not connect to host
 winnersports.co: could not connect to host
+wipc.net: could not connect to host
 wipply.com: could not connect to host
 wireframesoftware.com: could not connect to host
 wissl.org: could not connect to host
 wizznab.tk: could not connect to host
 wjglerum.nl: could not connect to host
 wolfemg.com: could not connect to host
 wolfenland.net: could not connect to host
 woomu.me: could not connect to host
 wooplagaming.com: could not connect to host
 workemy.com: could not connect to host
 wp-fastsearch.de: could not connect to host
 wp6.pw: could not connect to host
-wwv-8522.com: could not connect to host
 www-68277.com: could not connect to host
 www-8887999.com: could not connect to host
 www.re: could not connect to host
 www.sb: could not connect to host
 www.simbolo.co.uk: could not connect to host
 xeonlab.com: could not connect to host
 xeonlab.de: could not connect to host
 xia100.xyz: could not connect to host
 xing.ml: could not connect to host
 xn--8mr166hf6s.xn--fiqs8s: could not connect to host
 xn--d1acj9c.xn--90ais: could not connect to host
+xn--rdiger-kuhlmann-zvb.de: could not connect to host
 xn--yj8h0m.ws: could not connect to host
 xps2pdf.co.uk: could not connect to host
+xpwn.cz: could not connect to host
 xqin.net: could not connect to host
 xtremenutrition.com.br: could not connect to host
 xwaretech.info: could not connect to host
 yabrt.cn: could not connect to host
 yahoo.ax: could not connect to host
 yaucy.win: could not connect to host
 ybresson.com: could not connect to host
 yffengshi.ml: could not connect to host
 yhori.xyz: could not connect to host
-yiz96.com: could not connect to host
+yobst.tk: could not connect to host
 yoga.is-an-engineer.com: could not connect to host
 yogananda-roma.org: could not connect to host
 youftp.tk: could not connect to host
 yousite.by: could not connect to host
 yum.beer: could not connect to host
 yuna.tg: could not connect to host
 yux.fr: could not connect to host
 yvesx.com: could not connect to host
@@ -1089,17 +1093,17 @@ zuehlcke.de: could not connect to host
 zulu7.com: could not connect to host
 zuviel.space: could not connect to host
 zyx.im: could not connect to host
 zzw.ca: could not connect to host
 0005.com: could not connect to host
 0005aa.com: could not connect to host
 007sascha.de: did not receive HSTS header
 020wifi.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
-0222aa.com: could not connect to host
+0222aa.com: did not receive HSTS header
 048.ag: could not connect to host
 050508.com: could not connect to host
 0f.io: could not connect to host
 0fl.com: did not receive HSTS header
 0g.org.uk: could not connect to host
 0o0.ooo: could not connect to host
 0p.no: did not receive HSTS header
 0w0.vc: could not connect to host
@@ -1135,17 +1139,16 @@ 1396.cc: did not receive HSTS header
 1396.net: could not connect to host
 1536.cf: could not connect to host
 163pwd.com: could not connect to host
 166166.com: could not connect to host
 16deza.com: did not receive HSTS header
 16packets.com: could not connect to host
 173vpn.cn: could not connect to host
 173vpns.com: could not connect to host
-188522.com: did not receive HSTS header
 188betwarriors.co.uk: could not connect to host
 188trafalgar.ca: did not receive HSTS header
 195gm.com: could not connect to host
 1a-jva.de: could not connect to host
 1atic.com: could not connect to host
 1co-jp.net: did not receive HSTS header
 1cover.com: could not connect to host
 1k8b.com: could not connect to host
@@ -1185,25 +1188,25 @@ 341.mg: could not connect to host
 3555aa.com: could not connect to host
 35792.de: could not connect to host
 360gradus.com: did not receive HSTS header
 365.or.jp: could not connect to host
 368mibn.com: could not connect to host
 3778xl.com: did not receive HSTS header
 38sihu.com: could not connect to host
 39sihu.com: could not connect to host
-3ags.de: did not receive HSTS header
 3chit.cf: could not connect to host
 3click-loan.com: could not connect to host
 3d-bastler.de: could not connect to host
 3dcart.com: did not receive HSTS header
 3delivered.com: could not connect to host
 3dproteinimaging.com: did not receive HSTS header
 3fl.com: did not receive HSTS header
 3sreporting.com: did not receive HSTS header
+3wecommerce.com.br: did not receive HSTS header
 404.sh: could not connect to host
 404404.info: could not connect to host
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
 4455software.com: did not receive HSTS header
 44957.com: could not connect to host
 4679.space: could not connect to host
 4azino777.ru: did not receive HSTS header
@@ -1336,16 +1339,17 @@ addvocate.com: could not connect to host
 adelevie.com: could not connect to host
 adelinlydia-coach.com: did not receive HSTS header
 adequatetechnology.com: could not connect to host
 aderal.io: could not connect to host
 adesa-asesoria.com: did not receive HSTS header
 adfa-1.com: could not connect to host
 adhs-chaoten.net: did not receive HSTS header
 adindexr.com: could not connect to host
+adiponectinsupplement.net: did not receive HSTS header
 admin.google.com: did not receive HSTS header (error ignored - included regardless)
 admiral.dp.ua: did not receive HSTS header
 admitcard.co.in: did not receive HSTS header
 admsel.ec: could not connect to host
 adoge.me: could not connect to host
 adonairelogios.com.br: could not connect to host
 adopteunsiteflash.com: could not connect to host
 adquisitio.de: could not connect to host
@@ -1397,17 +1401,16 @@ ahoynetwork.com: did not receive HSTS he
 ahri.ovh: could not connect to host
 ahwatukeefoothillsmontessori.com: did not receive HSTS header
 aicial.co.uk: could not connect to host
 aicial.com.au: could not connect to host
 aidanwoods.com: did not receive HSTS header
 aids.gov: did not receive HSTS header
 aifreeze.ru: could not connect to host
 aify.eu: could not connect to host
-aimeeandalec.com: did not receive HSTS header
 ainrb.com: could not connect to host
 aip-marine.com: could not connect to host
 aiponne.com: could not connect to host
 airlea.com: could not connect to host
 airlinecheckins.com: did not receive HSTS header
 airproto.com: did not receive HSTS header
 aishnair.com: could not connect to host
 aisle3.space: could not connect to host
@@ -1419,35 +1422,33 @@ aka.my: did not receive HSTS header
 akboy.pw: could not connect to host
 akclinics.org: did not receive HSTS header
 akerek.hu: could not connect to host
 akgundemirbas.com: could not connect to host
 akhilindurti.com: could not connect to host
 akkadia.cc: could not connect to host
 akombakom.net: could not connect to host
 akselimedia.fi: did not receive HSTS header
-akstudentsfirst.org: did not receive HSTS header
+akstudentsfirst.org: could not connect to host
 aktivist.in: did not receive HSTS header
 al-shami.net: could not connect to host
 aladdin.ie: did not receive HSTS header
 alanlee.net: could not connect to host
 alanrickmanflipstable.com: could not connect to host
 alariel.de: did not receive HSTS header
 alarme-gps.ch: could not connect to host
 alarmegps.ch: could not connect to host
 alarmsystemreviews.com: did not receive HSTS header
 alaundeil.xyz: could not connect to host
 albanien.guide: could not connect to host
 alberguecimballa.es: could not connect to host
 albertbogdanowicz.pl: did not receive HSTS header
 albertopimienta.com: did not receive HSTS header
 alcatraz.online: could not connect to host
 alcazaar.com: could not connect to host
-alecpap.com: did not receive HSTS header
-alecpapierniak.com: did not receive HSTS header
 alecvannoten.be: did not receive HSTS header
 alenan.org: could not connect to host
 alessandro.pw: did not receive HSTS header
 alessandroz.pro: could not connect to host
 alethearose.com: did not receive HSTS header
 alexandre.sh: did not receive HSTS header
 alexbaker.org: did not receive HSTS header
 alexdodge.ca: could not connect to host
@@ -1521,16 +1522,17 @@ amo-entreprise-et-commerce.fr: could not
 amoory.com: could not connect to host
 amoozesh98.com: did not receive HSTS header
 amoozesh98.ir: did not receive HSTS header
 amorimendes.com.br: could not connect to host
 amri.nl: did not receive HSTS header
 anabol.nl: could not connect to host
 anadoluefessporkulubu.org: could not connect to host
 anagra.ms: could not connect to host
+anaisypirueta.es: did not receive HSTS header
 analytic-s.ml: did not receive HSTS header
 analyticsinmotion.net: could not connect to host
 ancientkarma.com: could not connect to host
 andere-gedanken.net: max-age too low: 10
 anderslind.dk: could not connect to host
 andre-ballensiefen.de: did not receive HSTS header
 andreasbreitenlohner.de: max-age too low: 600000
 andreasfritz-fotografie.de: could not connect to host
@@ -1538,17 +1540,16 @@ andreastoneman.com: could not connect to
 andreigec.net: did not receive HSTS header
 andrerose.ca: did not receive HSTS header
 andrew.london: did not receive HSTS header
 andrewbroekman.com: could not connect to host
 andrewmichaud.beer: could not connect to host
 andrewregan.me: could not connect to host
 andrewx.net: could not connect to host
 andreypopp.com: could not connect to host
-andro2id.com: did not receive HSTS header
 androidprosmart.com: could not connect to host
 androoz.se: could not connect to host
 andyclark.io: could not connect to host
 andymartin.cc: could not connect to host
 anfsanchezo.co: could not connect to host
 anfsanchezo.me: could not connect to host
 angeloroberto.ch: did not receive HSTS header
 anghami.com: did not receive HSTS header
@@ -2020,16 +2021,17 @@ blackburn.link: could not connect to hos
 blackkeg.ca: could not connect to host
 blacklane.com: did not receive HSTS header
 blackly.uk: max-age too low: 0
 blackpayment.ru: could not connect to host
 blackunicorn.wtf: could not connect to host
 blakerandall.xyz: could not connect to host
 blantik.net: could not connect to host
 blauwwit.be: did not receive HSTS header
+blazor.nl: did not receive HSTS header
 blendlecdn.com: could not connect to host
 blenheimchalcot.com: did not receive HSTS header
 blessnet.jp: did not receive HSTS header
 blha303.com.au: could not connect to host
 blitzprog.org: did not receive HSTS header
 blmiller.com: could not connect to host
 blocksatz-medien.de: could not connect to host
 blog-ritaline.com: could not connect to host
@@ -2332,17 +2334,16 @@ cdnb.co: could not connect to host
 cdndepo.com: could not connect to host
 cdreporting.co.uk: did not receive HSTS header
 cdt.org: did not receive HSTS header
 celebphotos.blog: did not receive HSTS header
 celeirorural.com.br: did not receive HSTS header
 celina-reads.de: did not receive HSTS header
 cellsites.nz: could not connect to host
 centennialrewards.com: did not receive HSTS header
-centillien.com: did not receive HSTS header
 centralpoint.be: did not receive HSTS header
 centralpoint.nl: did not receive HSTS header
 centralvacsunlimited.net: could not connect to host
 centralync.com: did not receive HSTS header
 centrepoint-community.com: could not connect to host
 centsforchange.net: could not connect to host
 ceresia.ch: could not connect to host
 ceritamalam.net: could not connect to host
@@ -2766,16 +2767,17 @@ cyberlab.kiev.ua: did not receive HSTS h
 cyberpunk.ca: could not connect to host
 cybershambles.com: could not connect to host
 cybersmart.co.uk: did not receive HSTS header
 cycleluxembourg.lu: did not receive HSTS header
 cyclingjunkies.com: could not connect to host
 cydia-search.io: could not connect to host
 cymtech.net: did not receive HSTS header
 cynoshair.com: could not connect to host
+cyoda.com: did not receive HSTS header
 cyphertite.com: could not connect to host
 cytadel.fr: did not receive HSTS header
 cyyzaid.cn: could not connect to host
 czbix.com: did not receive HSTS header
 d-rickroll-e.pw: could not connect to host
 d0xq.net: could not connect to host
 d1ves.io: did not receive HSTS header
 d4rkdeagle.tk: could not connect to host
@@ -2952,32 +2954,32 @@ dhpiggott.net: did not receive HSTS head
 diablotine.rocks: could not connect to host
 diagnosia.com: did not receive HSTS header
 diamondcare.com.br: could not connect to host
 dianlujitao.com: did not receive HSTS header
 dicando.com: max-age too low: 2592000
 dicelab.co.uk: could not connect to host
 dicionariofinanceiro.com: did not receive HSTS header
 dicionariopopular.com: did not receive HSTS header
+dicoding.com: did not receive HSTS header
 dieb.photo: could not connect to host
 dierenkruiden.nl: could not connect to host
 diewebstube.de: could not connect to host
 diezel.com: could not connect to host
 diferenca.com: did not receive HSTS header
 diggable.co: did not receive HSTS header
 digired.xyz: could not connect to host
 digitalbank.kz: could not connect to host
 digitaldaddy.net: could not connect to host
 digitaldashboard.gov: did not receive HSTS header
 digitalero.rip: did not receive HSTS header
 digitaljungle.net: could not connect to host
 digitalnonplus.com: could not connect to host
 digitalquery.com: did not receive HSTS header
 digitalriver.tk: did not receive HSTS header
-digitalrxcloud.com: did not receive HSTS header
 digitalskillswap.com: could not connect to host
 dim.lighting: could not connect to host
 dinamoelektrik.com: could not connect to host
 dingcc.me: could not connect to host
 dingcc.org: could not connect to host
 dingcc.xyz: could not connect to host
 dinkum.online: could not connect to host
 dipconsultants.com: could not connect to host
@@ -3208,17 +3210,16 @@ edelblack.ch: could not connect to host
 edelsteincosmetic.com: did not receive HSTS header
 eden-noel.at: could not connect to host
 edenaya.com: did not receive HSTS header
 edgereinvent.com: did not receive HSTS header
 ediscomp.sk: did not receive HSTS header
 edissecurity.sk: did not receive HSTS header
 edix.ru: could not connect to host
 edk.com.tr: did not receive HSTS header
-edlinus.cn: did not receive HSTS header
 edmodo.com: did not receive HSTS header
 edpubs.gov: did not receive HSTS header
 eduardnikolenko.ru: could not connect to host
 educatio.tech: could not connect to host
 educourse.ga: could not connect to host
 eduvance.in: did not receive HSTS header
 eengezinswoning-in-alphen-aan-den-rijn-kopen.nl: could not connect to host
 eengezinswoning-in-de-friese-meren-kopen.nl: could not connect to host
@@ -3442,16 +3443,17 @@ evites.me: could not connect to host
 evoludis.net: did not receive HSTS header
 evomon.com: could not connect to host
 evossd.tk: could not connect to host
 evowl.com: could not connect to host
 ewallet-optimizer.com: did not receive HSTS header
 ewex.org: could not connect to host
 excelgum.ca: did not receive HSTS header
 exceptionalservers.com: could not connect to host
+exeintel.com: did not receive HSTS header
 exfiles.cz: did not receive HSTS header
 exgravitus.com: could not connect to host
 exno.co: could not connect to host
 exousiakaidunamis.xyz: could not connect to host
 expertmile.com: did not receive HSTS header
 expo-designers.com: did not receive HSTS header
 expressfinance.co.za: did not receive HSTS header
 extrathemeshowcase.net: could not connect to host
@@ -3481,16 +3483,17 @@ fabhub.io: could not connect to host
 fabianfischer.de: did not receive HSTS header
 fabriko.fr: did not receive HSTS header
 factorable.net: did not receive HSTS header
 factorygw.com: did not receive HSTS header
 fadilus.com: did not receive HSTS header
 faesser.com: did not receive HSTS header
 fail4free.de: did not receive HSTS header
 failproof.be: max-age too low: 604800
+faircom.co.za: did not receive HSTS header
 fairkey.dk: did not receive HSTS header
 fairlyoddtreasures.com: did not receive HSTS header
 faizan.xyz: did not receive HSTS header
 fakeletters.org: did not receive HSTS header
 faktura.pl: did not receive HSTS header
 falconfrag.com: could not connect to host
 falconwiz.com: did not receive HSTS header
 falkhusemann.de: did not receive HSTS header
@@ -3573,16 +3576,17 @@ finalvpn.com: could not connect to host
 financieringsportaal.nl: did not receive HSTS header
 finanzkontor.net: could not connect to host
 findigo.fish: could not connect to host
 findingmyname.com: did not receive HSTS header
 findtutorsnearme.com: did not receive HSTS header
 fingent.com: did not receive HSTS header
 finiteheap.com: did not receive HSTS header
 finpt.com: did not receive HSTS header
+finsterlebnis.de: did not receive HSTS header
 fintechnics.com: did not receive HSTS header
 fiodental.com.br: did not receive HSTS header
 firebaseio-demo.com: could not connect to host
 firebaseio.com: could not connect to host (error ignored - included regardless)
 firebird.io: could not connect to host
 firefall.rocks: could not connect to host
 fireinthedeep.com: could not connect to host
 firemail.io: could not connect to host
@@ -3630,16 +3634,17 @@ flow.pe: could not connect to host
 flowersandclouds.com: could not connect to host
 floweslawncare.com: did not receive HSTS header
 flowlo.me: could not connect to host
 fluidojobs.com: could not connect to host
 flukethoughts.com: could not connect to host
 flurrybridge.com: did not receive HSTS header
 flushstudios.com: did not receive HSTS header
 flyaces.com: could not connect to host
+flyserver.co.il: did not receive HSTS header
 fm83.nl: could not connect to host
 fmi.gov: did not receive HSTS header
 fnvsecurity.com: could not connect to host
 fobc-usa.org: did not receive HSTS header
 fojtova.cz: did not receive HSTS header
 fojtovi.cz: did not receive HSTS header
 followback.net: did not receive HSTS header
 fonetiq.io: could not connect to host
@@ -3698,19 +3703,16 @@ frau-inge.de: could not connect to host
 fraudempire.com: could not connect to host
 freeflow.tv: could not connect to host
 freelanced.co.za: could not connect to host
 freelo.cz: did not receive HSTS header
 freematthale.net: did not receive HSTS header
 freesoftwaredriver.com: did not receive HSTS header
 freethought.org.au: could not connect to host
 freeutopia.org: did not receive HSTS header
-freifunk-in-solingen.de: did not receive HSTS header
-freifunk-lindlar.net: did not receive HSTS header
-freifunk-remscheid.de: did not receive HSTS header
 freqlabs.com: did not receive HSTS header
 freshfind.xyz: could not connect to host
 freshlymind.com: did not receive HSTS header
 frezbo.com: could not connect to host
 frforms.com: did not receive HSTS header
 fridaperfumaria.com.br: could not connect to host
 fridolinka.cz: could not connect to host
 friendica.ch: could not connect to host
@@ -3766,17 +3768,16 @@ fzslm.me: could not connect to host
 g-i-s.vn: did not receive HSTS header
 g-rickroll-o.pw: could not connect to host
 g2a.co: did not receive HSTS header
 g2g.com: did not receive HSTS header
 g4w.co: could not connect to host (error ignored - included regardless)
 g5led.nl: could not connect to host
 g77.ca: could not connect to host
 gabber.scot: could not connect to host
-gabethebabetv.com: did not receive HSTS header
 gabi.com.es: could not connect to host
 gabi.soy: did not receive HSTS header
 gabi.uno: could not connect to host
 gablaxian.com: max-age too low: 2592000
 gaelleetarnaud.com: did not receive HSTS header
 gainesvillegoneaustin.org: did not receive HSTS header
 gaite.me: did not receive HSTS header
 gakkainavi-epsilon.net: did not receive HSTS header
@@ -3810,17 +3811,17 @@ gamesdepartment.co.uk: did not receive H
 gameserver-sponsor.de: did not receive HSTS header
 gamesurferapp.com: could not connect to host
 gamingmedia.eu: did not receive HSTS header
 gaptek.id: could not connect to host
 garageon.net: did not receive HSTS header
 garciamartin.me: could not connect to host
 garcinia--cambogia.com: could not connect to host
 garden.trade: could not connect to host
-gardencarezone.com: could not connect to host
+gardencarezone.com: did not receive HSTS header
 garfieldairlines.net: did not receive HSTS header
 gatapro.net: could not connect to host
 gatorsa.es: did not receive HSTS header
 gaussorgues.me: could not connect to host
 gdegem.org: did not receive HSTS header
 gebn.co.uk: did not receive HSTS header
 gebn.uk: could not connect to host
 gedankenbude.info: could not connect to host
@@ -3882,16 +3883,17 @@ gfm.tech: could not connect to host
 gfournier.ca: could not connect to host
 gfwsb.ml: could not connect to host
 ggss.ml: could not connect to host
 gheorghe-sarcov.ga: could not connect to host
 gheorghesarcov.ga: could not connect to host
 gheorghesarcov.tk: could not connect to host
 ghkim.net: could not connect to host
 ghostcir.com: could not connect to host
+ghrelinblocker.info: did not receive HSTS header
 giakki.eu: could not connect to host
 gianlucapartengo.photography: did not receive HSTS header
 gibraltar-firma.com: did not receive HSTS header
 gidea.nu: could not connect to host
 gietvloergarant.nl: did not receive HSTS header
 giftgofers.com: did not receive HSTS header
 giftservices.nl: could not connect to host
 gigacloud.org: max-age too low: 0
@@ -3931,17 +3933,17 @@ gloucesterphotographer.com: did not rece
 glubbforum.de: did not receive HSTS header
 glws.org: did not receive HSTS header
 gm-assicurazioni.it: could not connect to host
 gmail.com: did not receive HSTS header (error ignored - included regardless)
 gmat.ovh: could not connect to host
 gmoes.at: max-age too low: 600000
 go.ax: did not receive HSTS header
 go2sh.de: did not receive HSTS header
-go4it.solutions: could not connect to host
+go4it.solutions: did not receive HSTS header
 goabonga.com: could not connect to host
 goalsetup.com: did not receive HSTS header
 goaltree.ch: did not receive HSTS header
 goarmy.eu: could not connect to host
 goat.chat: did not receive HSTS header
 goat.xyz: max-age too low: 86400
 goben.ch: could not connect to host
 goblins.net: did not receive HSTS header
@@ -4075,16 +4077,17 @@ gugga.dk: could not connect to host
 guguke.net: did not receive HSTS header
 guilde-vindicta.fr: did not receive HSTS header
 guillaume-leduc.fr: did not receive HSTS header
 guillaumematheron.fr: did not receive HSTS header
 guineafruitcorp.com: could not connect to host
 gulch.in.ua: did not receive HSTS header
 gulenet.com: could not connect to host
 gulfcoast-sandbox.com: could not connect to host
+guniram.com: did not receive HSTS header
 gunnarhafdal.com: did not receive HSTS header
 gunnaro.com: could not connect to host
 guntbert.net: could not connect to host
 guoqiang.info: could not connect to host
 gurom.lv: could not connect to host
 gurusupe.com: could not connect to host
 guso.gq: could not connect to host
 guso.ml: could not connect to host
@@ -4211,16 +4214,17 @@ healtious.com: could not connect to host
 heart.ge: did not receive HSTS header
 heartlandrentals.com: did not receive HSTS header
 hearty.ga: could not connect to host
 hearty.space: could not connect to host
 heartyme.net: could not connect to host
 heathmanners.com: could not connect to host
 heavystresser.com: could not connect to host
 hebaus.com: could not connect to host
+hegen.com.pl: did not receive HSTS header
 heidilein.info: did not receive HSTS header
 heimnetze.org: could not connect to host
 heimonen.eu: did not receive HSTS header
 helencrump.co.uk: did not receive HSTS header
 helgakristoffer.com: could not connect to host
 helgakristoffer.wedding: could not connect to host
 helloworldhost.com: did not receive HSTS header
 hellscanyonraft.com: did not receive HSTS header
@@ -4253,17 +4257,16 @@ hiexmerida-mailing.com: did not receive 
 highgrove.org.uk: could not connect to host
 highseer.com: did not receive HSTS header
 highsurf-miyazaki.com: did not receive HSTS header
 hightower.eu: could not connect to host
 highvelocitydesign.com: could not connect to host
 hiisukun.com: could not connect to host
 hiitcentre.com: did not receive HSTS header
 hikariempire.com: could not connect to host
-hikinggearlab.com: did not receive HSTS header
 hilinemerchandising.com: did not receive HSTS header
 hillcity.org.nz: did not receive HSTS header
 hilnu.tk: could not connect to host
 hintergedanken.com: did not receive HSTS header
 hipercultura.com: did not receive HSTS header
 hiphopconvention.nl: could not connect to host
 hipnos.net: did not receive HSTS header
 hirefitness.co.uk: did not receive HSTS header
@@ -4285,17 +4288,16 @@ hofiprojekt.cz: did not receive HSTS hea
 hogar123.es: could not connect to host
 hoiku-map.tokyo: could not connect to host
 hoiku-navi.com: did not receive HSTS header
 holgerlehner.com: could not connect to host
 holifestival-freyung.de: could not connect to host
 holymoly.lu: could not connect to host
 homa.website: could not connect to host
 homads.com: did not receive HSTS header
-homatism.com: did not receive HSTS header
 homeandyarddetailing.com: could not connect to host
 homeclouding.de: could not connect to host
 homedna.com: did not receive HSTS header
 homeexx.com: did not receive HSTS header
 homeownersassociationmanagementla.com: did not receive HSTS header
 homeseller.co.uk: could not connect to host
 hometownmall.com: did not receive HSTS header
 homeyantra.com: max-age too low: 86400
@@ -4372,17 +4374,17 @@ hydrodipcenter.nl: did not receive HSTS 
 hydronium.cf: could not connect to host
 hydronium.ga: could not connect to host
 hydronium.me: could not connect to host
 hydronium.ml: could not connect to host
 hydronium.tk: could not connect to host
 hypa.net.au: did not receive HSTS header
 hyper69.com: did not receive HSTS header
 hypnoresults.com.au: did not receive HSTS header
-hypnos.hu: could not connect to host
+hypnos.hu: did not receive HSTS header
 hysg.me: could not connect to host
 i-jp.net: could not connect to host
 i-partners.sk: did not receive HSTS header
 i-rickroll-n.pw: could not connect to host
 i10z.com: could not connect to host
 iacono.com.br: did not receive HSTS header
 iamjoshellis.com: could not connect to host
 iamokay.nl: did not receive HSTS header
@@ -4862,16 +4864,17 @@ justnaw.co.uk: could not connect to host
 justudin.com: did not receive HSTS header
 justwood.cz: did not receive HSTS header
 jutella.de: did not receive HSTS header
 juvenex.co: could not connect to host
 juwairen.cn: could not connect to host
 jvoice.net: could not connect to host
 jwilsson.me: could not connect to host
 jxm.in: could not connect to host
+jym.fit: did not receive HSTS header
 jysperm.me: did not receive HSTS header
 jznet.org: could not connect to host
 k-dev.de: could not connect to host
 k-rickroll-g.pw: could not connect to host
 k-wallet.com: did not receive HSTS header
 k1cp.com: could not connect to host
 ka-clan.com: could not connect to host
 kabinapp.com: could not connect to host
@@ -5287,32 +5290,31 @@ linuxmint.cz: could not connect to host
 linuxmonitoring.net: did not receive HSTS header
 liquid.solutions: did not receive HSTS header
 liquorsanthe.in: could not connect to host
 lisaco.de: could not connect to host
 lisbongold.com: did not receive HSTS header
 lisgade.dk: did not receive HSTS header
 listafirmelor.com: could not connect to host
 listage.ovh: did not receive HSTS header
-litcomphonors.com: did not receive HSTS header
 litespeed.io: could not connect to host
 little.pw: could not connect to host
 littlefreelibrary.org: did not receive HSTS header
 littleqiu.net: could not connect to host
 liujunyang.com: could not connect to host
 livecards.co.uk: did not receive HSTS header
 livedemo.io: could not connect to host
 livej.am: could not connect to host
 liverewrite.com: could not connect to host
 liviababynet.com.br: could not connect to host
 lixiang.one: could not connect to host
 lixingcong.com: could not connect to host
 lkp111138.me: could not connect to host
 llamasweet.tech: could not connect to host
-loacg.com: could not connect to host
+loacg.com: did not receive HSTS header
 loadingdeck.com: did not receive HSTS header
 loadso.me: could not connect to host
 loafbox.com: could not connect to host
 loansonline.today: could not connect to host
 lobste.rs: did not receive HSTS header
 localchum.com: could not connect to host
 localdrive.me: could not connect to host
 localnetwork.nz: could not connect to host
@@ -5379,17 +5381,17 @@ ls-a.org: did not receive HSTS header
 lsky.cn: could not connect to host
 lsp-sports.de: did not receive HSTS header
 ltbytes.com: could not connect to host
 ltechnologygroup.com: did not receive HSTS header
 ltu.social: could not connect to host
 lucas-garte.com: did not receive HSTS header
 lucaterzini.com: could not connect to host
 luclu7.pw: did not receive HSTS header
-ludwig.click: could not connect to host
+ludwig.click: did not receive HSTS header
 ludwiggrill.de: did not receive HSTS header
 lufthansaexperts.com: max-age too low: 2592000
 luganskservers.net: did not receive HSTS header
 luis-checa.com: could not connect to host
 lukeng.me: could not connect to host
 lukonet.com: did not receive HSTS header
 luludapomerania.com: could not connect to host
 lumd.me: could not connect to host
@@ -5405,17 +5407,17 @@ luoe.ml: could not connect to host
 luoxiao.im: could not connect to host
 luripump.se: could not connect to host
 lusis.fr: did not receive HSTS header
 lusis.net: did not receive HSTS header
 lustrumxi.nl: could not connect to host
 luther.fi: did not receive HSTS header
 luxus-russen.de: did not receive HSTS header
 luzfaltex.com: did not receive HSTS header
-lycly.top: did not receive HSTS header
+lycly.top: could not connect to host
 lydia-und-simon.de: could not connect to host
 lydiagorstein.com: could not connect to host
 lyonelkaufmann.ch: did not receive HSTS header
 lyuba.fr: could not connect to host
 lzkill.com: did not receive HSTS header
 lzzr.me: did not receive HSTS header
 m-ali.xyz: could not connect to host
 m-rickroll-v.pw: could not connect to host
@@ -5504,17 +5506,16 @@ manifestbin.com: did not receive HSTS he
 manitasicily.com: did not receive HSTS header
 manningbrothers.com: did not receive HSTS header
 mansfieldplacevt.com: did not receive HSTS header
 manshop24.com: could not connect to host
 mansion-note.com: did not receive HSTS header
 manududu.com.br: did not receive HSTS header
 maomaofuli.vip: could not connect to host
 maple5.com: did not receive HSTS header
-marakovits.net: did not receive HSTS header
 marcaudefroy.com: did not receive HSTS header
 marcelparra.com: could not connect to host
 marchagen.nl: did not receive HSTS header
 marco01809.net: could not connect to host
 marcoececilia.it: did not receive HSTS header
 marcofinke.de: could not connect to host
 marcontrol.com: did not receive HSTS header
 marcosteixeira.tk: could not connect to host
@@ -5619,17 +5620,16 @@ mcdonalds.ru: did not receive HSTS heade
 mcga.media: could not connect to host
 mclab.su: could not connect to host
 mclist.it: could not connect to host
 mclyr.com: max-age too low: 7776000
 mcmillansedationdentistry.com: did not receive HSTS header
 mcooperlaw.com: did not receive HSTS header
 mcuexchange.com: did not receive HSTS header
 mdfnet.se: did not receive HSTS header
-mdkr.nl: did not receive HSTS header
 mdscomp.net: did not receive HSTS header
 meadowfen.farm: could not connect to host
 meadowfenfarm.com: could not connect to host
 meamod.com: max-age too low: 0
 meat-education.com: could not connect to host
 mebio.us: did not receive HSTS header
 mecenat-cassous.com: did not receive HSTS header
 mechmk1.me: did not receive HSTS header
@@ -5729,17 +5729,17 @@ microme.ga: could not connect to host
 micropple.net: could not connect to host
 microtalk.org: could not connect to host
 midirs.org: did not receive HSTS header
 midonet.org: did not receive HSTS header
 midriversmotorsllc.com: did not receive HSTS header
 midwestwomenworkers.org: could not connect to host
 miegl.cz: could not connect to host
 miemie.jp: could not connect to host
-migeeks.de: could not connect to host
+migeeks.de: did not receive HSTS header
 mightydicks.io: could not connect to host
 mightydicks.tech: could not connect to host
 mightysounds.cz: max-age too low: 0
 migrator.co: could not connect to host
 miguksaram.com: could not connect to host
 mijcorijneveld.nl: did not receive HSTS header
 mijn-email.org: could not connect to host
 mijnetickets.nl: did not receive HSTS header
@@ -6001,23 +6001,23 @@ mynetblog.com: did not receive HSTS head
 myni.io: could not connect to host
 mynigma.org: did not receive HSTS header
 mypagella.com: could not connect to host
 mypagella.eu: could not connect to host
 mypagella.it: could not connect to host
 mypension.ca: could not connect to host
 myphonebox.de: could not connect to host
 myraytech.net: did not receive HSTS header
+myrig.com: did not receive HSTS header
 myrig.net: could not connect to host
 myrsa.in: did not receive HSTS header
 mysecretrewards.com: could not connect to host
 myspa.asia: did not receive HSTS header
 mystery-science-theater-3000.de: could not connect to host
 mysteryblog.de: did not receive HSTS header
-mysupboard.de: did not receive HSTS header
 mythlogic.com: did not receive HSTS header
 mythslegendscollection.com: did not receive HSTS header
 myweb360.de: did not receive HSTS header
 myzone.com: did not receive HSTS header
 n-rickroll-e.pw: could not connect to host
 n0psled.nl: could not connect to host
 n2x.in: could not connect to host
 n4l.pw: could not connect to host
@@ -6046,16 +6046,17 @@ nan.zone: could not connect to host
 nandex.org: could not connect to host
 naniki.co.uk: did not receive HSTS header
 nanogeneinc.com: could not connect to host
 nanokamo.com: did not receive HSTS header
 nanrenba.net: could not connect to host
 nansay.cn: could not connect to host
 nanto.eu: could not connect to host
 narodniki.com: did not receive HSTS header
+narviz.com: did not receive HSTS header
 nashira.cz: did not receive HSTS header
 nasralmabrooka.com: did not receive HSTS header
 natalia-fadeeva.ru: could not connect to host
 natalia.io: could not connect to host
 natalieandjoshua.com: could not connect to host
 natalt.org: did not receive HSTS header
 nathan.io: did not receive HSTS header
 nathanmfarrugia.com: did not receive HSTS header
@@ -6217,17 +6218,16 @@ nosecretshop.com: could not connect to h
 nostraspace.com: did not receive HSTS header
 notadd.com: did not receive HSTS header
 notadd.io: could not connect to host
 notarankastojkovic.me: could not connect to host
 notenoughtime.de: could not connect to host
 nothing.net.nz: max-age too low: 7776000
 nothing.org.uk: did not receive HSTS header
 noticia.do: did not receive HSTS header
-notinglife.com: could not connect to host
 notjustbitchy.com: did not receive HSTS header
 nottheonion.net: did not receive HSTS header
 nou.si: could not connect to host
 nouvelle-vague-saint-cast.fr: did not receive HSTS header
 nova-elearning.com: did not receive HSTS header
 novaco.in: max-age too low: 3600
 novacraft.me: did not receive HSTS header
 novatrucking.de: could not connect to host
@@ -6238,16 +6238,17 @@ novurania.com: did not receive HSTS head
 nowak.ninja: did not receive HSTS header
 noworrywp.com: could not connect to host
 nowprotein.com: did not receive HSTS header
 nozoe.jp: could not connect to host
 npol.de: could not connect to host
 nq7.pl: could not connect to host
 nrechn.de: could not connect to host
 nrizzio.me: could not connect to host
+nsboutique.com: did not receive HSTS header
 nsweb.solutions: could not connect to host
 ntbs.pro: could not connect to host
 ntse.xyz: could not connect to host
 nu3.at: did not receive HSTS header
 nu3.ch: did not receive HSTS header
 nu3.co.uk: could not connect to host
 nu3.com: did not receive HSTS header
 nu3.de: did not receive HSTS header
@@ -6468,17 +6469,17 @@ outsider.im: could not connect to host
 outurnate.com: could not connect to host
 ouvirmusica.com.br: did not receive HSTS header
 ovenapp.io: did not receive HSTS header
 override.io: could not connect to host
 oversight.io: could not connect to host
 ovuscloud.de: could not connect to host
 ovvy.net: did not receive HSTS header
 owennelson.me: could not connect to host
-owlishmedia.com: did not receive HSTS header
+owlishmedia.com: could not connect to host
 owncloud.help: could not connect to host
 ownmovies.fr: could not connect to host
 oxro.co: did not receive HSTS header
 oxygenabsorbers.com: did not receive HSTS header
 oxynux.fr: could not connect to host
 oyste.in: could not connect to host
 ozoz.cc: could not connect to host
 p-rickroll-o.pw: could not connect to host
@@ -6507,16 +6508,17 @@ paleosquawk.com: did not receive HSTS he
 palmer.im: could not connect to host
 pamplona.tv: could not connect to host
 pamsoft.pl: max-age too low: 0
 pan.tips: could not connect to host
 panaceallc.net: could not connect to host
 panama-gbs.com: did not receive HSTS header
 panamaequity.com: did not receive HSTS header
 panamateakforestry.com: did not receive HSTS header
+panascais.net: did not receive HSTS header
 panelomix.net: did not receive HSTS header
 panni.me: could not connect to host
 panoranordic.net: did not receive HSTS header
 pansu.space: could not connect to host
 pants-off.xyz: could not connect to host
 pantsu.cat: did not receive HSTS header
 papalytics.com: could not connect to host
 papeda.net: could not connect to host
@@ -6679,17 +6681,16 @@ pidomex.com: did not receive HSTS header
 pieterjangeeroms.me: could not connect to host
 piggott.me.uk: did not receive HSTS header
 pilgermaske.org: did not receive HSTS header
 piligrimname.com: could not connect to host
 pillowandpepper.com: did not receive HSTS header
 pimpmymac.ru: did not receive HSTS header
 pims.global: did not receive HSTS header
 pinkyf.com: could not connect to host
-pinpayments.com: did not receive HSTS header
 pippen.io: could not connect to host
 pirata.ga: could not connect to host
 piratebit.tech: could not connect to host
 piratedb.com: could not connect to host
 piratedot.com: could not connect to host
 piratelist.online: could not connect to host
 piratenlogin.de: could not connect to host
 pirateproxy.pe: could not connect to host
@@ -7141,17 +7142,17 @@ retroarms.com: did not receive HSTS head
 retroarms.cz: did not receive HSTS header
 returnofwar.com: could not connect to host
 revapost.ch: could not connect to host
 revealdata.com: did not receive HSTS header
 revelaciones.tv: could not connect to host
 revello.org: did not receive HSTS header
 reverie.pw: could not connect to host
 review.info: did not receive HSTS header
-reviewjust.com: could not connect to host
+reviewjust.com: did not receive HSTS header
 reviews.anime.my: max-age too low: 5184000
 revtut.net: could not connect to host
 rewardstock.com: max-age too low: 0
 rewopit.net: did not receive HSTS header
 rhapsodhy.hu: could not connect to host
 rhdigital.pro: could not connect to host
 rhering.de: could not connect to host
 rhodosdreef.nl: could not connect to host
@@ -7188,16 +7189,17 @@ rizon.me: could not connect to host
 rj.gg: could not connect to host
 rk6.cz: could not connect to host
 rkkhok.hu: did not receive HSTS header
 rkmantpur.org: did not receive HSTS header
 rmaqequipamentos.com.br: did not receive HSTS header
 rme.li: did not receive HSTS header
 roadfeast.com: could not connect to host
 roan24.pl: did not receive HSTS header
+rob.uk.com: did not receive HSTS header
 robertglastra.com: could not connect to host
 robigalia.org: did not receive HSTS header
 robteix.com: did not receive HSTS header
 robtex.com: did not receive HSTS header
 robtex.net: did not receive HSTS header
 robtex.org: did not receive HSTS header
 rochman.id: could not connect to host
 rocketnet.ml: could not connect to host
@@ -7467,16 +7469,17 @@ seiler-bad.de: did not receive HSTS head
 seizoushokoyuubangou.com: did not receive HSTS header
 sektor.team: could not connect to host
 selecadm.name: could not connect to host
 selectary.com: could not connect to host
 selectcertifiedautos.com: did not receive HSTS header
 selectruckscalltrackingreports.com: could not connect to host
 selfdefenserx.com: did not receive HSTS header
 selfie-france.fr: could not connect to host
+selfmade4u.de: did not receive HSTS header
 selldorado.com: could not connect to host
 sellercritic.com: did not receive HSTS header
 sello.com: did not receive HSTS header
 sellocdn.com: could not connect to host
 sellservs.co.za: could not connect to host
 semaf.at: max-age too low: 86400
 semantheme.fr: did not receive HSTS header
 semen3325.xyz: could not connect to host
@@ -7492,17 +7495,17 @@ senedirect.com: could not connect to hos
 sens2lavie.com: did not receive HSTS header
 senseofnumber.co.uk: did not receive HSTS header
 sensiblemn.org: could not connect to host
 sensibus.com: did not receive HSTS header
 seo-lagniappe.com: did not receive HSTS header
 seobot.com.au: could not connect to host
 seomobo.com: could not connect to host
 seosanantonioinc.com: did not receive HSTS header
-seowarp.net: did not receive HSTS header
+seowarp.net: could not connect to host
 seq.tf: did not receive HSTS header
 serathius.ovh: could not connect to host
 serbien.guide: could not connect to host
 serenitycreams.com: did not receive HSTS header
 serfdom.io: did not receive HSTS header
 serized.pw: could not connect to host
 serverangels.co.uk: could not connect to host
 servercode.ca: did not receive HSTS header
@@ -7622,17 +7625,16 @@ simon.butcher.name: max-age too low: 262
 simongong.net: did not receive HSTS header
 simonsaxon.com: did not receive HSTS header
 simpan.id: did not receive HSTS header
 simpleai.net: max-age too low: 600
 simplelearner.com: could not connect to host
 simplepractice.com: did not receive HSTS header
 simplixos.org: could not connect to host
 simplyenak.com: did not receive HSTS header
-simplyfixit.co.uk: did not receive HSTS header
 sin30.net: could not connect to host
 sincai666.com: could not connect to host
 sincron.org: could not connect to host
 sinful.pw: could not connect to host
 singul4rity.com: could not connect to host
 sinneserweiterung.de: could not connect to host
 sinosky.org: did not receive HSTS header
 sipc.org: did not receive HSTS header
@@ -7706,16 +7708,17 @@ smexpt.com: did not receive HSTS header
 smimea.com: could not connect to host
 smirkingwhorefromhighgarden.pro: could not connect to host
 smittix.co.uk: did not receive HSTS header
 smkn1lengkong.sch.id: did not receive HSTS header
 smksi2.com: could not connect to host
 smksultanismail2.com: did not receive HSTS header
 smove.sg: did not receive HSTS header
 smplix.com: could not connect to host
+smtp.bz: did not receive HSTS header
 smusg.com: did not receive HSTS header
 smzsq.com: did not receive HSTS header
 snailing.org: could not connect to host
 snakehosting.dk: did not receive HSTS header
 snapworks.net: did not receive HSTS header
 snekchat.moe: could not connect to host
 snel4u.nl: could not connect to host
 snelwerk.be: could not connect to host
@@ -7750,16 +7753,17 @@ solidus.systems: did not receive HSTS he
 soljem.com: did not receive HSTS header
 soll-i.ch: did not receive HSTS header
 solosmusic.xyz: could not connect to host
 solsystems.ru: could not connect to host
 solutive.fi: did not receive HSTS header
 someshit.xyz: could not connect to host
 something-else.cf: could not connect to host
 somethingnew.xyz: could not connect to host
+soniafauville.com: did not receive HSTS header
 sonic.network: did not receive HSTS header
 sonicrainboom.rocks: did not receive HSTS header
 sonyforum.no: did not receive HSTS header
 soobi.org: did not receive HSTS header
 soply.com: did not receive HSTS header
 soporte.cc: could not connect to host
 sorensen-online.com: could not connect to host
 sosaka.ml: could not connect to host
@@ -7796,17 +7800,16 @@ sparsa.army: could not connect to host
 sparta-trade.com: could not connect to host
 spauted.com: could not connect to host
 spdysync.com: could not connect to host
 specialedesigns.com: could not connect to host
 speculor.net: could not connect to host
 spedition-transport-umzug.de: did not receive HSTS header
 speed-mailer.com: could not connect to host
 speedcounter.net: did not receive HSTS header
-speeds.vip: did not receive HSTS header
 speedy.lt: max-age too low: 0
 speedyprep.com: did not receive HSTS header
 speidel.com.tr: did not receive HSTS header
 spencerbaer.com: could not connect to host
 sperohub.io: could not connect to host
 spiegels.nl: could not connect to host
 spielcasinos.com: did not receive HSTS header
 spikeykc.me: did not receive HSTS header
@@ -7814,17 +7817,16 @@ spillmaker.no: did not receive HSTS head
 spilsbury.io: could not connect to host
 spirit-dev.net: max-age too low: 0
 spisoggrin.dk: did not receive HSTS header
 spitefultowel.com: did not receive HSTS header
 spititout.it: could not connect to host
 spittersberger.recipes: did not receive HSTS header
 spokonline.com: could not connect to host
 sponsortobias.com: could not connect to host
-sport-socken.net: did not receive HSTS header
 sportchirp-internal.azurewebsites.net: did not receive HSTS header
 sporthit.ru: did not receive HSTS header
 sportifik.com: did not receive HSTS header
 sportingoods.com.br: could not connect to host
 sportscollection.com.br: could not connect to host
 sportwette.eu: did not receive HSTS header
 spot-events.com: could not connect to host
 spotifyripper.tk: could not connect to host
@@ -8055,17 +8057,16 @@ t-complex.space: could not connect to ho
 t-ken.xyz: could not connect to host
 t-tz.com: could not connect to host
 t0dd.eu: could not connect to host
 t2i.nl: max-age too low: 3600
 t4c-rebirth.com: could not connect to host
 t4x.org: could not connect to host
 taabe.xyz: could not connect to host
 taberu-fujitsubo.com: did not receive HSTS header
-tabithawebb.co.uk: did not receive HSTS header
 tadigitalstore.com: could not connect to host
 tafoma.com: did not receive HSTS header
 tageau.com: could not connect to host
 taglondon.org: did not receive HSTS header
 tailify.com: did not receive HSTS header
 tails.com.ar: did not receive HSTS header
 takumi-s.net: did not receive HSTS header
 talado.gr: could not connect to host
@@ -8078,16 +8079,17 @@ talklifestyle.nl: could not connect to h
 tallr.se: could not connect to host
 tallshoe.com: could not connect to host
 tamex.xyz: could not connect to host
 tandarts-haarlem.nl: did not receive HSTS header
 tangel.me: could not connect to host
 tangibilizing.com: could not connect to host
 taniesianie.pl: did not receive HSTS header
 tankfreunde.de: did not receive HSTS header
+tannerfilip.org: did not receive HSTS header
 tante-bugil.net: could not connect to host
 tantotiempo.de: did not receive HSTS header
 tanze-jetzt.de: could not connect to host
 taotuba.net: did not receive HSTS header
 taozj.org: did not receive HSTS header
 tapfinder.ca: could not connect to host
 tapka.cz: did not receive HSTS header
 tappublisher.com: did not receive HSTS header
@@ -8227,17 +8229,16 @@ thebrotherswarde.com: could not connect 
 thecapitalbank.com: did not receive HSTS header
 thecharlestonwaldorf.com: did not receive HSTS header
 thechunk.net: could not connect to host
 theclementinebutchers.com: could not connect to host
 theclubjersey.com: did not receive HSTS header
 thecoffeehouse.xyz: could not connect to host
 thecrochetcottage.net: could not connect to host
 thedrop.pw: did not receive HSTS header
-thedutchmarketers.com: did not receive HSTS header
 thedystance.com: could not connect to host
 theelitebuzz.com: did not receive HSTS header
 theendofzion.com: did not receive HSTS header
 theepankar.com: could not connect to host
 theescapistswiki.com: could not connect to host
 theeyeopener.com: did not receive HSTS header
 thefarbeyond.com: could not connect to host
 theflowerbasketonline.com: could not connect to host
@@ -8324,30 +8325,31 @@ thriveapproach.co.uk: did not receive HS
 thrivewellnesshub.co.za: did not receive HSTS header
 throughthelookingglasslens.co.uk: could not connect to host
 thumbtack.com: did not receive HSTS header
 thundercampaign.com: could not connect to host
 ti.blog.br: could not connect to host
 tianxing.pro: did not receive HSTS header
 tianxingvpn.pro: could not connect to host
 tibbitshall.ca: did not receive HSTS header
+ticketoplichting.nl: did not receive HSTS header
 tickopa.co.uk: could not connect to host
 tickreport.com: did not receive HSTS header
 ticktock.today: did not receive HSTS header
 tictactux.de: could not connect to host
 tidmore.us: could not connect to host
 tiendschuurstraat.nl: could not connect to host
 tiensnet.com: could not connect to host
 tierrarp.com: could not connect to host
 tightlineproductions.com: did not receive HSTS header
 tikutiku.pl: could not connect to host
 tildebot.com: could not connect to host
 tilient.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
 tilikum.io: did not receive HSTS header
-tilkah.com.au: could not connect to host
+tilkah.com.au: did not receive HSTS header
 tillcraft.com: could not connect to host
 timbeilby.com: could not connect to host
 timbuktutimber.com: did not receive HSTS header
 timcamara.com: could not connect to host
 time-river.xyz: could not connect to host
 timesavingplugins.com: could not connect to host
 timesavingplugins.net: could not connect to host
 timeserver0.de: could not connect to host
@@ -8374,17 +8376,16 @@ titanleaf.com: could not connect to host
 titouan.co: did not receive HSTS header
 tittarpuls.se: could not connect to host
 titties.ml: could not connect to host
 tjc.wiki: could not connect to host
 tjeckien.guide: could not connect to host
 tkappertjedemetamorfose.nl: could not connect to host
 tkarstens.de: did not receive HSTS header
 tkonstantopoulos.tk: could not connect to host
-tlach.cz: did not receive HSTS header
 tlcdn.net: could not connect to host
 tlo.hosting: could not connect to host
 tlo.link: could not connect to host
 tlo.network: could not connect to host
 tls.li: could not connect to host
 tlsbv.nl: did not receive HSTS header
 tlshost.net: could not connect to host
 tm-solutions.eu: did not receive HSTS header
@@ -8462,17 +8463,17 @@ touchstonefms.co.uk: did not receive HST
 touchtable.nl: did not receive HSTS header
 tourpeer.com: did not receive HSTS header
 toxme.se: could not connect to host
 toyotamotala.se: could not connect to host
 tpbcdn.com: could not connect to host
 tpe-edu.com: could not connect to host
 tpms4u.at: did not receive HSTS header
 tracker-gps.ch: could not connect to host
-tracktivity.com.au: did not receive HSTS header
+tracktivity.com.au: could not connect to host
 trade-smart.ru: could not connect to host
 tradingcentre.com.au: did not receive HSTS header
 tradinghope.com: could not connect to host
 traditional-knowledge.tk: did not receive HSTS header
 trafficquality.org: could not connect to host
 traindb.nl: did not receive HSTS header
 training4girls.ru: could not connect to host
 trainingproviderresults.gov: could not connect to host
@@ -8543,17 +8544,17 @@ tucker.wales: could not connect to host
 tunai.id: could not connect to host
 tunca.it: did not receive HSTS header
 tunebitfm.de: could not connect to host
 turkrock.com: did not receive HSTS header
 turnik-67.ru: could not connect to host
 turniker.ru: could not connect to host
 turnsticks.com: could not connect to host
 turtlementors.com: could not connect to host
-tusb.ml: did not receive HSTS header
+tusb.ml: could not connect to host
 tussengelegenwoningverkopen.nl: could not connect to host
 tuturulianda.com: did not receive HSTS header
 tuvalie.com: could not connect to host
 tuxcall.de: could not connect to host
 tuxz.net: could not connect to host
 tv.search.yahoo.com: could not connect to host
 tvtubeflix.com: did not receive HSTS header
 tvz-materijali.com: could not connect to host
@@ -8572,17 +8573,16 @@ twee-onder-een-kap-woning-in-zuidplas-ko
 twee-onder-een-kap-woning-in-zwartewaterland-kopen.nl: could not connect to host
 tweeondereenkapverkopen.nl: could not connect to host
 tweeondereenkapwoningverkopen.nl: could not connect to host
 tweetify.io: could not connect to host
 twillionmas.com: could not connect to host
 twinkseason.ca: could not connect to host
 twinkseason.co: could not connect to host
 twinkseason.co.uk: could not connect to host
-twinkseason.com: did not receive HSTS header
 twinkseason.net: could not connect to host
 twinkseason.org: could not connect to host
 twinkseason.xyz: could not connect to host
 twist.party: could not connect to host
 twogo.com: did not receive HSTS header
 twolinepassbrewing.com: could not connect to host
 twolivelife.com: could not connect to host
 tx041cap.org: did not receive HSTS header
@@ -8653,17 +8653,16 @@ unblockmy.tech: did not receive HSTS hea
 unblockmy.xyz: did not receive HSTS header
 unblockmyproxy.site: could not connect to host
 unblockthe.site: did not receive HSTS header
 unblockthe.top: could not connect to host
 unccdesign.club: could not connect to host
 unclegen.xyz: could not connect to host
 under30stravelinsurance.com.au: did not receive HSTS header
 underkin.com: could not connect to host
-underlined.fr: did not receive HSTS header
 unfiltered.nyc: could not connect to host
 ungern.guide: could not connect to host
 uni-games.com: could not connect to host
 unicefkaarten.be: did not receive HSTS header
 unicooo.com: could not connect to host
 unifei.edu.br: did not receive HSTS header
 uniformecomgas.com.br: could not connect to host
 uniformehumboldt.com.br: did not receive HSTS header
@@ -8713,16 +8712,17 @@ uscitizenship.info: did not receive HSTS
 uscntalk.com: could not connect to host
 uscurrency.gov: did not receive HSTS header
 used-in.jp: could not connect to host
 user-new.com: did not receive HSTS header
 usercare.com: did not receive HSTS header
 userify.com: max-age too low: 0
 uslab.io: could not connect to host
 ustr.gov: max-age too low: 86400
+utdscanner.com: did not receive HSTS header
 utilitronium-shockwave.com: could not connect to host
 utleieplassen.no: could not connect to host
 utopiagalaxy.space: could not connect to host
 utopian-surgery.com: could not connect to host
 utopianconcept.com: did not receive HSTS header
 utopianhomespa.com: did not receive HSTS header
 utopianrealms.org: did not receive HSTS header
 utopians.dk: did not receive HSTS header
@@ -8858,25 +8858,24 @@ vision-painting.com: did not receive HST
 visitbroadstairs.com: could not connect to host
 vissanum.com: did not receive HSTS header
 vissersgrootboek.nl: did not receive HSTS header
 vistarait.com: could not connect to host
 visualvotes.co.uk: could not connect to host
 vitagenda.nl: could not connect to host
 vitalita.cz: did not receive HSTS header
 vitalorange.com: max-age too low: 7889238
-vitamaxxi.com.br: did not receive HSTS header
+vitamaxxi.com.br: could not connect to host
 vitta.me: did not receive HSTS header
 viva-french.com: did not receive HSTS header
 vivasports.com.br: could not connect to host
 vivocloud.com: could not connect to host
-vivremoinscher.fr: did not receive HSTS header
 vizeat.com: did not receive HSTS header
 vizional.com: max-age too low: 0
-vjeff.com: could not connect to host
+vkino.com: did not receive HSTS header
 vlastimilburian.cz: did not receive HSTS header
 vlora.city: could not connect to host
 vlsk.eu: did not receive HSTS header
 vlvvl.com: did not receive HSTS header
 vm0.eu: did not receive HSTS header
 vmrdev.com: could not connect to host
 voceinveste.com: did not receive HSTS header
 voicesuk.co.uk: did not receive HSTS header
@@ -8959,17 +8958,16 @@ warped.com: did not receive HSTS header
 warrencreative.com: did not receive HSTS header
 warsentech.com: could not connect to host
 warsh.moe: did not receive HSTS header
 watchium.com: did not receive HSTS header
 waterforlife.net.au: did not receive HSTS header
 waterpoint.com.br: could not connect to host
 watersportmarkt.net: did not receive HSTS header
 watsonhall.uk: could not connect to host
-wattechweb.com: did not receive HSTS header
 wave.is: could not connect to host
 wavefloatrooms.com: did not receive HSTS header
 wavefrontsystemstech.com: could not connect to host
 we-bb.com: could not connect to host
 wear2work.nl: did not receive HSTS header
 wearesouthafricans.com: did not receive HSTS header
 weaverhairextensions.nl: could not connect to host
 web-industry.fr: could not connect to host
@@ -9043,18 +9041,18 @@ wetoxic.com: did not receive HSTS header
 wettbonus.info: max-age too low: 0
 wettbuero.de: did not receive HSTS header
 wetten.eu: did not receive HSTS header
 wettertoertchen.com: could not connect to host
 wetttipps.com: could not connect to host
 wetttipps.de: could not connect to host
 wevahoo.com: could not connect to host
 wevolver.com: did not receive HSTS header
-wewillgo.com: could not connect to host
-wewillgo.org: could not connect to host
+wewillgo.com: did not receive HSTS header
+wewillgo.org: did not receive HSTS header
 wewlad.me: did not receive HSTS header
 wftda.com: did not receive HSTS header
 wg3k.us: did not receive HSTS header
 whatnext.limited: did not receive HSTS header
 whats.io: could not connect to host
 whatsstalk.me: could not connect to host
 whatsyouroffer.co.uk: did not receive HSTS header
 wheresben.today: could not connect to host
@@ -9181,17 +9179,17 @@ www-1117.com: could not connect to host
 www-39988.com: did not receive HSTS header
 www-507.net: did not receive HSTS header
 www-746.com: could not connect to host
 www-771122.com: did not receive HSTS header
 www-8003.com: did not receive HSTS header
 www-88599.com: did not receive HSTS header
 www-9995.com: did not receive HSTS header
 www-djbet.com: did not receive HSTS header
-www-jinshavip.com: could not connect to host
+www-jinshavip.com: did not receive HSTS header
 www.braintreepayments.com: did not receive HSTS header
 www.calyxinstitute.org: max-age too low: 500
 www.cueup.com: could not connect to host
 www.cyveillance.com: did not receive HSTS header
 www.developer.mydigipass.com: could not connect to host
 www.elanex.biz: did not receive HSTS header
 www.gamesdepartment.co.uk: did not receive HSTS header
 www.gmail.com: did not receive HSTS header (error ignored - included regardless)
@@ -9357,17 +9355,16 @@ yoga-in-aying.de: did not receive HSTS h
 yohanesmario.com: could not connect to host
 yoiyado.info: did not receive HSTS header
 yokeepo.com: max-age too low: 0
 yoloboatrentals.com: did not receive HSTS header
 yoloprod.fr: could not connect to host
 yoloseo.com: could not connect to host
 yomepre.com: could not connect to host
 yoru.me: did not receive HSTS header
-yoshitsugu.net: did not receive HSTS header
 youcontrol.ru: could not connect to host
 youfencun.com: did not receive HSTS header
 youlog.net: could not connect to host
 youngandunited.nl: did not receive HSTS header
 youon.tokyo: could not connect to host
 yourbapp.ch: could not connect to host
 yourcomputer.expert: did not receive HSTS header
 yoursecondphone.co: could not connect to host
@@ -9404,16 +9401,18 @@ zamorano.edu: could not connect to host
 zamos.ru: max-age too low: 0
 zaneweb.org: could not connect to host
 zao.fi: could not connect to host
 zaoshanghao-dajia.rhcloud.com: could not connect to host
 zap.yt: did not receive HSTS header
 zarooba.com: could not connect to host
 zavca.com: did not receive HSTS header
 zbigniewgalucki.eu: did not receive HSTS header
+zcarot.com: did not receive HSTS header
+zcarrot.com: did not receive HSTS header
 zcon.nl: could not connect to host
 zdravotnickasluzba.eu: could not connect to host
 zdrowiepaleo.pl: did not receive HSTS header
 zebrababy.cn: could not connect to host
 zebry.nl: could not connect to host
 zecrypto.com: could not connect to host
 zeedroom.be: did not receive HSTS header
 zefiris.org: did not receive HSTS header
--- a/security/manager/ssl/nsSTSPreloadList.inc
+++ b/security/manager/ssl/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.     */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1522006643897000);
+const PRTime gPreloadListExpirationTime = INT64_C(1522092833437000);
 %%
 0-1.party, 1
 0.me.uk, 1
 00001.am, 1
 00002.am, 1
 0005pay.com, 1
 0010100.net, 1
 00220022.net, 1
@@ -138,16 +138,17 @@ 1590284872.rsc.cdn77.org, 1
 1600esplanade.com, 1
 16164f.com, 1
 1644091933.rsc.cdn77.org, 1
 173vpnv.com, 1
 174.net.nz, 1
 1750studios.com, 0
 17hats.com, 1
 1844329061.rsc.cdn77.org, 1
+188522.com, 0
 18888msc.com, 1
 1888zr.com, 1
 188dv.com, 1
 189dv.com, 1
 18f.gov, 1
 18f.gsa.gov, 0
 1921958389.rsc.cdn77.org, 1
 1972969867.rsc.cdn77.org, 1
@@ -276,16 +277,17 @@ 365healthworld.com, 1
 365maya.com, 1
 365skulls.com, 1
 3778vip.com, 1
 379700.com, 1
 38888msc.com, 1
 38blog.com, 1
 393335.ml, 1
 398.info, 1
+3ags.de, 1
 3bakayottu.com, 1
 3bigking.com, 1
 3c-d.de, 1
 3chat.org, 1
 3circlefunding.ch, 1
 3countiescastlehire.co.uk, 1
 3cs.ch, 1
 3dm.audio, 1
@@ -302,17 +304,16 @@ 3logic.ru, 1
 3mbo.de, 1
 3phase.pw, 1
 3plusdesign.gr, 1
 3r.org.uk, 1
 3s-hosting.de, 1
 3timegear.com, 1
 3trees.tk, 1
 3v4l.org, 1
-3wecommerce.com.br, 1
 3weekdietworks.com, 1
 3xx.link, 1
 4-1-where.com, 1
 4-it.de, 1
 403.ch, 1
 404forest.com, 1
 404notfound.com.br, 1
 4096bit.de, 1
@@ -783,17 +784,16 @@ adevel.eu, 1
 adhesivelaundry.co.uk, 1
 adhigamindia.com, 1
 adhoc.is, 1
 adhosting.nl, 1
 adigitali.biz, 1
 adimaja.com, 1
 adinariversloveschool.com, 1
 adiponectinsupplement.info, 1
-adiponectinsupplement.net, 1
 adjagu.org, 1
 adlershop.ch, 1
 adlerweb.info, 1
 adm-sarov.ru, 1
 adme.co.il, 1
 admin-serv.net, 1
 admin.fedoraproject.org, 1
 admin.google.com, 1
@@ -1036,16 +1036,17 @@ aiicy.org, 1
 aiida.se, 1
 aijsk.com, 1
 aikenorganics.com, 1
 aikenpromotions.com, 1
 aikido-club-limburg.de, 1
 aikido-linz.at, 1
 aikido-wels.at, 1
 aim-consultants.com, 1
+aimeeandalec.com, 1
 aimgroup.co.tz, 1
 aimotive.com, 1
 aintevenmad.ch, 1
 aioboot.com, 1
 aiois.com, 1
 aiphyron.com, 1
 air-craftglass.com, 1
 air-shots.ch, 1
@@ -1160,16 +1161,18 @@ alchemia.co.il, 1
 alchimic.ch, 1
 alcnutrition.com, 1
 alcorao.org, 1
 aldes.co.za, 1
 aldien.com.br, 1
 aldorr.net, 1
 aldous-huxley.com, 1
 aleax.me, 1
+alecpap.com, 1
+alecpapierniak.com, 1
 alecrust.com, 1
 aleksejjocic.tk, 1
 aleksib.fi, 1
 alela.fr, 1
 aleph.land, 1
 alertaenlinea.gov, 1
 alertboxx.com, 1
 alertonline.nl, 1
@@ -1494,17 +1497,16 @@ amyharrisonline.com, 1
 amyrussellhair.com, 1
 amyyeung.com, 1
 amzn.rocks, 1
 anacreon.de, 1
 anacruz.es, 1
 anadoluefessk.org, 1
 anaethelion.fr, 1
 anaiscoachpersonal.es, 1
-anaisypirueta.es, 1
 anajianu.ro, 1
 anakros.me, 0
 analangelsteen.com, 1
 analgesia.net, 1
 analpantyhose.org, 1
 analteengirls.net, 1
 analyticsinmotion.com, 1
 analyticum.at, 1
@@ -1576,16 +1578,17 @@ andrewrdaws.com, 1
 andrewrgoss.com, 1
 andrewryno.com, 1
 andrewsun.com, 1
 andrewtebert.com, 1
 andrewthelott.net, 1
 andrewvoce.com, 1
 andrewyg.net, 1
 andrezadnik.com, 1
+andro2id.com, 1
 andro4all.com, 1
 android.re, 1
 androide.com, 1
 androidhry.cz, 1
 androidkatalog.cz, 1
 androidnovinky.cz, 1
 androidtamer.com, 1
 androidtelefony.cz, 1
@@ -3607,17 +3610,16 @@ blarg.co, 1
 blastentertainment.com.au, 1
 blastersklan.com, 1
 blastzoneentertainments.co.uk, 1
 blaudev.es, 1
 blauerhunger.de, 1
 blayne.me, 1
 blayneallan.com, 1
 blazeit.io, 1
-blazor.nl, 1
 bleaching-tipps.de, 1
 bleche-onlineshop.de, 1
 blechinger.io, 1
 blechpirat.name, 1
 blechschmidt.saarland, 1
 blenderrecipereviews.com, 1
 blendle.com, 1
 blendle.nl, 1
@@ -4610,17 +4612,17 @@ caferagazzi.de, 1
 cafesg.net, 1
 caffeinatedcode.com, 1
 cainhosting.com, 0
 caipai.fm, 1
 cairnterrier.com.br, 1
 cais.de, 1
 caitcs.com, 1
 caja-pdf.es, 1
-cajio.ru, 1
+cajio.ru, 0
 cajunuk.co.uk, 1
 cake-time.co.uk, 1
 cakestart.net, 1
 caketoindia.com, 1
 cakingandbaking.com, 1
 cal.goip.de, 1
 cal9000.com, 1
 calaad.net, 1
@@ -5032,16 +5034,17 @@ cencalvia.org, 1
 censurfridns.dk, 1
 censurfridns.nu, 1
 censys.io, 1
 centaur.de, 1
 centennialradon.com, 1
 centerforpolicy.org, 1
 centerpereezd.ru, 0
 centerpoint.ovh, 1
+centillien.com, 0
 centio.bg, 1
 centos.pub, 1
 centos.tips, 1
 central4.me, 1
 centralcountiesservices.org, 1
 centralfor.me, 1
 centrallead.net, 1
 centralstatecu.org, 1
@@ -6785,17 +6788,16 @@ cyclehackluxembourgcity.lu, 1
 cyclisjumper.gallery, 1
 cyclop-editorial.fr, 1
 cydetec.com, 1
 cyfly.org, 1
 cygnatus.com, 1
 cygnius.net, 1
 cyhour.com, 1
 cylindricity.com, 1
-cyoda.com, 1
 cyon.ch, 1
 cyph.audio, 1
 cyph.com, 1
 cyph.healthcare, 1
 cyph.im, 1
 cyph.io, 1
 cyph.me, 1
 cyph.video, 1
@@ -7641,17 +7643,16 @@ dicionario.org, 1
 dicionariodegirias.com.br, 1
 dicionariodelatim.com.br, 1
 dicionariodenomesproprios.com.br, 1
 dicionariodesimbolos.com.br, 1
 dicionarioetimologico.com.br, 1
 dick.red, 1
 dickieslife.com, 1
 dickpics.ru, 1
-dicoding.com, 1
 didacte.com, 1
 didche.net, 1
 diddens.de, 1
 didierlaumen.be, 1
 didikhari.web.id, 1
 die-besten-weisheiten.de, 1
 die-blahuts.de, 1
 die-borts.ch, 1
@@ -7726,16 +7727,17 @@ digitaleoverheid.nl, 1
 digitalewelten.de, 1
 digitalgov.gov, 1
 digitalhurricane.io, 1
 digitalimpostor.co.uk, 1
 digitallocker.com, 0
 digitalmarketingindallas.com, 1
 digitalrights.center, 1
 digitalrights.fund, 1
+digitalrxcloud.com, 1
 digitalsurge.io, 1
 digitaltechnologies.ltd.uk, 1
 digitalunite.de, 1
 digitkon.com, 1
 digiworks.se, 1
 digminecraft.com, 1
 diguass.us, 1
 digwp.com, 1
@@ -8678,16 +8680,17 @@ edisonchee.com, 1
 edisonlee55.com, 1
 edisonluiz.com, 1
 edisonnissanparts.com, 1
 edit.yahoo.com, 0
 edited.de, 1
 edition-bambou.com, 1
 edition-sonblom.de, 1
 editoraacademiacrista.com.br, 1
+edlinus.cn, 1
 edmundcelis.com, 1
 edoss.co.za, 1
 edp-collaborative.com, 1
 edsm.net, 1
 edstep.com, 1
 edtech-hub.com, 1
 edtechwebb.com, 1
 edu6.cloud, 1
@@ -9632,17 +9635,16 @@ excentos.com, 1
 excessamerica.com, 1
 exchangecoordinator.com, 1
 exchangeworks.co, 1
 exclusivebouncycastles.co.uk, 1
 exdamo.de, 1
 exe-boss.tech, 1
 exebouncycastles.co.uk, 1
 exehack.net, 1
-exeintel.com, 1
 exekutori.com, 1
 exembit.com, 1
 exemples-de-stands.com, 1
 exeria.de, 1
 exgaywatch.com, 1
 exgen.io, 1
 exhalespa.com, 1
 exhibityour.com, 1
@@ -9812,17 +9814,16 @@ fafatiger.com, 1
 fag.wtf, 1
 fahmed.de, 1
 fahrenwal.de, 1
 fahrenwalde.de, 1
 fail.coach, 1
 failover.de, 1
 failover.eu, 1
 fairbill.com, 1
-faircom.co.za, 1
 fairedeseconomies.info, 1
 fairgolfteams.com, 1
 fairplay.im, 1
 fairviewmotel-simcoe.com, 1
 faithgrowth.com, 1
 faithmissionaries.com, 1
 faithwatch.org, 1
 faixaazul.com, 1
@@ -10213,17 +10214,16 @@ fini-de-jouer.ch, 1
 finisron.in, 1
 finkelstein.fr, 1
 finkenberger.org, 0
 finn.io, 1
 finnclass.cz, 1
 finneas.net, 1
 finsprings.org, 1
 finstererlebnis.de, 1
-finsterlebnis.de, 1
 fintandunleavy.com, 1
 finvantage.com, 1
 fionamcbride.com, 1
 fire-wolf.com, 1
 firebaseio.com, 1
 firebirdrangecookers.com, 1
 firebounty.com, 1
 fireboxfood.com, 1
@@ -10442,17 +10442,16 @@ flybunnyfly.dk, 1
 flygpost.com, 1
 flyingdoggy.net, 1
 flyinglocksmiths.com, 0
 flyingpackets.net, 1
 flyingrub.me, 1
 flymns.fr, 1
 flynn.io, 1
 flyp.me, 1
-flyserver.co.il, 1
 flyspace.ga, 1
 flyspace.ml, 1
 flyss.net, 1
 flyssh.net, 1
 flyt.online, 1
 flytoadventures.com, 1
 fm-cdn.de, 1
 fm.ie, 1
@@ -10778,18 +10777,21 @@ freetsa.org, 1
 freevps.us, 1
 freeweibo.com, 1
 freeyourmusic.com, 1
 freezion.com, 1
 freifahrt.de, 1
 freifamily.ch, 1
 freifunk-burgaltendorf.de, 1
 freifunk-essen.de, 1
+freifunk-in-solingen.de, 1
+freifunk-lindlar.net, 1
 freifunk-luenen.de, 1
 freifunk-nrw.de, 1
+freifunk-remscheid.de, 1
 freimeldungen.de, 1
 freims.cc, 1
 freiwurst.net, 1
 frenchcreekcog.org, 1
 frenzel.dk, 1
 frequencebanane.ch, 1
 fresh-hotel.org, 1
 fresh-networks.net, 1
@@ -11050,16 +11052,17 @@ g2links.com, 1
 g2pla.net, 1
 g2soft.net, 1
 g3dev.ch, 1
 g3rv4.com, 1
 g4w.co, 1
 gaanbaksho.com.au, 1
 gaasuper6.com, 1
 gabemack.com, 1
+gabethebabetv.com, 1
 gabriel.to, 1
 gabriele-kluge.de, 1
 gabrielsimonet.ch, 1
 gachter.name, 1
 gadabit.pl, 1
 gadgethacks.com, 1
 gaestehaus-monika.com, 1
 gafachi.com, 1
@@ -11493,17 +11496,16 @@ ggss.cf, 1
 ggx.us, 1
 gh16.com.ar, 1
 gha.st, 1
 ghaglund.se, 1
 ghcif.de, 1
 ghi.gov, 1
 ghislainphu.fr, 1
 ghostblog.info, 1
-ghrelinblocker.info, 1
 ghrelinblocker.org, 1
 ghuntley.com, 1
 giacomodrago.com, 1
 giacomodrago.it, 1
 giacomopelagatti.it, 1
 gianproperties.com, 1
 giant-panda.com, 1
 giant-powerfit.co.uk, 1
@@ -12105,17 +12107,16 @@ gulchuk.com, 1
 gulenbase.no, 1
 gulfstream.ru, 1
 gulleyperformancecenter.com, 1
 gulshankumar.net, 1
 gume4you.com, 1
 gumi.ca, 1
 gummibande.noip.me, 1
 gunhunter.com, 1
-guniram.com, 1
 gunwatch.co.uk, 1
 guochang.xyz, 1
 guoke.com, 1
 guphi.net, 0
 gurkan.in, 1
 gurmel.ru, 1
 gurochan.ch, 1
 guru-naradi.cz, 1
@@ -12551,17 +12552,16 @@ hedweb.co.uk, 1
 hedweb.com, 1
 hedweb.net, 1
 hedweb.org, 1
 heeler.blue, 1
 heeler.red, 1
 heello.es, 1
 hefengautoparts.com, 1
 heftkaufen.de, 1
-hegen.com.pl, 1
 hegen.cz, 1
 hegen.sk, 1
 hegenshop.de, 1
 heh.ee, 1
 heha.co, 0
 heiaheia.com, 1
 heid.ws, 1
 heidisheroes.org, 1
@@ -12787,16 +12787,17 @@ highspeed-arnsberg.de, 1
 hightechbasementsystems.com, 1
 highwaytohoell.de, 1
 higilopocht.li, 1
 higp.de, 1
 hijoan.com, 1
 hik-cloud.com, 1
 hikagestudios.com, 1
 hike.pics, 1
+hikinggearlab.com, 1
 hikingguy.com, 1
 hilahdih.cz, 1
 hilaolu.com, 1
 hilaolu.studio, 1
 hilchenba.ch, 1
 hilfreiche-server.tips, 1
 hill.selfip.net, 1
 hillebrand.io, 1
@@ -12951,16 +12952,17 @@ holyhiphopdatabase.com, 1
 holymolycasinos.com, 1
 holytransaction.com, 1
 holywhite.com, 1
 holz.nu, 1
 holzheizer-forum.de, 1
 holzheizerforum.de, 1
 holzspielzeug-shop.ch, 1
 holzvergaser-forum.de, 1
+homatism.com, 1
 home-cloud.online, 1
 home-coaching.be, 1
 home-v.ind.in, 1
 home-work-jobs.com, 1
 homeautomated.com, 1
 homebodyalberta.com, 1
 homecareassociatespa.com, 1
 homecarpetcleaning.co.uk, 1
@@ -14162,17 +14164,17 @@ irfan.id, 1
 irgit.pl, 1
 iridiumbrowser.de, 1
 iridiumflare.de, 1
 irinkeby.nu, 1
 iriomote.com, 1
 iris-design.info, 1
 iris-insa.com, 1
 irische-segenswuensche.info, 1
-irisdina.de, 0
+irisdina.de, 1
 irish.dating, 1
 irishmusic.nu, 1
 irisjieun.com, 1
 irland-firma.com, 1
 irmag.ru, 1
 irmgard-woelfle.de, 1
 irmgardkoch.com, 1
 irodorinet.com, 1
@@ -15211,17 +15213,16 @@ jwatt.org, 1
 jwe.nl, 1
 jwilsson.com, 1
 jwjwjw.com, 1
 jwnotifier.org, 1
 jwolt-lx.com, 1
 jwschuepfheim.ch, 1
 jxir.de, 1
 jyggen.com, 1
-jym.fit, 1
 jyoti-fairworks.org, 1
 jzbk.org, 1
 k-netz.de, 1
 k-pan.com, 1
 k-pture.com, 1
 k-scr.me, 1
 k-tube.com, 1
 k258059.net, 1
@@ -15747,17 +15748,17 @@ kitchen-profi.kz, 1
 kitchenaccessories.pro, 1
 kitchenpunx.com, 0
 kiteadventure.nl, 1
 kitegarage.eu, 1
 kiteschoolamsterdam.nl, 1
 kiteschooledam.nl, 1
 kiteschoolijmuiden.nl, 1
 kiteschoolkatwijk.nl, 1
-kiteschoolnoordwijk.nl, 0
+kiteschoolnoordwijk.nl, 1
 kiteschoolschellinkhout.nl, 1
 kiteschoolwijkaanzee.nl, 1
 kiteschoolzandvoort.nl, 1
 kittmedia.com, 1
 kittpress.com, 1
 kittyhacker101.tk, 1
 kiwi.digital, 1
 kiwi.global, 1
@@ -17032,16 +17033,17 @@ lissabon.guide, 1
 listahu.org, 1
 listen.dk, 1
 lister-kirchweg.de, 1
 listminut.be, 1
 lists.fedoraproject.org, 1
 lists.mayfirst.org, 0
 lists.stg.fedoraproject.org, 1
 litchidova.nl, 1
+litcomphonors.com, 1
 litebits.com, 1
 litemind.com, 1
 litevault.net, 1
 litfin.name, 1
 lithan.com, 1
 lithesalar.se, 1
 lithianissaneugeneparts.com, 1
 litsovet.com, 1
@@ -17854,16 +17856,17 @@ mapasmundi.com.br, 1
 mapblender.com, 1
 maplanetebeaute.fr, 1
 mapletime.com, 1
 mapresidentielle.fr, 1
 maquettage.com, 1
 maquillage-permanent-tatoo.com, 1
 maquinariaspesadas.org, 1
 marabumadrid.com, 1
+marakovits.net, 1
 marbinvest.com, 1
 marble.com, 1
 marbogardenlidkoping.se, 1
 marc-schlagenhauf.de, 1
 marcbuehlmann.com, 1
 marcdorka.de, 1
 marceau.ovh, 1
 marcel-preuss.de, 1
@@ -18256,16 +18259,17 @@ md5file.com, 1
 md5hashing.net, 1
 mdbouncycastlehirelondon.co.uk, 1
 mdcloudpracticesolutions.com, 1
 mdcloudps.com, 1
 mdek.at, 1
 mdewendt.de, 1
 mdf-bis.com, 1
 mdiv.pl, 1
+mdkr.nl, 1
 mdma.net, 1
 mdmed.clinic, 1
 mdoering.de, 1
 mdosch.de, 1
 mdpraha.cz, 1
 mdsave.com, 1
 mdwftw.com, 1
 mdx.no, 1
@@ -19287,17 +19291,17 @@ mpi-sa.fr, 1
 mpintaamalabanna.it, 1
 mplanetphl.fr, 1
 mplant.io, 1
 mplicka.cz, 1
 mplusm.eu, 1
 mpn.poker, 1
 mpnpokertour.com, 1
 mpodraza.pl, 1
-mpreserver.com, 1
+mpreserver.com, 0
 mpserver12.org, 1
 mpsgarage.com.au, 1
 mpsoundcraft.com, 1
 mpy.ovh, 1
 mr-anderson.org, 1
 mr-labo.jp, 1
 mr-nachhilfe.de, 1
 mr-wolf.nl, 1
@@ -19695,17 +19699,16 @@ mypup.nl, 1
 myrandomtips.com, 1
 myranicol.com, 1
 myrealestatemate.com.au, 1
 myrekber.co.id, 1
 myrent.quebec, 1
 myrepublic.co.id, 1
 myresearchapp.com, 1
 myriadof.com, 1
-myrig.com, 1
 myrig.com.ua, 1
 myrig.io, 1
 myrig.ru, 1
 myrotvorets.center, 1
 myruststats.com, 1
 myschoolphoto.org, 1
 myseatime.com, 1
 mysecretcase.com, 1
@@ -19726,16 +19729,17 @@ mysterymind.ch, 1
 mysterysear.ch, 1
 mystic-welten.de, 1
 mystickphysick.com, 1
 mysticplumes.com, 1
 mystorymonster.com, 1
 mystown.org, 1
 mystudy.me, 1
 mystudycart.com, 1
+mysupboard.de, 1
 myswissmailaddress.com, 1
 mytc.fr, 1
 mythengay.ch, 1
 mythicdelirium.com, 1
 mytraiteurs.com, 1
 mytravelblog.de, 1
 mytripcar.co.uk, 1
 mytripcar.com, 1
@@ -19866,17 +19870,16 @@ narindal.ch, 1
 narko.space, 1
 narmos.ch, 1
 naro.se, 1
 narodsovety.ru, 1
 naroska.name, 1
 narrativasdigitais.pt, 1
 narrenverein-wolkenschieber.de, 1
 narthollis.net, 1
-narviz.com, 1
 nasarawanewsonline.com, 1
 nasbi.pl, 1
 nasbnation.com, 1
 nascher.org, 0
 nasmocopati.com, 1
 nasrsolar.com, 1
 nassi.me, 1
 nastoletni.pl, 1
@@ -20627,16 +20630,17 @@ notboring.co.uk, 1
 notcompletelycorrect.com, 1
 notdienstreform-nordrhein.de, 1
 note7forever.com, 1
 notesforpebble.com, 1
 notevencode.com, 1
 noticiasdehumor.com, 1
 notificami.com, 1
 notify.moe, 1
+notinglife.com, 1
 notjustvacs.com, 1
 notnize.net, 1
 notnl.com, 1
 notoriousdev.com, 1
 notrecourrier.net, 1
 nottres.com, 1
 notypiesni.sk, 0
 noudjalink.nl, 1
@@ -20679,17 +20683,16 @@ nrdstd.io, 1
 nrev.ch, 1
 nrkn.fr, 1
 nrnjn.xyz, 1
 ns-frontier.com, 1
 nsa.lol, 1
 nsa.wtf, 1
 nsbfalconacademy.org, 1
 nsboston.org, 1
-nsboutique.com, 1
 nscnet.jp, 1
 nsdev.cn, 1
 nsfw-story.com, 1
 nshost.ro, 1
 nsm.ee, 1
 nsm.stat.no, 1
 nsmail.cn, 1
 nso.ie, 1
@@ -21523,17 +21526,16 @@ pan.digital, 1
 panasca.is, 1
 panascais.co, 1
 panascais.com, 1
 panascais.de, 1
 panascais.eu, 1
 panascais.host, 1
 panascais.io, 1
 panascais.me, 1
-panascais.net, 1
 panascais.pw, 1
 panascais.site, 1
 panascais.tech, 1
 panascais.us, 1
 panaxis.ch, 1
 panda-community.com, 1
 panda.tf, 1
 pandapsy.com, 1
@@ -22245,16 +22247,17 @@ pinkfis.ch, 1
 pinkhq.com, 1
 pinkinked.com, 1
 pinkladyapples.co.uk, 1
 pinklecfest.org, 1
 pinnaclelife.co.nz, 1
 pinnaclelife.nz, 1
 pinnacles.com, 1
 pinoyonlinetv.com, 1
+pinpayments.com, 1
 pinpointengineer.co.uk, 1
 pinscher.com.br, 1
 pinterest.at, 1
 pinterest.co.uk, 1
 pinterest.com, 1
 pinterest.de, 1
 pinterest.engineering, 1
 pinterest.ie, 1
@@ -24180,17 +24183,16 @@ rmsupply.nl, 1
 rnag.ie, 1
 rnb-storenbau.ch, 1
 rngmeme.com, 1
 rnt.cl, 1
 ro.search.yahoo.com, 0
 roadguard.nl, 1
 roadtopgm.com, 1
 roave.com, 1
-rob.uk.com, 1
 rob006.net, 1
 robandjanine.com, 1
 robbertt.com, 1
 robert-flynn.de, 1
 robertabittle.com, 1
 robertattfield.com, 1
 robertg.me, 1
 roberthurlbut.com, 1
@@ -25366,17 +25368,16 @@ self-signed.com, 1
 self.nu, 1
 selfassess.govt.nz, 1
 selfdestruct.net, 1
 selfhosters.com, 1
 selfici.com, 1
 selfici.cz, 1
 selfishness.com, 1
 selfloath.in, 1
-selfmade4u.de, 1
 selfserverx.com, 0
 selkiemckatrick.com, 1
 sellajoch.com, 1
 sellguard.pl, 1
 sellme.biz, 1
 sellmoretires.com, 1
 seltendoof.de, 1
 semacode.com, 1
@@ -25992,16 +25993,17 @@ simplexgame.net, 1
 simplexsupport.com, 0
 simplia.cz, 1
 simplicitypvp.net, 1
 simplidesigns.nl, 1
 simplifylivelove.com, 1
 simply.scot, 1
 simplycharlottemason.com, 1
 simplycloud.de, 1
+simplyfixit.co.uk, 1
 simplyhelen.de, 1
 simplylovejesus.com, 1
 simplymozzo.se, 1
 simplystudio.com, 1
 simpte.com, 1
 simpul.nl, 1
 sims4hub.ga, 1
 simsnieuws.nl, 1
@@ -26335,17 +26337,16 @@ smow.com, 1
 smow.de, 1
 smpetrey.com, 1
 sms1.ro, 1
 smsappointment.com, 1
 smsg-dev.ch, 1
 smskeywords.co.uk, 1
 smspodmena.ru, 1
 smsprivacy.org, 1
-smtp.bz, 1
 smuhelper.cn, 1
 smuncensored.com, 1
 smutba.se, 1
 smutek.net, 1
 snafarms.com, 1
 snafu.cz, 1
 snakafya.com, 1
 snake.dog, 1
@@ -26546,17 +26547,16 @@ sona-gaming.com, 1
 sonacupalova.cz, 1
 sonafe.info, 1
 sonarqube.com, 0
 sondergaard.de, 1
 sonerezh.bzh, 1
 songsmp3.co, 1
 songsthatsavedyourlife.com, 1
 songzhuolun.com, 1
-soniafauville.com, 1
 sonic.sk, 0
 sonixonline.com, 1
 sonja-daniels.com, 1
 sonja-kowa.de, 1
 sonoecoracao.com.br, 1
 sonyunlock.nu, 1
 soomee.be, 1
 soomee1.be, 1
@@ -26683,16 +26683,17 @@ spearfishingmx.com, 1
 speciesism.com, 1
 spectrosoftware.de, 1
 spedplus.com.br, 0
 speech-balloon.com, 1
 speechmate.com, 1
 speechndraw.com, 1
 speeddate.it, 0
 speedracer.ca, 1
+speeds.vip, 1
 speedsportofhull.co.uk, 1
 speedtailors.com, 1
 speedtest-russia.com, 1
 speedychat.it, 1
 speerpunt.info, 1
 speich.net, 1
 spek.tech, 1
 spellcheck24.net, 1
@@ -26757,16 +26758,17 @@ spoofhaus.com, 1
 spookbook.net, 1
 spookquest.com, 1
 spoopy.link, 1
 sporcard.com, 1
 spornkuller.de, 1
 sport-in-sundern.de, 1
 sport-potreby.cz, 1
 sport-potreby.sk, 1
+sport-socken.net, 1
 sporter.com, 1
 sportflash.info, 1
 sportnesia.com, 1
 sportovnidum.cz, 1
 sportressofblogitude.com, 1
 sports.dating, 1
 sportsmanadvisor.com, 1
 sportsmansblog.com, 1
@@ -27663,16 +27665,17 @@ ta-65.com, 1
 ta-sports.net, 1
 ta65.com, 1
 taabe.net, 1
 taartenfeesies.nl, 1
 tab.watch, 1
 tabelfirme.ro, 1
 tabernadovinho.com.br, 1
 tabino.top, 1
+tabithawebb.co.uk, 1
 tabla-periodica.com, 1
 tablescraps.com, 1
 tablet.facebook.com, 0
 tablotv.com, 0
 taboragroup.com, 0
 taborsky.cz, 1
 tac-volley.com, 1
 tacklog.com, 1
@@ -27749,17 +27752,16 @@ tango-cats.de, 1
 tango-ouest.com, 1
 tangoalpha.co.uk, 1
 tangyue.date, 1
 tangzhao.net, 1
 tanhit.com, 1
 taniku-succulent.com, 1
 tankski.co.uk, 1
 tannenhof-moelln.de, 1
-tannerfilip.org, 1
 tantalos.nl, 1
 tantei100.net, 1
 tanto259.name, 1
 tanz.info, 1
 tanzhijun.com, 1
 taoburee.com, 1
 tapestries.tk, 1
 taqsim.jp, 1
@@ -28253,16 +28255,17 @@ thediaryofadam.com, 1
 thedisc.nl, 1
 thediscovine.com, 1
 thedocumentrefinery.com, 1
 thedominatorsclan.com, 1
 thedreamtravelgroup.co.uk, 1
 thedrinks.co, 1
 thedronechart.com, 1
 thedrunkencabbage.com, 1
+thedutchmarketers.com, 1
 theebookkeepers.co.za, 1
 theeducationchannel.info, 1
 theeducationdirectory.org, 1
 theevergreen.me, 1
 theexpatriate.de, 1
 thefanimatrix.net, 1
 thefbstalker.com, 1
 theferrarista.com, 1
@@ -28563,17 +28566,16 @@ tianshili.me, 1
 tianxicaipiao.com, 1
 tianxicaipiao.win, 1
 tianxicp.com, 1
 tibipg.com, 1
 tibovanheule.site, 1
 ticfleet.com, 1
 ticketluck.com, 1
 ticketmates.com.au, 1
-ticketoplichting.nl, 1
 ticketpro.ca, 1
 ticketslover.com, 1
 ticketsmate.com, 1
 ticketsource.co.uk, 1
 ticketsource.eu, 1
 ticketsource.us, 1
 ticketsourcebeta.co.uk, 1
 ticketsvergleichen.de, 1
@@ -28705,16 +28707,17 @@ tkanemoto.com, 1
 tkat.ch, 1
 tkgpm.com, 1
 tkjg.fi, 1
 tkn.me, 1
 tkn.tokyo, 1
 tkts.cl, 1
 tkusano.jp, 1
 tkw01536.de, 1
+tlach.cz, 1
 tlca.org, 1
 tlcnet.info, 1
 tlehseasyads.com, 1
 tlo.xyz, 1
 tloxygen.com, 1
 tls.builders, 1
 tls.care, 1
 tls1914.org, 1
@@ -29461,16 +29464,17 @@ twelve.rocks, 1
 twelve.today, 1
 twelverocks.com, 1
 twem.ddns.net, 1
 twenty71.com, 1
 twentymilliseconds.com, 1
 twilleys.com, 1
 twincitynissantxparts.com, 1
 twinkieman.com, 1
+twinkseason.com, 1
 twiri.net, 1
 twisata.com, 1
 twistapp.com, 1
 twisted-brains.org, 1
 twistedwave.com, 1
 twisto.cz, 1
 twit-guide.com, 1
 twittelzie.nl, 1
@@ -29658,16 +29662,17 @@ unblockedbay.info, 1
 unblockweb.co, 1
 uncensoreddns.dk, 1
 uncensoreddns.org, 1
 undeadbrains.de, 1
 undecidable.de, 1
 underbridgeleisure.co.uk, 1
 undercovercondoms.co.uk, 1
 undercovercondoms.com, 1
+underlined.fr, 1
 undernet.uy, 0
 underskatten.tk, 1
 undo.co.il, 1
 undone.me, 1
 unearaigneeauplafond.fr, 0
 unefuite.ch, 1
 unerosesurlalune.fr, 1
 unexpected.nu, 1
@@ -29878,17 +29883,16 @@ uspsoig.gov, 1
 usr.nz, 1
 ussm.gov, 1
 ussuka.com, 1
 ust.space, 1
 usualbeings.com, 1
 uswitch.com, 1
 ut-addicted.com, 1
 utahlocal.net, 1
-utdscanner.com, 1
 utdsgda.com, 1
 utepils.de, 1
 utilia.tools, 1
 utilitarian.com, 1
 utilitarian.net, 1
 utilitarian.org, 1
 utilitarianism.com, 1
 utilitarianism.org, 1
@@ -30395,22 +30399,23 @@ vivatv.com.tw, 1
 vivendi.de, 1
 vivianmaier.cn, 1
 vivid-academy.com, 1
 vividinflatables.co.uk, 1
 vividlumen.com, 1
 viviennevandenbos.nl, 1
 vivirenelmundo.com, 1
 vivo.sx, 1
+vivremoinscher.fr, 1
 vizards.cc, 1
 vizzboard.com, 1
+vjeff.com, 1
 vjeff.net, 1
 vk4wip.org.au, 1
 vkennke.org, 1
-vkino.com, 1
 vkirichenko.name, 0
 vkox.com, 1
 vksportphoto.com, 1
 vladimiroff.org, 1
 vladislavstoyanov.com, 1
 vldkn.net, 1
 vleij.com, 1
 vleij.family, 1
@@ -30701,16 +30706,17 @@ watchstyle.com, 1
 watchtv-online.pw, 1
 watchweasel.com, 1
 waterfedpole.com, 1
 watermonitor.gov, 1
 watersb.org, 1
 watertrails.io, 1
 waterworkscondos.com, 1
 watsonwork.me, 1
+wattechweb.com, 1
 wave-ola.es, 1
 wavesboardshop.com, 1
 wavesoftime.com, 1
 waveum.com, 1
 wawak.pl, 1
 waxdramatic.com, 1
 waylaydesign.com, 1
 wayne.cloud, 0
@@ -32145,16 +32151,17 @@ yorcool.nl, 1
 yorkshiredalesinflatables.co.uk, 1
 yorkshireinflatables.co.uk, 1
 yorkshireterrier.com.br, 1
 yorname.ml, 1
 yosbeda.com, 1
 yosemo.de, 1
 yosheenetwork.fr, 1
 yoshibaworks.com, 1
+yoshitsugu.net, 1
 yospos.org, 1
 yoticonnections.com, 1
 yotilab.com, 1
 yotilabs.com, 1
 yotta-zetta.com, 1
 yotubaiotona.net, 1
 youcancraft.de, 1
 youcanfuckoff.xyz, 1
@@ -32359,18 +32366,16 @@ zbasenem.pl, 1
 zbchen.com, 1
 zberger.com, 1
 zbetcheck.in, 1
 zbp.at, 0
 zbrane-doplnky.cz, 1
 zby.io, 1
 zbyga.cz, 1
 zbyte.it, 1
-zcarot.com, 1
-zcarrot.com, 1
 zcgram.com, 1
 zcr.ca, 1
 zdbl.de, 1
 zdenekspacek.cz, 1
 zdorovayasimya.com, 1
 zdravesteny.cz, 1
 zdrojak.cz, 1
 zdx.ch, 1
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -427,17 +427,17 @@ win64-rusttests/opt:
 win64-ccov/debug:
     description: "Win64 Debug Code Coverage"
     index:
         product: firefox
         job-name: win64-ccov-debug
     treeherder:
         platform: windows2012-64/ccov
         symbol: tc(B)
-        tier: 2
+        tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 14400
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
--- a/taskcluster/ci/test/compiled.yml
+++ b/taskcluster/ci/test/compiled.yml
@@ -57,16 +57,17 @@ jittest:
     treeherder-symbol: tc(Jit)
     run-on-projects:
         by-test-platform:
             linux64-qr/.*: ['mozilla-central', 'try']
             default: built-projects
     chunks:
         by-test-platform:
             windows.*: 1
+            windows10-64-ccov/debug: 6
             macosx.*: 1
             default: 6
     mozharness:
         chunked:
             by-test-platform:
                 windows.*: false
                 macosx.*: false
                 default: true
--- a/taskcluster/ci/test/mochitest.yml
+++ b/taskcluster/ci/test/mochitest.yml
@@ -34,16 +34,17 @@ mochitest:
             default: default
     chunks:
         by-test-platform:
             android-4.3-arm7-api-16/debug: 48
             android.*: 20
             linux.*/debug: 16
             linux64-asan/opt: 10
             linux64-.*cov/opt: 10
+            windows10-64-ccov/debug: 10
             default: 5
     e10s:
         by-test-platform:
             linux64-jsdcov/opt: false
             windows7-32/debug: both
             default: true
     max-run-time:
         by-test-platform:
@@ -99,16 +100,17 @@ mochitest-browser-chrome:
     e10s:
         by-test-platform:
             linux64-jsdcov/opt: false
             windows7-32/debug: both
             default: true
     max-run-time:
         by-test-platform:
             linux64-*cov/opt: 7200
+            windows10-64-ccov/debug: 7200
             linux.*/debug: 5400
             default: 3600
     mozharness:
         mochitest-flavor: browser
         chunked: true
     # Bug 1281241: migrating to m3.large instances
     instance-size:
         by-test-platform:
--- a/taskcluster/ci/test/reftest.yml
+++ b/taskcluster/ci/test/reftest.yml
@@ -48,16 +48,17 @@ jsreftest:
         by-test-platform:
             android.*: xlarge
             default: default
     chunks:
         by-test-platform:
             android-4.3-arm7-api-16/debug: 100
             android.*: 40
             windows.*: 2
+            windows10-64-ccov/debug: 5
             linux64-ccov/.*: 5
             linux64-qr/.*: 4
             macosx.*: 2
             default: 3
     e10s:
         by-test-platform:
             linux64-jsdcov/opt: false
             windows10-64/debug: both
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -100,43 +100,16 @@ linux64-stylo-disabled/debug:
         - stylo-disabled-tests
         - devtools-tests
 linux64-stylo-disabled/opt:
     build-platform: linux64/opt
     test-sets:
         - awsy-stylo-disabled
         - stylo-disabled-tests
         - devtools-tests
-macosx64-stylo-disabled/debug:
-    build-platform: macosx64/debug
-    test-sets:
-        - stylo-disabled-tests
-macosx64-stylo-disabled/opt:
-    build-platform: macosx64/opt
-    test-sets:
-        - awsy-stylo-disabled
-        - stylo-disabled-tests
-windows7-32-stylo-disabled/debug:
-    build-platform: win32/debug
-    test-sets:
-        - stylo-disabled-tests
-windows7-32-stylo-disabled/opt:
-    build-platform: win32/opt
-    test-sets:
-        - awsy-stylo-disabled
-        - stylo-disabled-tests
-windows10-64-stylo-disabled/debug:
-    build-platform: win64/debug
-    test-sets:
-        - stylo-disabled-tests
-windows10-64-stylo-disabled/opt:
-    build-platform: win64/opt
-    test-sets:
-        - awsy-stylo-disabled
-        - stylo-disabled-tests
 
 # Stylo sequential runs check memory and performance when using a single thread.
 linux64-stylo-sequential/opt:
     build-platform: linux64/opt
     test-sets:
         - awsy-stylo-sequential
 
 # QR builds just run a subset right now. Note that the tests in this
@@ -176,27 +149,25 @@ windows7-32/debug:
 
 windows7-32/opt:
     build-platform: win32/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-reftest-gpu
         - windows-talos
-        - windows-talos-stylo-disabled
         - windows-tests
 
 windows7-32-pgo/opt:
     build-platform: win32-pgo/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-reftest-gpu
         - windows-talos
-        - windows-talos-stylo-disabled
         - windows-tests
 
 windows7-32-nightly/opt:
     build-platform: win32-nightly/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-reftest-gpu
@@ -226,27 +197,25 @@ windows10-64/debug:
         - mochitest-headless
 
 windows10-64/opt:
     build-platform: win64/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-talos
-        - windows-talos-stylo-disabled
         - windows-tests
         - mochitest-headless
 
 windows10-64-pgo/opt:
     build-platform: win64-pgo/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - windows-talos
-        - windows-talos-stylo-disabled
         - windows-tests
 
 windows10-64-nightly/opt:
     build-platform: win64-nightly/opt
     test-sets:
         - awsy
         - desktop-screenshot-capture
         - desktop-instrumentation
@@ -270,17 +239,16 @@ macosx64/debug:
     build-platform: macosx64/debug
     test-sets:
         - macosx64-tests
 
 macosx64/opt:
     build-platform: macosx64/opt
     test-sets:
         - macosx64-talos
-        - macosx64-talos-stylo-disabled
         - macosx64-tests
         - desktop-screenshot-capture
         - awsy
 
 macosx64-nightly/opt:
     build-platform: macosx64-nightly/opt
     test-sets:
         - macosx64-tests
--- a/taskcluster/ci/test/xpcshell.yml
+++ b/taskcluster/ci/test/xpcshell.yml
@@ -39,16 +39,17 @@ xpcshell:
             default: built-projects
     chunks:
         by-test-platform:
             linux32/debug: 12
             linux64/debug: 10
             android-4.2-x86/opt: 6
             macosx.*: 1
             windows.*: 1
+            windows10-64-ccov/debug: 8
             default: 8
     instance-size:
         by-test-platform:
             android.*: xlarge
             default: default
     max-run-time: 5400
     e10s: false
     allow-software-gl-layers: false
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -567,16 +567,22 @@ def set_tier(config, tests):
                                          'macosx64-stylo-disabled/debug',
                                          'macosx64-stylo-disabled/opt',
                                          'android-4.3-arm7-api-16/opt',
                                          'android-4.3-arm7-api-16/debug',
                                          'android-4.2-x86/opt']:
                 test['tier'] = 1
             else:
                 test['tier'] = 2
+
+        # Temporarily set windows10-64-ccov/debug tests as tier 3, until we get the tests
+        # consistently green.
+        if test['test-platform'] == 'windows10-64-ccov/debug':
+            test['tier'] = 3
+
         yield test
 
 
 @transforms.add
 def set_expires_after(config, tests):
     """Try jobs expire after 2 weeks; everything else lasts 1 year.  This helps
     keep storage costs low."""
     for test in tests:
--- a/testing/mozharness/scripts/release/push-candidate-to-releases.py
+++ b/testing/mozharness/scripts/release/push-candidate-to-releases.py
@@ -33,17 +33,17 @@ class ReleasePusher(BaseScript, Virtuale
             "dest": "credentials",
             "help": "File containing access key and secret access key",
         }],
         [["--exclude"], {
             "dest": "excludes",
             "default": [
                 r"^.*tests.*$",
                 r"^.*crashreporter.*$",
-                r"^.*[^k]\.zip(\.asc)?$",
+                r"^(?!.*jsshell-).*\.zip(\.asc)?$",
                 r"^.*\.log$",
                 r"^.*\.txt$",
                 r"^.*/partner-repacks.*$",
                 r"^.*.checksums(\.asc)?$",
                 r"^.*/logs/.*$",
                 r"^.*json$",
                 r"^.*/host.*$",
                 r"^.*/mar-tools/.*$",
deleted file mode 100644
--- a/testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-[EventTarget-constructible.any.html]
-  type: testharness
-  [A constructed EventTarget can be used as expected]
-    expected: FAIL
-
-  [EventTarget can be subclassed]
-    expected: FAIL
-
-
-[EventTarget-constructible.any.worker.html]
-  type: testharness
-  [A constructed EventTarget can be used as expected]
-    expected: FAIL
-
-  [EventTarget can be subclassed]
-    expected: FAIL
-
--- a/testing/web-platform/meta/dom/interfaces.html.ini
+++ b/testing/web-platform/meta/dom/interfaces.html.ini
@@ -17,58 +17,19 @@
     bug: 931884
 
   [Element interface: element must inherit property "assignedSlot" with the proper type (48)]
     expected: FAIL
 
   [Text interface: document.createTextNode("abc") must inherit property "assignedSlot" with the proper type (2)]
     expected: FAIL
 
-  [EventTarget must be primary interface of new EventTarget()]
-    expected: FAIL
-
-  [Stringification of new EventTarget()]
-    expected: FAIL
-
-  [EventTarget interface: new EventTarget() must inherit property "addEventListener" with the proper type (0)]
-    expected: FAIL
-
-  [EventTarget interface: calling addEventListener(DOMString,EventListener,[object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [EventTarget interface: new EventTarget() must inherit property "removeEventListener" with the proper type (1)]
-    expected: FAIL
-
-  [EventTarget interface: calling removeEventListener(DOMString,EventListener,[object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [EventTarget interface: new EventTarget() must inherit property "dispatchEvent" with the proper type (2)]
-    expected: FAIL
-
-  [EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError]
-    expected: FAIL
-
   [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type (1)]
     expected: FAIL
 
-  [EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type]
-    expected: FAIL
-
-  [EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type]
-    expected: FAIL
-
-  [EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type]
-    expected: FAIL
-
   [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "origin" with the proper type]
     expected: FAIL
 
   [Document interface: xmlDoc must inherit property "origin" with the proper type]
     expected: FAIL
--- a/testing/web-platform/tests/eventsource/interfaces.html
+++ b/testing/web-platform/tests/eventsource/interfaces.html
@@ -4,17 +4,17 @@
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/WebIDLParser.js></script>
 <script src=/resources/idlharness.js></script>
 
 <h1>EventSource IDL tests</h1>
 <div id=log></div>
 
 <script type=text/plain>
-[Exposed=(Window,Worker)]
+[Constructor(), Exposed=(Window,Worker)]
 interface EventTarget {
   void addEventListener(DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options);
   void removeEventListener(DOMString type, EventListener? listener, optional (EventListenerOptions or boolean) options);
   boolean dispatchEvent(Event event);
 };
 callback interface EventListener {
   void handleEvent(Event event);
 };
--- a/testing/web-platform/tests/interfaces/dedicated-workers.idl
+++ b/testing/web-platform/tests/interfaces/dedicated-workers.idl
@@ -1,12 +1,12 @@
 // -----------------------------------------------------------------------------
 // DOM
 // -----------------------------------------------------------------------------
-[Exposed=(Window,Worker)]
+[Constructor(), Exposed=(Window,Worker)]
 interface EventTarget {
   void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
   void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
   boolean dispatchEvent(Event event);
 };
 
 callback interface EventListener {
   void handleEvent(Event event);
--- a/testing/web-platform/tests/service-workers/service-worker/resources/interfaces-idls.js
+++ b/testing/web-platform/tests/service-workers/service-worker/resources/interfaces-idls.js
@@ -88,17 +88,17 @@ interface ServiceWorkerRegistration : Ev
 
   [NewObject] Promise<void> update();
   [NewObject] Promise<boolean> unregister();
 
   // event
   attribute EventHandler onupdatefound;
 };
 
-[Exposed=(Window,Worker)]
+[Constructor(), Exposed=(Window,Worker)]
 interface EventTarget {
   void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
   void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
   boolean dispatchEvent(Event event);
 };
 
 [SecureContext, Exposed=(Window,Worker)]
 interface NavigationPreloadManager {
--- a/testing/web-platform/tests/webrtc/RTCPeerConnection-idl.html
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-idl.html
@@ -13,16 +13,17 @@
 <div id='log'></div>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/WebIDLParser.js></script>
 <script src=/resources/idlharness.js></script>
 
 <!-- The IDL is copied from the 22 September 2015 editors' draft. -->
 <script type="text/plain">
+[Constructor()]
 interface EventTarget {
     // Only a dummy definition is needed here.
 };
 [ Constructor (optional RTCConfiguration configuration)]
 interface RTCPeerConnection : EventTarget  {
     Promise<RTCSessionDescription> createOffer (optional RTCOfferOptions options);
     Promise<RTCSessionDescription> createAnswer (optional RTCAnswerOptions options);
     Promise<void>                  setLocalDescription (RTCSessionDescription description);
--- a/toolkit/components/telemetry/GCTelemetry.jsm
+++ b/toolkit/components/telemetry/GCTelemetry.jsm
@@ -4,22 +4,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /**
  * This module records detailed timing information about selected
  * GCs. The data is sent back in the telemetry session ping. To avoid
  * bloating the ping, only a few GCs are included. There are two
- * selection strategies. We always save the five GCs with the worst
- * max_pause time. Additionally, five collections are selected at
+ * selection strategies. We always save the two GCs with the worst
+ * max_pause time. Additionally, two collections are selected at
  * random. If a GC runs for C milliseconds and the total time for all
  * GCs since the session began is T milliseconds, then the GC has a
- * 5*C/T probablility of being selected (the factor of 5 is because we
- * save 5 of them).
+ * 2*C/T probablility of being selected (the factor of 2 is because we
+ * save two of them).
  *
  * GCs from both the main process and all content processes are
  * recorded. The data is cleared for each new subsession.
  */
 
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
@@ -77,17 +77,17 @@ class GCData {
     // practice.
     for (let i = 0; i < this.randomlySelected.length; i++) {
       let r = Math.random();
       if (r <= prob) {
         this.randomlySelected[i] = data;
       }
     }
 
-    // Save the 5 worst GCs based on max_pause. A GC may appear in
+    // Save the 2 worst GCs based on max_pause. A GC may appear in
     // both worst and randomlySelected.
     for (let i = 0; i < this.worst.length; i++) {
       if (!this.worst[i]) {
         this.worst[i] = data;
         break;
       }
 
       if (this.worst[i].max_pause < data.max_pause) {
@@ -105,19 +105,19 @@ class GCData {
     };
   }
 }
 
 // If you adjust any of the constants here (slice limit, number of keys, etc.)
 // make sure to update the JSON schema at:
 // https://github.com/mozilla-services/mozilla-pipeline-schemas/blob/master/telemetry/main.schema.json
 // You should also adjust browser_TelemetryGC.js.
-const MAX_GC_KEYS = 30;
+const MAX_GC_KEYS = 24;
 const MAX_SLICES = 4;
-const MAX_SLICE_KEYS = 15;
+const MAX_SLICE_KEYS = 12;
 const MAX_PHASES = 65;
 
 function limitProperties(obj, count) {
   // If there are too many properties, just delete them all. We don't
   // expect this ever to happen.
   if (Object.keys(obj).length > count) {
     for (let key of Object.keys(obj)) {
       delete obj[key];
--- a/toolkit/components/telemetry/docs/data/main-ping.rst
+++ b/toolkit/components/telemetry/docs/data/main-ping.rst
@@ -476,50 +476,55 @@ Structure:
           "timestamp": 294872.2,
           // All durations are in milliseconds.
           "max_pause": 73.629,
           "total_time": 364.951, // Sum of all slice times.
           "zones_collected": 9,
           "total_zones": 9,
           "total_compartments": 309,
           "minor_gcs": 44,
+          // Present if non-zero.
           "store_buffer_overflows": 19,
           "mmu_20ms": 0,
           "mmu_50ms": 0,
           // Reasons include "None", "NonIncrementalRequested",
           // "AbortRequested", "KeepAtomsSet", "IncrementalDisabled",
           // "ModeChange", "MallocBytesTrigger", "GCBytesTrigger",
           // "ZoneChange", "CompartmentRevived".
-          "nonincremental_reason": "None",
-          "allocated": 37, // In megabytes.
+          // Present for non-incremental GCs only.
+          "nonincremental_reason": "GCBytesTrigger",
           "allocated_bytes": 38853696 // in bytes
+
+          // Present if non-zero.
           "added_chunks": 54,
           "removed_chunks": 12,
+
           // Total number of slices (some of which may not appear
           // in the "slices" array).
           "slices": 15,
           // We record at most 4 slices.
           "slice_number": 218, // The first slice number for this GC event.
           "slices_list": [
             {
               "slice": 218,  // The global index of this slice.
-              "pause": 23.221,  // How long the slice took.
-              "when": 0,  // Milliseconds since the start of the GC.
+              "pause": 23.221,  // How long the slice took (milliseconds).
               "reason": "SET_NEW_DOCUMENT",
               // GC state when the slice started
               "initial_state": "NotActive",
               // GC state when the slice ended
               "final_state": "Mark",
               // Budget is either "Xms", "work(Y)", or
               // "unlimited".
               "budget": "10ms",
               // Number of page faults during the slice.
-              "page_faults": 0,
+              // optional field, missing means 0.
+              "page_faults": 1,
+              // The start time of this slice in seconds.  The end time is
+              // given by the start_timestamp + pause.
               "start_timestamp": 294875,
-              "end_timestamp": 294879,
               // Time taken by each phase. There are at most 65 possible
               // phases, but usually only a few phases run in a given slice.
               "times": {
                 "wait_background_thread": 0.012,
                 "mark_discard_code": 2.845,
                 "purge": 0.723,
                 "mark": 9.831,
                 "mark_roots": 0.102,
--- a/toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js
+++ b/toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js
@@ -36,17 +36,17 @@ function check(entries) {
 
     ok(entries[f].length <= 2, "not too many GCs");
 
     for (let gc of entries[f]) {
       isnot(gc, null, "GC is non-null");
 
       foundGCs++;
 
-      ok(Object.keys(gc).length <= 30, "number of keys in GC is not too large");
+      ok(Object.keys(gc).length <= 24, "number of keys in GC is not too large");
 
       // Sanity check the GC data.
       ok("status" in gc, "status field present");
       is(gc.status, "completed", "status field correct");
       ok("total_time" in gc, "total_time field present");
       ok("max_pause" in gc, "max_pause field present");
 
       ok("slices_list" in gc, "slices_list field present");
@@ -63,17 +63,17 @@ function check(entries) {
         if (key != "slices_list" && key != "totals") {
           isnot(typeof(gc[key]), "object", `${key} property should be primitive`);
         }
       }
 
       let phases = new Set();
 
       for (let slice of gc.slices_list) {
-        ok(Object.keys(slice).length <= 15, "slice is not too large");
+        ok(Object.keys(slice).length <= 12, "slice is not too large");
 
         ok("pause" in slice, "pause field present in slice");
         ok("reason" in slice, "reason field present in slice");
         ok("times" in slice, "times field present in slice");
 
         // Make sure we don't skip any big objects.
         for (let key in slice) {
           if (key != "times") {
--- a/toolkit/content/tests/chrome/chrome.ini
+++ b/toolkit/content/tests/chrome/chrome.ini
@@ -66,16 +66,17 @@ subsuite = clipboard
 [test_autocomplete_placehold_last_complete.xul]
 [test_browser_drop.xul]
 [test_bug253481.xul]
 subsuite = clipboard
 [test_bug263683.xul]
 skip-if = debug && (os == 'win' || os == 'linux')
 [test_bug304188.xul]
 [test_bug331215.xul]
+skip-if = os == 'win' && debug # Bug 1339326
 [test_bug360220.xul]
 [test_bug360437.xul]
 skip-if = os == 'linux' # Bug 1264604
 [test_bug365773.xul]
 [test_bug366992.xul]
 [test_bug382990.xul]
 [test_bug409624.xul]
 [test_bug418874.xul]
--- a/toolkit/locales/Makefile.in
+++ b/toolkit/locales/Makefile.in
@@ -18,19 +18,8 @@ chrome-%: AB_CD=$*
 chrome-%:
 	@$(MAKE) -C $(DEPTH)/netwerk/locales/ chrome AB_CD=$*
 	@$(MAKE) -C $(DEPTH)/dom/locales/ chrome AB_CD=$*
 	@$(MAKE) -C $(DEPTH)/security/manager/locales/ chrome AB_CD=$*
 	@$(MAKE) chrome AB_CD=$*
 
 libs:: update.locale
 	sed -e 's/%AB_CD%/$(AB_CD)/' $< > $(FINAL_TARGET)/update.locale
-
-ifndef IS_LANGPACK
-ifdef MOZ_CRASHREPORTER
-libs:: $(call MERGE_FILE,crashreporter/crashreporter.ini)
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/crashreporter.app/Contents/Resources
-else
-	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
-endif
-endif
-endif
--- a/toolkit/locales/moz.build
+++ b/toolkit/locales/moz.build
@@ -18,8 +18,19 @@ JAR_MANIFESTS += ['jar.mn']
 GENERATED_FILES = [
     'multilocale.json',
 ]
 multilocale = GENERATED_FILES['multilocale.json']
 multilocale.script = 'gen_multilocale.py'
 FINAL_TARGET_FILES.res += [
     '!multilocale.json',
 ]
+
+if CONFIG['MOZ_CRASHREPORTER']:
+    if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+        # TODO: fixing bug 1223748 should let us remove this special case
+        LOCALIZED_FILES['crashreporter.app'].Contents.Resources += [
+            'en-US/crashreporter/crashreporter.ini'
+        ]
+    else:
+        LOCALIZED_FILES += [
+            'en-US/crashreporter/crashreporter.ini'
+        ]