merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 09 Nov 2017 00:00:16 +0200
changeset 390844 c10cf7082a9b84839e7c3fdda80bd468e091739a
parent 390843 6d99b1e6c77737f2d6b1f1a95580c9937fcf4793 (current diff)
parent 390837 de981f0569845f3061cd784dc8b14f71f85645fa (diff)
child 390845 56b71dd4d04ba67840c65c07576de12c48d0e904
child 390859 21cccb0cb5fd5e685b4d5640eb50bba821caeea9
child 390920 7d799a93ed72e65fbf277170eafe45535276c671
push id55020
push userarchaeopteryx@coole-files.de
push dateWed, 08 Nov 2017 22:31:06 +0000
treeherderautoland@56b71dd4d04b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.0a1
first release with
nightly linux32
c10cf7082a9b / 58.0a1 / 20171108221316 / files
nightly linux64
c10cf7082a9b / 58.0a1 / 20171108221316 / files
nightly mac
c10cf7082a9b / 58.0a1 / 20171108221316 / files
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
merge mozilla-inbound to mozilla-central. r=merge a=merge
dom/base/nsDocument.cpp
dom/base/nsIDocument.h
dom/html/crashtests/crashtests.list
dom/html/nsHTMLDocument.cpp
intl/unicharutil/nsIUnicodeNormalizer.idl
intl/unicharutil/nsUnicodeNormalizer.cpp
intl/unicharutil/nsUnicodeNormalizer.h
intl/unicharutil/tests/NormalizationData.h
intl/unicharutil/tests/NormalizationTest.cpp
intl/unicharutil/tests/genNormalizationData.pl
intl/unicharutil/tests/moz.build
intl/unicharutil/tests/unit/xpcshell.ini
old-configure.in
testing/mach_commands.py
toolkit/modules/Troubleshoot.jsm
--- a/browser/base/content/test/urlbar/browser_dragdropURL.js
+++ b/browser/base/content/test/urlbar/browser_dragdropURL.js
@@ -1,15 +1,36 @@
 "use strict";
 
 const TEST_URL = "data:text/html,a test page";
 const DRAG_URL = "http://www.example.com/";
 const DRAG_FORBIDDEN_URL = "chrome://browser/content/aboutDialog.xul";
 const DRAG_TEXT = "Firefox is awesome";
+const DRAG_TEXT_URL = "http://example.com/?q=Firefox+is+awesome";
 const DRAG_WORD = "Firefox";
+const DRAG_WORD_URL = "http://example.com/?q=Firefox";
+
+registerCleanupFunction(async function cleanup() {
+  while (gBrowser.tabs.length > 1) {
+    await BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
+  }
+  Services.search.currentEngine = originalEngine;
+  let engine = Services.search.getEngineByName("MozSearch");
+  Services.search.removeEngine(engine);
+});
+
+let originalEngine;
+add_task(async function test_setup() {
+  // Stop search-engine loads from hitting the network
+  Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
+                                       "http://example.com/?q={searchTerms}");
+  let engine = Services.search.getEngineByName("MozSearch");
+  originalEngine = Services.search.currentEngine;
+  Services.search.currentEngine = engine;
+});
 
 add_task(async function checkDragURL() {
   await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
     // Have to use something other than the URL bar as a source, so picking the
     // home button somewhat arbitrarily:
     EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
                               [[{type: "text/plain", data: DRAG_URL}]], "copy", window);
     is(gURLBar.value, TEST_URL, "URL bar value should not have changed");
@@ -21,18 +42,20 @@ add_task(async function checkDragForbidd
   await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
     EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
                               [[{type: "text/plain", data: DRAG_FORBIDDEN_URL}]], "copy", window);
     isnot(gURLBar.value, DRAG_FORBIDDEN_URL, "Shouldn't be allowed to drop forbidden URL on URL bar");
   });
 });
 
 add_task(async function checkDragText() {
-  await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
+  await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
+    let promiseLoad = BrowserTestUtils.browserLoaded(browser, false, DRAG_TEXT_URL);
     EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
                               [[{type: "text/plain", data: DRAG_TEXT}]], "copy", window);
-    is(gURLBar.value, DRAG_TEXT, "Dragging normal text should replace the URL bar value");
+    await promiseLoad;
 
+    promiseLoad = BrowserTestUtils.browserLoaded(browser, false, DRAG_WORD_URL);
     EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
                               [[{type: "text/plain", data: DRAG_WORD}]], "copy", window);
-    is(gURLBar.value, DRAG_WORD, "Dragging a single word should replace the URL bar value");
+    await promiseLoad;
   });
 });
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -946,22 +946,20 @@ file, You can obtain one at http://mozil
       <method name="onDrop">
         <parameter name="aEvent"/>
         <body><![CDATA[
           let droppedItem = this._getDroppableItem(aEvent);
           if (droppedItem) {
             this.value = droppedItem instanceof URL ? droppedItem.href : droppedItem;
             SetPageProxyState("invalid");
             this.focus();
-            if (droppedItem instanceof URL) {
-              this.handleCommand();
-              // Force not showing the dropped URI immediately.
-              gBrowser.userTypedValue = null;
-              URLBarSetURI();
-            }
+            this.handleCommand();
+            // Force not showing the dropped URI immediately.
+            gBrowser.userTypedValue = null;
+            URLBarSetURI();
           }
         ]]></body>
       </method>
 
       <method name="makeURIReadable">
         <parameter name="aURI"/>
         <body>
           <![CDATA[
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -310,17 +310,16 @@
 @RESPATH@/components/toolkit_xulstore.xpt
 @RESPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @RESPATH@/components/toolkitremote.xpt
 #endif
 @RESPATH@/components/txtsvc.xpt
 @RESPATH@/components/txmgr.xpt
 @RESPATH@/components/uconv.xpt
-@RESPATH@/components/unicharutil.xpt
 @RESPATH@/components/update.xpt
 @RESPATH@/components/uriloader.xpt
 @RESPATH@/components/urlformatter.xpt
 @RESPATH@/components/webBrowser_core.xpt
 @RESPATH@/components/webbrowserpersist.xpt
 @RESPATH@/components/webextensions.xpt
 @RESPATH@/components/widget.xpt
 #ifdef XP_MACOSX
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -64,16 +64,17 @@ included_inclnames_to_ignore = set([
     'double-conversion.h',      # strange MFBT case
     'javascript-trace.h',       # generated in $OBJDIR if HAVE_DTRACE is defined
     'frontend/ReservedWordsGenerated.h', # generated in $OBJDIR
     'gc/StatsPhasesGenerated.h',         # generated in $OBJDIR
     'gc/StatsPhasesGenerated.cpp',       # generated in $OBJDIR
     'jscustomallocator.h',      # provided by embedders;  allowed to be missing
     'js-config.h',              # generated in $OBJDIR
     'fdlibm.h',                 # fdlibm
+    'mozmemory.h',              # included without a path
     'pratom.h',                 # NSPR
     'prcvar.h',                 # NSPR
     'prerror.h',                # NSPR
     'prinit.h',                 # NSPR
     'prio.h',                   # NSPR
     'private/pprio.h',          # NSPR
     'prlink.h',                 # NSPR
     'prlock.h',                 # NSPR
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -8,16 +8,17 @@
 #include "nsIDocShellTreeItem.idl"
 #include "nsIRequest.idl"
 
 %{ C++
 #include "js/TypeDecls.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/NotNull.h"
 #include "nsCOMPtr.h"
+#include "nsIURI.h"
 class nsPresContext;
 class nsIPresShell;
 namespace mozilla {
 class Encoding;
 class HTMLEditor;
 }
 %}
 
--- a/dom/abort/AbortSignal.cpp
+++ b/dom/abort/AbortSignal.cpp
@@ -1,15 +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 "AbortSignal.h"
+
+#include "AbortController.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/AbortSignalBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AbortSignal)
 
--- a/dom/animation/AnimationEffectReadOnly.cpp
+++ b/dom/animation/AnimationEffectReadOnly.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/AnimationEffectReadOnly.h"
 #include "mozilla/dom/AnimationEffectReadOnlyBinding.h"
+
+#include "mozilla/dom/Animation.h"
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/FloatingPoint.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AnimationEffectReadOnly)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AnimationEffectReadOnly)
--- a/dom/animation/CSSPseudoElement.cpp
+++ b/dom/animation/CSSPseudoElement.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/CSSPseudoElement.h"
 #include "mozilla/dom/CSSPseudoElementBinding.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/AnimationComparator.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CSSPseudoElement, mParentElement)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CSSPseudoElement, AddRef)
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -8,16 +8,17 @@
 
 #include "jsfriendapi.h"
 #include "WrapperFactory.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/IdleDeadline.h"
+#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */ void
 ChromeUtils::NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/CustomElementRegistry.h"
 
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/dom/CustomElementRegistryBinding.h"
 #include "mozilla/dom/HTMLElementBinding.h"
+#include "mozilla/dom/Promise.h"
 #include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/DocGroup.h"
 #include "nsHTMLTags.h"
 #include "jsapi.h"
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.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 "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMErrorBinding.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/UseCounter.h"
+#include "nsIDocument.h"
 #include "nsPIDOMWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMError, mWindow)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMError)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMError)
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7731,16 +7731,41 @@ nsIDocument::SetDir(const nsAString& aDi
 {
   Element* rootElement = GetHtmlElement();
   if (rootElement) {
     rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir,
                          aDirection, true);
   }
 }
 
+/* static */
+bool
+nsIDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
+                                nsAtom* aAtom, void* aData)
+{
+  NS_PRECONDITION(aElement, "Must have element to work with!");
+
+  if (!aElement->HasName()) {
+    return false;
+  }
+
+  nsString* elementName = static_cast<nsString*>(aData);
+  return
+    aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
+    aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+                          *elementName, eCaseMatters);
+}
+
+/* static */
+void*
+nsIDocument::UseExistingNameString(nsINode* aRootNode, const nsString* aName)
+{
+  return const_cast<nsString*>(aName);
+}
+
 NS_IMETHODIMP
 nsDocument::GetInputEncoding(nsAString& aInputEncoding)
 {
   nsIDocument::GetCharacterSet(aInputEncoding);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -52,16 +52,17 @@ namespace dom {
 class ElementCreationOptionsOrString;
 } // namespace dom
 } // namespace mozilla
 #endif // MOZILLA_INTERNAL_API
 
 class gfxUserFontSet;
 class imgIRequest;
 class nsBindingManager;
+class nsCachableElementsByNameNodeList;
 class nsIDocShell;
 class nsDocShell;
 class nsDOMNavigationTiming;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsAtom;
@@ -2936,16 +2937,24 @@ public:
   void GetReadyState(nsAString& aReadyState) const;
   // Not const because otherwise the compiler can't figure out whether to call
   // this GetTitle or the nsAString version from non-const methods, since
   // neither is an exact match.
   virtual void GetTitle(nsString& aTitle) = 0;
   virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) = 0;
   void GetDir(nsAString& aDirection) const;
   void SetDir(const nsAString& aDirection);
+  already_AddRefed<nsContentList> GetElementsByName(const nsAString& aName)
+  {
+    return GetFuncStringContentList<nsCachableElementsByNameNodeList>(this,
+                                                                      MatchNameAttribute,
+                                                                      nullptr,
+                                                                      UseExistingNameString,
+                                                                      aName);
+  }
   nsPIDOMWindowOuter* GetDefaultView() const
   {
     return GetWindow();
   }
   Element* GetActiveElement();
   bool HasFocus(mozilla::ErrorResult& rv) const;
   mozilla::TimeStamp LastFocusTime() const;
   void SetLastFocusTime(const mozilla::TimeStamp& aFocusTime);
@@ -3316,16 +3325,22 @@ protected:
   // mFrameRequestCallbacksScheduled.  aOldShell should only be passed when
   // mPresShell is becoming null; in that case it will be used to get hold of
   // the relevant refresh driver.
   void UpdateFrameRequestCallbackSchedulingState(nsIPresShell* aOldShell = nullptr);
 
   // Helper for GetScrollingElement/IsScrollingElement.
   bool IsPotentiallyScrollable(mozilla::dom::HTMLBodyElement* aBody);
 
+  // Helpers for GetElementsByName.
+  static bool MatchNameAttribute(mozilla::dom::Element* aElement,
+                                 int32_t aNamespaceID,
+                                 nsAtom* aAtom, void* aData);
+  static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
+
   nsCString mReferrer;
   nsString mLastModified;
 
   nsCOMPtr<nsIURI> mDocumentURI;
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mChromeXHRDocURI;
   nsCOMPtr<nsIURI> mDocumentBaseURI;
   nsCOMPtr<nsIURI> mChromeXHRDocBaseURI;
--- a/dom/bindings/WebIDLGlobalNameHash.cpp
+++ b/dom/bindings/WebIDLGlobalNameHash.cpp
@@ -1,24 +1,28 @@
 /* -*- 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 "WebIDLGlobalNameHash.h"
 #include "js/GCAPI.h"
+#include "jswrapper.h"
+#include "mozilla/ErrorResult.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/DOMJSProxyHandler.h"
 #include "mozilla/dom/PrototypeList.h"
 #include "mozilla/dom/RegisterBindings.h"
+#include "nsGlobalWindow.h"
 #include "nsIMemoryReporter.h"
 #include "nsTHashtable.h"
+#include "WrapperFactory.h"
 
 namespace mozilla {
 namespace dom {
 
 struct MOZ_STACK_CLASS WebIDLNameTableKey
 {
   explicit WebIDLNameTableKey(JSFlatString* aJSString)
     : mLength(js::GetFlatStringLength(aJSString))
--- a/dom/bindings/nsScriptError.cpp
+++ b/dom/bindings/nsScriptError.cpp
@@ -7,16 +7,17 @@
 /*
  * nsIScriptError implementation.
  */
 
 #include "nsScriptError.h"
 #include "jsprf.h"
 #include "MainThreadUtils.h"
 #include "mozilla/Assertions.h"
+#include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsILoadContext.h"
 #include "nsIDocShell.h"
 #include "nsIMutableArray.h"
 #include "nsIScriptError.h"
 #include "nsISensitiveInfoHiddenURI.h"
--- a/dom/bindings/nsScriptError.h
+++ b/dom/bindings/nsScriptError.h
@@ -9,16 +9,18 @@
 
 #include "mozilla/Atomics.h"
 
 #include <stdint.h>
 
 #include "jsapi.h"
 #include "js/RootingAPI.h"
 
+#include "nsCOMArray.h"
+#include "nsCycleCollectionParticipant.h"
 #include "nsIScriptError.h"
 #include "nsString.h"
 
 class nsScriptErrorNote final : public nsIScriptErrorNote {
  public:
   nsScriptErrorNote();
 
   NS_DECL_THREADSAFE_ISUPPORTS
new file mode 100644
--- /dev/null
+++ b/dom/canvas/crashtests/844280.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+  var canvas = document.createElement("canvas");
+  canvas.setAttribute("width", "7623");
+  canvas.setAttribute("height", "14064");
+  canvas.getContext("experimental-webgl");
+}
+
+</script>
+</head>
+
+<body onload="boom();"></body>
+</html>
--- a/dom/canvas/crashtests/crashtests.list
+++ b/dom/canvas/crashtests/crashtests.list
@@ -11,16 +11,17 @@ load 746813-1.html
 load 743499-negative-size.html
 skip-if(Android) load 745818-large-source.html # Bug XXX - Crashes Android mid-run w/o a stack
 load 767337-1.html
 load 779426.html
 skip-if(Android) load 780392-1.html
 skip-if(Android) skip-if(gtkWidget&&isDebugBuild) load 789933-1.html # bug 1155252 for linux
 load 794463-1.html
 load 802926-1.html
+skip-if(winWidget&&isDebugBuild&&/^Windows\x20NT\x206\.1/.test(http.oscpu)) load 844280.html # intermittent OOMs on Win7 debug
 load 896047-1.html
 load 916128-1.html
 load 934939-1.html
 load 989628.html
 load 1099143-1.html
 load 1161277-1.html
 load 1183363.html
 load 1190705.html
--- a/dom/clients/manager/ClientState.cpp
+++ b/dom/clients/manager/ClientState.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ClientState.h"
 
+#include "mozilla/dom/ClientIPCTypes.h"
+
 namespace mozilla {
 namespace dom {
 
 ClientWindowState::ClientWindowState(mozilla::dom::VisibilityState aVisibilityState,
                                      const TimeStamp& aLastFocusTime,
                                      bool aFocused)
   : mData(MakeUnique<IPCClientWindowState>(aVisibilityState, aLastFocusTime,
                                            aFocused))
--- a/dom/clients/manager/ClientState.h
+++ b/dom/clients/manager/ClientState.h
@@ -2,16 +2,19 @@
 /* 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_ClientState_h
 #define _mozilla_dom_ClientState_h
 
+#include "mozilla/dom/DocumentBinding.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class IPCClientState;
 class IPCClientWindowState;
 class IPCClientWorkerState;
--- a/dom/crypto/WebCryptoThreadPool.cpp
+++ b/dom/crypto/WebCryptoThreadPool.cpp
@@ -1,19 +1,21 @@
 /* -*- 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/WebCryptoThreadPool.h"
 
+#include "MainThreadUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsComponentManagerUtils.h"
+#include "nsNSSComponent.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsXPCOMPrivate.h"
 #include "nsIObserverService.h"
 #include "nsIThreadPool.h"
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/crypto/WebCryptoThreadPool.h
+++ b/dom/crypto/WebCryptoThreadPool.h
@@ -2,16 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_WebCryptoThreadPool_h
 #define mozilla_dom_WebCryptoThreadPool_h
 
+#include "mozilla/Mutex.h"
+#include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIThreadPool.h"
 
 namespace mozilla {
 namespace dom {
 
 class WebCryptoThreadPool final : nsIObserver {
 public:
new file mode 100644
--- /dev/null
+++ b/dom/html/crashtests/768344.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+    function f() {
+        document.removeEventListener("DOMSubtreeModified", f, true);
+        document.documentElement.setAttributeNS(null, "contenteditable", "false");
+    }
+
+    document.addEventListener("DOMSubtreeModified", f, true);
+
+    document.documentElement.contentEditable = "true";
+}
+
+</script>
+</head>
+
+<body onload="boom();"></body>
+</html>
--- a/dom/html/crashtests/crashtests.list
+++ b/dom/html/crashtests/crashtests.list
@@ -48,16 +48,17 @@ load 620078-2.html
 load 631421.html
 load 673853.html
 load 680922-1.xul
 load 682058.xhtml
 load 682460.html
 load 738744.xhtml
 load 741218.json
 load 741250.xhtml
+load 768344.html
 load 795221-1.html
 load 795221-2.html
 load 795221-3.html
 load 795221-4.html
 load 795221-5.xml
 load 811226.html
 load 819745.html
 load 828180.html
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -2058,48 +2058,16 @@ nsHTMLDocument::Writeln(const nsAString&
 
 void
 nsHTMLDocument::Writeln(JSContext* cx, const Sequence<nsString>& aText,
                         ErrorResult& rv)
 {
   WriteCommon(cx, aText, true, rv);
 }
 
-bool
-nsHTMLDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
-                                   nsAtom* aAtom, void* aData)
-{
-  NS_PRECONDITION(aElement, "Must have element to work with!");
-
-  if (!aElement->HasName()) {
-    return false;
-  }
-
-  nsString* elementName = static_cast<nsString*>(aData);
-  return
-    aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
-    aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
-                          *elementName, eCaseMatters);
-}
-
-/* static */
-void*
-nsHTMLDocument::UseExistingNameString(nsINode* aRootNode, const nsString* aName)
-{
-  return const_cast<nsString*>(aName);
-}
-
-NS_IMETHODIMP
-nsHTMLDocument::GetElementsByName(const nsAString& aElementName,
-                                  nsIDOMNodeList** aReturn)
-{
-  *aReturn = GetElementsByName(aElementName).take();
-  return NS_OK;
-}
-
 void
 nsHTMLDocument::AddedForm()
 {
   ++mNumForms;
 }
 
 void
 nsHTMLDocument::RemovedForm()
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -188,24 +188,16 @@ public:
   nsIHTMLCollection* Embeds();
   nsIHTMLCollection* Plugins();
   nsIHTMLCollection* Links();
   nsIHTMLCollection* Forms()
   {
     return nsHTMLDocument::GetForms();
   }
   nsIHTMLCollection* Scripts();
-  already_AddRefed<nsContentList> GetElementsByName(const nsAString & aName)
-  {
-    return GetFuncStringContentList<nsCachableElementsByNameNodeList>(this,
-                                                                      MatchNameAttribute,
-                                                                      nullptr,
-                                                                      UseExistingNameString,
-                                                                      aName);
-  }
   already_AddRefed<nsIDocument> Open(JSContext* cx,
                                      const nsAString& aType,
                                      const nsAString& aReplace,
                                      mozilla::ErrorResult& aError);
   already_AddRefed<nsPIDOMWindowOuter>
   Open(JSContext* cx,
        const nsAString& aURL,
        const nsAString& aName,
@@ -275,20 +267,16 @@ protected:
                        int32_t* aHeight);
 
   nsIContent *MatchId(nsIContent *aContent, const nsAString& aId);
 
   static bool MatchLinks(mozilla::dom::Element* aElement, int32_t aNamespaceID,
                          nsAtom* aAtom, void* aData);
   static bool MatchAnchors(mozilla::dom::Element* aElement, int32_t aNamespaceID,
                            nsAtom* aAtom, void* aData);
-  static bool MatchNameAttribute(mozilla::dom::Element* aElement,
-                                 int32_t aNamespaceID,
-                                 nsAtom* aAtom, void* aData);
-  static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
 
   static void DocumentWriteTerminationFunc(nsISupports *aRef);
 
   already_AddRefed<nsIURI> GetDomainURI();
   already_AddRefed<nsIURI> CreateInheritingURIForHost(const nsACString& aHostString);
   already_AddRefed<nsIURI> RegistrableDomainSuffixOfInternal(const nsAString& aHostSuffixString,
                                                              nsIURI* aOrigHost);
 
--- a/dom/interfaces/html/nsIDOMHTMLDocument.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl
@@ -24,17 +24,16 @@ interface nsIDOMHTMLDocument : nsIDOMDoc
 
   readonly attribute nsIDOMHTMLCollection images;
   readonly attribute nsIDOMHTMLCollection embeds;
   // mapped to attribute embeds for NS4 compat
   readonly attribute nsIDOMHTMLCollection plugins;
   readonly attribute nsIDOMHTMLCollection links;
   readonly attribute nsIDOMHTMLCollection forms;
   readonly attribute nsIDOMHTMLCollection scripts;
-  nsIDOMNodeList            getElementsByName(in DOMString elementName);
 
   // If aContentType is not something supported by nsHTMLDocument and
   // the HTML content sink, trying to write to the document will
   // probably throw.
   // Pass aReplace = true to trigger a replacement of the previous
   // document in session history; pass false for normal history handling.
   [implicit_jscontext, optional_argc]
   nsISupports               open([optional] in DOMString aContentTypeOrUrl,
new file mode 100644
--- /dev/null
+++ b/dom/media/test/crashtests/1267263.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<script>
+
+function boom()
+{
+    vid.setMediaKeys(null);
+    vid.fastSeek(111);
+}
+
+</script>
+</head>
+
+<body onload="boom();">
+  <video id="vid" src="../../../../layout/reftests/webm-video/frames.webm"></video>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/test/crashtests/1389304.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: Negative duration.</title>
+</head>
+<body>
+
+<video id="v" controls src="1389304.mp4">
+</video>
+<p id="msg"></p>
+
+<script type="text/javascript">
+
+function log(x) {
+  msg.innerHTML = x + "<br>";
+}
+
+v.play();
+v.onended = function() {
+	log("endded!");
+	let seekable = v.seekable;
+	for (let i = 0; i < seekable.length; ++i) {
+		let start = seekable.start(i);
+		let end = seekable.end(i);
+		log(`[${i}]: start=${start} end=${end}`);
+	}
+}
+
+</script>
+
+</body>
+</html>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..25cd7469725d9db3286c9831a83885a89fcf1b10
GIT binary patch
literal 198320
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
--- a/dom/media/test/crashtests/crashtests.list
+++ b/dom/media/test/crashtests/crashtests.list
@@ -81,23 +81,25 @@ skip-if(Android&&AndroidVersion=='21') l
 load 1197935.html
 load 1122218.html
 load 1127188.html
 load 1157994.html
 load 1158427.html
 load 1185176.html
 load 1185192.html
 load 1257700.html
+load 1267263.html
 load 1270303.html
 load 1304948.html
 load 1319486.html
 load 1368490.html
 load 1291702.html
 load 1378826.html
 load 1384248.html
+load 1389304.html
 load 1393272.webm
 load disconnect-wrong-destination.html
 load analyser-channels-1.html
 load audiocontext-double-suspend.html
 load buffer-source-duration-1.html
 load buffer-source-ended-1.html
 load buffer-source-resampling-start-1.html
 load buffer-source-slow-resampling-1.html
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -118,17 +118,18 @@ partial interface Document {
   //(HTML only)         attribute HTMLElement? body;
   //(HTML only)readonly attribute HTMLHeadElement? head;
   //(HTML only)readonly attribute HTMLCollection images;
   //(HTML only)readonly attribute HTMLCollection embeds;
   //(HTML only)readonly attribute HTMLCollection plugins;
   //(HTML only)readonly attribute HTMLCollection links;
   //(HTML only)readonly attribute HTMLCollection forms;
   //(HTML only)readonly attribute HTMLCollection scripts;
-  //(HTML only)NodeList getElementsByName(DOMString elementName);
+  [Pure]
+  NodeList getElementsByName(DOMString elementName);
   //(Not implemented)readonly attribute DOMElementMap cssElementMap;
 
   // dynamic markup insertion
   //(HTML only)Document open(optional DOMString type, optional DOMString replace);
   //(HTML only)WindowProxy open(DOMString url, DOMString name, DOMString features, optional boolean replace);
   //(HTML only)void close();
   //(HTML only)void write(DOMString... text);
   //(HTML only)void writeln(DOMString... text);
--- a/dom/webidl/HTMLDocument.webidl
+++ b/dom/webidl/HTMLDocument.webidl
@@ -24,17 +24,16 @@ interface HTMLDocument : Document {
   [Pure]
   readonly attribute HTMLCollection plugins;
   [Pure]
   readonly attribute HTMLCollection links;
   [Pure]
   readonly attribute HTMLCollection forms;
   [Pure]
   readonly attribute HTMLCollection scripts;
-  NodeList getElementsByName(DOMString elementName);
 
   // dynamic markup insertion
   [CEReactions, Throws]
   Document open(optional DOMString type = "text/html", optional DOMString replace = "");
   [CEReactions, Throws]
   WindowProxy? open(DOMString url, DOMString name, DOMString features, optional boolean replace = false);
   [CEReactions, Throws]
   void close();
new file mode 100644
--- /dev/null
+++ b/gfx/tests/crashtests/766422-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html style="-moz-perspective: 1000px; -moz-transform: skewY(277deg); overflow: -moz-hidden-unscrollable;">
+  <body style="-moz-transform: skewY(127deg);">
+    <div style="height: 20px; background: lightgreen;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/gfx/tests/crashtests/766422-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+  var ctx = document.getElementById("c").getContext('2d');
+  ctx.stroke();
+}
+
+</script>
+</head>
+<body onload="boom();">
+<canvas id="c" width="800" style="overflow: -moz-hidden-unscrollable; transform: skewY(30rad);"></canvas>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/gfx/tests/crashtests/951893.xhtml
@@ -0,0 +1,7 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body style="display: flex; position: absolute; transform: matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); overflow-y: hidden;">
+
+<video></video><video></video><video></video><track style="transform: rotate(45deg) scale(2, 1); position: absolute;"><video></video></track>
+
+</body>
+</html>
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -109,16 +109,18 @@ load 746491.html
 load 746495.html
 load 746497.html
 load 746844.html
 load 746847.html
 load 746849.html
 load 746866.html
 load 747132.html
 load 747302.html
+load 766422-1.html
+load 766422-2.html
 load 766452-1.html
 load 766452-2.html
 load 768079-1.html
 load 783041-1.html
 load 783041-2.html
 load 783041-3.html
 load 783041-4.html
 load 798853.html # bug 868792
@@ -131,16 +133,17 @@ load 893572-1.html
 load 893572-2.html
 load 893572-3.html
 load 893572-4.html
 load 895233.html
 pref(layers.force-active,true) load 914457-1.html
 load 944579.svg
 load 944579.html
 pref(security.fileuri.strict_origin_policy,false) load 950000.html
+load 951893.xhtml
 load 1011218.html
 load 1034403-1.html
 load 1056516.html
 load 1205900.html
 load 1134549-1.svg
 load balinese-letter-spacing.html
 load 1216832-1.html
 load 1221304.html
--- a/intl/build/nsI18nModule.cpp
+++ b/intl/build/nsI18nModule.cpp
@@ -5,67 +5,59 @@
 
 #include "mozilla/ModuleUtils.h"
 
 // lwbrk
 #include "nsLWBrkCIID.h"
 #include "nsJISx4051LineBreaker.h"
 #include "nsSampleWordBreaker.h"
 
-// unicharutil
-#include "nsUnicodeNormalizer.h"
-
 // string bundles (intl)
 #include "nsStringBundleService.h"
 #include "nsStringBundleTextOverride.h"
 
 // locale
 #include "nsLocaleConstructors.h"
 
 // uconv
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJISx4051LineBreaker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSampleWordBreaker)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStringBundleService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStringBundleTextOverride, Init)
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeNormalizer)
-
 NS_DEFINE_NAMED_CID(MOZ_LOCALESERVICE_CID);
 NS_DEFINE_NAMED_CID(MOZ_OSPREFERENCES_CID);
 NS_DEFINE_NAMED_CID(NS_LBRK_CID);
 NS_DEFINE_NAMED_CID(NS_WBRK_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODE_NORMALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLETEXTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATIONFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_PLATFORMCHARSET_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
 
 static const mozilla::Module::CIDEntry kIntlCIDs[] = {
     { &kMOZ_LOCALESERVICE_CID, false, nullptr, mozilla::intl::LocaleServiceConstructor },
     { &kMOZ_OSPREFERENCES_CID, false, nullptr, mozilla::intl::OSPreferencesConstructor },
     { &kNS_LBRK_CID, false, nullptr, nsJISx4051LineBreakerConstructor },
     { &kNS_WBRK_CID, false, nullptr, nsSampleWordBreakerConstructor },
-    { &kNS_UNICODE_NORMALIZER_CID, false, nullptr, nsUnicodeNormalizerConstructor },
     { &kNS_STRINGBUNDLESERVICE_CID, false, nullptr, nsStringBundleServiceConstructor },
     { &kNS_STRINGBUNDLETEXTOVERRIDE_CID, false, nullptr, nsStringBundleTextOverrideConstructor },
     { &kNS_COLLATIONFACTORY_CID, false, nullptr, nsCollationFactoryConstructor },
     { &kNS_PLATFORMCHARSET_CID, false, nullptr, nsPlatformCharsetConstructor },
     { &kNS_COLLATION_CID, false, nullptr, nsCollationConstructor },
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
     { MOZ_LOCALESERVICE_CONTRACTID, &kMOZ_LOCALESERVICE_CID },
     { MOZ_OSPREFERENCES_CONTRACTID, &kMOZ_OSPREFERENCES_CID },
     { NS_LBRK_CONTRACTID, &kNS_LBRK_CID },
     { NS_WBRK_CONTRACTID, &kNS_WBRK_CID },
-    { NS_UNICODE_NORMALIZER_CONTRACTID, &kNS_UNICODE_NORMALIZER_CID },
     { NS_STRINGBUNDLE_CONTRACTID, &kNS_STRINGBUNDLESERVICE_CID },
     { NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID, &kNS_STRINGBUNDLETEXTOVERRIDE_CID },
     { NS_COLLATIONFACTORY_CONTRACTID, &kNS_COLLATIONFACTORY_CID },
     { NS_PLATFORMCHARSET_CONTRACTID, &kNS_PLATFORMCHARSET_CID },
     { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
     { nullptr }
 };
 
--- a/intl/unicharutil/moz.build
+++ b/intl/unicharutil/moz.build
@@ -1,28 +1,13 @@
 # -*- 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/.
 
 DIRS += ['util']
-TEST_DIRS += ['tests']
-
-XPIDL_SOURCES += [
-    'nsIUnicodeNormalizer.idl',
-]
-
-XPIDL_MODULE = 'unicharutil'
 
 EXPORTS += [
     'nsUGenCategory.h',
-    'nsUnicodeNormalizer.h',
-]
-
-UNIFIED_SOURCES += [
-    'nsUnicodeNormalizer.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
-
-if CONFIG['GNU_CXX']:
-    CXXFLAGS += ['-Wno-error=shadow']
deleted file mode 100644
--- a/intl/unicharutil/nsIUnicodeNormalizer.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-%{C++
-#define NS_UNICODE_NORMALIZER_CID { 0xa665e49a, 0xf3e6, 0x4fed, { 0x9f, 0x31, 0xf7, 0xc5, 0x68, 0xa2, 0x98, 0x99 } }
-#define NS_UNICODE_NORMALIZER_CONTRACTID "@mozilla.org/intl/unicodenormalizer;1"
-%}
-
-[scriptable, uuid(B43A461F-1BCF-4329-820B-66E48C979E14)]
-interface nsIUnicodeNormalizer : nsISupports
-{
- /**
- * Normalize Unicode (NFD, NFC, NFKD, NFKC).
- *
- * NFD: Canonical Decomposition
- * NFC: Canonical Decomposition, followed by Canonical Composition
- * NFKD: Compatibility Decomposition
- * NFKC: Compatibility Decomposition, followed by Canonical Composition
- * Reference: Unicode Standard, TR15, Unicode Normalization Forms
- *
- * @param aSrc         [IN]  nsAString which contains an input UTF-16 string.
- * @param aDest        [OUT] A pointer to an output buffer provided by a callee.
- * @return             NS_OK for success, 
- */
-  void NormalizeUnicodeNFD(in AString aSrc, out AString aDest);
-  void NormalizeUnicodeNFC(in AString aSrc, out AString aDest);
-  void NormalizeUnicodeNFKD(in AString aSrc, out AString aDest);
-  void NormalizeUnicodeNFKC(in AString aSrc, out AString aDest);
-};
deleted file mode 100644
--- a/intl/unicharutil/nsUnicodeNormalizer.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* 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 "nsUnicodeNormalizer.h"
-#include "ICUUtils.h"
-#include "unicode/unorm2.h"
-#include "unicode/utext.h"
-
-NS_IMPL_ISUPPORTS(nsUnicodeNormalizer, nsIUnicodeNormalizer)
-
-static nsresult
-DoNormalization(const UNormalizer2* aNorm, const nsAString& aSrc,
-                nsAString& aDest)
-{
-  UErrorCode errorCode = U_ZERO_ERROR;
-  const int32_t length = aSrc.Length();
-  const UChar* src = reinterpret_cast<const UChar*>(aSrc.BeginReading());
-  // Initial guess for a capacity that is likely to be enough for most cases.
-  int32_t capacity = length + (length >> 8) + 8;
-  while (true) {
-    aDest.SetLength(capacity);
-    UChar* dest = reinterpret_cast<UChar*>(aDest.BeginWriting());
-    int32_t len = unorm2_normalize(aNorm, src, aSrc.Length(), dest, capacity,
-                                   &errorCode);
-    if (U_SUCCESS(errorCode)) {
-      aDest.SetLength(len);
-      break;
-    }
-    if (errorCode != U_BUFFER_OVERFLOW_ERROR) {
-      // Some other error that we don't handle
-      break;
-    }
-    // Buffer wasn't big enough; adjust to the reported size and try again.
-    capacity = len;
-    errorCode = U_ZERO_ERROR;
-  }
-  return ICUUtils::UErrorToNsResult(errorCode);
-}
-
-nsresult
-nsUnicodeNormalizer::NormalizeUnicodeNFD(const nsAString& aSrc,
-                                         nsAString& aDest)
-{
-  // The unorm2_getNF*Instance functions return static singletons that should
-  // not be deleted, so we just get them once on first use.
-  static UErrorCode errorCode = U_ZERO_ERROR;
-  static const UNormalizer2* norm = unorm2_getNFDInstance(&errorCode);
-  if (U_SUCCESS(errorCode)) {
-    return DoNormalization(norm, aSrc, aDest);
-  }
-  return ICUUtils::UErrorToNsResult(errorCode);
-}
-
-nsresult
-nsUnicodeNormalizer::NormalizeUnicodeNFC(const nsAString& aSrc,
-                                         nsAString& aDest)
-{
-  static UErrorCode errorCode = U_ZERO_ERROR;
-  static const UNormalizer2* norm = unorm2_getNFCInstance(&errorCode);
-  if (U_SUCCESS(errorCode)) {
-    return DoNormalization(norm, aSrc, aDest);
-  }
-  return ICUUtils::UErrorToNsResult(errorCode);
-}
-
-nsresult
-nsUnicodeNormalizer::NormalizeUnicodeNFKD(const nsAString& aSrc,
-                                          nsAString& aDest)
-{
-  static UErrorCode errorCode = U_ZERO_ERROR;
-  static const UNormalizer2* norm = unorm2_getNFKDInstance(&errorCode);
-  if (U_SUCCESS(errorCode)) {
-    return DoNormalization(norm, aSrc, aDest);
-  }
-  return ICUUtils::UErrorToNsResult(errorCode);
-}
-
-nsresult
-nsUnicodeNormalizer::NormalizeUnicodeNFKC(const nsAString& aSrc,
-                                          nsAString& aDest)
-{
-  static UErrorCode errorCode = U_ZERO_ERROR;
-  static const UNormalizer2* norm = unorm2_getNFKCInstance(&errorCode);
-  if (U_SUCCESS(errorCode)) {
-    return DoNormalization(norm, aSrc, aDest);
-  }
-  return ICUUtils::UErrorToNsResult(errorCode);
-}
deleted file mode 100644
--- a/intl/unicharutil/nsUnicodeNormalizer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 nsUnicodeNormalizer_h__
-#define nsUnicodeNormalizer_h__
-
-#include "nscore.h"
-#include "nsISupports.h"
-
-#include "nsIUnicodeNormalizer.h"
-
-nsresult NS_NewUnicodeNormalizer(nsISupports** oResult);
-
-
-class nsUnicodeNormalizer : public nsIUnicodeNormalizer {
-public:
-   nsUnicodeNormalizer() { }
-
-   NS_DECL_ISUPPORTS
-
-   NS_IMETHOD NormalizeUnicodeNFD( const nsAString& aSrc, nsAString& aDest) override;
-   NS_IMETHOD NormalizeUnicodeNFC( const nsAString& aSrc, nsAString& aDest) override;
-   NS_IMETHOD NormalizeUnicodeNFKD( const nsAString& aSrc, nsAString& aDest) override;
-   NS_IMETHOD NormalizeUnicodeNFKC( const nsAString& aSrc, nsAString& aDest) override;
-
-private:
-   virtual ~nsUnicodeNormalizer() { }
-};
-
-#endif //nsUnicodeNormalizer_h__
-
deleted file mode 100644
--- a/intl/unicharutil/tests/NormalizationData.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* dummy test data will be overwritten by generator */
-static char versionText[] = "\0";
-static testcaseLine Part0TestData[1];
-static testcaseLine Part1TestData[1];
-static testcaseLine Part2TestData[1];
-static testcaseLine Part3TestData[1];
-
deleted file mode 100644
--- a/intl/unicharutil/tests/NormalizationTest.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include "gtest/gtest.h"
-#include "nsXPCOM.h"
-#include "nsIUnicodeNormalizer.h"
-#include "nsString.h"
-#include "nsCharTraits.h"
-#include "nsServiceManagerUtils.h"
-#include "mozilla/Sprintf.h"
-
-struct testcaseLine {
-  wchar_t* c1;
-  wchar_t* c2;
-  wchar_t* c3;
-  wchar_t* c4;
-  wchar_t* c5;
-  char* description;
-};
-
-#ifdef DEBUG_smontagu
-#define DEBUG_NAMED_TESTCASE(t, s) \
-  printf(t ": "); \
-  for (uint32_t i = 0; i < s.Length(); ++i) \
-    printf("%x ", s.CharAt(i)); \
-  printf("\n")
-#else
-#define DEBUG_NAMED_TESTCASE(t, s)
-#endif
-
-#define DEBUG_TESTCASE(x) DEBUG_NAMED_TESTCASE(#x, x)
-
-#define NORMALIZE_AND_COMPARE(base, comparison, form, description) \
-   normalized.Truncate();\
-   normalizer->NormalizeUnicode##form(comparison, normalized);\
-   DEBUG_NAMED_TESTCASE(#form "(" #comparison ")", normalized);\
-   if (!base.Equals(normalized)) {\
-     rv = false;\
-     showError(description, #base " != " #form "(" #comparison ")\n");\
-   }
-
-NS_DEFINE_CID(kUnicodeNormalizerCID, NS_UNICODE_NORMALIZER_CID);
-
-nsIUnicodeNormalizer *normalizer;
-
-#include "NormalizationData.h"
-
-void showError(const char* description, const char* errorText)
-{
-  printf("%s failed: %s", description, errorText);
-}
-
-bool TestInvariants(testcaseLine* testLine)
-{
-  nsAutoString c1, c2, c3, c4, c5, normalized;
-  c1 = nsDependentString((char16_t*)testLine->c1);
-  c2 = nsDependentString((char16_t*)testLine->c2);
-  c3 = nsDependentString((char16_t*)testLine->c3);
-  c4 = nsDependentString((char16_t*)testLine->c4);
-  c5 = nsDependentString((char16_t*)testLine->c5);
-  bool rv = true;
-
-  /*
-    1. The following invariants must be true for all conformant implementations
-
-    NFC
-      c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3)
-  */
-  DEBUG_TESTCASE(c2);
-  NORMALIZE_AND_COMPARE(c2, c1, NFC, testLine->description);
-  NORMALIZE_AND_COMPARE(c2, c2, NFC, testLine->description);
-  NORMALIZE_AND_COMPARE(c2, c3, NFC, testLine->description);
-
-  /*
-      c4 ==  NFC(c4) ==  NFC(c5)
-  */
-  DEBUG_TESTCASE(c4);
-  NORMALIZE_AND_COMPARE(c4, c4, NFC, testLine->description);
-  NORMALIZE_AND_COMPARE(c4, c5, NFC, testLine->description);
-
-  /*
-    NFD
-      c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3)
-  */
-  DEBUG_TESTCASE(c3);
-  NORMALIZE_AND_COMPARE(c3, c1, NFD, testLine->description);
-  NORMALIZE_AND_COMPARE(c3, c2, NFD, testLine->description);
-  NORMALIZE_AND_COMPARE(c3, c3, NFD, testLine->description);
-  /*
-      c5 ==  NFD(c4) ==  NFD(c5)
-  */
-  DEBUG_TESTCASE(c5);
-  NORMALIZE_AND_COMPARE(c5, c4, NFD, testLine->description);
-  NORMALIZE_AND_COMPARE(c5, c5, NFD, testLine->description);
-
-  /*
-    NFKC
-      c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5)
-  */
-  DEBUG_TESTCASE(c4);
-  NORMALIZE_AND_COMPARE(c4, c1, NFKC, testLine->description);
-  NORMALIZE_AND_COMPARE(c4, c2, NFKC, testLine->description);
-  NORMALIZE_AND_COMPARE(c4, c3, NFKC, testLine->description);
-  NORMALIZE_AND_COMPARE(c4, c4, NFKC, testLine->description);
-  NORMALIZE_AND_COMPARE(c4, c5, NFKC, testLine->description);
-
-  /*
-    NFKD
-      c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5)
-  */
-  DEBUG_TESTCASE(c5);
-  NORMALIZE_AND_COMPARE(c5, c1, NFKD, testLine->description);
-  NORMALIZE_AND_COMPARE(c5, c2, NFKD, testLine->description);
-  NORMALIZE_AND_COMPARE(c5, c3, NFKD, testLine->description);
-  NORMALIZE_AND_COMPARE(c5, c4, NFKD, testLine->description);
-  NORMALIZE_AND_COMPARE(c5, c5, NFKD, testLine->description);
-
-  return rv;
-}
-
-uint32_t UTF32CodepointFromTestcase(testcaseLine* testLine)
-{
-  if (!IS_SURROGATE(testLine->c1[0]))
-    return testLine->c1[0];
-
-  NS_ASSERTION(NS_IS_HIGH_SURROGATE(testLine->c1[0]) &&
-               NS_IS_LOW_SURROGATE(testLine->c1[1]),
-               "Test data neither in BMP nor legal surrogate pair");
-  return SURROGATE_TO_UCS4(testLine->c1[0], testLine->c1[1]);
-}
-
-bool TestUnspecifiedCodepoint(uint32_t codepoint)
-{
-  bool rv = true;
-  char16_t unicharArray[3];
-  nsAutoString X, normalized;
-
-  if (IS_IN_BMP(codepoint)) {
-    unicharArray[0] = codepoint;
-    unicharArray[1] = 0;
-    X = nsDependentString(unicharArray);
-  }
-  else {
-    unicharArray[0] = H_SURROGATE(codepoint);
-    unicharArray[1] = L_SURROGATE(codepoint);
-    unicharArray[2] = 0;
-    X = nsDependentString(unicharArray);
-  }
-
-  /*
- 2. For every code point X assigned in this version of Unicode that is not specifically
-    listed in Part 1, the following invariants must be true for all conformant
-    implementations:
-
-      X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X)
-  */
-  static const size_t len = 9;
-  char description[len];
-
-  DEBUG_TESTCASE(X);
-  snprintf(description, len, "U+%04X", codepoint);
-  NORMALIZE_AND_COMPARE(X, X, NFC, description);
-  NORMALIZE_AND_COMPARE(X, X, NFD, description);
-  NORMALIZE_AND_COMPARE(X, X, NFKC, description);
-  NORMALIZE_AND_COMPARE(X, X, NFKD, description);
-  return rv;
-}
-
-void TestPart0()
-{
-  printf("Test Part0: Specific cases\n");
-
-  uint32_t i = 0;
-  uint32_t numFailed = 0;
-  uint32_t numPassed = 0;
-
-  while (Part0TestData[i].c1[0] != 0) {
-    if (TestInvariants(&Part0TestData[i++]))
-      ++numPassed;
-    else
-      ++numFailed;
-  }
-  printf(" %d cases passed, %d failed\n\n", numPassed, numFailed);
-  EXPECT_EQ(0u, numFailed);
-}
-
-void TestPart1()
-{
-  printf("Test Part1: Character by character test\n");
-
-  uint32_t i = 0;
-  uint32_t numFailed = 0;
-  uint32_t numPassed = 0;
-  uint32_t codepoint;
-  uint32_t testDataCodepoint = UTF32CodepointFromTestcase(&Part1TestData[i]);
-
-  for (codepoint = 1; codepoint < 0x110000; ++codepoint) {
-    if (testDataCodepoint == codepoint) {
-      if (TestInvariants(&Part1TestData[i]))
-        ++numPassed;
-      else
-        ++numFailed;
-      testDataCodepoint = UTF32CodepointFromTestcase(&Part1TestData[++i]);
-    } else {
-      if (TestUnspecifiedCodepoint(codepoint))
-        ++numPassed;
-      else
-        ++numFailed;
-    }
-  }
-  printf(" %d cases passed, %d failed\n\n", numPassed, numFailed);
-  EXPECT_EQ(0u, numFailed);
-}
-
-void TestPart2()
-{
-  printf("Test Part2: Canonical Order Test\n");
-
-  uint32_t i = 0;
-  uint32_t numFailed = 0;
-  uint32_t numPassed = 0;
-
-  while (Part2TestData[i].c1[0] != 0) {
-    if (TestInvariants(&Part2TestData[i++]))
-      ++numPassed;
-    else
-      ++numFailed;
-  }
-  printf(" %d cases passed, %d failed\n\n", numPassed, numFailed);
-  EXPECT_EQ(0u, numFailed);
-}
-
-void TestPart3()
-{
-  printf("Test Part3: PRI #29 Test\n");
-
-  uint32_t i = 0;
-  uint32_t numFailed = 0;
-  uint32_t numPassed = 0;
-
-  while (Part3TestData[i].c1[0] != 0) {
-    if (TestInvariants(&Part3TestData[i++]))
-      ++numPassed;
-    else
-      ++numFailed;
-  }
-  printf(" %d cases passed, %d failed\n\n", numPassed, numFailed);
-  EXPECT_EQ(0u, numFailed);
-}
-
-TEST(NormalizationTest, Main) {
-  if (sizeof(wchar_t) != 2) {
-    printf("This test can only be run where sizeof(wchar_t) == 2\n");
-    return;
-  }
-  if (strlen(versionText) == 0) {
-    printf("No testcases: to run the tests generate the header file using\n");
-    printf(" perl genNormalizationData.pl\n");
-    printf("in intl/unichar/tools and rebuild\n");
-    return;
-  }
-
-  printf("NormalizationTest: test nsIUnicodeNormalizer. UCD version: %s\n",
-         versionText);
-
-  normalizer = nullptr;
-  nsresult res;
-  res = CallGetService(kUnicodeNormalizerCID, &normalizer);
-
-  ASSERT_FALSE(NS_FAILED(res)) << "GetService failed";
-  ASSERT_NE(nullptr, normalizer);
-
-  TestPart0();
-  TestPart1();
-  TestPart2();
-  TestPart3();
-
-  NS_RELEASE(normalizer);
-}
deleted file mode 100644
--- a/intl/unicharutil/tests/genNormalizationData.pl
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/perl 
-#
-# 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/.
-
-open ( TEXTFILE , "< NormalizationTest.txt")
-    || die "Cannot find NormalizationTest.txt. The latest version should be available from\n http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt\n";
-
-open ( OUT , "> NormalizationData.h")
-#open ( OUT , "> test.txt")
-    || die "Cannot create output file NormalizationData.h\n";
-
-$mpl = <<END_OF_MPL;
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* 
-    DO NOT EDIT THIS DOCUMENT !!! THIS DOCUMENT IS GENERATED BY
-    mozilla/intl/unicharutil/tools/genNormalizationData.pl
- */
-END_OF_MPL
-
-print OUT $mpl;
-
-# XXX This code assumes that wchar_t is 16-bit unsigned, which is currently
-#      true on Windows, Linux and Mac (with |g++ -fshort-wchar|).
-#      To make it work where that assumption doesn't hold, one could generate
-#      one huge array containing all the strings as 16-bit units (including
-#      the 0 terminator) and initialize the array of testcaseLine with pointers
-#      into the huge array.
-
-while(<TEXTFILE>) {
-    chop;
-    if (/^# NormalizationTest-(.+)\.txt/) {
-	print OUT "static char versionText[] = \"$1\";\n";
-    } elsif (/^\@Part(.)/) {
-	if ($1 != "0") {
-	    print OUT "  {\n";
-	    print OUT "    L\"\",\n";
-	    print OUT "    L\"\",\n";
-	    print OUT "    L\"\",\n";
-	    print OUT "    L\"\",\n";
-	    print OUT "    L\"\",\n";
-	    print OUT "    \"\",\n";
-	    print OUT "  },\n";
-	    print OUT "};\n";
-	}
-	print OUT "\n";
-	print OUT "static testcaseLine Part$1TestData[] = \n";
-	print OUT "{\n";
-    } else {
-	unless (/^\#/) {
-	    @cases = split(/;/ , $_);
-	    print OUT "  {\n";
-	    for ($case = 0; $case < 5; ++$case) {
-		$c = $cases[$case];
-		print OUT "    L\"";
-		@codepoints = split(/ / , $c);
-		foreach (@codepoints) {
-		    $cp = hex($_);
-		    if ($cp < 0x10000) {
-                      # BMP codepoint
-			printf OUT "\\x%04X", $cp;
-		    } else {
-                      # non-BMP codepoint, convert to surrogate pair
-			printf OUT "\\x%04X\\x%04X",
-			           ($cp >> 10) + 0xD7C0,
-			           ($cp & 0x03FF) | 0xDC00;
-		    }
-		}
-		print OUT "\",\n";
-	    }
-	    $description = $cases[10];
-	    $description =~ s/^ \) //;
-	    print OUT "    \"$description\"\n";
-	    print OUT "  },\n";
-	}
-    }
-}
- 
-print OUT "  {\n";
-print OUT "    L\"\",\n";
-print OUT "    L\"\",\n";
-print OUT "    L\"\",\n";
-print OUT "    L\"\",\n";
-print OUT "    L\"\",\n";
-print OUT "    \"\",\n";
-print OUT "  },\n";
-print OUT "};\n";
-close (OUT);
-close (TEXTFILE);
deleted file mode 100755
--- a/intl/unicharutil/tests/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- 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/.
-
-SOURCES += [
-    'NormalizationTest.cpp',
-]
-
-FINAL_LIBRARY = 'xul-gtest'
deleted file mode 100755
--- a/intl/unicharutil/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[DEFAULT]
-head = 
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -21,16 +21,18 @@
 
 #ifdef JS_OOM_DO_BACKTRACES
 #include <execinfo.h>
 #include <stdio.h>
 #endif
 
 #include "jstypes.h"
 
+#include "mozmemory.h"
+
 /* The public JS engine namespace. */
 namespace JS {}
 
 /* The mozilla-shared reusable template/utility namespace. */
 namespace mozilla {}
 
 /* The private JS engine namespace. */
 namespace js {}
@@ -359,55 +361,65 @@ struct MOZ_RAII JS_PUBLIC_DATA(AutoEnter
 
     bool oomEnabled_;
     int64_t oomAfter_;
 #endif
 };
 
 } /* namespace js */
 
+// Malloc allocation.
+
+namespace js {
+
+extern JS_PUBLIC_DATA(arena_id_t) MallocArena;
+
+extern void InitMallocAllocator();
+extern void ShutDownMallocAllocator();
+
+} /* namespace js */
+
 static inline void* js_malloc(size_t bytes)
 {
     JS_OOM_POSSIBLY_FAIL();
-    return malloc(bytes);
+    return moz_arena_malloc(js::MallocArena, bytes);
 }
 
 static inline void* js_calloc(size_t bytes)
 {
     JS_OOM_POSSIBLY_FAIL();
-    return calloc(bytes, 1);
+    return moz_arena_calloc(js::MallocArena, bytes, 1);
 }
 
 static inline void* js_calloc(size_t nmemb, size_t size)
 {
     JS_OOM_POSSIBLY_FAIL();
-    return calloc(nmemb, size);
+    return moz_arena_calloc(js::MallocArena, nmemb, size);
 }
 
 static inline void* js_realloc(void* p, size_t bytes)
 {
     // realloc() with zero size is not portable, as some implementations may
     // return nullptr on success and free |p| for this.  We assume nullptr
     // indicates failure and that |p| is still valid.
     MOZ_ASSERT(bytes != 0);
 
     JS_OOM_POSSIBLY_FAIL();
-    return realloc(p, bytes);
+    return moz_arena_realloc(js::MallocArena, p, bytes);
 }
 
 static inline void js_free(void* p)
 {
+    // TODO: This should call |moz_arena_free(js::MallocArena, p)| but we
+    // currently can't enforce that all memory freed here was allocated by
+    // js_malloc().
     free(p);
 }
 
-static inline char* js_strdup(const char* s)
-{
-    JS_OOM_POSSIBLY_FAIL();
-    return strdup(s);
-}
+JS_PUBLIC_API(char*) js_strdup(const char* s);
 #endif/* JS_USE_CUSTOM_ALLOCATOR */
 
 #include <new>
 
 /*
  * Low-level memory management in SpiderMonkey:
  *
  *  ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -2267,16 +2267,17 @@ PerformPromiseRace(JSContext *cx, JS::Fo
         // Step i.
         if (!BlockOnPromise(cx, nextPromise, promiseObj, resolveFunVal, rejectFunVal))
             return false;
     }
 
     MOZ_ASSERT_UNREACHABLE("Shouldn't reach the end of PerformPromiseRace");
 }
 
+
 // ES2016, Sub-steps of 25.4.4.4 and 25.4.4.5.
 static MOZ_MUST_USE JSObject*
 CommonStaticResolveRejectImpl(JSContext* cx, HandleValue thisVal, HandleValue argVal,
                               ResolutionMode mode)
 {
     // Steps 1-2.
     if (!thisVal.isObject()) {
         const char* msg = mode == ResolveMode
@@ -2327,16 +2328,23 @@ CommonStaticResolveRejectImpl(JSContext*
     {
         return nullptr;
     }
 
     // Step 6 of Resolve, 4 of Reject.
     return promise;
 }
 
+MOZ_MUST_USE JSObject*
+js::PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value)
+{
+    RootedValue C(cx, ObjectValue(*constructor));
+    return CommonStaticResolveRejectImpl(cx, C, value, ResolveMode);
+}
+
 /**
  * ES2016, 25.4.4.4, Promise.reject.
  */
 bool
 js::Promise_reject(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedValue thisVal(cx, args.thisv());
@@ -3675,16 +3683,17 @@ static JSObject*
 CreatePromisePrototype(JSContext* cx, JSProtoKey key)
 {
     return GlobalObject::createBlankPrototype(cx, cx->global(), &PromiseObject::protoClass_);
 }
 
 static const JSFunctionSpec promise_methods[] = {
     JS_SELF_HOSTED_FN("catch", "Promise_catch", 1, 0),
     JS_FN("then", Promise_then, 2, 0),
+    JS_SELF_HOSTED_FN("finally", "Promise_finally", 1, 0),
     JS_FS_END
 };
 
 static const JSPropertySpec promise_properties[] = {
     JS_STRING_SYM_PS(toStringTag, "Promise", JSPROP_READONLY),
     JS_PS_END
 };
 
--- a/js/src/builtin/Promise.h
+++ b/js/src/builtin/Promise.h
@@ -119,16 +119,25 @@ GetWaitForAllPromise(JSContext* cx, cons
  * `promise` field that can contain null. That field is only ever used by
  * devtools, which have to treat these reactions specially.
  */
 MOZ_MUST_USE bool
 OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
                     HandleValue onFulfilled, HandleValue onRejected,
                     MutableHandleObject dependent, bool createDependent);
 
+/**
+ * PromiseResolve ( C, x )
+ *
+ * The abstract operation PromiseResolve, given a constructor and a value,
+ * returns a new promise resolved with that value.
+ */
+MOZ_MUST_USE JSObject*
+PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
+
 
 MOZ_MUST_USE PromiseObject*
 CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
 
 MOZ_MUST_USE bool
 AsyncFunctionReturned(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
 
 MOZ_MUST_USE bool
--- a/js/src/builtin/Promise.js
+++ b/js/src/builtin/Promise.js
@@ -2,8 +2,76 @@
  * 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/. */
 
 // ES6, 25.4.5.1.
 function Promise_catch(onRejected) {
     // Steps 1-2.
     return callContentFunction(this.then, this, undefined, onRejected);
 }
+
+// Promise.prototype.finally proposal, stage 3.
+// Promise.prototype.finally ( onFinally )
+function Promise_finally(onFinally) {
+    // Step 1.
+    var promise = this;
+
+    // Step 2.
+    if (!IsObject(promise))
+        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Promise", "finally", "value");
+
+    // Step 3.
+    var C = SpeciesConstructor(promise, GetBuiltinConstructor("Promise"));
+
+    // Step 4.
+    assert(IsConstructor(C), "SpeciesConstructor returns a constructor function");
+
+    // Steps 5-6.
+    var thenFinally, catchFinally;
+    if (!IsCallable(onFinally)) {
+        thenFinally = onFinally;
+        catchFinally = onFinally;
+    } else {
+        // ThenFinally Function.
+        // The parentheses prevent the infering of a function name.
+        (thenFinally) = function(value) {
+            // Steps 1-2 (implicit).
+
+            // Step 3.
+            var result = onFinally();
+
+            // Steps 4-5 (implicit).
+
+            // Step 6.
+            var promise = PromiseResolve(C, result);
+
+            // Step 7.
+            // FIXME: spec issue - "be equivalent to a function that" is not a defined spec term.
+            // https://github.com/tc39/ecma262/issues/933
+
+            // Step 8.
+            return callContentFunction(promise.then, promise, function() { return value; });
+        };
+
+        // CatchFinally Function.
+        (catchFinally) = function(reason) {
+            // Steps 1-2 (implicit).
+
+            // Step 3.
+            var result = onFinally();
+
+            // Steps 4-5 (implicit).
+
+            // Step 6.
+            var promise = PromiseResolve(C, result);
+
+            // Step 7.
+            // FIXME: spec issue - "be equivalent to a function that" is not a defined spec term.
+            // https://github.com/tc39/ecma262/issues/933
+
+            // Step 8.
+            return callContentFunction(promise.then, promise, function() { throw reason; });
+        };
+    }
+
+    // Step 7.
+    return callContentFunction(promise.then, promise, thenFinally, catchFinally);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/rinstructions-no-sse4.js
@@ -0,0 +1,37 @@
+// |jit-test| --no-sse4;
+
+// This test is a fork of dce-with-rinstructions.js. It tests recover
+// instructions which are only executed on pre-SSE4 processors.
+
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+const max = 200;
+
+// Check that we are able to remove the operation inside recover test
+// functions (denoted by "rop..."), when we inline the first version
+// of uceFault, and ensure that the bailout is correct when uceFault
+// is replaced (which cause an invalidation bailout)
+let uceFault = function (i) {
+    if (i > 98)
+        uceFault = function (i) { return true; };
+    return false;
+};
+
+let uceFault_floor_double = eval(
+    uneval(uceFault)
+        .replace('uceFault', 'uceFault_floor_double')
+);
+function rfloor_double(i) {
+    const x = Math.floor(i + (-1 >>> 0));
+    if (uceFault_floor_double(i) || uceFault_floor_double(i))
+        assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */
+    assertRecoveredOnBailout(x, true);
+    return i;
+}
+
+for (let j = 100 - max; j < 100; j++) {
+    with({}){} // Do not Ion-compile this loop.
+    const i = j < 2 ? (Math.abs(j) % 50) + 2 : j;
+    rfloor_double(i);
+}
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -4075,17 +4075,17 @@ AnalyzePoppedThis(JSContext* cx, ObjectG
             // The prototype chain already contains a getter/setter for this
             // property, or type information is too imprecise.
             return true;
         }
 
         // Add the property to the object, being careful not to update type information.
         DebugOnly<unsigned> slotSpan = baseobj->slotSpan();
         MOZ_ASSERT(!baseobj->containsPure(id));
-        if (!NativeObject::addDataProperty(cx, baseobj, id, baseobj->slotSpan(), JSPROP_ENUMERATE))
+        if (!NativeObject::addDataProperty(cx, baseobj, id, SHAPE_INVALID_SLOT, JSPROP_ENUMERATE))
             return false;
         MOZ_ASSERT(baseobj->slotSpan() != slotSpan);
         MOZ_ASSERT(!baseobj->inDictionaryMode());
 
         Vector<MResumePoint*> callerResumePoints(cx);
         for (MResumePoint* rp = ins->block()->callerResumePoint();
              rp;
              rp = rp->block()->callerResumePoint())
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -853,18 +853,23 @@ IonBuilder::inlineArrayPush(CallInfo& ca
     for (uint32_t i = 0; i < callInfo.argc(); i++) {
         MDefinition* value = callInfo.getArg(i);
         if (toDouble) {
             MInstruction* valueDouble = MToDouble::New(alloc(), value);
             current->add(valueDouble);
             value = valueDouble;
         }
 
-        if (needsPostBarrier(value))
-            current->add(MPostWriteBarrier::New(alloc(), obj, value));
+        if (needsPostBarrier(value)) {
+            MInstruction* elements = MElements::New(alloc(), obj);
+            current->add(elements);
+            MInstruction* initLength = MInitializedLength::New(alloc(), elements);
+            current->add(initLength);
+            current->add(MPostWriteElementBarrier::New(alloc(), obj, value, initLength));
+        }
 
         ins = MArrayPush::New(alloc(), obj, value);
         current->add(ins);
 
         if (callInfo.argc() > 1) {
             // Restore that call stack and the array length.
             MOZ_TRY(resumeAt(ins, pc));
             ins->resumePoint()->addStore(alloc(), truncate, lastRp);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -7012,16 +7012,17 @@ class MMathFunction
     void computeRange(TempAllocator& alloc) override;
     MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
     bool canRecoverOnBailout() const override {
         if (input()->type() == MIRType::SinCosDouble)
             return false;
         switch(function_) {
           case Sin:
           case Log:
+          case Floor:
           case Round:
             return true;
           default:
             return false;
         }
     }
 
     ALLOW_CLONE(MMathFunction)
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -957,16 +957,19 @@ RHypot::recover(JSContext* cx, SnapshotI
     return true;
 }
 
 bool
 MMathFunction::writeRecoverData(CompactBufferWriter& writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     switch (function_) {
+      case Floor:
+        writer.writeUnsigned(uint32_t(RInstruction::Recover_Floor));
+        return true;
       case Round:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
         return true;
       case Sin:
       case Log:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_MathFunction));
         writer.writeByte(function_);
         return true;
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -686,19 +686,17 @@ PostWriteElementBarrier(JSRuntime* rt, J
 {
     AutoUnsafeCallWithABI unsafe;
 
     MOZ_ASSERT(!IsInsideNursery(obj));
 
     if (InBounds == IndexInBounds::Yes) {
         MOZ_ASSERT(uint32_t(index) < obj->as<NativeObject>().getDenseInitializedLength());
     } else {
-        if (MOZ_UNLIKELY(!obj->is<NativeObject>()) ||
-            uint32_t(index) >= obj->as<NativeObject>().getDenseInitializedLength())
-        {
+        if (MOZ_UNLIKELY(!obj->is<NativeObject>() || index < 0)) {
             rt->gc.storeBuffer().putWholeCell(obj);
             return;
         }
     }
 
     NativeObject* nobj = &obj->as<NativeObject>();
     if (nobj->isInWholeCellBuffer())
         return;
--- a/js/src/jsapi-tests/testHashTable.cpp
+++ b/js/src/jsapi-tests/testHashTable.cpp
@@ -389,22 +389,23 @@ BEGIN_TEST(testHashMapLookupWithDefaultO
     return true;
 }
 
 END_TEST(testHashMapLookupWithDefaultOOM)
 #endif // defined(DEBUG)
 
 BEGIN_TEST(testHashTableMovableEnum)
 {
+    IntSet set;
     CHECK(set.init());
 
     // Exercise returning a hash table Enum object from a function.
 
     CHECK(set.put(1));
-    for (auto e = enumerateSet(); !e.empty(); e.popFront())
+    for (auto e = enumerateSet(set); !e.empty(); e.popFront())
         e.removeFront();
     CHECK(set.count() == 0);
 
     // Test moving an Enum object explicitly.
 
     CHECK(set.put(1));
     CHECK(set.put(2));
     CHECK(set.put(3));
@@ -420,16 +421,14 @@ BEGIN_TEST(testHashTableMovableEnum)
         e2.removeFront();
         e2.popFront();
     }
 
     CHECK(set.count() == 1);
     return true;
 }
 
-IntSet set;
-
-IntSet::Enum enumerateSet()
+IntSet::Enum enumerateSet(IntSet& set)
 {
     return IntSet::Enum(set);
 }
 
 END_TEST(testHashTableMovableEnum)
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -40,16 +40,17 @@ void JSAPITest::uninit()
         JS_LeaveCompartment(cx, nullptr);
         global = nullptr;
     }
     if (cx) {
         JS_EndRequest(cx);
         destroyContext();
         cx = nullptr;
     }
+    msgs.clear();
 }
 
 bool JSAPITest::exec(const char* bytes, const char* filename, int lineno)
 {
     JS::RootedValue v(cx);
     JS::CompileOptions opts(cx);
     opts.setFileAndLine(filename, lineno);
     return JS::Evaluate(cx, opts, bytes, strlen(bytes), &v) ||
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -28,16 +28,17 @@ class JSAPITestString {
   public:
     JSAPITestString() {}
     explicit JSAPITestString(const char* s) { *this += s; }
     JSAPITestString(const JSAPITestString& s) { *this += s; }
 
     const char* begin() const { return chars.begin(); }
     const char* end() const { return chars.end(); }
     size_t length() const { return chars.length(); }
+    void clear() { chars.clearAndFree(); }
 
     JSAPITestString& operator +=(const char* s) {
         if (!chars.append(s, strlen(s)))
             abort();
         return *this;
     }
 
     JSAPITestString& operator +=(const JSAPITestString& s) {
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3863,17 +3863,22 @@ js::DuplicateString(JSContext* cx, const
         return ret;
     PodCopy(ret.get(), s, n);
     return ret;
 }
 
 UniqueChars
 js::DuplicateString(const char* s)
 {
-    return UniqueChars(js_strdup(s));
+    size_t n = strlen(s) + 1;
+    UniqueChars ret(js_pod_malloc<char>(n));
+    if (!ret)
+        return ret;
+    PodCopy(ret.get(), s, n);
+    return ret;
 }
 
 UniqueChars
 js::DuplicateString(const char* s, size_t n)
 {
     UniqueChars ret(js_pod_malloc<char>(n + 1));
     if (!ret)
         return nullptr;
@@ -3894,16 +3899,22 @@ js::DuplicateString(const char16_t* s, s
     UniqueTwoByteChars ret(js_pod_malloc<char16_t>(n + 1));
     if (!ret)
         return nullptr;
     PodCopy(ret.get(), s, n);
     ret[n] = 0;
     return ret;
 }
 
+JS_PUBLIC_API(char*)
+js_strdup(const char* s)
+{
+    return DuplicateString(s).release();
+}
+
 template <typename CharT>
 const CharT*
 js_strchr_limit(const CharT* s, char16_t c, const CharT* limit)
 {
     while (s < limit) {
         if (*s == c)
             return s;
         s++;
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -165,16 +165,30 @@ ResetSimulatedInterrupt()
     maxInterruptChecks = UINT64_MAX;
     interruptCheckFailAlways = false;
 }
 
 } // namespace oom
 } // namespace js
 #endif // defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
 
+JS_PUBLIC_DATA(arena_id_t) js::MallocArena;
+
+void
+js::InitMallocAllocator()
+{
+    MallocArena = moz_create_arena();
+}
+
+void
+js::ShutDownMallocAllocator()
+{
+    moz_dispose_arena(MallocArena);
+}
+
 JS_PUBLIC_API(void)
 JS_Assert(const char* s, const char* file, int ln)
 {
     MOZ_ReportAssertionFailure(s, file, ln);
     MOZ_CRASH();
 }
 
 #ifdef __linux__
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3988,16 +3988,18 @@ KillWorkerThreads(JSContext* cx)
             AutoLockWorkerThreads alwt;
             if (workerThreads.empty())
                 break;
             thread = workerThreads.popCopy();
         }
         thread->join();
     }
 
+    workerThreads.clearAndFree();
+
     js_delete(workerThreadsLock);
     workerThreadsLock = nullptr;
 
     js_delete(cooperationState);
     cooperationState = nullptr;
 }
 
 static void
@@ -4924,22 +4926,22 @@ NestedShell(JSContext* cx, unsigned argc
     AutoCStringVector argv(cx);
 
     // The first argument to the shell is its path, which we assume is our own
     // argv[0].
     if (sArgc < 1) {
         JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_NESTED_FAIL);
         return false;
     }
-    if (!argv.append(strdup(sArgv[0])))
+    if (!argv.append(js_strdup(sArgv[0])))
         return false;
 
     // Propagate selected flags from the current shell
     for (unsigned i = 0; i < sPropagatedFlags.length(); i++) {
-        char* cstr = strdup(sPropagatedFlags[i]);
+        char* cstr = js_strdup(sPropagatedFlags[i]);
         if (!cstr || !argv.append(cstr))
             return false;
     }
 
     // The arguments to nestedShell are stringified and append to argv.
     RootedString str(cx);
     for (unsigned i = 0; i < args.length(); i++) {
         str = ToString(cx, args[i]);
@@ -8626,16 +8628,17 @@ main(int argc, char** argv, char** envp)
 {
     PreInit();
 
     auto shutdownBufferStreams = MakeScopeExit([] {
         auto state = bufferStreamState.lock();
         state->shutdown = true;
         while (!state->jobs.empty())
             state.wait(/* jobs empty */);
+        state->jobs.clearAndFree();
     });
 
     sArgc = argc;
     sArgv = argv;
 
     int result;
 
 #ifdef HAVE_SETLOCALE
@@ -8647,16 +8650,22 @@ main(int argc, char** argv, char** envp)
     RCFile rcStdout(stdout);
     rcStdout.acquire();
     RCFile rcStderr(stderr);
     rcStderr.acquire();
 
     SetOutputFile("JS_STDOUT", &rcStdout, &gOutFile);
     SetOutputFile("JS_STDERR", &rcStderr, &gErrFile);
 
+    // Start the engine.
+    if (!JS_Init())
+        return 1;
+
+    auto shutdownEngine = MakeScopeExit([]() { JS_ShutDown(); });
+
     OptionParser op("Usage: {progname} [options] [[script] scriptArgs*]");
 
     op.setDescription("The SpiderMonkey shell provides a command line interface to the "
         "JavaScript engine. Code and file options provided via the command line are "
         "run left to right. If provided, the optional script argument is run after "
         "all options have been processed. Just-In-Time compilation modes may be enabled via "
         "command line options.");
     op.setDescriptionWidth(72);
@@ -8870,20 +8879,16 @@ main(int argc, char** argv, char** envp)
         js::jit::CPUInfo::SetAVXEnabled();
         PropagateFlagToNestedShells("--enable-avx");
     }
 #endif
 
     if (op.getBoolOption("no-threads"))
         js::DisableExtraThreads();
 
-    // Start the engine.
-    if (!JS_Init())
-        return 1;
-
     if (!InitSharedArrayBufferMailbox())
         return 1;
 
     // The fake CPU count must be set before initializing the Runtime,
     // which spins up the thread pool.
     int32_t cpuCount = op.getIntOption("cpu-count"); // What we're really setting
     if (cpuCount < 0)
         cpuCount = op.getIntOption("thread-count");  // Legacy name
@@ -8973,11 +8978,10 @@ main(int argc, char** argv, char** envp)
 
     KillWatchdog(cx);
 
     KillWorkerThreads(cx);
 
     DestructSharedArrayBufferMailbox();
 
     JS_DestroyContext(cx);
-    JS_ShutDown();
     return result;
 }
--- a/js/src/tests/test262-update.py
+++ b/js/src/tests/test262-update.py
@@ -17,17 +17,16 @@ import sys
 from functools import partial
 from itertools import chain, imap
 
 # Skip all tests which use features not supported in SpiderMonkey.
 UNSUPPORTED_FEATURES = set([
                             "tail-call-optimization",
                             "BigInt",
                             "class-fields",
-                            "Promise.prototype.finally",
                             "optional-catch-binding",
                             "regexp-dotall",
                             "regexp-lookbehind",
                             "regexp-named-groups",
                             "regexp-unicode-property-escapes",
                        ])
 RELEASE_OR_BETA = set()
 
--- a/js/src/tests/test262/GIT-INFO
+++ b/js/src/tests/test262/GIT-INFO
@@ -1,7 +1,8 @@
 commit a456b0a390bb0f70b4cb8d38cb5ab0ecb557a851
+Merge: db05f2f 297502b
 Author: Rick Waldron <waldron.rick@gmail.com>
 Date:   Mon Oct 23 11:02:44 2017 -0400
 
     Merge pull request #1310 from bocoup/contributing
     
     CONTRIBUTING.md Fix mistake in test generation section
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally invokes `then` method
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 ---*/
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally invokes `then` method
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 ---*/
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally is a function
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 ---*/
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally is a method on a Promise
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 ---*/
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/length.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/length.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally `length` property
 esid: sec-promise.prototype.finally
 info: >
     ES6 Section 17:
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/name.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/name.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally `name` property
 esid: sec-promise.prototype.finally
 info: >
     ES Section 17:
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: Promise.prototype.finally property descriptor
 esid: sec-promise.prototype.finally
 info: >
     Every other data property described in clauses 18 through 26 and in Annex
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally observably calls .then
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally on a rejected promise can not convert to a fulfillment
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally on a rejected promise can override the rejection reason
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally on a fulfilled promise can not override the resolution value
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: finally observably calls .then
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: >
   Promise.prototype.finally called with a non-object-coercible `this` value
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: >
   Promise.prototype.finally called with a `this` value that does not define a
   callable `then` property
 esid: sec-promise.prototype.finally
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: >
   Promise.prototype.finally called with a `this` value whose `then` property is
   an accessor property that returns an abrupt completion
 esid: sec-promise.prototype.finally
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js
@@ -1,9 +1,8 @@
-// |reftest| skip -- Promise.prototype.finally is not supported
 // Copyright (C) 2017 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Jordan Harband
 description: >
   Promise.prototype.finally called with a `this` value that defines a `then`
   method which returns an abrupt completion.
 esid: sec-promise.prototype.finally
--- a/js/src/tests/test262/harness/shell.js
+++ b/js/src/tests/test262/harness/shell.js
@@ -1,39 +1,8 @@
-// file: timer.js
-// Copyright (C) 2017 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-description: |
-    Used in website/scripts/sth.js
----*/
-//setTimeout is not available, hence this script was loaded
-if (Promise === undefined && this.setTimeout === undefined) {
-  if(/\$DONE()/.test(code))
-    $ERROR("Async test capability is not supported in your test environment");
-}
-
-if (Promise !== undefined && this.setTimeout === undefined) {
-  (function(that) {
-     that.setTimeout = function(callback, delay) {
-      var p = Promise.resolve();
-      var start = Date.now();
-      var end = start + delay;
-      function check(){
-        var timeLeft = end - Date.now();
-        if(timeLeft > 0)
-          p.then(check);
-        else
-          callback();
-      }
-      p.then(check);
-    }
-  })(this);
-}
-
 // file: fnGlobalObject.js
 // Copyright (C) 2017 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
     Produce a reliable global object
 ---*/
 
@@ -565,16 +534,30 @@ var byteConversionValues = {
       -4294967296, // -4294967296
       Infinity,    // Infinity
       -Infinity,   // -Infinity
       0
     ]
   }
 };
 
+// file: nans.js
+// Copyright (C) 2017 Ecma International.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    A collection of NaN values produced from expressions that have been observed
+    to create distinct bit representations on various platforms. These provide a
+    weak basis for assertions regarding the consistent canonicalization of NaN
+    values in Array buffers.
+---*/
+var distinctNaNs = [
+  0/0, Infinity/Infinity, -(0/0), Math.pow(-1, 0.5), -Math.pow(-1, 0.5)
+];
+
 // file: testBuiltInObject.js
 // Copyright 2012 Mozilla Corporation. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
     A function used to assert the correctness of built-in objects.
 ---*/
 
@@ -694,36 +677,45 @@ function testBuiltInObject(obj, isFuncti
   if (isFunction && !isConstructor && obj.hasOwnProperty("prototype")) {
     $ERROR("Built-in functions that aren't constructors must not have a prototype property.");
   }
 
   // passed the complete test!
   return true;
 }
 
-// file: promiseHelper.js
+// file: timer.js
 // Copyright (C) 2017 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
-    Check that an array contains a numeric sequence starting at 1
-    and incrementing by 1 for each entry in the array. Used by
-    Promise tests to assert the order of execution in deep Promise
-    resolution pipelines.
+    Used in website/scripts/sth.js
 ---*/
+//setTimeout is not available, hence this script was loaded
+if (Promise === undefined && this.setTimeout === undefined) {
+  if(/\$DONE()/.test(code))
+    $ERROR("Async test capability is not supported in your test environment");
+}
 
-function checkSequence(arr, message) {
-  arr.forEach(function(e, i) {
-    if (e !== (i+1)) {
-      $ERROR((message ? message : "Steps in unexpected sequence:") +
-             " '" + arr.join(',') + "'");
+if (Promise !== undefined && this.setTimeout === undefined) {
+  (function(that) {
+     that.setTimeout = function(callback, delay) {
+      var p = Promise.resolve();
+      var start = Date.now();
+      var end = start + delay;
+      function check(){
+        var timeLeft = end - Date.now();
+        if(timeLeft > 0)
+          p.then(check);
+        else
+          callback();
+      }
+      p.then(check);
     }
-  });
-
-  return true;
+  })(this);
 }
 
 // file: proxyTrapsHelper.js
 // Copyright (C) 2017 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
     Used to assert the correctness of object behavior in the presence
@@ -846,29 +838,37 @@ description: |
     ES2015 tail call optimization semantics.
 ---*/
 
 
 
 
 var $MAX_ITERATIONS = 100000;
 
-// file: nans.js
+// file: promiseHelper.js
 // Copyright (C) 2017 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
-    A collection of NaN values produced from expressions that have been observed
-    to create distinct bit representations on various platforms. These provide a
-    weak basis for assertions regarding the consistent canonicalization of NaN
-    values in Array buffers.
+    Check that an array contains a numeric sequence starting at 1
+    and incrementing by 1 for each entry in the array. Used by
+    Promise tests to assert the order of execution in deep Promise
+    resolution pipelines.
 ---*/
-var distinctNaNs = [
-  0/0, Infinity/Infinity, -(0/0), Math.pow(-1, 0.5), -Math.pow(-1, 0.5)
-];
+
+function checkSequence(arr, message) {
+  arr.forEach(function(e, i) {
+    if (e !== (i+1)) {
+      $ERROR((message ? message : "Steps in unexpected sequence:") +
+             " '" + arr.join(',') + "'");
+    }
+  });
+
+  return true;
+}
 
 // file: detachArrayBuffer.js
 // Copyright (C) 2017 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
     A function used in the process of asserting correctness of TypedArray objects.
 
--- a/js/src/threading/Mutex.cpp
+++ b/js/src/threading/Mutex.cpp
@@ -1,16 +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 "threading/Mutex.h"
 
+#include "js/Initialization.h"
 #include "js/Utility.h"
 
 using namespace js;
 
 #ifdef DEBUG
 
 MOZ_THREAD_LOCAL(js::Mutex::MutexVector*) js::Mutex::HeldMutexStack;
 
@@ -39,16 +40,21 @@ js::Mutex::heldMutexStack()
     HeldMutexStack.set(stack);
   }
   return *stack;
 }
 
 void
 js::Mutex::lock()
 {
+  if (!JS_IsInitialized()) {
+    MutexImpl::lock();
+    return;
+  }
+
   auto& stack = heldMutexStack();
   if (!stack.empty()) {
     const Mutex& prev = *stack.back();
     if (id_.order <= prev.id_.order) {
       fprintf(stderr,
               "Attempt to acquire mutex %s with order %d while holding %s with order %d\n",
               id_.name, id_.order, prev.id_.name, prev.id_.order);
       MOZ_CRASH("Mutex ordering violation");
@@ -60,16 +66,21 @@ js::Mutex::lock()
   AutoEnterOOMUnsafeRegion oomUnsafe;
   if (!stack.append(this))
     oomUnsafe.crash("js::Mutex::lock");
 }
 
 void
 js::Mutex::unlock()
 {
+  if (!JS_IsInitialized()) {
+    MutexImpl::unlock();
+    return;
+  }
+
   auto& stack = heldMutexStack();
   MOZ_ASSERT(stack.back() == this);
   MutexImpl::unlock();
   stack.popBack();
 }
 
 bool
 js::Mutex::ownedByCurrentThread() const
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -807,17 +807,17 @@ GlobalObject::addIntrinsicValue(JSContex
     if (!holder)
         return false;
 
     uint32_t slot = holder->slotSpan();
     RootedShape last(cx, holder->lastProperty());
     Rooted<UnownedBaseShape*> base(cx, last->base()->unowned());
 
     RootedId id(cx, NameToId(name));
-    Rooted<StackShape> child(cx, StackShape(base, id, slot, 0, 0));
+    Rooted<StackShape> child(cx, StackShape(base, id, slot, 0));
     Shape* shape = cx->zone()->propertyTree().getChild(cx, last, child);
     if (!shape)
         return false;
 
     if (!holder->setLastProperty(cx, shape))
         return false;
 
     holder->setSlot(shape->slot(), value);
--- a/js/src/vm/Initialization.cpp
+++ b/js/src/vm/Initialization.cpp
@@ -95,16 +95,18 @@ JS::detail::InitWithFailureDiagnostic(bo
 #endif
 
     RETURN_IF_FAIL(js::TlsContext.init());
 
 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
     RETURN_IF_FAIL(js::oom::InitThreadType());
 #endif
 
+    js::InitMallocAllocator();
+
     RETURN_IF_FAIL(js::Mutex::Init());
 
     RETURN_IF_FAIL(js::wasm::InitInstanceStaticData());
 
     js::gc::InitMemorySubsystem(); // Ensure gc::SystemPageSize() works.
 
     RETURN_IF_FAIL(js::jit::InitProcessExecutableMemory());
 
@@ -165,16 +167,17 @@ JS_ShutDown(void)
 #ifdef JS_TRACE_LOGGING
     js::DestroyTraceLoggerThreadState();
     js::DestroyTraceLoggerGraphState();
 #endif
 
     js::MemoryProtectionExceptionHandler::uninstall();
 
     js::wasm::ShutDownInstanceStaticData();
+    js::wasm::ShutDownProcessStaticData();
 
     js::Mutex::ShutDown();
 
     // The only difficult-to-address reason for the restriction that you can't
     // call JS_Init/stuff/JS_ShutDown multiple times is the Windows PRMJ
     // NowInit initialization code, which uses PR_CallOnce to initialize the
     // PRMJ_Now subsystem.  (For reinitialization to be permitted, we'd need to
     // "reset" the called-once status -- doable, but more trouble than it's
@@ -194,16 +197,18 @@ JS_ShutDown(void)
 
     js::FinishDateTimeState();
 
     if (!JSRuntime::hasLiveRuntimes()) {
         js::wasm::ReleaseBuiltinThunks();
         js::jit::ReleaseProcessExecutableMemory();
     }
 
+    js::ShutDownMallocAllocator();
+
     libraryInitState = InitState::ShutDown;
 }
 
 JS_PUBLIC_API(bool)
 JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, JS_ICUReallocFn reallocFn, JS_ICUFreeFn freeFn)
 {
     MOZ_ASSERT(libraryInitState == InitState::Uninitialized,
                "must call JS_SetICUMemoryFunctions before any other JSAPI "
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -476,40 +476,38 @@ NativeObject::sparsifyDenseElement(JSCon
     if (!obj->maybeCopyElementsForWrite(cx))
         return false;
 
     RootedValue value(cx, obj->getDenseElement(index));
     MOZ_ASSERT(!value.isMagic(JS_ELEMENTS_HOLE));
 
     removeDenseElementForSparseIndex(cx, obj, index);
 
-    uint32_t slot = obj->slotSpan();
-
     RootedId id(cx, INT_TO_JSID(index));
 
     AutoKeepShapeTables keep(cx);
     ShapeTable::Entry* entry = nullptr;
     if (obj->inDictionaryMode()) {
         ShapeTable* table = obj->lastProperty()->ensureTableForDictionary(cx, keep);
         if (!table)
             return false;
         entry = &table->search<MaybeAdding::Adding>(id, keep);
     }
 
     // NOTE: We don't use addDataProperty because we don't want the
     // extensibility check if we're, for example, sparsifying frozen objects..
-    if (!addDataPropertyInternal(cx, obj, id, slot,
-                                 obj->getElementsHeader()->elementAttributes(),
-                                 entry, keep)) {
+    Shape* shape = addDataPropertyInternal(cx, obj, id, SHAPE_INVALID_SLOT,
+                                           obj->getElementsHeader()->elementAttributes(),
+                                           entry, keep);
+    if (!shape) {
         obj->setDenseElementUnchecked(index, value);
         return false;
     }
 
-    MOZ_ASSERT(slot == obj->slotSpan() - 1);
-    obj->initSlot(slot, value);
+    obj->initSlot(shape->slot(), value);
 
     return true;
 }
 
 /* static */ bool
 NativeObject::sparsifyDenseElements(JSContext* cx, HandleNativeObject obj)
 {
     if (!obj->maybeCopyElementsForWrite(cx))
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -842,19 +842,22 @@ class NativeObject : public ShapedObject
      * FIXME: bug 593129 -- slot allocation should be done by object methods
      * after calling object-parameter-free shape methods, avoiding coupling
      * logic across the object vs. shape module wall.
      */
     static bool allocDictionarySlot(JSContext* cx, HandleNativeObject obj, uint32_t* slotp);
     void freeSlot(JSContext* cx, uint32_t slot);
 
   private:
-    static MOZ_ALWAYS_INLINE Shape* getChildProperty(JSContext* cx, HandleNativeObject obj,
-                                                     HandleShape parent,
-                                                     MutableHandle<StackShape> child);
+    static MOZ_ALWAYS_INLINE Shape* getChildDataProperty(JSContext* cx, HandleNativeObject obj,
+                                                         HandleShape parent,
+                                                         MutableHandle<StackShape> child);
+    static MOZ_ALWAYS_INLINE Shape* getChildAccessorProperty(JSContext* cx, HandleNativeObject obj,
+                                                             HandleShape parent,
+                                                             MutableHandle<StackShape> child);
 
   public:
     /* Add a property whose id is not yet in this scope. */
     static MOZ_ALWAYS_INLINE Shape* addDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
                                                     uint32_t slot, unsigned attrs);
 
     static MOZ_ALWAYS_INLINE Shape* addAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
                                                         JSGetterOp getter, JSSetterOp setter,
--- a/js/src/vm/Scope.cpp
+++ b/js/src/vm/Scope.cpp
@@ -110,17 +110,17 @@ NextEnvironmentShape(JSContext* cx, Hand
       case BindingKind::NamedLambdaCallee:
         attrs |= JSPROP_READONLY;
         break;
       default:
         break;
     }
 
     jsid id = NameToId(name->asPropertyName());
-    Rooted<StackShape> child(cx, StackShape(base, id, slot, attrs, 0));
+    Rooted<StackShape> child(cx, StackShape(base, id, slot, attrs));
     return cx->zone()->propertyTree().getChild(cx, shape, child);
 }
 
 static Shape*
 CreateEnvironmentShape(JSContext* cx, BindingIter& bi, const Class* cls,
                        uint32_t numSlots, uint32_t baseShapeFlags)
 {
     RootedShape shape(cx, EmptyEnvironmentShape(cx, cls, numSlots, baseShapeFlags));
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2088,110 +2088,27 @@ intrinsic_ModuleNamespaceExports(JSConte
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     RootedModuleNamespaceObject namespace_(cx, &args[0].toObject().as<ModuleNamespaceObject>());
     args.rval().setObject(namespace_->exports());
     return true;
 }
 
 static bool
-intrinsic_CreatePendingPromise(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 0);
-    JSObject* promise = PromiseObject::createSkippingExecutor(cx);
-    if (!promise)
-        return false;
-    args.rval().setObject(*promise);
-    return true;
-}
-
-static bool
-intrinsic_CreatePromiseResolvedWith(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 1);
-    JSObject* promise = PromiseObject::unforgeableResolve(cx, args[0]);
-    if (!promise)
-        return false;
-    args.rval().setObject(*promise);
-    return true;
-}
-
-static bool
-intrinsic_CreatePromiseRejectedWith(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 1);
-    JSObject* promise = PromiseObject::unforgeableReject(cx, args[0]);
-    if (!promise)
-        return false;
-    args.rval().setObject(*promise);
-    return true;
-}
-
-static bool
-intrinsic_ResolvePromise(JSContext* cx, unsigned argc, Value* vp)
+intrinsic_PromiseResolve(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    Rooted<PromiseObject*> promise(cx, &args[0].toObject().as<PromiseObject>());
-    if (!PromiseObject::resolve(cx, promise, args[1]))
-        return false;
-    args.rval().setUndefined();
-    return true;
-}
-
-static bool
-intrinsic_RejectPromise(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 2);
-    Rooted<PromiseObject*> promise(cx, &args[0].toObject().as<PromiseObject>());
-    if (!PromiseObject::reject(cx, promise, args[1]))
+
+    RootedObject constructor(cx, &args[0].toObject());
+    JSObject* promise = js::PromiseResolve(cx, constructor, args[1]);
+    if (!promise)
         return false;
-    args.rval().setUndefined();
-    return true;
-}
-
-static bool
-intrinsic_CallOriginalPromiseThen(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() >= 2);
-
-    RootedObject promise(cx, &args[0].toObject());
-    Value val = args[1];
-    RootedObject onResolvedObj(cx, val.isUndefined() ? nullptr : val.toObjectOrNull());
-    val = args.get(2);
-    RootedObject onRejectedObj(cx, val.isUndefined() ? nullptr : val.toObjectOrNull());
-
-    JSObject* resultPromise = JS::CallOriginalPromiseThen(cx, promise, onResolvedObj,
-                                                          onRejectedObj);
-    if (!resultPromise)
-        return false;
-    args.rval().setObject(*resultPromise);
-    return true;
-}
-
-static bool
-intrinsic_AddPromiseReactions(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() >= 2);
-
-    RootedObject promise(cx, &args[0].toObject());
-    Value val = args[1];
-    RootedObject onResolvedObj(cx, val.isUndefined() ? nullptr : val.toObjectOrNull());
-    val = args.get(2);
-    RootedObject onRejectedObj(cx, val.isUndefined() ? nullptr : val.toObjectOrNull());
-
-    if (!JS::AddPromiseReactions(cx, promise, onResolvedObj, onRejectedObj))
-        return false;
-    args.rval().setUndefined();
+
+    args.rval().setObject(*promise);
     return true;
 }
 
 // The self-hosting global isn't initialized with the normal set of builtins.
 // Instead, individual C++-implemented functions that're required by
 // self-hosted code are defined as global functions. Accessing these
 // functions via a content compartment's builtins would be unsafe, because
 // content script might have changed the builtins' prototypes' members.
@@ -2604,23 +2521,19 @@ static const JSFunctionSpec intrinsic_fu
     JS_FN("CreateNamespaceBinding", intrinsic_CreateNamespaceBinding, 3, 0),
     JS_FN("InstantiateModuleFunctionDeclarations",
           intrinsic_InstantiateModuleFunctionDeclarations, 1, 0),
     JS_FN("ExecuteModule", intrinsic_ExecuteModule, 1, 0),
     JS_FN("NewModuleNamespace", intrinsic_NewModuleNamespace, 2, 0),
     JS_FN("AddModuleNamespaceBinding", intrinsic_AddModuleNamespaceBinding, 4, 0),
     JS_FN("ModuleNamespaceExports", intrinsic_ModuleNamespaceExports, 1, 0),
 
-    JS_FN("CreatePendingPromise", intrinsic_CreatePendingPromise, 0, 0),
-    JS_FN("CreatePromiseResolvedWith", intrinsic_CreatePromiseResolvedWith, 1, 0),
-    JS_FN("CreatePromiseRejectedWith", intrinsic_CreatePromiseRejectedWith, 1, 0),
-    JS_FN("ResolvePromise", intrinsic_ResolvePromise, 2, 0),
-    JS_FN("RejectPromise", intrinsic_RejectPromise, 2, 0),
-    JS_FN("AddPromiseReactions", intrinsic_AddPromiseReactions, 3, 0),
-    JS_FN("CallOriginalPromiseThen", intrinsic_CallOriginalPromiseThen, 3, 0),
+    JS_FN("IsPromiseObject", intrinsic_IsInstanceOfBuiltin<PromiseObject>, 1, 0),
+    JS_FN("CallPromiseMethodIfWrapped", CallNonGenericSelfhostedMethod<Is<PromiseObject>>, 2, 0),
+    JS_FN("PromiseResolve", intrinsic_PromiseResolve, 2, 0),
 
     JS_FS_END
 };
 
 void
 js::FillSelfHostingCompileOptions(CompileOptions& options)
 {
     /*
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -287,66 +287,59 @@ Shape::replaceLastProperty(JSContext* cx
 }
 
 /*
  * Get or create a property-tree or dictionary child property of |parent|,
  * which must be lastProperty() if inDictionaryMode(), else parent must be
  * one of lastProperty() or lastProperty()->parent.
  */
 /* static */ MOZ_ALWAYS_INLINE Shape*
-NativeObject::getChildProperty(JSContext* cx,
-                               HandleNativeObject obj, HandleShape parent,
-                               MutableHandle<StackShape> child)
+NativeObject::getChildDataProperty(JSContext* cx,
+                                   HandleNativeObject obj, HandleShape parent,
+                                   MutableHandle<StackShape> child)
 {
-    /*
-     * Shared properties have no slot, but slot_ will reflect that of parent.
-     * Unshared properties allocate a slot here but may lose it due to a
-     * JS_ClearScope call.
-     */
-    if (!child.isDataProperty()) {
-        child.setSlot(parent->maybeSlot());
+    MOZ_ASSERT(child.isDataProperty());
+
+    if (child.hasMissingSlot()) {
+        uint32_t slot;
+        if (obj->inDictionaryMode()) {
+            if (!allocDictionarySlot(cx, obj, &slot))
+                return nullptr;
+        } else {
+            slot = obj->slotSpan();
+            MOZ_ASSERT(slot >= JSSLOT_FREE(obj->getClass()));
+            // Objects with many properties are converted to dictionary
+            // mode, so we can't overflow SHAPE_MAXIMUM_SLOT here.
+            MOZ_ASSERT(slot < JSSLOT_FREE(obj->getClass()) + PropertyTree::MAX_HEIGHT);
+            MOZ_ASSERT(slot < SHAPE_MAXIMUM_SLOT);
+        }
+        child.setSlot(slot);
     } else {
-        if (child.hasMissingSlot()) {
-            uint32_t slot;
-            if (obj->inDictionaryMode()) {
-                if (!allocDictionarySlot(cx, obj, &slot))
-                    return nullptr;
-            } else {
-                slot = obj->slotSpan();
-                MOZ_ASSERT(slot >= JSSLOT_FREE(obj->getClass()));
-                // Objects with many properties are converted to dictionary
-                // mode, so we can't overflow SHAPE_MAXIMUM_SLOT here.
-                MOZ_ASSERT(slot < JSSLOT_FREE(obj->getClass()) + PropertyTree::MAX_HEIGHT);
-                MOZ_ASSERT(slot < SHAPE_MAXIMUM_SLOT);
-            }
-            child.setSlot(slot);
-        } else {
-            /*
-             * Slots can only be allocated out of order on objects in
-             * dictionary mode.  Otherwise the child's slot must be after the
-             * parent's slot (if it has one), because slot number determines
-             * slot span for objects with that shape.  Usually child slot
-             * *immediately* follows parent slot, but there may be a slot gap
-             * when the object uses some -- but not all -- of its reserved
-             * slots to store properties.
-             */
-            MOZ_ASSERT(obj->inDictionaryMode() ||
-                       parent->hasMissingSlot() ||
-                       child.slot() == parent->maybeSlot() + 1 ||
-                       (parent->maybeSlot() + 1 < JSSLOT_FREE(obj->getClass()) &&
-                        child.slot() == JSSLOT_FREE(obj->getClass())));
-        }
+        /*
+         * Slots can only be allocated out of order on objects in
+         * dictionary mode.  Otherwise the child's slot must be after the
+         * parent's slot (if it has one), because slot number determines
+         * slot span for objects with that shape.  Usually child slot
+         * *immediately* follows parent slot, but there may be a slot gap
+         * when the object uses some -- but not all -- of its reserved
+         * slots to store properties.
+         */
+        MOZ_ASSERT(obj->inDictionaryMode() ||
+                   parent->hasMissingSlot() ||
+                   child.slot() == parent->maybeSlot() + 1 ||
+                   (parent->maybeSlot() + 1 < JSSLOT_FREE(obj->getClass()) &&
+                    child.slot() == JSSLOT_FREE(obj->getClass())));
     }
 
     if (obj->inDictionaryMode()) {
         MOZ_ASSERT(parent == obj->lastProperty());
-        Shape* shape = child.isAccessorShape() ? Allocate<AccessorShape>(cx) : Allocate<Shape>(cx);
+        Shape* shape = Allocate<Shape>(cx);
         if (!shape)
             return nullptr;
-        if (child.isDataProperty() && child.slot() >= obj->lastProperty()->base()->slotSpan()) {
+        if (child.slot() >= obj->lastProperty()->base()->slotSpan()) {
             if (!obj->setSlotSpan(cx, child.slot() + 1)) {
                 new (shape) Shape(obj->lastProperty()->base()->unowned(), 0);
                 return nullptr;
             }
         }
         shape->initDictionaryShape(child, obj->numFixedSlots(), &obj->shape_);
         return shape;
     }
@@ -358,16 +351,47 @@ NativeObject::getChildProperty(JSContext
     MOZ_ASSERT(shape->parent == parent);
     MOZ_ASSERT_IF(parent != obj->lastProperty(), parent == obj->lastProperty()->parent);
 
     if (!obj->setLastProperty(cx, shape))
         return nullptr;
     return shape;
 }
 
+/* static */ MOZ_ALWAYS_INLINE Shape*
+NativeObject::getChildAccessorProperty(JSContext* cx,
+                                       HandleNativeObject obj, HandleShape parent,
+                                       MutableHandle<StackShape> child)
+{
+    MOZ_ASSERT(!child.isDataProperty());
+
+    // Accessor properties have no slot, but slot_ will reflect that of parent.
+    child.setSlot(parent->maybeSlot());
+
+    if (obj->inDictionaryMode()) {
+        MOZ_ASSERT(parent == obj->lastProperty());
+        Shape* shape = Allocate<AccessorShape>(cx);
+        if (!shape)
+            return nullptr;
+        shape->initDictionaryShape(child, obj->numFixedSlots(), &obj->shape_);
+        return shape;
+    }
+
+    Shape* shape = cx->zone()->propertyTree().inlinedGetChild(cx, parent, child);
+    if (!shape)
+        return nullptr;
+
+    MOZ_ASSERT(shape->parent == parent);
+    MOZ_ASSERT_IF(parent != obj->lastProperty(), parent == obj->lastProperty()->parent);
+
+    if (!obj->setLastProperty(cx, shape))
+        return nullptr;
+    return shape;
+}
+
 /* static */ bool
 js::NativeObject::toDictionaryMode(JSContext* cx, HandleNativeObject obj)
 {
     MOZ_ASSERT(!obj->inDictionaryMode());
     MOZ_ASSERT(cx->isInsideCurrentCompartment(obj));
 
     uint32_t span = obj->slotSpan();
 
@@ -480,20 +504,18 @@ NativeObject::addAccessorPropertyInterna
                                           HandleNativeObject obj, HandleId id,
                                           GetterOp getter, SetterOp setter,
                                           unsigned attrs, ShapeTable::Entry* entry,
                                           const AutoKeepShapeTables& keep)
 {
     AutoCheckShapeConsistency check(obj);
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
-    /*
-     * The code below deals with either converting obj to dictionary mode or
-     * growing an object that's already in dictionary mode.
-     */
+    // The code below deals with either converting obj to dictionary mode or
+    // growing an object that's already in dictionary mode.
     ShapeTable* table = nullptr;
     if (!obj->inDictionaryMode()) {
         if (ShouldConvertToDictionary(obj)) {
             if (!toDictionaryMode(cx, obj))
                 return nullptr;
             table = obj->lastProperty()->maybeTable(keep);
             entry = &table->search<MaybeAdding::Adding>(id, keep);
         }
@@ -506,65 +528,63 @@ NativeObject::addAccessorPropertyInterna
                 return nullptr;
             entry = &table->search<MaybeAdding::Adding>(id, keep);
             MOZ_ASSERT(!entry->shape());
         }
     }
 
     MOZ_ASSERT(!!table == !!entry);
 
-    /* Find or create a property tree node labeled by our arguments. */
+    // Find or create a property tree node labeled by our arguments.
     RootedShape shape(cx);
     {
         RootedShape last(cx, obj->lastProperty());
         Rooted<UnownedBaseShape*> nbase(cx, GetBaseShapeForNewShape(cx, last, id));
         if (!nbase)
             return nullptr;
 
-        Rooted<StackShape> child(cx, StackShape(nbase, id, SHAPE_INVALID_SLOT, attrs, 0));
+        Rooted<StackShape> child(cx, StackShape(nbase, id, SHAPE_INVALID_SLOT, attrs));
         child.updateGetterSetter(getter, setter);
-        shape = getChildProperty(cx, obj, last, &child);
+        shape = getChildAccessorProperty(cx, obj, last, &child);
         if (!shape)
             return nullptr;
     }
 
     MOZ_ASSERT(shape == obj->lastProperty());
 
     if (table) {
-        /* Store the tree node pointer in the table entry for id. */
+        // Store the tree node pointer in the table entry for id.
         entry->setPreservingCollision(shape);
         table->incEntryCount();
 
-        /* Pass the table along to the new last property, namely shape. */
+        // Pass the table along to the new last property, namely shape.
         MOZ_ASSERT(shape->parent->maybeTable(keep) == table);
         shape->parent->handoffTableTo(shape);
     }
 
     return shape;
 }
 
 /* static */ Shape*
 NativeObject::addDataPropertyInternal(JSContext* cx,
                                       HandleNativeObject obj, HandleId id,
                                       uint32_t slot, unsigned attrs,
                                       ShapeTable::Entry* entry, const AutoKeepShapeTables& keep)
 {
     AutoCheckShapeConsistency check(obj);
 
-    /*
-     * The code below deals with either converting obj to dictionary mode or
-     * growing an object that's already in dictionary mode.
-     */
+    // The slot, if any, must be a reserved slot.
+    MOZ_ASSERT(slot == SHAPE_INVALID_SLOT ||
+               slot < JSCLASS_RESERVED_SLOTS(obj->getClass()));
+
+    // The code below deals with either converting obj to dictionary mode or
+    // growing an object that's already in dictionary mode.
     ShapeTable* table = nullptr;
     if (!obj->inDictionaryMode()) {
-        bool stableSlot =
-            (slot == SHAPE_INVALID_SLOT) ||
-            obj->lastProperty()->hasMissingSlot() ||
-            (slot == obj->lastProperty()->maybeSlot() + 1);
-        if (!stableSlot || ShouldConvertToDictionary(obj)) {
+        if (ShouldConvertToDictionary(obj)) {
             if (!toDictionaryMode(cx, obj))
                 return nullptr;
             table = obj->lastProperty()->maybeTable(keep);
             entry = &table->search<MaybeAdding::Adding>(id, keep);
         }
     } else {
         table = obj->lastProperty()->ensureTableForDictionary(cx, keep);
         if (!table)
@@ -574,38 +594,38 @@ NativeObject::addDataPropertyInternal(JS
                 return nullptr;
             entry = &table->search<MaybeAdding::Adding>(id, keep);
             MOZ_ASSERT(!entry->shape());
         }
     }
 
     MOZ_ASSERT(!!table == !!entry);
 
-    /* Find or create a property tree node labeled by our arguments. */
+    // Find or create a property tree node labeled by our arguments.
     RootedShape shape(cx);
     {
         RootedShape last(cx, obj->lastProperty());
         Rooted<UnownedBaseShape*> nbase(cx, GetBaseShapeForNewShape(cx, last, id));
         if (!nbase)
             return nullptr;
 
-        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, attrs, 0));
-        shape = getChildProperty(cx, obj, last, &child);
+        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, attrs));
+        shape = getChildDataProperty(cx, obj, last, &child);
         if (!shape)
             return nullptr;
     }
 
     MOZ_ASSERT(shape == obj->lastProperty());
 
     if (table) {
-        /* Store the tree node pointer in the table entry for id. */
+        // Store the tree node pointer in the table entry for id.
         entry->setPreservingCollision(shape);
         table->incEntryCount();
 
-        /* Pass the table along to the new last property, namely shape. */
+        // Pass the table along to the new last property, namely shape.
         MOZ_ASSERT(shape->parent->maybeTable(keep) == table);
         shape->parent->handoffTableTo(shape);
     }
 
     return shape;
 }
 
 /* static */ Shape*
@@ -648,17 +668,17 @@ NativeObject::addEnumerableDataProperty(
         return nullptr;
 
     Shape* shape;
     if (obj->inDictionaryMode()) {
         uint32_t slot;
         if (!allocDictionarySlot(cx, obj, &slot))
             return nullptr;
 
-        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, JSPROP_ENUMERATE, 0));
+        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, JSPROP_ENUMERATE));
 
         MOZ_ASSERT(last == obj->lastProperty());
         shape = Allocate<Shape>(cx);
         if (!shape)
             return nullptr;
         if (slot >= obj->lastProperty()->base()->slotSpan()) {
             if (MOZ_UNLIKELY(!obj->setSlotSpan(cx, slot + 1))) {
                 new (shape) Shape(obj->lastProperty()->base()->unowned(), 0);
@@ -669,17 +689,17 @@ NativeObject::addEnumerableDataProperty(
     } else {
         uint32_t slot = obj->slotSpan();
         MOZ_ASSERT(slot >= JSSLOT_FREE(obj->getClass()));
         // Objects with many properties are converted to dictionary
         // mode, so we can't overflow SHAPE_MAXIMUM_SLOT here.
         MOZ_ASSERT(slot < JSSLOT_FREE(obj->getClass()) + PropertyTree::MAX_HEIGHT);
         MOZ_ASSERT(slot < SHAPE_MAXIMUM_SLOT);
 
-        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, JSPROP_ENUMERATE, 0));
+        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, JSPROP_ENUMERATE));
         shape = cx->zone()->propertyTree().inlinedGetChild(cx, last, child);
         if (!shape)
             return nullptr;
         if (!obj->setLastProperty(cx, shape))
             return nullptr;
     }
 
     MOZ_ASSERT(shape == obj->lastProperty());
@@ -727,17 +747,17 @@ js::ReshapeForAllocKind(JSContext* cx, S
 
     for (unsigned i = 0; i < ids.length(); i++) {
         id = ids[i];
 
         Rooted<UnownedBaseShape*> nbase(cx, GetBaseShapeForNewShape(cx, newShape, id));
         if (!nbase)
             return nullptr;
 
-        Rooted<StackShape> child(cx, StackShape(nbase, id, i, JSPROP_ENUMERATE, 0));
+        Rooted<StackShape> child(cx, StackShape(nbase, id, i, JSPROP_ENUMERATE));
         newShape = cx->zone()->propertyTree().getChild(cx, newShape, child);
         if (!newShape)
             return nullptr;
     }
 
     return newShape;
 }
 
@@ -778,139 +798,112 @@ AssertValidArrayIndex(NativeObject* obj,
 NativeObject::putDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
                               unsigned attrs)
 {
     MOZ_ASSERT(!JSID_IS_VOID(id));
 
     AutoCheckShapeConsistency check(obj);
     AssertValidArrayIndex(obj, id);
 
-    /*
-     * Search for id in order to claim its entry if table has been allocated.
-     *
-     * Note that we can only try to claim an entry in a table that is thread
-     * local. An object may be thread local *without* its shape being thread
-     * local. The only thread local objects that *also* have thread local
-     * shapes are dictionaries that were allocated/converted thread
-     * locally. Only for those objects we can try to claim an entry in its
-     * shape table.
-     */
+    // Search for id in order to claim its entry if table has been allocated.
     AutoKeepShapeTables keep(cx);
     ShapeTable::Entry* entry;
     RootedShape shape(cx);
     if (!Shape::search<MaybeAdding::Adding>(cx, obj->lastProperty(), id, keep,
                                             shape.address(), &entry))
     {
         return nullptr;
     }
 
     if (!shape) {
-        /*
-         * You can't add properties to a non-extensible object, but you can change
-         * attributes of properties in such objects.
-         */
-        MOZ_ASSERT(obj->nonProxyIsExtensible());
-
+        MOZ_ASSERT(obj->nonProxyIsExtensible(),
+                   "Can't add new property to non-extensible object");
         return addDataPropertyInternal(cx, obj, id, SHAPE_INVALID_SLOT, attrs, entry, keep);
     }
 
-    /* Property exists: search must have returned a valid entry. */
+    // Property exists: search must have returned a valid entry.
     MOZ_ASSERT_IF(entry, !entry->isRemoved());
 
     AssertCanChangeAttrs(shape, attrs);
 
-    /*
-     * If the caller wants to allocate a slot, but doesn't care which slot,
-     * copy the existing shape's slot into slot so we can match shape, if all
-     * other members match.
-     */
+    // If the caller wants to allocate a slot, but doesn't care which slot,
+    // copy the existing shape's slot into slot so we can match shape, if all
+    // other members match.
     bool hadSlot = shape->isDataProperty();
     uint32_t oldSlot = shape->maybeSlot();
     uint32_t slot = hadSlot ? oldSlot : SHAPE_INVALID_SLOT;
 
     Rooted<UnownedBaseShape*> nbase(cx);
     {
         RootedShape shape(cx, obj->lastProperty());
         nbase = GetBaseShapeForNewShape(cx, shape, id);
         if (!nbase)
             return nullptr;
     }
 
-    /*
-     * Now that we've possibly preserved slot, check whether all members match.
-     * If so, this is a redundant "put" and we can return without more work.
-     */
-    if (shape->matchesParamsAfterId(nbase, slot, attrs, 0, nullptr, nullptr))
+    // Now that we've possibly preserved slot, check whether all members match.
+    // If so, this is a redundant "put" and we can return without more work.
+    if (shape->matchesParamsAfterId(nbase, slot, attrs, nullptr, nullptr))
         return shape;
 
-    /*
-     * Overwriting a non-last property requires switching to dictionary mode.
-     * The shape tree is shared immutable, and we can't removeProperty and then
-     * addPropertyInternal because a failure under add would lose data.
-     */
+    // Overwriting a non-last property requires switching to dictionary mode.
+    // The shape tree is shared immutable, and we can't removeProperty and then
+    // addDataPropertyInternal because a failure under add would lose data.
     if (shape != obj->lastProperty() && !obj->inDictionaryMode()) {
         if (!toDictionaryMode(cx, obj))
             return nullptr;
         ShapeTable* table = obj->lastProperty()->maybeTable(keep);
         MOZ_ASSERT(table);
         entry = &table->search<MaybeAdding::NotAdding>(shape->propid(), keep);
         shape = entry->shape();
     }
 
     MOZ_ASSERT_IF(shape->isDataProperty(), shape->slot() == slot);
 
     if (obj->inDictionaryMode()) {
-        /*
-         * Updating some property in a dictionary-mode object. Create a new
-         * shape for the existing property, and also generate a new shape for
-         * the last property of the dictionary (unless the modified property
-         * is also the last property).
-         */
+        // Updating some property in a dictionary-mode object. Create a new
+        // shape for the existing property, and also generate a new shape for
+        // the last property of the dictionary (unless the modified property
+        // is also the last property).
         bool updateLast = (shape == obj->lastProperty());
         shape = NativeObject::replaceWithNewEquivalentShape(cx, obj, shape, nullptr,
                                                             /* accessorShape = */ false);
         if (!shape)
             return nullptr;
         if (!updateLast && !NativeObject::generateOwnShape(cx, obj))
             return nullptr;
 
-        /*
-         * FIXME bug 593129 -- slot allocation and NativeObject *this must move
-         * out of here!
-         */
         if (slot == SHAPE_INVALID_SLOT) {
             if (!allocDictionarySlot(cx, obj, &slot))
                 return nullptr;
         }
 
         if (updateLast)
             shape->base()->adoptUnowned(nbase);
         else
             shape->base_ = nbase;
 
         shape->setSlot(slot);
         shape->attrs = uint8_t(attrs);
         shape->flags = Shape::IN_DICTIONARY;
     } else {
-        /*
-         * Updating the last property in a non-dictionary-mode object. Find an
-         * alternate shared child of the last property's previous shape.
-         */
+        // Updating the last property in a non-dictionary-mode object. Find an
+        // alternate shared child of the last property's previous shape.
         StackBaseShape base(obj->lastProperty()->base());
 
         UnownedBaseShape* nbase = BaseShape::getUnowned(cx, base);
         if (!nbase)
             return nullptr;
 
         MOZ_ASSERT(shape == obj->lastProperty());
 
-        /* Find or create a property tree node labeled by our arguments. */
-        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, attrs, 0));
+        // Find or create a property tree node labeled by our arguments.
+        Rooted<StackShape> child(cx, StackShape(nbase, id, slot, attrs));
         RootedShape parent(cx, shape->parent);
-        shape = getChildProperty(cx, obj, parent, &child);
+        shape = getChildDataProperty(cx, obj, parent, &child);
         if (!shape)
             return nullptr;
     }
 
     MOZ_ASSERT(shape->isDataProperty());
     return shape;
 }
 
@@ -920,89 +913,70 @@ NativeObject::putAccessorProperty(JSCont
 {
     MOZ_ASSERT(!JSID_IS_VOID(id));
 
     AutoCheckShapeConsistency check(obj);
     AssertValidArrayIndex(obj, id);
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
-    /*
-     * Search for id in order to claim its entry if table has been allocated.
-     *
-     * Note that we can only try to claim an entry in a table that is thread
-     * local. An object may be thread local *without* its shape being thread
-     * local. The only thread local objects that *also* have thread local
-     * shapes are dictionaries that were allocated/converted thread
-     * locally. Only for those objects we can try to claim an entry in its
-     * shape table.
-     */
+    // Search for id in order to claim its entry if table has been allocated.
     AutoKeepShapeTables keep(cx);
     ShapeTable::Entry* entry;
     RootedShape shape(cx);
     if (!Shape::search<MaybeAdding::Adding>(cx, obj->lastProperty(), id, keep,
                                             shape.address(), &entry))
     {
         return nullptr;
     }
 
     if (!shape) {
-        /*
-         * You can't add properties to a non-extensible object, but you can change
-         * attributes of properties in such objects.
-         */
-        MOZ_ASSERT(obj->nonProxyIsExtensible());
-
+        MOZ_ASSERT(obj->nonProxyIsExtensible(),
+                   "Can't add new property to non-extensible object");
         return addAccessorPropertyInternal(cx, obj, id, getter, setter, attrs, entry, keep);
     }
 
-    /* Property exists: search must have returned a valid entry. */
+    // Property exists: search must have returned a valid entry.
     MOZ_ASSERT_IF(entry, !entry->isRemoved());
 
     AssertCanChangeAttrs(shape, attrs);
 
     bool hadSlot = shape->isDataProperty();
     uint32_t oldSlot = shape->maybeSlot();
 
     Rooted<UnownedBaseShape*> nbase(cx);
     {
         RootedShape shape(cx, obj->lastProperty());
         nbase = GetBaseShapeForNewShape(cx, shape, id);
         if (!nbase)
             return nullptr;
     }
 
-    /*
-     * Now that we've possibly preserved slot, check whether all members match.
-     * If so, this is a redundant "put" and we can return without more work.
-     */
-    if (shape->matchesParamsAfterId(nbase, SHAPE_INVALID_SLOT, attrs, 0, getter, setter))
+    // Check whether all members match. If so, this is a redundant "put" and we can
+    // return without more work.
+    if (shape->matchesParamsAfterId(nbase, SHAPE_INVALID_SLOT, attrs, getter, setter))
         return shape;
 
-    /*
-     * Overwriting a non-last property requires switching to dictionary mode.
-     * The shape tree is shared immutable, and we can't removeProperty and then
-     * addPropertyInternal because a failure under add would lose data.
-     */
+    // Overwriting a non-last property requires switching to dictionary mode.
+    // The shape tree is shared immutable, and we can't removeProperty and then
+    // addAccessorPropertyInternal because a failure under add would lose data.
     if (shape != obj->lastProperty() && !obj->inDictionaryMode()) {
         if (!toDictionaryMode(cx, obj))
             return nullptr;
         ShapeTable* table = obj->lastProperty()->maybeTable(keep);
         MOZ_ASSERT(table);
         entry = &table->search<MaybeAdding::NotAdding>(shape->propid(), keep);
         shape = entry->shape();
     }
 
     if (obj->inDictionaryMode()) {
-        /*
-         * Updating some property in a dictionary-mode object. Create a new
-         * shape for the existing property, and also generate a new shape for
-         * the last property of the dictionary (unless the modified property
-         * is also the last property).
-         */
+        // Updating some property in a dictionary-mode object. Create a new
+        // shape for the existing property, and also generate a new shape for
+        // the last property of the dictionary (unless the modified property
+        // is also the last property).
         bool updateLast = (shape == obj->lastProperty());
         shape = NativeObject::replaceWithNewEquivalentShape(cx, obj, shape, nullptr,
                                                             /* accessorShape = */ true);
         if (!shape)
             return nullptr;
         if (!updateLast && !NativeObject::generateOwnShape(cx, obj))
             return nullptr;
 
@@ -1015,43 +989,39 @@ NativeObject::putAccessorProperty(JSCont
         shape->attrs = uint8_t(attrs);
         shape->flags = Shape::IN_DICTIONARY | Shape::ACCESSOR_SHAPE;
 
         AccessorShape& accShape = shape->asAccessorShape();
         accShape.rawGetter = getter;
         accShape.rawSetter = setter;
         GetterSetterWriteBarrierPost(&accShape);
     } else {
-        /*
-         * Updating the last property in a non-dictionary-mode object. Find an
-         * alternate shared child of the last property's previous shape.
-         */
+        // Updating the last property in a non-dictionary-mode object. Find an
+        // alternate shared child of the last property's previous shape.
         StackBaseShape base(obj->lastProperty()->base());
 
         UnownedBaseShape* nbase = BaseShape::getUnowned(cx, base);
         if (!nbase)
             return nullptr;
 
         MOZ_ASSERT(shape == obj->lastProperty());
 
-        /* Find or create a property tree node labeled by our arguments. */
-        Rooted<StackShape> child(cx, StackShape(nbase, id, SHAPE_INVALID_SLOT, attrs, 0));
+        // Find or create a property tree node labeled by our arguments.
+        Rooted<StackShape> child(cx, StackShape(nbase, id, SHAPE_INVALID_SLOT, attrs));
         child.updateGetterSetter(getter, setter);
         RootedShape parent(cx, shape->parent);
-        shape = getChildProperty(cx, obj, parent, &child);
+        shape = getChildAccessorProperty(cx, obj, parent, &child);
         if (!shape)
             return nullptr;
     }
 
-    /*
-     * Can't fail now, so free the previous incarnation's slot. But we do not
-     * need to free oldSlot (and must not, as trying to will botch an assertion
-     * in JSObject::freeSlot) if the new last property (shape here) has a
-     * slotSpan that does not cover it.
-     */
+    // Can't fail now, so free the previous incarnation's slot. But we do not
+    // need to free oldSlot (and must not, as trying to will botch an assertion
+    // in NativeObject::freeSlot) if the new last property (shape here) has a
+    // slotSpan that does not cover it.
     if (hadSlot && oldSlot < obj->slotSpan())
         obj->freeSlot(cx, oldSlot);
 
     MOZ_ASSERT(!shape->isDataProperty());
     return shape;
 }
 
 /* static */ Shape*
@@ -1853,18 +1823,17 @@ Shape::fixupShapeTreeAfterMovingGC()
 
         SetterOp setter = key->setter();
         if (key->hasSetterObject())
             setter = SetterOp(MaybeForwarded(key->setterObject()));
 
         StackShape lookup(unowned,
                           const_cast<Shape*>(key)->propidRef(),
                           key->slotInfo & Shape::SLOT_MASK,
-                          key->attrs,
-                          key->flags);
+                          key->attrs);
         lookup.updateGetterSetter(getter, setter);
         e.rekeyFront(lookup, key);
     }
 }
 
 void
 Shape::fixupAfterMovingGC()
 {
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -989,23 +989,23 @@ class Shape : public gc::TenuredCell
     bool hadOverwrite() const {
         return flags & OVERWRITTEN;
     }
 
     void update(GetterOp getter, SetterOp setter, uint8_t attrs);
 
     bool matches(const Shape* other) const {
         return propid_.get() == other->propid_.get() &&
-               matchesParamsAfterId(other->base(), other->maybeSlot(), other->attrs, other->flags,
+               matchesParamsAfterId(other->base(), other->maybeSlot(), other->attrs,
                                     other->getter(), other->setter());
     }
 
     inline bool matches(const StackShape& other) const;
 
-    bool matchesParamsAfterId(BaseShape* base, uint32_t aslot, unsigned aattrs, unsigned aflags,
+    bool matchesParamsAfterId(BaseShape* base, uint32_t aslot, unsigned aattrs,
                               GetterOp rawGetter, SetterOp rawSetter) const
     {
         return base->unowned() == this->base()->unowned() &&
                maybeSlot() == aslot &&
                attrs == aattrs &&
                getter() == rawGetter &&
                setter() == rawSetter;
     }
@@ -1438,24 +1438,24 @@ struct StackShape
     jsid propid;
     GetterOp rawGetter;
     SetterOp rawSetter;
     uint32_t slot_;
     uint8_t attrs;
     uint8_t flags;
 
     explicit StackShape(UnownedBaseShape* base, jsid propid, uint32_t slot,
-                        unsigned attrs, unsigned flags)
+                        unsigned attrs)
       : base(base),
         propid(propid),
         rawGetter(nullptr),
         rawSetter(nullptr),
         slot_(slot),
         attrs(uint8_t(attrs)),
-        flags(uint8_t(flags))
+        flags(0)
     {
         MOZ_ASSERT(base);
         MOZ_ASSERT(!JSID_IS_VOID(propid));
         MOZ_ASSERT(slot <= SHAPE_INVALID_SLOT);
     }
 
     explicit StackShape(Shape* shape)
       : base(shape->base()->unowned()),
@@ -1618,17 +1618,17 @@ Shape::searchLinear(jsid id)
 
     return nullptr;
 }
 
 inline bool
 Shape::matches(const StackShape& other) const
 {
     return propid_.get() == other.propid &&
-           matchesParamsAfterId(other.base, other.slot_, other.attrs, other.flags,
+           matchesParamsAfterId(other.base, other.slot_, other.attrs,
                                 other.rawGetter, other.rawSetter);
 }
 
 Shape*
 ReshapeForAllocKind(JSContext* cx, Shape* shape, TaggedProto proto,
                     gc::AllocKind allocKind);
 
 } // namespace js
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -393,18 +393,20 @@ MakeReplacementTemplateObject(JSContext*
                                                                  TenuredObject));
     if (!obj)
         return nullptr;
 
     RootedId id(cx);
     for (size_t i = 0; i < layout.properties().length(); i++) {
         const UnboxedLayout::Property& property = layout.properties()[i];
         id = NameToId(property.name);
-        if (!NativeObject::addDataProperty(cx, obj, id, i, JSPROP_ENUMERATE))
+        Shape* shape = NativeObject::addDataProperty(cx, obj, id, SHAPE_INVALID_SLOT, JSPROP_ENUMERATE);
+        if (!shape)
             return nullptr;
+        MOZ_ASSERT(shape->slot() == i);
         MOZ_ASSERT(obj->slotSpan() == i + 1);
         MOZ_ASSERT(!obj->inDictionaryMode());
     }
 
     return obj;
 }
 
 /* static */ bool
@@ -480,17 +482,17 @@ UnboxedLayout::makeNativeGroup(JSContext
     if (!shape)
         return false;
 
     // Add shapes for each property, if this is for a plain object.
     for (size_t i = 0; i < layout.properties().length(); i++) {
         const UnboxedLayout::Property& property = layout.properties()[i];
 
         Rooted<StackShape> child(cx, StackShape(shape->base()->unowned(), NameToId(property.name),
-                                                i, JSPROP_ENUMERATE, 0));
+                                                i, JSPROP_ENUMERATE));
         shape = cx->zone()->propertyTree().getChild(cx, shape, child);
         if (!shape)
             return false;
     }
 
     ObjectGroup* nativeGroup =
         ObjectGroupCompartment::makeGroup(cx, &PlainObject::class_, proto,
                                           group->flags() & OBJECT_FLAG_DYNAMIC_MASK);
--- a/js/src/wasm/WasmProcess.cpp
+++ b/js/src/wasm/WasmProcess.cpp
@@ -121,16 +121,23 @@ class ProcessCodeSegmentMap
     }
 
     ~ProcessCodeSegmentMap()
     {
         MOZ_ASSERT(segments1_.empty());
         MOZ_ASSERT(segments2_.empty());
     }
 
+    void freeAll() {
+        MOZ_ASSERT(segments1_.empty());
+        MOZ_ASSERT(segments2_.empty());
+        segments1_.clearAndFree();
+        segments2_.clearAndFree();
+    }
+
     bool insert(const CodeSegment* cs) {
         LockGuard<Mutex> lock(mutatorsMutex_);
 
         size_t index;
         MOZ_ALWAYS_FALSE(BinarySearchIf(*mutableCodeSegments_, 0, mutableCodeSegments_->length(),
                                         CodeSegmentPC(cs->base()), &index));
 
         if (!mutableCodeSegments_->insert(mutableCodeSegments_->begin() + index, cs))
@@ -225,8 +232,14 @@ wasm::LookupCodeSegment(const void* pc)
 }
 
 const Code*
 wasm::LookupCode(const void* pc)
 {
     const CodeSegment* found = LookupCodeSegment(pc);
     return found ? found->code() : nullptr;
 }
+
+void
+wasm::ShutDownProcessStaticData()
+{
+    processCodeSegmentMap.freeAll();
+}
--- a/js/src/wasm/WasmProcess.h
+++ b/js/src/wasm/WasmProcess.h
@@ -46,12 +46,15 @@ extern mozilla::Atomic<bool> CodeExists;
 // via pc in the methods described above.
 
 bool
 RegisterCodeSegment(const CodeSegment* cs);
 
 void
 UnregisterCodeSegment(const CodeSegment* cs);
 
+void
+ShutDownProcessStaticData();
+
 } // namespace wasm
 } // namespace js
 
 #endif // wasm_process_h
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -244,17 +244,17 @@ https://bugzilla.mozilla.org/show_bug.cg
      "flags", "global", "ignoreCase", "multiline", "source", "sticky", "unicode"];
   gConstructorProperties['RegExp'] =
     constructorProps(["input", "lastMatch", "lastParen",
                       "leftContext", "rightContext", "$1", "$2", "$3", "$4",
                       "$5", "$6", "$7", "$8", "$9", "$_", "$&", "$+",
                       "$`", "$'", Symbol.species])
 
   gPrototypeProperties['Promise'] =
-    ["constructor", "catch", "then", Symbol.toStringTag];
+    ["constructor", "catch", "then", "finally", Symbol.toStringTag];
   gConstructorProperties['Promise'] =
     constructorProps(["resolve", "reject", "all", "race", Symbol.species]);
 
   gPrototypeProperties['ArrayBuffer'] =
     ["constructor", "byteLength", "slice", Symbol.toStringTag];
   gConstructorProperties['ArrayBuffer'] =
     constructorProps(["isView", Symbol.species]);
 
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -737,16 +737,17 @@ nsIPresShell::nsIPresShell()
 #endif
 #ifdef DEBUG
     , mDrawEventTargetFrame(nullptr)
 #endif
     , mPaintCount(0)
     , mAutoWeakFrames(nullptr)
     , mCanvasBackgroundColor(NS_RGBA(0,0,0,0))
     , mSelectionFlags(0)
+    , mChangeNestCount(0)
     , mRenderFlags(0)
     , mDidInitialize(false)
     , mIsDestroying(false)
     , mIsReflowing(false)
     , mPaintingSuppressed(false)
     , mIsActive(false)
     , mFrozen(false)
     , mIsFirstPaint(false)
@@ -782,17 +783,16 @@ PresShell::PresShell()
 #endif
   , mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)
   , mCurrentEventFrame(nullptr)
   , mFirstCallbackEventRequest(nullptr)
   , mLastCallbackEventRequest(nullptr)
   , mLastReflowStart(0.0)
   , mLastAnchorScrollPositionY(0)
   , mAPZFocusSequenceNumber(0)
-  , mChangeNestCount(0)
   , mDocumentLoading(false)
   , mIgnoreFrameDestruction(false)
   , mHaveShutDown(false)
   , mLastRootReflowHadUnconstrainedBSize(false)
   , mNoDelayedMouseEvents(false)
   , mNoDelayedKeyEvents(false)
   , mIsDocumentGone(false)
   , mShouldUnsuppressPainting(false)
@@ -3070,20 +3070,19 @@ PresShell::GoToAnchor(const nsAString& a
 
   // Search for an element with a matching "id" attribute
   if (mDocument) {
     content = mDocument->GetElementById(aAnchorName);
   }
 
   // Search for an anchor element with a matching "name" attribute
   if (!content && htmlDoc) {
-    nsCOMPtr<nsIDOMNodeList> list;
     // Find a matching list of named nodes
-    rv = htmlDoc->GetElementsByName(aAnchorName, getter_AddRefs(list));
-    if (NS_SUCCEEDED(rv) && list) {
+    nsCOMPtr<nsIDOMNodeList> list = mDocument->GetElementsByName(aAnchorName);
+    if (list) {
       uint32_t i;
       // Loop through the named nodes looking for the first anchor
       for (i = 0; true; i++) {
         nsCOMPtr<nsIDOMNode> node;
         rv = list->Item(i, getter_AddRefs(node));
         if (!node) {  // End of list
           break;
         }
@@ -4033,35 +4032,33 @@ PresShell::HandlePostedReflowCallbacks(b
    FlushType flushType =
      aInterruptible ? FlushType::InterruptibleLayout : FlushType::Layout;
    if (shouldFlush && !mIsDestroying) {
      FlushPendingNotifications(flushType);
    }
 }
 
 bool
-PresShell::IsSafeToFlush() const
+nsIPresShell::IsSafeToFlush() const
 {
   // Not safe if we are reflowing or in the middle of frame construction
-  bool isSafeToFlush = !mIsReflowing &&
-                         !mChangeNestCount;
-
-  if (isSafeToFlush) {
+  if (mIsReflowing || mChangeNestCount) {
+    return false;
+  }
+
     // Not safe if we are painting
-    nsViewManager* viewManager = GetViewManager();
-    if (viewManager) {
-      bool isPainting = false;
-      viewManager->IsPainting(isPainting);
-      if (isPainting) {
-        isSafeToFlush = false;
-      }
-    }
-  }
-
-  return isSafeToFlush;
+  if (nsViewManager* viewManager = GetViewManager()) {
+    bool isPainting = false;
+    viewManager->IsPainting(isPainting);
+    if (isPainting) {
+      return false;
+    }
+  }
+
+  return true;
 }
 
 
 void
 PresShell::DoFlushPendingNotifications(FlushType aType)
 {
   // by default, flush animations if aType >= FlushType::Style
   mozilla::ChangesToFlush flush(aType, aType >= FlushType::Style);
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -123,17 +123,16 @@ public:
   virtual nsCanvasFrame* GetCanvasFrame() const override;
 
   virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
                                 nsFrameState aBitToAdd,
                                 ReflowRootHandling aRootHandling =
                                   eInferFromBitToAdd) override;
   virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
   virtual void CancelAllPendingReflows() override;
-  virtual bool IsSafeToFlush() const override;
   virtual void DoFlushPendingNotifications(mozilla::FlushType aType) override;
   virtual void DoFlushPendingNotifications(mozilla::ChangesToFlush aType) override;
   virtual void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement) override;
 
   /**
    * Post a callback that should be handled after reflow has finished.
    */
   virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
@@ -852,21 +851,16 @@ protected:
   // when target of pointer event was deleted during executing user handlers.
   nsCOMPtr<nsIContent>      mPointerEventTarget;
 
   // The focus sequence number of the last processed input event
   uint64_t                  mAPZFocusSequenceNumber;
   // The focus information needed for async keyboard scrolling
   FocusTarget               mAPZFocusTarget;
 
-  // This is used to protect ourselves from triggering reflow while in the
-  // middle of frame construction and the like... it really shouldn't be
-  // needed, one hopes, but it is for now.
-  uint16_t                  mChangeNestCount;
-
   bool                      mDocumentLoading : 1;
   bool                      mIgnoreFrameDestruction : 1;
   bool                      mHaveShutDown : 1;
   bool                      mLastRootReflowHadUnconstrainedBSize : 1;
   bool                      mNoDelayedMouseEvents : 1;
   bool                      mNoDelayedKeyEvents : 1;
 
   // We've been disconnected from the document.  We will refuse to paint the
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -536,21 +536,19 @@ public:
                            nsRestyleHint aHint);
 
   // ShadowRoot has APIs that can change styles so we only
   // want to restyle elements in the ShadowRoot and not the whole
   // document.
   virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) = 0;
 
   /**
-   * Determine if it is safe to flush all pending notifications
-   * @param aIsSafeToFlush true if it is safe, false otherwise.
-   *
+   * Determine if it is safe to flush all pending notifications.
    */
-  virtual bool IsSafeToFlush() const = 0;
+  bool IsSafeToFlush() const;
 
   /**
    * Flush pending notifications of the type specified.  This method
    * will not affect the content model; it'll just affect style and
    * frames. Callers that actually want up-to-date presentation (other
    * than the document itself) should probably be calling
    * nsIDocument::FlushPendingNotifications.
    *
@@ -1703,16 +1701,21 @@ protected:
   nscolor                   mCanvasBackgroundColor;
 
   // Used to force allocation and rendering of proportionally more or
   // less pixels in both dimensions.
   mozilla::Maybe<float>     mResolution;
 
   int16_t                   mSelectionFlags;
 
+  // This is used to protect ourselves from triggering reflow while in the
+  // middle of frame construction and the like... it really shouldn't be
+  // needed, one hopes, but it is for now.
+  uint16_t                  mChangeNestCount;
+
   // Flags controlling how our document is rendered.  These persist
   // between paints and so are tied with retained layer pixels.
   // PresShell flushes retained layers when the rendering state
   // changes in a way that prevents us from being able to (usefully)
   // re-use old pixels.
   RenderFlags               mRenderFlags;
   bool                      mDidInitialize : 1;
   bool                      mIsDestroying : 1;
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/849987.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html dir="rtl">
+<head>
+<meta charset="UTF-8">
+</head>
+<body>
+<div style="unicode-bidi: bidi-override;">u&#x0302;&#x0302;</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/963878.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<script>
+
+function repeatManyTimes(s)
+{
+    while (s.length < 0x8000)
+        s = s + s;
+    return s;
+}
+
+function boom()
+{
+    var initialText =
+        "\u062A" + // ARABIC LETTER TEH
+        repeatManyTimes(
+            "\u2029" + // PARAGRAPH SEPARATOR
+            "\u202D" + // LEFT-TO-RIGHT OVERRIDE
+            " "
+        ) +
+        "1"; // THE LONELIEST ASCII CHARACTER
+
+    var textNode = document.createTextNode(initialText);
+    document.getElementById("v").appendChild(textNode);
+    document.documentElement.offsetHeight;
+    textNode.data = "*" + textNode.data;
+}
+
+</script>
+</head>
+
+<body onload="boom();">
+<div id="v" style="display: table-row; font-size: 500%;"></div>
+</body>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -533,16 +533,17 @@ load 840818.html
 load 842132-1.html
 load 842166.html
 load 844529-1.html
 load 847130.xhtml
 load 847208.html
 asserts-if(Android,2) asserts-if(Android&&asyncPan,4) asserts-if(!Android,4) asserts-if(stylo,4) load 847209.html # bug 847368
 load 847211-1.html
 load 849603.html
+load 849987.html
 asserts(0-12) load 850931.html # bug 569193
 load 851396-1.html
 load 854263-1.html
 load 862185.html
 load 862947-1.html
 load 863935.html
 load 866547-1.html
 needs-focus pref(accessibility.browsewithcaret,true) load 868906.html
@@ -558,16 +559,17 @@ asserts(0-3) load 914501.html # bug 1144
 load 914891.html
 load 915475.xhtml
 load 927558.html
 load 943509-1.html
 load 944909-1.html
 load 946167-1.html
 load 947158.html
 load 949932.html
+load 963878.html
 load 964078.html
 load 970710.html
 load 973701-1.xhtml
 load 973701-2.xhtml
 load 986899.html
 load 1001233.html
 load 1001258-1.html
 load 1001994.html
new file mode 100644
--- /dev/null
+++ b/layout/tables/crashtests/750147.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<html><body><table width="1" height="1"><tr><td width="50" height="100%"><div>div</div></td></tr></table></body></html>
new file mode 100644
--- /dev/null
+++ b/layout/tables/crashtests/862624.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+    <body>
+        <table>
+            <tbody>
+                <tr>
+                    <td colspan="0"></td>
+                </tr>
+                <tr>
+                    <td rowspan="5" colspan="900"></td>
+                </tr>
+                <tr>
+                    <td colspan="496"></td>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </body>
+</html>
--- a/layout/tables/crashtests/crashtests.list
+++ b/layout/tables/crashtests/crashtests.list
@@ -145,19 +145,21 @@ load 691824-1.xhtml
 load 695430-1.html
 load 696640-1.html
 load 696640-2.html
 load 705996-1.html
 load 705996-2.html
 load 707622-1.html
 load 710098-1.html
 load 711864-1.html
+pref(font.size.inflation.minTwips,120) load 750147.html
 load 759249-1.html
 load 759249-2.html
 load 814713.html
+load 862624.html
 load 980223.html
 load 1027611-1.html
 load 1031934.html
 load 1144641.html
 load 1183896.html
 load 1223282.html
 load 1223232.html
 load 1243623-1.html
--- a/layout/tools/reftest/globals.jsm
+++ b/layout/tools/reftest/globals.jsm
@@ -20,16 +20,20 @@ for (let [key, val] of Object.entries({
   TYPE_REFTEST_EQUAL: '==',
   TYPE_REFTEST_NOTEQUAL: '!=',
   TYPE_LOAD: 'load',     // test without a reference (just test that it does
                          // not assert, crash, hang, or leak)
   TYPE_SCRIPT: 'script', // test contains individual test results
   TYPE_PRINT: 'print',   // test and reference will be printed to PDF's and
                          // compared structurally
 
+  // keep this in sync with reftest-content.js
+  URL_TARGET_TYPE_TEST: 0,      // first url
+  URL_TARGET_TYPE_REFERENCE: 1, // second url, if any
+
   // The order of these constants matters, since when we have a status
   // listed for a *manifest*, we combine the status with the status for
   // the test by using the *larger*.
   // FIXME: In the future, we may also want to use this rule for combining
   // statuses that are on the same line (rather than making the last one
   // win).
   EXPECTED_PASS: 0,
   EXPECTED_FAIL: 1,
@@ -97,18 +101,18 @@ for (let [key, val] of Object.entries({
       // Known problems...
       KnownFail : 0,
       AssertionKnown: 0,
       Random : 0,
       Skip: 0,
       Slow: 0,
     },
     totalTests: 0,
-    state: undefined,
     currentURL: undefined,
+    currentURLTargetType: undefined,
     testLog: [],
     logLevel: undefined,
     logFile: null,
     logger: undefined,
     server: undefined,
     count: 0,
     assertionCount: 0,
 
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -19,31 +19,31 @@ const NS_GFXINFO_CONTRACTID = "@mozilla.
 const IO_SERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"
 
 // "<!--CLEAR-->"
 const BLANK_URL_FOR_CLEARING = "data:text/html;charset=UTF-8,%3C%21%2D%2DCLEAR%2D%2D%3E";
 
 CU.import("resource://gre/modules/Timer.jsm");
 CU.import("chrome://reftest/content/AsyncSpellCheckTestHelper.jsm");
 CU.import("resource://gre/modules/Services.jsm");
-CU.import('resource://gre/modules/XPCOMUtils.jsm');
 
 var gBrowserIsRemote;
 var gIsWebRenderEnabled;
 var gHaveCanvasSnapshot = false;
 // Plugin layers can be updated asynchronously, so to make sure that all
 // layer surfaces have the right content, we need to listen for explicit
 // "MozPaintWait" and "MozPaintWaitFinished" events that signal when it's OK
 // to take snapshots. We cannot take a snapshot while the number of
 // "MozPaintWait" events fired exceeds the number of "MozPaintWaitFinished"
 // events fired. We count the number of such excess events here. When
 // the counter reaches zero we call gExplicitPendingPaintsCompleteHook.
 var gExplicitPendingPaintCount = 0;
 var gExplicitPendingPaintsCompleteHook;
 var gCurrentURL;
+var gCurrentURLTargetType;
 var gCurrentTestType;
 var gTimeoutHook = null;
 var gFailureTimeout = null;
 var gFailureReason;
 var gAssertionCount = 0;
 
 var gDebug;
 var gVerbose = false;
@@ -52,16 +52,20 @@ var gCurrentTestStartTime;
 var gClearingForAssertionCheck = false;
 
 const TYPE_LOAD = 'load';  // test without a reference (just test that it does
                            // not assert, crash, hang, or leak)
 const TYPE_SCRIPT = 'script'; // test contains individual test results
 const TYPE_PRINT = 'print'; // test and reference will be printed to PDF's and
                             // compared structurally
 
+// keep this in sync with globals.jsm
+const URL_TARGET_TYPE_TEST = 0;      // first url
+const URL_TARGET_TYPE_REFERENCE = 1; // second url, if any
+
 function markupDocumentViewer() {
     return docShell.contentViewer;
 }
 
 function webNavigation() {
     return docShell.QueryInterface(CI.nsIWebNavigation);
 }
 
@@ -119,57 +123,63 @@ function OnInitialLoad()
     addEventListener("load", OnDocumentLoad, true);
 
     addEventListener("MozPaintWait", PaintWaitListener, true);
     addEventListener("MozPaintWaitFinished", PaintWaitFinishedListener, true);
 
     LogInfo("Using browser remote="+ gBrowserIsRemote +"\n");
 }
 
-function SetFailureTimeout(cb, timeout)
+function SetFailureTimeout(cb, timeout, uri)
 {
   var targetTime = Date.now() + timeout;
 
   var wrapper = function() {
     // Timeouts can fire prematurely in some cases (e.g. in chaos mode). If this
     // happens, set another timeout for the remaining time.
     let remainingMs = targetTime - Date.now();
     if (remainingMs > 0) {
       SetFailureTimeout(cb, remainingMs);
     } else {
       cb();
     }
   }
 
+  // Once OnDocumentLoad is called to handle the 'load' event it will update
+  // this error message to reflect what stage of the processing it has reached
+  // as it advances to each stage in turn.
+  gFailureReason = "timed out after " + timeout +
+                   " ms waiting for 'load' event for " + uri;
   gFailureTimeout = setTimeout(wrapper, timeout);
 }
 
-function StartTestURI(type, uri, timeout)
+function StartTestURI(type, uri, uriTargetType, timeout)
 {
     // The GC is only able to clean up compartments after the CC runs. Since
     // the JS ref tests disable the normal browser chrome and do not otherwise
     // create substatial DOM garbage, the CC tends not to run enough normally.
     windowUtils().runNextCollectorTimer();
 
     // Reset gExplicitPendingPaintCount in case there was a timeout or
     // the count is out of sync for some other reason
     if (gExplicitPendingPaintCount != 0) {
         LogWarning("Resetting gExplicitPendingPaintCount to zero (currently " +
                    gExplicitPendingPaintCount + "\n");
         gExplicitPendingPaintCount = 0;
     }
 
     gCurrentTestType = type;
     gCurrentURL = uri;
+    gCurrentURLTargetType = uriTargetType;
 
     gCurrentTestStartTime = Date.now();
     if (gFailureTimeout != null) {
         SendException("program error managing timeouts\n");
     }
-    SetFailureTimeout(LoadFailed, timeout);
+    SetFailureTimeout(LoadFailed, timeout, uri);
 
     LoadURI(gCurrentURL);
 }
 
 function setupFullZoom(contentRootElement) {
     if (!contentRootElement || !contentRootElement.hasAttribute('reftest-zoom'))
         return;
     markupDocumentViewer().fullZoom =
@@ -946,16 +956,17 @@ function RecordResult()
     LogInfo("RecordResult fired");
 
     var currentTestRunTime = Date.now() - gCurrentTestStartTime;
 
     clearTimeout(gFailureTimeout);
     gFailureReason = null;
     gFailureTimeout = null;
     gCurrentURL = null;
+    gCurrentURLTargetType = undefined;
 
     if (gCurrentTestType == TYPE_PRINT) {
         printToPdf(function (status, fileName) {
             SendPrintResult(currentTestRunTime, status, fileName);
             FinishTestItem();
         });
         return;
     }
@@ -1106,43 +1117,45 @@ function RegisterMessageListeners()
         function (m) { RecvLoadScriptTest(m.json.uri, m.json.timeout); }
     );
     addMessageListener(
         "reftest:LoadPrintTest",
         function (m) { RecvLoadPrintTest(m.json.uri, m.json.timeout); }
     );
     addMessageListener(
         "reftest:LoadTest",
-        function (m) { RecvLoadTest(m.json.type, m.json.uri, m.json.timeout); }
+        function (m) { RecvLoadTest(m.json.type, m.json.uri,
+                                    m.json.uriTargetType,
+                                    m.json.timeout); }
     );
     addMessageListener(
         "reftest:ResetRenderingState",
         function (m) { RecvResetRenderingState(); }
     );
 }
 
 function RecvClear()
 {
     gClearingForAssertionCheck = true;
     LoadURI(BLANK_URL_FOR_CLEARING);
 }
 
-function RecvLoadTest(type, uri, timeout)
+function RecvLoadTest(type, uri, uriTargetType, timeout)
 {
-    StartTestURI(type, uri, timeout);
+    StartTestURI(type, uri, uriTargetType, timeout);
 }
 
 function RecvLoadScriptTest(uri, timeout)
 {
-    StartTestURI(TYPE_SCRIPT, uri, timeout);
+    StartTestURI(TYPE_SCRIPT, uri, URL_TARGET_TYPE_TEST, timeout);
 }
 
 function RecvLoadPrintTest(uri, timeout)
 {
-    StartTestURI(TYPE_PRINT, uri, timeout);
+    StartTestURI(TYPE_PRINT, uri, URL_TARGET_TYPE_TEST, timeout);
 }
 
 function RecvResetRenderingState()
 {
     resetZoom();
     resetDisplayportAndViewport();
 }
 
--- a/layout/tools/reftest/reftest.jsm
+++ b/layout/tools/reftest/reftest.jsm
@@ -599,31 +599,35 @@ function StartCurrentTest()
             g.windowUtils.enterChaosMode();
         }
         if (!g.urls[0].needsFocus) {
             Blur();
         }
         var currentTest = g.totalTests - g.urls.length;
         g.containingWindow.document.title = "reftest: " + currentTest + " / " + g.totalTests +
             " (" + Math.floor(100 * (currentTest / g.totalTests)) + "%)";
-        StartCurrentURI(1);
+        StartCurrentURI(URL_TARGET_TYPE_TEST);
     }
 }
 
-function StartCurrentURI(aState)
+function StartCurrentURI(aURLTargetType)
 {
-    g.state = aState;
-    g.currentURL = g.urls[0]["url" + aState].spec;
+    const isStartingRef = (aURLTargetType == URL_TARGET_TYPE_REFERENCE);
+
+    g.currentURL = g.urls[0][isStartingRef ? "url2" : "url1"].spec;
+    g.currentURLTargetType = aURLTargetType;
 
     RestoreChangedPreferences();
 
     var prefs = Components.classes["@mozilla.org/preferences-service;1"].
         getService(Components.interfaces.nsIPrefBranch);
 
-    var prefSettings = g.urls[0]["prefSettings" + aState];
+    const prefSettings =
+      g.urls[0][isStartingRef ? "prefSettings2" : "prefSettings1"];
+
     if (prefSettings.length > 0) {
         var badPref = undefined;
         try {
             prefSettings.forEach(function(ps) {
                 var oldVal;
                 if (ps.type == PREF_BOOLEAN) {
                     try {
                         oldVal = prefs.getBoolPref(ps.name);
@@ -703,17 +707,17 @@ function StartCurrentURI(aState)
                 " (" + Math.floor(100 * (currentTest / g.totalTests)) + "%)\n");
         TestBuffer("START " + g.currentURL);
         var type = g.urls[0].type
         if (TYPE_SCRIPT == type) {
             SendLoadScriptTest(g.currentURL, g.loadTimeout);
         } else if (TYPE_PRINT == type) {
             SendLoadPrintTest(g.currentURL, g.loadTimeout);
         } else {
-            SendLoadTest(type, g.currentURL, g.loadTimeout);
+            SendLoadTest(type, g.currentURL, g.currentURLTargetType, g.loadTimeout);
         }
     }
 }
 
 function DoneTests()
 {
     logger.suiteEnd({'results': g.testResults});
     g.suiteStarted = false
@@ -889,25 +893,25 @@ function RecordResult(testRunTime, error
     if (g.urls[0].type == TYPE_LOAD) {
         ++g.testResults.LoadOnly;
         logger.testStatus(g.urls[0].identifier, "(LOAD ONLY)", "PASS", "PASS");
         g.currentCanvas = null;
         FinishTestItem();
         return;
     }
     if (g.urls[0].type == TYPE_PRINT) {
-        switch (g.state) {
-        case 1:
+        switch (g.currentURLTargetType) {
+        case URL_TARGET_TYPE_TEST:
             // First document has been loaded.
             g.testPrintOutput = typeSpecificResults;
             // Proceed to load the second document.
             CleanUpCrashDumpFiles();
-            StartCurrentURI(2);
+            StartCurrentURI(URL_TARGET_TYPE_REFERENCE);
             break;
-        case 2:
+        case URL_TARGET_TYPE_REFERENCE:
             let pathToTestPdf = g.testPrintOutput;
             let pathToRefPdf = typeSpecificResults;
             comparePdfs(pathToTestPdf, pathToRefPdf, function(error, results) {
                 let expected = g.urls[0].expected;
                 // TODO: We should complain here if results is empty!
                 // (If it's empty, we'll spuriously succeed, regardless of
                 // our expectations)
                 if (error) {
@@ -995,42 +999,42 @@ function RecordResult(testRunTime, error
         if (anyFailed && expected == EXPECTED_PASS) {
             FlushTestBuffer();
         }
 
         FinishTestItem();
         return;
     }
 
-    if (g.urls[0]["prefSettings" + g.state].length == 0 &&
-        g.uriCanvases[g.currentURL]) {
+    const isRecordingRef =
+      (g.currentURLTargetType == URL_TARGET_TYPE_REFERENCE);
+    const prefSettings =
+      g.urls[0][isRecordingRef ? "prefSettings2" : "prefSettings1"];
+
+    if (prefSettings.length == 0 && g.uriCanvases[g.currentURL]) {
         g.currentCanvas = g.uriCanvases[g.currentURL];
     }
     if (g.currentCanvas == null) {
         logger.error(g.currentURL, "program error managing snapshots");
         ++g.testResults.Exception;
     }
-    if (g.state == 1) {
-        g.canvas1 = g.currentCanvas;
-    } else {
-        g.canvas2 = g.currentCanvas;
-    }
+    g[isRecordingRef ? "canvas2" : "canvas1"] = g.currentCanvas;
     g.currentCanvas = null;
 
     ResetRenderingState();
 
-    switch (g.state) {
-        case 1:
+    switch (g.currentURLTargetType) {
+        case URL_TARGET_TYPE_TEST:
             // First document has been loaded.
             // Proceed to load the second document.
 
             CleanUpCrashDumpFiles();
-            StartCurrentURI(2);
+            StartCurrentURI(URL_TARGET_TYPE_REFERENCE);
             break;
-        case 2:
+        case URL_TARGET_TYPE_REFERENCE:
             // Both documents have been loaded. Compare the renderings and see
             // if the comparison result matches the expected result specified
             // in the manifest.
 
             // number of different pixels
             var differences;
             // whether the two renderings match:
             var equal;
@@ -1167,20 +1171,24 @@ function RecordResult(testRunTime, error
         default:
             throw "Unexpected state.";
     }
 }
 
 function LoadFailed(why)
 {
     ++g.testResults.FailedLoad;
-    // Once bug 896840 is fixed, this can go away, but for now it will give log
-    // output that is TBPL starable for bug 789751 and bug 720452.
     if (!why) {
-        logger.error("load failed with unknown reason");
+        // reftest-content.js sets an initial reason before it sets the
+        // timeout that will call us with the currently set reason, so we
+        // should never get here.  If we do then there's a logic error
+        // somewhere.  Perhaps tests are somehow running overlapped and the
+        // timeout for one test is not being cleared before the timeout for
+        // another is set?  Maybe there's some sort of race?
+        logger.error("load failed with unknown reason (we should always have a reason!)");
     }
     logger.testStatus(g.urls[0].identifier, "load failed: " + why, "FAIL", "PASS");
     FlushTestBuffer();
     FinishTestItem();
 }
 
 function RemoveExpectedCrashDumpFiles()
 {
@@ -1538,20 +1546,22 @@ function SendLoadScriptTest(uri, timeout
 }
 
 function SendLoadPrintTest(uri, timeout)
 {
     g.browserMessageManager.sendAsyncMessage("reftest:LoadPrintTest",
                                             { uri: uri, timeout: timeout });
 }
 
-function SendLoadTest(type, uri, timeout)
+function SendLoadTest(type, uri, uriTargetType, timeout)
 {
     g.browserMessageManager.sendAsyncMessage("reftest:LoadTest",
-                                            { type: type, uri: uri, timeout: timeout }
+                                            { type: type, uri: uri,
+                                              uriTargetType: uriTargetType,
+                                              timeout: timeout }
     );
 }
 
 function SendResetRenderingState()
 {
     g.browserMessageManager.sendAsyncMessage("reftest:ResetRenderingState");
 }
 
--- a/mobile/android/chrome/content/about.js
+++ b/mobile/android/chrome/content/about.js
@@ -25,17 +25,17 @@ function init() {
   try {
     let distroId = Services.prefs.getCharPref("distribution.id");
     if (distroId) {
       let distroVersion = Services.prefs.getCharPref("distribution.version");
       let distroIdField = document.getElementById("distributionID");
       distroIdField.textContent = distroId + " - " + distroVersion;
       distroIdField.hidden = false;
 
-      let distroAbout = Services.prefs.getStringPref("distribution.about");
+      let distroAbout = Services.prefs.getComplexValue("distribution.about", Ci.nsISupportsString);
       let distroField = document.getElementById("distributionAbout");
       distroField.textContent = distroAbout;
       distroField.hidden = false;
     }
   } catch (e) {
     // Pref is unset
   }
 
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -230,17 +230,16 @@
 @BINPATH@/components/toolkit_xulstore.xpt
 @BINPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @BINPATH@/components/toolkitremote.xpt
 #endif
 @BINPATH@/components/txtsvc.xpt
 @BINPATH@/components/txmgr.xpt
 @BINPATH@/components/uconv.xpt
-@BINPATH@/components/unicharutil.xpt
 @BINPATH@/components/update.xpt
 @BINPATH@/components/uriloader.xpt
 @BINPATH@/components/urlformatter.xpt
 @BINPATH@/components/webBrowser_core.xpt
 @BINPATH@/components/webbrowserpersist.xpt
 @BINPATH@/components/webextensions.xpt
 @BINPATH@/components/widget.xpt
 @BINPATH@/components/widget_android.xpt
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -159,16 +159,35 @@ union PrefValue {
 enum class PrefType
 {
   Invalid = 0,
   String = 1,
   Int = 2,
   Bool = 3,
 };
 
+#ifdef DEBUG
+const char*
+PrefTypeToString(PrefType aType)
+{
+  switch (aType) {
+    case PrefType::Invalid:
+      return "INVALID";
+    case PrefType::String:
+      return "string";
+    case PrefType::Int:
+      return "int";
+    case PrefType::Bool:
+      return "bool";
+    default:
+      MOZ_CRASH("Unhandled enum value");
+  }
+}
+#endif
+
 // Keep the type of the preference, as well as the flags guiding its behaviour.
 class PrefTypeFlags
 {
 public:
   PrefTypeFlags()
     : mValue(AsInt(PrefType::Invalid))
   {
   }
@@ -974,18 +993,21 @@ pref_HashPref(const char* aKey,
     pref->mKey = ArenaStrdup(aKey, gPrefNameArena);
     memset(&pref->mDefaultPref, 0, sizeof(pref->mDefaultPref));
     memset(&pref->mUserPref, 0, sizeof(pref->mUserPref));
 
   } else if (pref->mPrefFlags.HasDefault() &&
              !pref->mPrefFlags.IsPrefType(aType)) {
     NS_WARNING(
       nsPrintfCString(
-        "Trying to overwrite value of default pref %s with the wrong type!",
-        aKey)
+        "Ignoring attempt to overwrite value of default pref %s (type %s) with "
+        "the wrong type (%s)!",
+        aKey,
+        PrefTypeToString(pref->mPrefFlags.GetPrefType()),
+        PrefTypeToString(aType))
         .get());
 
     return NS_ERROR_UNEXPECTED;
   }
 
   bool valueChanged = false;
   if (aFlags & kPrefSetDefault) {
     if (!pref->mPrefFlags.IsLocked()) {
@@ -2536,16 +2558,30 @@ nsPrefBranch::GetComplexValue(const char
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     relativePref.forget(reinterpret_cast<nsIRelativeFilePref**>(aRetVal));
     return NS_OK;
   }
 
+  if (aType.Equals(NS_GET_IID(nsISupportsString))) {
+    nsCOMPtr<nsISupportsString> theString(
+      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
+
+    if (NS_SUCCEEDED(rv)) {
+      // Debugging to see why we end up with very long strings here with
+      // some addons, see bug 836263.
+      NS_ConvertUTF8toUTF16 wdata(utf8String);
+      theString->SetData(wdata);
+      theString.forget(reinterpret_cast<nsISupportsString**>(aRetVal));
+    }
+    return rv;
+  }
+
   NS_WARNING("nsPrefBranch::GetComplexValue - Unsupported interface type");
   return NS_NOINTERFACE;
 }
 
 nsresult
 nsPrefBranch::CheckSanityOfStringLength(const char* aPrefName,
                                         const nsAString& aValue)
 {
@@ -2667,17 +2703,18 @@ nsPrefBranch::SetComplexValue(const char
     nsAutoCString descriptorString;
     descriptorString.Append('[');
     descriptorString.Append(relativeToKey);
     descriptorString.Append(']');
     descriptorString.Append(relDescriptor);
     return SetCharPrefInternal(aPrefName, descriptorString);
   }
 
-  if (aType.Equals(NS_GET_IID(nsIPrefLocalizedString))) {
+  if (aType.Equals(NS_GET_IID(nsISupportsString)) ||
+      aType.Equals(NS_GET_IID(nsIPrefLocalizedString))) {
     nsCOMPtr<nsISupportsString> theString = do_QueryInterface(aValue);
 
     if (theString) {
       nsString wideString;
 
       rv = theString->GetData(wideString);
       if (NS_SUCCEEDED(rv)) {
         // Check sanity of string length before any lengthy conversion
--- a/modules/libpref/nsIPrefBranch.idl
+++ b/modules/libpref/nsIPrefBranch.idl
@@ -186,16 +186,18 @@ interface nsIPrefBranch : nsISupports
    * Called to get the state of an individual complex preference. A complex
    * preference is a preference which represents an XPCOM object that can not
    * be easily represented using a standard boolean, integer or string value.
    *
    * @param aPrefName The complex preference to get the value of.
    * @param aType     The XPCOM interface that this complex preference
    *                  represents. Interfaces currently supported are:
    *                    - nsIFile
+   *                    - nsISupportsString (UniChar)
+   *                      (deprecated; see getStringPref)
    *                    - nsIPrefLocalizedString (Localized UniChar)
    * @param aValue    The XPCOM object into which to the complex preference 
    *                  value should be retrieved.
    *
    * @throws Error The value does not exist or is the wrong type.
    *
    * @see setComplexValue
    */
--- a/modules/libpref/test/unit/test_defaultValues.js
+++ b/modules/libpref/test/unit/test_defaultValues.js
@@ -31,16 +31,23 @@ function run_test() {
   prefName = "test.default.values.string";
   do_check_throws(function() { ps.getCharPref(prefName); },
                   Cr.NS_ERROR_UNEXPECTED);
   strictEqual(ps.getStringPref(prefName, ""), "");
   strictEqual(ps.getStringPref(prefName, "éèçàê€"), "éèçàê€");
   ps.setStringPref(prefName, "éèçàê€");
   strictEqual(ps.getStringPref(prefName), "éèçàê€");
   strictEqual(ps.getStringPref(prefName, "string"), "éèçàê€");
+  strictEqual(ps.getStringPref(prefName),
+              ps.getComplexValue(prefName, Ci.nsISupportsString).data);
+  let str = Cc["@mozilla.org/supports-string;1"].
+              createInstance(Ci.nsISupportsString);
+  str.data = "ù€ÚîœïŒëøÇ“";
+  ps.setComplexValue(prefName, Ci.nsISupportsString, str);
+  strictEqual(ps.getStringPref(prefName), "ù€ÚîœïŒëøÇ“");
 
   prefName = "test.default.values.float";
   do_check_throws(function() { ps.getFloatPref(prefName); },
                   Cr.NS_ERROR_UNEXPECTED);
   strictEqual(ps.getFloatPref(prefName, 3.5), 3.5);
   strictEqual(ps.getFloatPref(prefName, 0), 0);
   ps.setCharPref(prefName, 1.75);
   strictEqual(ps.getFloatPref(prefName), 1.75);
--- a/modules/libpref/test/unit/test_libPrefs.js
+++ b/modules/libpref/test/unit/test_libPrefs.js
@@ -43,19 +43,19 @@ function run_test() {
     pb.getIntPref(null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.setIntPref(null, 0); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.getCharPref(null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.setCharPref(null, null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
-    pb.getStringPref(null); },  Cr.NS_ERROR_INVALID_ARG);
+    pb.getComplexValue(null, Components.interfaces.nsISupportsString); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
-    pb.setStringPref(null, null); },  Cr.NS_ERROR_INVALID_ARG);
+    pb.setComplexValue(null, Components.interfaces.nsISupportsString, pb); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.clearUserPref(null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.prefHasUserValue(null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.lockPref(null); },  Cr.NS_ERROR_INVALID_ARG);
   do_check_throws(function() {
     pb.prefIsLocked(null); },  Cr.NS_ERROR_INVALID_ARG);
--- a/netwerk/dns/nsIDNService.cpp
+++ b/netwerk/dns/nsIDNService.cpp
@@ -97,24 +97,24 @@ NS_IMETHODIMP nsIDNService::Observe(nsIS
 }
 
 void nsIDNService::prefsChanged(nsIPrefBranch *prefBranch, const char16_t *pref)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mLock.AssertCurrentThreadOwns();
 
   if (!pref || NS_LITERAL_STRING(NS_NET_PREF_IDNBLACKLIST).Equals(pref)) {
-    nsAutoCString blacklist;
-    nsresult rv =
-      prefBranch->GetStringPref(NS_NET_PREF_IDNBLACKLIST, EmptyCString(), 0, blacklist);
-    if (NS_SUCCEEDED(rv)) {
-      CopyUTF8toUTF16(blacklist, mIDNBlacklist);
-    } else {
+    nsCOMPtr<nsISupportsString> blacklist;
+    nsresult rv = prefBranch->GetComplexValue(NS_NET_PREF_IDNBLACKLIST,
+                                              NS_GET_IID(nsISupportsString),
+                                              getter_AddRefs(blacklist));
+    if (NS_SUCCEEDED(rv))
+      blacklist->ToString(getter_Copies(mIDNBlacklist));
+    else
       mIDNBlacklist.Truncate();
-    }
   }
   if (!pref || NS_LITERAL_STRING(NS_NET_PREF_SHOWPUNYCODE).Equals(pref)) {
     bool val;
     if (NS_SUCCEEDED(prefBranch->GetBoolPref(NS_NET_PREF_SHOWPUNYCODE, &val)))
       mShowPunycode = val;
   }
   if (!pref || NS_LITERAL_STRING(NS_NET_PREF_IDNUSEWHITELIST).Equals(pref)) {
     bool val;
--- a/old-configure.in
+++ b/old-configure.in
@@ -1910,17 +1910,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.35, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.34, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_SYSTEM_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS="-I${DIST}/include/nss"
    case "${OS_ARCH}" in
         # Only few platforms have been tested with GYP
--- a/python/mozbuild/mozbuild/backend/cpp_eclipse.py
+++ b/python/mozbuild/mozbuild/backend/cpp_eclipse.py
@@ -735,16 +735,18 @@ org.eclipse.cdt.core.formatter.lineSplit
 org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
 org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
 org.eclipse.cdt.core.formatter.tabulation.char=space
 org.eclipse.cdt.core.formatter.tabulation.size=2
 org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
 """
 
 STATIC_CDT_UI_PREFS="""eclipse.preferences.version=1
+buildConsoleLines=10000
+Console.limitConsoleOutput=false
 ensureNewlineAtEOF=false
 formatter_profile=_Mozilla
 formatter_settings_version=1
 org.eclipse.cdt.ui.formatterprofiles.version=1
 scalability.numberOfLines=15000
 """
 
 NOINDEX_TEMPLATE = """eclipse.preferences.version=1
--- a/python/mozbuild/mozpack/packager/l10n.py
+++ b/python/mozbuild/mozpack/packager/l10n.py
@@ -215,17 +215,18 @@ def _repack(app_finder, l10n_finder, cop
             for p, f in l10n_finder.find(mozpath.join(base, pattern)):
                 if not formatter.contains(p):
                     formatter.add(p, f)
 
     # Resources in `localization` directories are packaged from the source and then
     # if localized versions are present in the l10n dir, we package them as well
     # keeping the source dir resources as a runtime fallback.
     for p, f in l10n_finder.find('**/localization'):
-        formatter.add(p, f)
+        if not formatter.contains(p):
+            formatter.add(p, f)
 
     # Transplant jar preloading information.
     for path, log in app_finder.jarlogs.iteritems():
         assert isinstance(copier[path], Jarrer)
         copier[path].preload([l.replace(locale, l10n_locale) for l in log])
 
 
 def repack(source, l10n, extra_l10n={}, non_resources=[], non_chrome=set()):
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-de7e5e67e878
+NSS_3_34_BETA3
--- a/security/nss/automation/abi-check/expected-report-libnss3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libnss3.so.txt
@@ -0,0 +1,11 @@
+Functions changes summary: 0 Removed, 0 Changed, 4 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+4 Added functions:
+
+  'function SECItem* SEC_CreateSignatureAlgorithmParameters(SECItem*, SECOidTag, SECOidTag, const SECItem*, const SECKEYPrivateKey*)'    {SEC_CreateSignatureAlgorithmParameters@@NSS_3.34}
+  'function SECStatus SEC_DerSignDataWithAlgorithmID(SECItem*, const unsigned char*, int, SECKEYPrivateKey*, SECAlgorithmID*)'    {SEC_DerSignDataWithAlgorithmID@@NSS_3.34}
+  'function SECStatus SEC_SignDataWithAlgorithmID(SECItem*, const unsigned char*, int, SECKEYPrivateKey*, SECAlgorithmID*)'    {SEC_SignDataWithAlgorithmID@@NSS_3.34}
+  'function void SGN_NewContextWithAlgorithmID(SECAlgorithmID*, SECKEYPrivateKey*)'    {SGN_NewContextWithAlgorithmID@@NSS_3.34}
+
+
--- a/security/nss/automation/abi-check/expected-report-libssl3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libssl3.so.txt
@@ -0,0 +1,15 @@
+Functions changes summary: 0 Removed, 1 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+  [C]'function SECStatus SSL_GetChannelInfo(SSLChannelInfo*, PRUintn)' at sslinfo.c:26:1 has some indirect sub-type changes:
+    parameter 1 of type 'SSLChannelInfo*' has sub-type changes:
+      in pointed to type 'typedef SSLChannelInfo' at sslt.h:288:1:
+        underlying type 'struct SSLChannelInfoStr' at sslt.h:229:1 changed:
+          type size changed from 896 to 960 bits
+          2 data member insertions:
+            'SSLNamedGroup SSLChannelInfoStr::originalKeaGroup', at offset 864 (in bits) at sslt.h:281:1
+            'PRBool SSLChannelInfoStr::resumed', at offset 896 (in bits) at sslt.h:284:1
+
+
--- a/security/nss/automation/abi-check/previous-nss-release
+++ b/security/nss/automation/abi-check/previous-nss-release
@@ -1,1 +1,1 @@
-NSS_3_34_BRANCH
+NSS_3_33_BRANCH
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -223,17 +223,18 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
             PORT_FreeArena(arena, PR_FALSE);
             SECKEY_DestroySubjectPublicKeyInfo(spki);
             SECU_PrintError(progName, "unable to create RSA-PSS parameters");
             return SECFailure;
         }
 
         spki->algorithm.parameters.data = NULL;
         rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
-                                   SEC_OID_PKCS1_RSA_PSS_SIGNATURE, params);
+                                   SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
+                                   hashAlgTag == SEC_OID_UNKNOWN ? NULL : params);
         if (rv != SECSuccess) {
             PORT_FreeArena(arena, PR_FALSE);
             SECKEY_DestroySubjectPublicKeyInfo(spki);
             SECU_PrintError(progName, "unable to set algorithm ID");
             return SECFailure;
         }
     }
 
--- a/security/nss/gtests/common/util.h
+++ b/security/nss/gtests/common/util.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef util_h__
 #define util_h__
 
 #include <cassert>
 #include <vector>
 
-static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) {
+std::vector<uint8_t> hex_string_to_bytes(std::string s) {
   std::vector<uint8_t> bytes;
   for (size_t i = 0; i < s.length(); i += 2) {
     bytes.push_back(std::stoul(s.substr(i, 2), nullptr, 16));
   }
   return bytes;
 }
 
 #endif  // util_h__
--- a/security/nss/gtests/pk11_gtest/manifest.mn
+++ b/security/nss/gtests/pk11_gtest/manifest.mn
@@ -6,17 +6,16 @@ CORE_DEPTH = ../..
 DEPTH      = ../..
 MODULE = nss
 
 CPPSRCS = \
       pk11_aeskeywrap_unittest.cc \
       pk11_chacha20poly1305_unittest.cc \
       pk11_curve25519_unittest.cc \
       pk11_ecdsa_unittest.cc \
-      pk11_encrypt_derive_unittest.cc \
       pk11_export_unittest.cc \
       pk11_pbkdf2_unittest.cc \
       pk11_prf_unittest.cc \
       pk11_prng_unittest.cc \
       pk11_rsapss_unittest.cc \
       pk11_der_private_key_import_unittest.cc \
       $(NULL)
 
--- a/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
@@ -11,17 +11,16 @@
       'target_name': 'pk11_gtest',
       'type': 'executable',
       'sources': [
         'pk11_aeskeywrap_unittest.cc',
         'pk11_aes_gcm_unittest.cc',
         'pk11_chacha20poly1305_unittest.cc',
         'pk11_curve25519_unittest.cc',
         'pk11_ecdsa_unittest.cc',
-        'pk11_encrypt_derive_unittest.cc',
         'pk11_pbkdf2_unittest.cc',
         'pk11_prf_unittest.cc',
         'pk11_prng_unittest.cc',
         'pk11_rsapss_unittest.cc',
         'pk11_der_private_key_import_unittest.cc',
         '<(DEPTH)/gtests/common/gtests.cc'
       ],
       'dependencies': [
new file mode 100644
--- /dev/null
+++ b/security/nss/gtests/ssl_gtest/ssl_alths_unittest.cc
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=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 <memory>
+#include <vector>
+#include "ssl.h"
+#include "sslerr.h"
+#include "sslproto.h"
+
+#include "gtest_utils.h"
+#include "tls_connect.h"
+#include "tls_filter.h"
+#include "tls_parser.h"
+
+namespace nss_test {
+
+static const uint32_t kServerHelloVersionAlt = SSL_LIBRARY_VERSION_TLS_1_2;
+static const uint16_t kServerHelloVersionRegular =
+    0x7f00 | TLS_1_3_DRAFT_VERSION;
+
+class AltHandshakeTest : public TlsConnectStreamTls13 {
+ protected:
+  void SetUp() {
+    TlsConnectStreamTls13::SetUp();
+    client_ccs_recorder_ =
+        std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType);
+    server_handshake_recorder_ =
+        std::make_shared<TlsRecordRecorder>(kTlsHandshakeType);
+    server_ccs_recorder_ =
+        std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType);
+    server_hello_recorder_ =
+        std::make_shared<TlsInspectorRecordHandshakeMessage>(
+            kTlsHandshakeServerHello);
+  }
+
+  void SetAltHandshakeTypeEnabled() {
+    client_->SetAltHandshakeTypeEnabled();
+    server_->SetAltHandshakeTypeEnabled();
+  }
+
+  void InstallFilters() {
+    client_->SetPacketFilter(client_ccs_recorder_);
+    auto chain = std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
+        {server_handshake_recorder_, server_ccs_recorder_,
+         server_hello_recorder_}));
+    server_->SetPacketFilter(chain);
+  }
+
+  void CheckServerHelloRecordVersion(uint16_t record_version) {
+    ASSERT_EQ(record_version,
+              server_handshake_recorder_->record(0).header.version());
+  }
+
+  void CheckServerHelloVersion(uint16_t server_hello_version) {
+    uint32_t ver;
+    ASSERT_TRUE(server_hello_recorder_->buffer().Read(0, 2, &ver));
+    ASSERT_EQ(server_hello_version, ver);
+  }
+
+  void CheckForRegularHandshake() {
+    EXPECT_EQ(0U, client_ccs_recorder_->count());
+    EXPECT_EQ(0U, server_ccs_recorder_->count());
+    CheckServerHelloVersion(kServerHelloVersionRegular);
+    CheckServerHelloRecordVersion(SSL_LIBRARY_VERSION_TLS_1_0);
+  }
+
+  void CheckForAltHandshake() {
+    EXPECT_EQ(1U, client_ccs_recorder_->count());
+    EXPECT_EQ(1U, server_ccs_recorder_->count());
+    CheckServerHelloVersion(kServerHelloVersionAlt);
+    CheckServerHelloRecordVersion(SSL_LIBRARY_VERSION_TLS_1_2);
+  }
+
+  std::shared_ptr<TlsRecordRecorder> client_ccs_recorder_;
+  std::shared_ptr<TlsRecordRecorder> server_handshake_recorder_;
+  std::shared_ptr<TlsRecordRecorder> server_ccs_recorder_;
+  std::shared_ptr<TlsInspectorRecordHandshakeMessage> server_hello_recorder_;
+};
+
+TEST_F(AltHandshakeTest, ClientOnly) {
+  client_->SetAltHandshakeTypeEnabled();
+  InstallFilters();
+  Connect();
+  CheckForRegularHandshake();
+}
+
+TEST_F(AltHandshakeTest, ServerOnly) {
+  server_->SetAltHandshakeTypeEnabled();
+  InstallFilters();
+  Connect();
+  CheckForRegularHandshake();
+}
+
+TEST_F(AltHandshakeTest, Enabled) {
+  SetAltHandshakeTypeEnabled();
+  InstallFilters();
+  Connect();
+  CheckForAltHandshake();
+}
+
+TEST_F(AltHandshakeTest, ZeroRtt) {
+  SetAltHandshakeTypeEnabled();
+  SetupForZeroRtt();
+  SetAltHandshakeTypeEnabled();
+  client_->Set0RttEnabled(true);
+  server_->Set0RttEnabled(true);
+
+  InstallFilters();
+
+  ExpectResumption(RESUME_TICKET);
+  ZeroRttSendReceive(true, true);
+  Handshake();
+  ExpectEarlyDataAccepted(true);
+  CheckConnected();
+
+  CheckForAltHandshake();
+}
+
+// Neither client nor server has the extension prior to resumption, so the
+// client doesn't send a CCS before its 0-RTT data.
+TEST_F(AltHandshakeTest, DisabledBeforeZeroRtt) {
+  SetupForZeroRtt();
+  SetAltHandshakeTypeEnabled();
+  client_->Set0RttEnabled(true);
+  server_->Set0RttEnabled(true);
+
+  InstallFilters();
+
+  ExpectResumption(RESUME_TICKET);
+  ZeroRttSendReceive(true, true);
+  Handshake();
+  ExpectEarlyDataAccepted(true);
+  CheckConnected();
+
+  EXPECT_EQ(0U, client_ccs_recorder_->count());
+  EXPECT_EQ(1U, server_ccs_recorder_->count());
+  CheckServerHelloVersion(kServerHelloVersionAlt);
+}
+
+// Both use the alternative in the initial handshake but only the server enables
+// it on resumption.
+TEST_F(AltHandshakeTest, ClientDisabledAfterZeroRtt) {
+  SetAltHandshakeTypeEnabled();
+  SetupForZeroRtt();
+  server_->SetAltHandshakeTypeEnabled();
+  client_->Set0RttEnabled(true);
+  server_->Set0RttEnabled(true);
+
+  InstallFilters();
+
+  ExpectResumption(RESUME_TICKET);
+  ZeroRttSendReceive(true, true);
+  Handshake();
+  ExpectEarlyDataAccepted(true);
+  CheckConnected();
+
+  CheckForRegularHandshake();
+}
+
+// If the alternative handshake isn't negotiated after 0-RTT, and the client has
+// it enabled, it will send a ChangeCipherSpec.  The server chokes on it if it
+// hasn't negotiated the alternative handshake.
+TEST_F(AltHandshakeTest, ServerDisabledAfterZeroRtt) {
+  SetAltHandshakeTypeEnabled();
+  SetupForZeroRtt();
+  client_->SetAltHandshakeTypeEnabled();
+  client_->Set0RttEnabled(true);
+  server_->Set0RttEnabled(true);
+
+  client_->ExpectSendAlert(kTlsAlertEndOfEarlyData);
+  client_->Handshake();  // Send ClientHello (and CCS)
+
+  server_->Handshake();  // Consume the ClientHello, which is OK.
+  client_->ExpectResumption();
+  client_->Handshake();  // Read the server handshake.
+  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
+
+  // Now the server reads the CCS instead of more handshake messages.
+  ExpectAlert(server_, kTlsAlertBadRecordMac);
+  server_->Handshake();
+  EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state());
+  client_->Handshake();  // Consume the alert.
+  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
+}
+
+}  // nss_test
--- a/security/nss/lib/freebl/poly1305.h
+++ b/security/nss/lib/freebl/poly1305.h
@@ -3,18 +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 FREEBL_POLY1305_H_
 #define FREEBL_POLY1305_H_
 
-#include "stddef.h"
-
 typedef unsigned char poly1305_state[512];
 
 /* Poly1305Init sets up |state| so that it can be used to calculate an
  * authentication tag with the one-time key |key|. Note that |key| is a
  * one-time key and therefore there is no `reset' method because that would
  * enable several messages to be authenticated with the same key. */
 extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
 
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -17,19 +17,19 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION "3.35" _NSS_CUSTOMIZED " Beta"
+#define NSS_VERSION "3.34" _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR 3
-#define NSS_VMINOR 35
+#define NSS_VMINOR 34
 #define NSS_VPATCH 0
 #define NSS_VBUILD 0
 #define NSS_BETA PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -416,30 +416,21 @@ static const struct mechanismList mechan
     { CKM_IDEA_ECB, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
     { CKM_IDEA_CBC, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
     { CKM_IDEA_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
     { CKM_IDEA_MAC_GENERAL, { 16, 16, CKF_SN_VR }, PR_TRUE },
     { CKM_IDEA_CBC_PAD, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
 #endif
     /* --------------------- Secret Key Operations ------------------------ */
     { CKM_GENERIC_SECRET_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE },
-    { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
+    { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE },
     { CKM_EXTRACT_KEY_FROM_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_DES3_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_DES3_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_AES_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_AES_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CAMELLIA_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CAMELLIA_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_SEED_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_SEED_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-
     /* ---------------------- SSL Key Derivations ------------------------- */
     { CKM_SSL3_PRE_MASTER_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_FALSE },
     { CKM_SSL3_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE }, PR_FALSE },
     { CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE }, PR_FALSE },
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -1519,17 +1519,18 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSes
             rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
                                     maxout, context->padBuf, context->blockSize);
             if (rv != SECSuccess)
                 return sftk_MapDecryptError(PORT_GetError());
             pPart += padoutlen;
             maxout -= padoutlen;
         }
         /* now save the final block for the next decrypt or the final */
-        PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize],
+        PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen -
+                                                     context->blockSize],
                     context->blockSize);
         context->padDataLength = context->blockSize;
         ulEncryptedPartLen -= context->padDataLength;
     }
 
     /* do it: NOTE: this assumes buf size in is >= buf size out! */
     rv = (*context->update)(context->cipherInfo, pPart, &outlen,
                             maxout, pEncryptedPart, ulEncryptedPartLen);
@@ -6236,53 +6237,16 @@ sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_UL
     else if (kdf == CKD_SHA512_KDF)
         return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                            SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH);
     else
         return CKR_MECHANISM_INVALID;
 }
 
 /*
- *  Handle the derive from a block encryption cipher
- */
-CK_RV
-sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo,
-                   int blockSize, SFTKObject *key, CK_ULONG keySize,
-                   unsigned char *data, CK_ULONG len)
-{
-    /* large enough for a 512-bit key */
-    unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE];
-    SECStatus rv;
-    unsigned int outLen;
-    CK_RV crv;
-
-    if ((len % blockSize) != 0) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (len > SFTK_MAX_DERIVE_KEY_SIZE) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (keySize && (len < keySize)) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (keySize == 0) {
-        keySize = len;
-    }
-
-    rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len);
-    if (rv != SECSuccess) {
-        crv = sftk_MapCryptError(PORT_GetError());
-        return crv;
-    }
-
-    crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize);
-    return crv;
-}
-
-/*
  * SSL Key generation given pre master secret
  */
 #define NUM_MIXERS 9
 static const char *const mixers[NUM_MIXERS] = {
     "A",
     "BB",
     "CCC",
     "DDDD",
@@ -6930,182 +6894,16 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
             }
             MD5_DestroyContext(md5, PR_TRUE);
             SHA1_DestroyContext(sha, PR_TRUE);
             sftk_FreeObject(key);
             key = NULL;
             break;
         }
 
-        case CKM_DES3_ECB_ENCRYPT_DATA:
-        case CKM_DES3_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            unsigned char des3key[MAX_DES3_KEY_SIZE];
-            CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) {
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                mode = NSS_DES_EDE3;
-                iv = NULL;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-            } else {
-                mode = NSS_DES_EDE3_CBC;
-                desEncryptPtr =
-                    (CK_DES_CBC_ENCRYPT_DATA_PARAMS *)
-                        pMechanism->pParameter;
-                iv = desEncryptPtr->iv;
-                data = desEncryptPtr->pData;
-                len = desEncryptPtr->length;
-            }
-            if (att->attrib.ulValueLen == 16) {
-                PORT_Memcpy(des3key, att->attrib.pValue, 16);
-                PORT_Memcpy(des3key + 16, des3key, 8);
-            } else if (att->attrib.ulValueLen == 24) {
-                PORT_Memcpy(des3key, att->attrib.pValue, 24);
-            } else {
-                crv = CKR_KEY_SIZE_RANGE;
-                break;
-            }
-            cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE);
-            PORT_Memset(des3key, 0, 24);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt,
-                                     cipherInfo, 8, key, keySize,
-                                     data, len);
-            DES_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_AES_ECB_ENCRYPT_DATA:
-        case CKM_AES_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) {
-                mode = NSS_AES;
-                iv = NULL;
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-            } else {
-                aesEncryptPtr =
-                    (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
-                mode = NSS_AES_CBC;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue,
-                                           iv, mode, PR_TRUE,
-                                           att->attrib.ulValueLen, 16);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            AES_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_CAMELLIA_ECB_ENCRYPT_DATA:
-        case CKM_CAMELLIA_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) {
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                aesEncryptPtr = NULL;
-                mode = NSS_CAMELLIA;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-                iv = NULL;
-            } else {
-                stringPtr = NULL;
-                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
-                                    pMechanism->pParameter;
-                mode = NSS_CAMELLIA_CBC;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue,
-                                                iv, mode, PR_TRUE,
-                                                att->attrib.ulValueLen);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            Camellia_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_SEED_ECB_ENCRYPT_DATA:
-        case CKM_SEED_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) {
-                mode = NSS_SEED;
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                aesEncryptPtr = NULL;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-                iv = NULL;
-            } else {
-                mode = NSS_SEED_CBC;
-                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
-                                    pMechanism->pParameter;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue,
-                                            iv, mode, PR_TRUE);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            SEED_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
         case CKM_CONCATENATE_BASE_AND_KEY: {
             SFTKObject *newKey;
 
             crv = sftk_DeriveSensitiveCheck(sourceKey, key);
             if (crv != CKR_OK)
                 break;
 
             session = sftk_SessionFromHandle(hSession);
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -12,16 +12,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION "3.35" SOFTOKEN_ECC_STRING " Beta"
+#define SOFTOKEN_VERSION "3.34" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 35
+#define SOFTOKEN_VMINOR 34
 #define SOFTOKEN_VPATCH 0
 #define SOFTOKEN_VBUILD 0
 #define SOFTOKEN_BETA PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -4,19 +4,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 _SOFTOKNT_H_
 #define _SOFTOKNT_H_
 
 #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
-#define DES_BLOCK_SIZE 8     /* bytes */
-#define MAX_DES3_KEY_SIZE 24 /* DES_BLOCK_SIZE * 3 */
-#define SFTK_MAX_DERIVE_KEY_SIZE 64
 
 /*
  * FIPS 140-2 auditing
  */
 typedef enum {
     NSS_AUDIT_ERROR = 3,   /* errors */
     NSS_AUDIT_WARNING = 2, /* warning messages */
     NSS_AUDIT_INFO = 1     /* informational messages */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -4319,17 +4319,17 @@ ssl3_ConsumeHandshake(sslSocket *ss, voi
  *
  * On error, an alert has been sent, and a generic error code has been set.
  */
 SECStatus
 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes,
                             PRUint8 **b, PRUint32 *length)
 {
     PRUint8 *buf = *b;
-    PRUint32 i;
+    int i;
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     *num = 0;
     if (bytes > *length || bytes > sizeof(*num)) {
         return ssl3_DecodeError(ss);
     }
@@ -4941,17 +4941,17 @@ ssl_MakeFakeSid(sslSocket *ss, PRUint8 *
  * - client_hello_renegotiation is used to renegotiate (in TLS <1.3)
  */
 SECStatus
 ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
 {
     sslSessionID *sid;
     ssl3CipherSpec *cwSpec;
     SECStatus rv;
-    unsigned int i;
+    int i;
     int length;
     int num_suites;
     int actual_count = 0;
     PRBool isTLS = PR_FALSE;
     PRBool requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE;
     PRInt32 total_exten_len = 0;
     unsigned numCompressionMethods;
     PRUint16 version;
@@ -7136,21 +7136,21 @@ ssl_HandleDHServerKeyExchange(sslSocket 
     SECKEYPublicKey *peerKey = NULL;
 
     rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
     if (rv != SECSuccess) {
         goto loser; /* malformed. */
     }
 
     rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH);
-    if (rv != SECSuccess || minDH <= 0) {
+    if (rv != SECSuccess) {
         minDH = SSL_DH_MIN_P_BITS;
     }
     dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p);
-    if (dh_p_bits < (unsigned)minDH) {
+    if (dh_p_bits < minDH) {
         errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
         goto alert_loser;
     }
     rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
     if (rv != SECSuccess) {
         goto loser; /* malformed. */
     }
     /* Abort if dh_g is 0, 1, or obviously too big. */
@@ -8077,18 +8077,18 @@ ssl3_KEASupportsTickets(const ssl3KEADef
 ** cipher suites. Therefore, we refuse to negotiate export cipher suites
 ** with any client that indicates support for TLS 1.1 or higher when we
 ** (the server) have TLS 1.1 support enabled.
 */
 SECStatus
 ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
                           PRBool initHashes)
 {
-    unsigned int j;
-    unsigned int i;
+    int j;
+    int i;
 
     for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
         ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
         SSLVersionRange vrange = { ss->version, ss->version };
         if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) {
             continue;
         }
         for (i = 0; i + 1 < suites->len; i += 2) {
@@ -8678,16 +8678,25 @@ ssl3_HandleClientHello(sslSocket *ss, PR
             sid = NULL;
         }
     }
 
     if (IS_DTLS(ss)) {
         ssl3_DisableNonDTLSSuites(ss);
     }
 
+#ifdef PARANOID
+    /* Look for a matching cipher suite. */
+    j = ssl3_config_match_init(ss);
+    if (j <= 0) {                  /* no ciphers are working/supported by PK11 */
+        errCode = PORT_GetError(); /* error code is already set. */
+        goto alert_loser;
+    }
+#endif
+
     if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
         rv = tls13_HandleClientHelloPart2(ss, &suites, sid);
     } else {
         rv = ssl3_HandleClientHelloPart2(ss, &suites, &comps, sid);
     }
     if (rv != SECSuccess) {
         errCode = PORT_GetError();
         goto loser;
@@ -8709,17 +8718,17 @@ ssl3_HandleClientHelloPart2(sslSocket *s
                             sslSessionID *sid)
 {
     PRBool haveSpecWriteLock = PR_FALSE;
     PRBool haveXmitBufLock = PR_FALSE;
     int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
     SSL3AlertDescription desc = illegal_parameter;
     SECStatus rv;
     unsigned int i;
-    unsigned int j;
+    int j;
 
     /* If we already have a session for this client, be sure to pick the
     ** same cipher suite and compression method we picked before.
     ** This is not a loop, despite appearances.
     */
     if (sid)
         do {
             ssl3CipherSuiteCfg *suite;
@@ -8741,17 +8750,17 @@ ssl3_HandleClientHelloPart2(sslSocket *s
 
             suite = ss->cipherSuites;
             /* Find the entry for the cipher suite used in the cached session. */
             for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) {
                 if (suite->cipher_suite == sid->u.ssl3.cipherSuite)
                     break;
             }
             PORT_Assert(j > 0);
-            if (j == 0)
+            if (j <= 0)
                 break;
 #ifdef PARANOID
             /* Double check that the cached cipher suite is still enabled,
              * implemented, and allowed by policy.  Might have been disabled.
              * The product policy won't change during the process lifetime.
              * Implemented ("isPresent") shouldn't change for servers.
              */
             if (!config_match(suite, ss->ssl3.policy, &vrange, ss))
@@ -8778,17 +8787,18 @@ ssl3_HandleClientHelloPart2(sslSocket *s
                     goto compression_found;
                 }
             }
         } while (0);
 /* START A NEW SESSION */
 
 #ifndef PARANOID
     /* Look for a matching cipher suite. */
-    if (ssl3_config_match_init(ss) <= 0) {
+    j = ssl3_config_match_init(ss);
+    if (j <= 0) { /* no ciphers are working/supported by PK11 */
         desc = internal_error;
         errCode = PORT_GetError(); /* error code is already set. */
         goto alert_loser;
     }
 #endif
 
     rv = ssl3_NegotiateCipherSuite(ss, suites, PR_TRUE);
     if (rv != SECSuccess) {
@@ -9680,22 +9690,22 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, 
 }
 
 static SECStatus
 ssl3_SendCertificateRequest(sslSocket *ss)
 {
     PRBool isTLS12;
     const PRUint8 *certTypes;
     SECStatus rv;
-    PRUint32 length;
+    int length;
     SECItem *names;
     unsigned int calen;
     unsigned int nnames;
     SECItem *name;
-    unsigned int i;
+    int i;
     int certTypesLength;
     PRUint8 sigAlgs[MAX_SIGNATURE_SCHEMES * 2];
     unsigned int sigAlgsLength = 0;
 
     SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
                 SSL_GETPID(), ss->fd));
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
@@ -10903,51 +10913,50 @@ ssl3_AuthCertificate(sslSocket *ss)
         if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
             /* These are filled in in tls13_HandleCertificateVerify and
              * tls13_HandleServerKeyShare. */
             ss->sec.authType = ss->ssl3.hs.kea_def->authKeyType;
             ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
         }
         if (pubKey) {
             KeyType pubKeyType;
-            PRUint32 minKey;
-            PRInt32 optval;
+            PRInt32 minKey;
             /* This partly fixes Bug 124230 and may cause problems for
              * callers which depend on the old (wrong) behavior. */
             ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey);
             pubKeyType = SECKEY_GetPublicKeyType(pubKey);
             minKey = ss->sec.authKeyBits;
             switch (pubKeyType) {
                 case rsaKey:
                 case rsaPssKey:
                 case rsaOaepKey:
                     rv =
-                        NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &optval);
-                    if (rv == SECSuccess && optval > 0) {
-                        minKey = (PRUint32)optval;
-                    } else {
-                        minKey = SSL_RSA_MIN_MODULUS_BITS;
+                        NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey);
+                    if (rv !=
+                        SECSuccess) {
+                        minKey =
+                            SSL_RSA_MIN_MODULUS_BITS;
                     }
                     break;
                 case dsaKey:
                     rv =
-                        NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &optval);
-                    if (rv == SECSuccess && optval > 0) {
-                        minKey = (PRUint32)optval;
-                    } else {
-                        minKey = SSL_DSA_MIN_P_BITS;
+                        NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey);
+                    if (rv !=
+                        SECSuccess) {
+                        minKey =
+                            SSL_DSA_MIN_P_BITS;
                     }
                     break;
                 case dhKey:
                     rv =
-                        NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &optval);
-                    if (rv == SECSuccess && optval > 0) {
-                        minKey = (PRUint32)optval;
-                    } else {
-                        minKey = SSL_DH_MIN_P_BITS;
+                        NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey);
+                    if (rv !=
+                        SECSuccess) {
+                        minKey =
+                            SSL_DH_MIN_P_BITS;
                     }
                     break;
                 default:
                     break;
             }
 
             /* Too small: not good enough. Send a fatal alert. */
             /* We aren't checking EC here on the understanding that we only
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,19 +14,19 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION "3.35 Beta"
+#define NSSUTIL_VERSION "3.34 Beta"
 #define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 35
+#define NSSUTIL_VMINOR 34
 #define NSSUTIL_VPATCH 0
 #define NSSUTIL_VBUILD 0
 #define NSSUTIL_BETA PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
--- a/security/nss/lib/util/pkcs11uri.c
+++ b/security/nss/lib/util/pkcs11uri.c
@@ -237,17 +237,17 @@ fail:
 
 /* Compare two attribute names by the array index in attr_names.  Both
  * attribute names must be present in attr_names, otherwise it is a
  * programming error. */
 static int
 pk11uri_CompareByPosition(const char *a, const char *b,
                           const char **attr_names, size_t num_attr_names)
 {
-    size_t i, j;
+    int i, j;
 
     for (i = 0; i < num_attr_names; i++) {
         if (strcmp(a, attr_names[i]) == 0) {
             break;
         }
     }
     PR_ASSERT(i < num_attr_names);
 
--- a/security/nss/lib/util/secport.c
+++ b/security/nss/lib/util/secport.c
@@ -784,14 +784,14 @@ NSS_SecureMemcmp(const void *ia, const v
 /*
  * Perform a constant-time check if a memory region is all 0. The return value
  * is 0 if the memory region is all zero.
  */
 unsigned int
 NSS_SecureMemcmpZero(const void *mem, size_t n)
 {
     PRUint8 zero = 0;
-    size_t i;
+    int i;
     for (i = 0; i < n; ++i) {
         zero |= *(PRUint8 *)((uintptr_t)mem + i);
     }
     return zero;
 }
--- a/security/nss/tests/ssl_gtests/ssl_gtests.sh
+++ b/security/nss/tests/ssl_gtests/ssl_gtests.sh
@@ -16,27 +16,26 @@
 # ---------------
 #   FIXME ... known problems, search for this string
 #   NOTE .... unexpected behavior
 #
 ########################################################################
 
 # Generate input to certutil
 certscript() {
-  ca=n
   while [ $# -gt 0 ]; do
     case $1 in
       sign) echo 0 ;;
       kex) echo 2 ;;
-      ca) echo 5;echo 6;ca=y ;;
+      ca) echo 5;echo 6 ;;
     esac; shift
   done;
   echo 9
   echo n
-  echo $ca
+  echo ${ca:-n}
   echo
   echo n
 }
 
 # $1: name
 # $2: type
 # $3+: usages: sign or kex
 make_cert() {
@@ -46,19 +45,19 @@ make_cert() {
   case $type in
     dsa) type_args='-g 1024' ;;
     rsa) type_args='-g 1024' ;;
     rsa2048) type_args='-g 2048';type=rsa ;;
     rsapss) type_args='-g 1024 --pss';type=rsa ;;
     p256) type_args='-q nistp256';type=ec ;;
     p384) type_args='-q secp384r1';type=ec ;;
     p521) type_args='-q secp521r1';type=ec ;;
-    rsa_ca) type_args='-g 1024';trust='CT,CT,CT';type=rsa ;;
+    rsa_ca) type_args='-g 1024';trust='CT,CT,CT';ca=y;type=rsa ;;
     rsa_chain) type_args='-g 1024';sign='-c rsa_ca';type=rsa;;
-    rsapss_ca) type_args='-g 1024 --pss';trust='CT,CT,CT';type=rsa ;;
+    rsapss_ca) type_args='-g 1024 --pss';trust='CT,CT,CT';ca=y;type=rsa ;;
     rsapss_chain) type_args='-g 1024';sign='-c rsa_pss_ca';type=rsa;;
     rsa_ca_rsapss_chain) type_args='-g 1024 --pss-sign';sign='-c rsa_ca';type=rsa;;
     ecdh_rsa) type_args='-q nistp256';sign='-c rsa_ca';type=ec ;;
   esac
   shift 2
   counter=$(($counter + 1))
   certscript $@ | ${BINDIR}/certutil -S \
     -z ${R_NOISE_FILE} -d "${PROFILEDIR}" \
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -716,17 +716,20 @@ class TestInfoCommand(MachCommandBase):
         else:
             print("Unable to find matching records in ActiveData; using %s!" %
                   self.test_name)
             self.activedata_test_name = self.test_name
 
     def get_platform(self, record):
         platform = record['build']['platform']
         type = record['build']['type']
-        e10s = "-%s" % record['run']['type'] if 'run' in record else ""
+        if 'run' in record and 'e10s' in record['run']['type']:
+            e10s = "-e10s"
+        else:
+            e10s = ""
         return "%s/%s%s:" % (platform, type, e10s)
 
     def submit(self, query):
         import requests
         import datetime
         if self.verbose:
             print(datetime.datetime.now())
             print(json.dumps(query))
@@ -781,17 +784,17 @@ class TestInfoCommand(MachCommandBase):
                 failures = record['failures']
                 total_failures = total_failures + failures
                 rate = (float)(failures) / runs
                 if rate >= worst_rate:
                     worst_rate = rate
                     worst_platform = platform
                     worst_failures = failures
                     worst_runs = runs
-                print("%-30s %6d failures in %6d runs" % (
+                print("%-40s %6d failures in %6d runs" % (
                     platform, failures, runs))
             print("\nTotal: %d failures in %d runs or %.3f failures/run" %
                   (total_failures, total_runs, (float)(total_failures) / total_runs))
             if worst_failures > 0:
                 print("Worst rate on %s %d failures in %d runs or %.3f failures/run" %
                       (worst_platform, worst_failures, worst_runs, worst_rate))
         else:
             print("No test result data found.")
@@ -820,17 +823,17 @@ class TestInfoCommand(MachCommandBase):
         }
         data = self.submit(query)
         print("\nTest durations for %s on %s between %s and %s" %
               (self.activedata_test_name, self.branches, self.start, self.end))
         if data and len(data) > 0:
             data.sort(key=self.get_platform)
             for record in data:
                 platform = self.get_platform(record)
-                print("%-30s %6.2f s (%.2f s - %.2f s over %d runs)" % (
+                print("%-40s %6.2f s (%.2f s - %.2f s over %d runs)" % (
                     platform, record['average'], record['min'],
                     record['max'], record['count']))
         else:
             print("No test durations found.")
 
     def report_bugs(self):
         # Report open bugs matching test name
         import requests
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -863,26 +863,26 @@ class Marionette(object):
         :param pref: Name of the preference.
         """
         with self.using_context(self.CONTEXT_CHROME):
             self.execute_script("""
                Components.utils.import("resource://gre/modules/Preferences.jsm");
                Preferences.reset(arguments[0]);
                """, script_args=(pref,))
 
-    def get_pref(self, pref, default_branch=False, value_type="unspecified"):
+    def get_pref(self, pref, default_branch=False, value_type="nsISupportsString"):
         """Get the value of the specified preference.
 
         :param pref: Name of the preference.
         :param default_branch: Optional, if `True` the preference value will be read
                                from the default branch. Otherwise the user-defined
                                value if set is returned. Defaults to `False`.
         :param value_type: Optional, XPCOM interface of the pref's complex value.
-                           Possible values are: `nsIFile` and
-                           `nsIPrefLocalizedString`.
+                           Defaults to `nsISupportsString`. Other possible values are:
+                           `nsIFile`, and `nsIPrefLocalizedString`.
 
         Usage example::
 
             marionette.get_pref("browser.tabs.warnOnClose")
 
         """
         with self.using_context(self.CONTEXT_CHROME):
             pref_value = self.execute_script("""
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -658,20 +658,58 @@ class DesktopUnittest(TestingMixin, Merc
         self._stage_files()
         dirs = self.query_abs_dirs()
         modules = ['jsbridge', 'mozmill']
         for module in modules:
             self.install_module(module=os.path.join(dirs['abs_mozmill_dir'],
                                                     'resources',
                                                     module))
 
+    def _report_line(self, f, tag, info):
+        try:
+            f.write("%s %s\n" % (tag, str(info)))
+        except:
+            f.write("Exception getting system info: %s" % sys.exc_info()[0])
+
+    def _report_system_info(self):
+        """
+           Create the system-info.log artifact file, containing a variety of
+           system information that might be useful in diagnosing test failures.
+        """
+        import psutil
+        dir = self.query_abs_dirs()['abs_blob_upload_dir']
+        self.mkdir_p(dir)
+        path = os.path.join(dir, "system-info.log")
+        with open(path, "w") as f:
+            self._report_line(f, "System info collected at ", datetime.now())
+            self._report_line(f, "\nBoot time ", datetime.fromtimestamp(psutil.boot_time()))
+            self._report_line(f, "\nVirtual memory: ", psutil.virtual_memory())
+            self._report_line(f, "\nDisk partitions: ", psutil.disk_partitions())
+            self._report_line(f, "\nDisk usage (/): ", psutil.disk_usage(os.path.sep))
+            self._report_line(f, "\nUsers: ", psutil.users())
+            self._report_line(f, "\nNetwork connections:", "")
+            try:
+                for nc in psutil.net_connections():
+                    self._report_line(f, "  ", nc)
+            except:
+                f.write("Exception getting network info: %s" % sys.exc_info()[0])
+            self._report_line(f, "\nProcesses:", "")
+            try:
+                for p in psutil.process_iter():
+                    ctime = str(datetime.fromtimestamp(p.create_time()))
+                    self._report_line(f, "  PID", "%d %s %s created at %s" %
+                                      (p.pid, p.name(), str(p.cmdline()), ctime))
+            except:
+                f.write("Exception getting process info: %s" % sys.exc_info()[0])
+
     # pull defined in VCSScript.
     # preflight_run_tests defined in TestingMixin.
 
     def run_tests(self):
+        self._report_system_info()
         self.start_time = datetime.now()
         for category in SUITE_CATEGORIES:
             if not self._run_category_suites(category):
                 break
 
     def get_timeout_for_category(self, suite_category):
         if suite_category == 'cppunittest':
             return 2500
--- a/testing/web-platform/meta/html/dom/interfaces.html.ini
+++ b/testing/web-platform/meta/html/dom/interfaces.html.ini
@@ -26,19 +26,16 @@
     expected: FAIL
 
   [Document interface: attribute forms]
     expected: FAIL
 
   [Document interface: attribute scripts]
     expected: FAIL
 
-  [Document interface: operation getElementsByName(DOMString)]
-    expected: FAIL
-
   [Document interface: operation getItems(DOMString)]
     expected: FAIL
 
   [Document interface: attribute cssElementMap]
     expected: FAIL
 
   [Document interface: operation open(DOMString,DOMString)]
     expected: FAIL
@@ -197,22 +194,16 @@
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "forms" with the proper type (48)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "scripts" with the proper type (49)]
     expected: FAIL
 
-  [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getElementsByName" with the proper type (50)]
-    expected: FAIL
-
-  [Document interface: calling getElementsByName(DOMString) on document.implementation.createDocument(null, "", null) with too few arguments must throw TypeError]
-    expected: FAIL
-
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getItems" with the proper type (51)]
     expected: FAIL
 
   [Document interface: calling getItems(DOMString) on document.implementation.createDocument(null, "", null) with too few arguments must throw TypeError]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "cssElementMap" with the proper type (52)]
     expected: FAIL
@@ -1853,19 +1844,16 @@
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "forms" with the proper type (49)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "scripts" with the proper type (50)]
     expected: FAIL
 
-  [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getElementsByName" with the proper type (51)]
-    expected: FAIL
-
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getItems" with the proper type (52)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "cssElementMap" with the proper type (53)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "open" with the proper type (56)]
     expected: FAIL
@@ -2051,22 +2039,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "forms" with the proper type (49)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "scripts" with the proper type (50)]
     expected: FAIL
 
-  [Document interface: new Document() must inherit property "getElementsByName" with the proper type (51)]
-    expected: FAIL
-
-  [Document interface: calling getElementsByName(DOMString) on new Document() with too few arguments must throw TypeError]
-    expected: FAIL
-
   [Document interface: new Document() must inherit property "cssElementMap" with the proper type (52)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "open" with the proper type (54)]
     expected: FAIL
 
   [Document interface: calling open(DOMString,DOMString) on new Document() with too few arguments must throw TypeError]
     expected: FAIL
@@ -2813,19 +2795,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "forms" with the proper type (50)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "scripts" with the proper type (51)]
     expected: FAIL
 
-  [Document interface: new Document() must inherit property "getElementsByName" with the proper type (52)]
-    expected: FAIL
-
   [Document interface: new Document() must inherit property "fgColor" with the proper type (70)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "linkColor" with the proper type (71)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "vlinkColor" with the proper type (72)]
     expected: FAIL
@@ -2891,19 +2870,16 @@
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "forms" with the proper type (50)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "scripts" with the proper type (51)]
     expected: FAIL
 
-  [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getElementsByName" with the proper type (52)]
-    expected: FAIL
-
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "fgColor" with the proper type (70)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "linkColor" with the proper type (71)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "vlinkColor" with the proper type (72)]
     expected: FAIL
@@ -3035,19 +3011,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "forms" with the proper type (45)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "scripts" with the proper type (46)]
     expected: FAIL
 
-  [Document interface: new Document() must inherit property "getElementsByName" with the proper type (47)]
-    expected: FAIL
-
   [Document interface: new Document() must inherit property "open" with the proper type (49)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "open" with the proper type (50)]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "close" with the proper type (51)]
     expected: FAIL
@@ -3146,19 +3119,16 @@
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "forms" with the proper type (45)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "scripts" with the proper type (46)]
     expected: FAIL
 
-  [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getElementsByName" with the proper type (47)]
-    expected: FAIL
-
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "open" with the proper type (49)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "open" with the proper type (50)]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "close" with the proper type (51)]
     expected: FAIL
@@ -3461,19 +3431,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "forms" with the proper type]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "scripts" with the proper type]
     expected: FAIL
 
-  [Document interface: new Document() must inherit property "getElementsByName(DOMString)" with the proper type]
-    expected: FAIL
-
   [Document interface: new Document() must inherit property "open(DOMString, DOMString)" with the proper type]
     expected: FAIL
 
   [Document interface: calling open(DOMString, DOMString) on new Document() with too few arguments must throw TypeError]
     expected: FAIL
 
   [Document interface: new Document() must inherit property "open(USVString, DOMString, DOMString)" with the proper type]
     expected: FAIL
@@ -3581,19 +3548,16 @@
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "forms" with the proper type]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "scripts" with the proper type]
     expected: FAIL
 
-  [Document interface: document.implementation.createDocument(null, "", null) must inherit property "getElementsByName(DOMString)" with the proper type]
-    expected: FAIL
-
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "open(DOMString, DOMString)" with the proper type]
     expected: FAIL
 
   [Document interface: calling open(DOMString, DOMString) on document.implementation.createDocument(null, "", null) with too few arguments must throw TypeError]
     expected: FAIL
 
   [Document interface: document.implementation.createDocument(null, "", null) must inherit property "open(USVString, DOMString, DOMString)" with the proper type]
     expected: FAIL
--- a/toolkit/components/telemetry/EventInfo.h
+++ b/toolkit/components/telemetry/EventInfo.h
@@ -20,19 +20,16 @@ struct CommonEventInfo {
   // Indices for the category and expiration strings.
   uint32_t category_offset;
   uint32_t expiration_version_offset;
 
   // The index and count for the extra key offsets in the extra table.
   uint32_t extra_index;
   uint32_t extra_count;
 
-  // The day since UNIX epoch that this probe expires on.
-  uint32_t expiration_day;
-
   // The dataset this event is recorded in.
   uint32_t dataset;
 
   // Which processes to record this event in.
   mozilla::Telemetry::Common::RecordedProcessType record_in_processes;
 
   // Convenience functions for accessing event strings.
   const nsCString expiration_version() const;
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -21,52 +21,44 @@ navigation:
 telemetry.test:
   test:
     methods: ["test1", "test2"]
     objects: ["object1", "object2"]
     bug_numbers: [1286606]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     record_in_processes: ["main"]
     description: This is a test entry for Telemetry.
-    expiry_date: never
+    expiry_version: never
     extra_keys:
       key1: This is just a test description.
       key2: This is another test description.
   optout:
     objects: ["object1", "object2"]
     bug_numbers: [1286606]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     release_channel_collection: opt-out
     record_in_processes: ["main"]
     description: This is an opt-out test entry.
-    expiry_date: never
+    expiry_version: never
     extra_keys:
       key1: This is just a test description.
   expired_version:
     objects: ["object1", "object2"]
     bug_numbers: [1286606]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     record_in_processes: ["main"]
     description: This is a test entry with an expired version.
     expiry_version: "3.6"
-  expired_date:
-    objects: ["object1", "object2"]
-    bug_numbers: [1286606]
-    notification_emails: ["telemetry-client-dev@mozilla.com"]
-    record_in_processes: ["main"]
-    description: This is a test entry with an expired date.
-    expiry_date: 2014-01-28
   not_expired_optout:
     objects: ["object1"]
     bug_numbers: [1286606]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     description: This is an opt-out test entry with unexpired date and version.
     release_channel_collection: opt-out
     record_in_processes: ["main"]
-    expiry_date: 2099-01-01
     expiry_version: "999.0"
   main_only:
     objects: ["object1"]
     bug_numbers: [1313326]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     record_in_processes: ["main"]
     description: This event is used to test main-process only recording.
     expiry_version: never
@@ -92,11 +84,11 @@ telemetry.test:
 # The events here will not be sent out with any pings.
 telemetry.test.second:
   test:
     objects: ["object1", "object2", "object3"]
     bug_numbers: [1286606]
     notification_emails: ["telemetry-client-dev@mozilla.com"]
     record_in_processes: ["main"]
     description: This is a test entry for Telemetry.
-    expiry_date: never
+    expiry_version: never
     extra_keys:
       key1: This is just a test description.
--- a/toolkit/components/telemetry/TelemetryEvent.cpp
+++ b/toolkit/components/telemetry/TelemetryEvent.cpp
@@ -163,21 +163,16 @@ enum class RecordEventResult {
   Ok,
   UnknownEvent,
   InvalidExtraKey,
   StorageLimitReached,
   ExpiredEvent,
   WrongProcess,
 };
 
-enum class RegisterEventResult {
-  Ok,
-  AlreadyRegistered,
-};
-
 typedef nsTArray<EventExtraEntry> ExtraArray;
 
 class EventRecord {
 public:
   EventRecord(double timestamp, const EventKey& key, const Maybe<nsCString>& value,
               const ExtraArray& extra)
     : mTimestamp(timestamp)
     , mEventKey(key)
@@ -279,26 +274,16 @@ UniqueEventName(const EventInfo& info)
 nsCString
 UniqueEventName(const DynamicEventInfo& info)
 {
   return UniqueEventName(info.category,
                          info.method,
                          info.object);
 }
 
-bool
-IsExpiredDate(uint32_t expires_days_since_epoch) {
-  if (expires_days_since_epoch == 0) {
-    return false;
-  }
-
-  const uint32_t days_since_epoch = PR_Now() / (PRTime(PR_USEC_PER_SEC) * 24 * 60 * 60);
-  return expires_days_since_epoch <= days_since_epoch;
-}
-
 void
 TruncateToByteLength(nsCString& str, uint32_t length)
 {
   // last will be the index of the first byte of the current multi-byte sequence.
   uint32_t last = RewindToPriorUTF8Codepoint(str.get(), length);
   str.Truncate(last);
 }
 
@@ -515,45 +500,48 @@ ShouldRecordChildEvent(const StaticMutex
   const auto processes = gEventInfo[eventKey->id].common_info.record_in_processes;
   if (!CanRecordInProcess(processes, XRE_GetProcessType())) {
     return RecordEventResult::WrongProcess;
   }
 
   return RecordEventResult::Ok;
 }
 
-RegisterEventResult
+void
 RegisterEvents(const StaticMutexAutoLock& lock, const nsACString& category,
                const nsTArray<DynamicEventInfo>& eventInfos,
                const nsTArray<bool>& eventExpired)
 {
   MOZ_ASSERT(eventInfos.Length() == eventExpired.Length(), "Event data array sizes should match.");
 
-  // Check that none of the events are already registered.
-  for (auto& info : eventInfos) {
-    if (gEventNameIDMap.Get(UniqueEventName(info))) {
-      return RegisterEventResult::AlreadyRegistered;
-    }
-  }
-
   // Register the new events.
   if (!gDynamicEventInfo) {
     gDynamicEventInfo = new nsTArray<DynamicEventInfo>();
   }
 
   for (uint32_t i = 0, len = eventInfos.Length(); i < len; ++i) {
+    const nsCString& eventName = UniqueEventName(eventInfos[i]);
+
+    // Re-registering events can happen when add-ons update, so we don't print warnings.
+    // We don't support changing their definition, but the expiry might have changed.
+    EventKey* existing = nullptr;
+    if (gEventNameIDMap.Get(eventName, &existing)) {
+      if (eventExpired[i]) {
+        existing->id = kExpiredEventId;
+      }
+      continue;
+    }
+
     gDynamicEventInfo->AppendElement(eventInfos[i]);
     uint32_t eventId = eventExpired[i] ? kExpiredEventId : gDynamicEventInfo->Length() - 1;
-    gEventNameIDMap.Put(UniqueEventName(eventInfos[i]), new EventKey{eventId, true});
+    gEventNameIDMap.Put(eventName, new EventKey{eventId, true});
   }
 
   // Now after successful registration enable recording for this category.
   gEnabledCategories.PutEntry(category);
-
-  return RegisterEventResult::Ok;
 }
 
 } // anonymous namespace
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: thread-unsafe helpers for event handling.
@@ -695,18 +683,17 @@ TelemetryEvent::InitializeGlobalState(bo
   const uint32_t eventCount = static_cast<uint32_t>(mozilla::Telemetry::EventID::EventCount);
   for (uint32_t i = 0; i < eventCount; ++i) {
     const EventInfo& info = gEventInfo[i];
     uint32_t eventId = i;
 
     // If this event is expired or not recorded in this process, mark it with
     // a special event id.
     // This avoids doing repeated checks at runtime.
-    if (IsExpiredVersion(info.common_info.expiration_version().get()) ||
-        IsExpiredDate(info.common_info.expiration_day)) {
+    if (IsExpiredVersion(info.common_info.expiration_version().get())) {
       eventId = kExpiredEventId;
     }
 
     gEventNameIDMap.Put(UniqueEventName(info), new EventKey{eventId, false});
     if (!gCategoryNameIDMap.Contains(info.common_info.category())) {
       gCategoryNameIDMap.Put(info.common_info.category(),
                              info.common_info.category_offset);
     }
@@ -1075,28 +1062,19 @@ TelemetryEvent::RegisterEvents(const nsA
         DynamicEventInfo info{nsCString(aCategory), method, object,
                               nsTArray<nsCString>(extra_keys), recordOnRelease};
         newEventInfos.AppendElement(info);
         newEventExpired.AppendElement(expired);
       }
     }
   }
 
-  RegisterEventResult res = RegisterEventResult::Ok;
   {
     StaticMutexAutoLock locker(gTelemetryEventsMutex);
-    res = ::RegisterEvents(locker, aCategory, newEventInfos, newEventExpired);
-  }
-
-  switch (res) {
-    case RegisterEventResult::AlreadyRegistered:
-      JS_ReportErrorASCII(cx, "Attempt to register event that is already registered.");
-      return NS_ERROR_INVALID_ARG;
-    default:
-      break;
+    RegisterEvents(locker, aCategory, newEventInfos, newEventExpired);
   }
 
   return NS_OK;
 }
 
 nsresult
 TelemetryEvent::CreateSnapshots(uint32_t aDataset, bool aClear, JSContext* cx,
                                 uint8_t optional_argc, JS::MutableHandleValue aResult)
--- a/toolkit/components/telemetry/docs/collection/events.rst
+++ b/toolkit/components/telemetry/docs/collection/events.rst
@@ -108,17 +108,16 @@ The following event properties are valid
   - ``all_child`` (record in all the child processes)
   - ``all`` (record in all the processes).
 
 - ``bug_numbers`` *(required, list of numbers)*: A list of Bugzilla bug numbers that are relevant to this event.
 - ``notification_emails`` *(required, list of strings)*: A list of emails of owners for this event. This is used for contact for data reviews and potentially to email alerts.
 - expiry: There are two properties that can specify expiry, at least one needs to be set:
 
   - ``expiry_version`` *(string)*: The version number in which the event expires, e.g. ``"50"``, or ``"never"``. A version number of type "N" and "N.0" is automatically converted to "N.0a1" in order to expire the event also in the development channels. For events that never expire the value ``never`` can be used.
-  - ``expiry_date`` *(date)*: A date of the format ``2014-01-28``. If the local client clock reaches this date, the event will expire and not be recorded.
 
 - ``extra_keys`` *(optional, object)*: An object that specifies valid keys for the ``extra`` argument and a description - see the example above.
 
 The API
 =======
 
 Public JS API
 -------------
@@ -192,16 +191,18 @@ Register new events from add-ons.
 
 For events recorded from add-ons, registration happens at runtime. Any new events must first be registered through this function before they can be recorded.
 The registered categories will automatically be enabled for recording.
 
 After registration, the events can be recorded through the ``recordEvent()`` function. They will be submitted in the main pings payload under ``processes.dynamic.events``.
 
 New events registered here are subject to the same limitations as the ones registered through ``Events.yaml``, although the naming was in parts updated to recent policy changes.
 
+When add-ons are updated, they may re-register all of their events. In that case, any changes to events that are already registered are ignored. The only exception is expiry; an event that is re-registered with ``expired: true`` will not be recorded anymore.
+
 Example:
 
 .. code-block:: js
 
   Services.telemetry.registerEvents("myAddon.interaction", {
     "click": {
       methods: ["click"],
       objects: ["red_button", "blue_button"],
@@ -222,8 +223,12 @@ These functions are only supposed to be 
 
 Version History
 ===============
 
 - Firefox 52: Initial event support (`bug 1302663 <https://bugzilla.mozilla.org/show_bug.cgi?id=1302663>`_).
 - Firefox 53: Event recording disabled by default (`bug 1329139 <https://bugzilla.mozilla.org/show_bug.cgi?id=1329139>`_).
 - Firefox 54: Added child process events (`bug 1313326 <https://bugzilla.mozilla.org/show_bug.cgi?id=1313326>`_).
 - Firefox 56: Added support for recording new probes from add-ons (`bug 1302681 <bug https://bugzilla.mozilla.org/show_bug.cgi?id=1302681>`_).
+- Firefox 58:
+
+   - Ignore re-registering existing events for a category instead of failing (`bug 1408975 <https://bugzilla.mozilla.org/show_bug.cgi?id=1408975>`_).
+   - Removed support for the ``expiry_date`` property, as it was unused (`bug 1414638 <https://bugzilla.mozilla.org/show_bug.cgi?id=1414638>`_).
--- a/toolkit/components/telemetry/gen-event-data.py
+++ b/toolkit/components/telemetry/gen-event-data.py
@@ -69,22 +69,21 @@ def write_common_event_table(events, out
     print("const CommonEventInfo %s[] = {" % table_name, file=output)
     for e, extras in zip(events, extra_table):
         # Write a comment to make the file human-readable.
         print("  // category: %s" % e.category, file=output)
         print("  // methods: [%s]" % ", ".join(e.methods), file=output)
         print("  // objects: [%s]" % ", ".join(e.objects), file=output)
 
         # Write the common info structure
-        print("  {%d, %d, %d, %d, %d, %s, %s}," %
+        print("  {%d, %d, %d, %d, %s, %s}," %
               (string_table.stringIndex(e.category),
                string_table.stringIndex(e.expiry_version),
                extras[0],  # extra keys index
                extras[1],  # extra keys count
-               e.expiry_day,
                e.dataset,
                " | ".join(e.record_in_processes_enum)),
               file=output)
 
     print("};", file=output)
     static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name,
                   "index overflow")
 
--- a/toolkit/components/telemetry/parse_events.py
+++ b/toolkit/components/telemetry/parse_events.py
@@ -1,29 +1,27 @@
 # 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/.
 
 import re
 import yaml
 import itertools
-import datetime
 import string
 import shared_telemetry_utils as utils
 
 from shared_telemetry_utils import ParserError
 
 MAX_CATEGORY_NAME_LENGTH = 30
 MAX_METHOD_NAME_LENGTH = 20
 MAX_OBJECT_NAME_LENGTH = 20
 MAX_EXTRA_KEYS_COUNT = 10
 MAX_EXTRA_KEY_NAME_LENGTH = 15
 
 IDENTIFIER_PATTERN = r'^[a-zA-Z][a-zA-Z0-9_.]*[a-zA-Z0-9]$'
-DATE_PATTERN = r'^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
 
 
 def nice_type_name(t):
     if issubclass(t, basestring):
         return "string"
     return t.__name__
 
 
@@ -116,17 +114,16 @@ def type_check_event_fields(identifier, 
         'bug_numbers': ListTypeChecker(int),
         'notification_emails': ListTypeChecker(basestring),
         'record_in_processes': ListTypeChecker(basestring),
         'description': AtomicTypeChecker(basestring),
     }
     OPTIONAL_FIELDS = {
         'methods': ListTypeChecker(basestring),
         'release_channel_collection': AtomicTypeChecker(basestring),
-        'expiry_date': MultiTypeChecker(basestring, datetime.date),
         'expiry_version': AtomicTypeChecker(basestring),
         'extra_keys': DictTypeChecker(basestring, basestring),
     }
     ALL_FIELDS = REQUIRED_FIELDS.copy()
     ALL_FIELDS.update(OPTIONAL_FIELDS)
 
     # Check that all the required fields are available.
     missing_fields = [f for f in REQUIRED_FIELDS.keys() if f not in definition]
@@ -198,26 +195,19 @@ class EventData:
             raise ParserError("%s: Number of extra_keys exceeds limit %d." %
                               (self.identifier, MAX_EXTRA_KEYS_COUNT))
         for key in extra_keys.iterkeys():
             string_check(self.identifier, field='extra_keys', value=key,
                          min_length=1, max_length=MAX_EXTRA_KEY_NAME_LENGTH,
                          regex=IDENTIFIER_PATTERN)
 
         # Check expiry.
-        if 'expiry_version' not in definition and 'expiry_date' not in definition:
-            raise ParserError("%s: event is missing an expiration - either expiry_version or"
-                              " expiry_date is required" % (self.identifier))
-        expiry_date = definition.get('expiry_date')
-        if expiry_date and isinstance(expiry_date, basestring) and expiry_date != 'never':
-            if not re.match(DATE_PATTERN, expiry_date):
-                raise ParserError("%s: Event has invalid expiry_date, it should be either 'never'"
-                                  " or match this format: %s" % (self.identifier, DATE_PATTERN))
-            # Parse into date.
-            definition['expiry_date'] = datetime.datetime.strptime(expiry_date, '%Y-%m-%d')
+        if 'expiry_version' not in definition:
+            raise ParserError("%s: event is missing required field expiry_version"
+                              % (self.identifier))
 
         # Finish setup.
         expiry_version = definition.get('expiry_version', 'never')
         if not utils.validate_expiration_version(expiry_version):
             raise ParserError('{}: invalid expiry_version: {}.'
                               .format(self.identifier, expiry_version))
         definition['expiry_version'] = utils.add_expiration_postfix(expiry_version)
 
@@ -255,29 +245,16 @@ class EventData:
         """Get the non-empty list of flags representing the processes to record data in"""
         return [utils.process_name_to_enum(p) for p in self.record_in_processes]
 
     @property
     def expiry_version(self):
         return self._definition.get('expiry_version')
 
     @property
-    def expiry_day(self):
-        date = self._definition.get('expiry_date')
-        if not date:
-            return 0
-        if isinstance(date, basestring) and date == 'never':
-            return 0
-
-        # Convert date to days since UNIX epoch.
-        epoch = datetime.date(1970, 1, 1)
-        days = (date - epoch).total_seconds() / (24 * 60 * 60)
-        return round(days)
-
-    @property
     def cpp_guard(self):
         return self._definition.get('cpp_guard')
 
     @property
     def enum_labels(self):
         def enum(method_name, object_name):
             m = convert_to_cpp_identifier(method_name, "_")
             o = convert_to_cpp_identifier(object_name, "_")
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEvents.js
@@ -179,26 +179,21 @@ add_task(async function test_clear() {
 add_task(async function test_expiry() {
   Telemetry.clearEvents();
 
   // Recording call with event that is expired by version.
   Telemetry.recordEvent("telemetry.test", "expired_version", "object1");
   let snapshot = Telemetry.snapshotEvents(OPTIN, true);
   Assert.equal(Object.keys(snapshot).length, 0, "Should not record event with expired version.");
 
-  // Recording call with event that is expired by date.
-  Telemetry.recordEvent("telemetry.test", "expired_date", "object1");
-  snapshot = Telemetry.snapshotEvents(OPTIN, true);
-  Assert.equal(Object.keys(snapshot).length, 0, "Should not record event with expired date.");
-
-  // Recording call with event that has expiry_version and expiry_date in the future.
+  // Recording call with event that has expiry_version set into the future.
   Telemetry.recordEvent("telemetry.test", "not_expired_optout", "object1");
   snapshot = Telemetry.snapshotEvents(OPTOUT, true);
   Assert.ok(("parent" in snapshot), "Should have entry for main process.");
-  Assert.equal(snapshot.parent.length, 1, "Should record event when date and version are not expired.");
+  Assert.equal(snapshot.parent.length, 1, "Should record event when version is not expired.");
 });
 
 add_task(async function test_invalidParams() {
   Telemetry.clearEvents();
 
   // Recording call with wrong type for value argument.
   Telemetry.recordEvent("telemetry.test", "test1", "object1", 1);
   let snapshot = Telemetry.snapshotEvents(OPTIN, true);
@@ -514,19 +509,95 @@ add_task(function* test_dynamicEventRegi
     "Should throw when registering too many extra keys.");
   Telemetry.registerEvents("telemetry.test.dynamic10", {
     "test1": {
       methods: ["test1"],
       objects: ["object1"],
       extra_keys: ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"],
     },
   });
+});
 
-  // Test registering an event thats already registered through Events.yaml.
-  Assert.throws(() => Telemetry.registerEvents("telemetry.test", {
-      "test1": {
-        methods: ["test1"],
-        objects: ["object1"],
-      },
-    }),
-    /Attempt to register event that is already registered\./,
-    "Should throw when registering event that already was registered.");
+// When add-ons update, they may re-register some of the dynamic events.
+// Test through some possible scenarios.
+add_task(function* test_dynamicEventRegisterAgain() {
+  Telemetry.canRecordExtended = true;
+  Telemetry.clearEvents();
+
+  const category = "telemetry.test.register.again";
+  let events = {
+    "test1": {
+      methods: ["test1"],
+      objects: ["object1"],
+    }
+  };
+
+  // First register the initial event and make sure it can be recorded.
+  Telemetry.registerEvents(category, events);
+  let expected = [
+    [category, "test1", "object1"],
+  ];
+  expected.forEach(e => Telemetry.recordEvent(...e));
+
+  let snapshot = Telemetry.snapshotEvents(OPTIN, true);
+  Assert.equal(snapshot.dynamic.length, expected.length,
+               "Should have right number of events in the snapshot.");
+  Assert.deepEqual(snapshot.dynamic.map(e => e.slice(1)), expected);
+
+  // Register the same event again and make sure it can still be recorded.
+  Telemetry.registerEvents(category, events);
+  Telemetry.recordEvent(category, "test1", "object1");
+
+  snapshot = Telemetry.snapshotEvents(OPTIN, true);
+  Assert.equal(snapshot.dynamic.length, expected.length,
+               "Should have right number of events in the snapshot.");
+  Assert.deepEqual(snapshot.dynamic.map(e => e.slice(1)), expected);
+
+  // Now register another event in the same category and make sure both events can be recorded.
+  events.test2 = {
+    methods: ["test2"],
+    objects: ["object2"],
+  };
+  Telemetry.registerEvents(category, events);
+
+  expected = [
+    [category, "test1", "object1"],
+    [category, "test2", "object2"],
+  ];
+  expected.forEach(e => Telemetry.recordEvent(...e));
+
+  snapshot = Telemetry.snapshotEvents(OPTIN, true);
+  Assert.equal(snapshot.dynamic.length, expected.length,
+               "Should have right number of events in the snapshot.");
+  Assert.deepEqual(snapshot.dynamic.map(e => e.slice(1)), expected);
+
+  // Check that adding a new object to an event entry works.
+  events.test1.methods = ["test1a"];
+  events.test2.objects = ["object2", "object2a"];
+  Telemetry.registerEvents(category, events);
+
+  expected = [
+    [category, "test1", "object1"],
+    [category, "test2", "object2"],
+    [category, "test1a", "object1"],
+    [category, "test2", "object2a"],
+  ];
+  expected.forEach(e => Telemetry.recordEvent(...e));
+
+  snapshot = Telemetry.snapshotEvents(OPTIN, true);
+  Assert.equal(snapshot.dynamic.length, expected.length,
+               "Should have right number of events in the snapshot.");
+  Assert.deepEqual(snapshot.dynamic.map(e => e.slice(1)), expected);
+
+  // Make sure that we can expire events that are already registered.
+  events.test2.expired = true;
+  Telemetry.registerEvents(category, events);
+
+  expected = [
+    [category, "test1", "object1"],
+  ];
+  expected.forEach(e => Telemetry.recordEvent(...e));
+
+  snapshot = Telemetry.snapshotEvents(OPTIN, true);
+  Assert.equal(snapshot.dynamic.length, expected.length,
+               "Should have right number of events in the snapshot.");
+  Assert.deepEqual(snapshot.dynamic.map(e => e.slice(1)), expected);
 });
--- a/toolkit/content/tests/chrome/test_preferences.xul
+++ b/toolkit/content/tests/chrome/test_preferences.xul
@@ -17,44 +17,50 @@
                             .getService(Components.interfaces.nsIPrefBranch);
 
     // preference values, set 1
     const kPrefValueSet1 =
     {
         int:          23,
         bool:         true,
         string:       "rheeet!",
-        unichar:      "äöüßÄÖÜ",
         wstring_data: "日本語",
+        unichar_data: "äöüßÄÖÜ",
         file_data:    "/",
 
         wstring: Components.classes["@mozilla.org/pref-localizedstring;1"]
                            .createInstance(Components.interfaces.nsIPrefLocalizedString),
+        unichar: Components.classes["@mozilla.org/supports-string;1"]
+                           .createInstance(Components.interfaces.nsISupportsString),
         file:    Components.classes["@mozilla.org/file/local;1"]
                            .createInstance(Components.interfaces.nsIFile)
     };
     kPrefValueSet1.wstring.data = kPrefValueSet1.wstring_data;
+    kPrefValueSet1.unichar.data = kPrefValueSet1.unichar_data;
     SafeFileInit(kPrefValueSet1.file, kPrefValueSet1.file_data);
 
     // preference values, set 2
     const kPrefValueSet2 =
     {
         int:          42,
         bool:         false,
         string:       "Mozilla",
-        unichar:      "áôùšŽ",
         wstring_data: "헤드라인A",
+        unichar_data: "áôùšŽ",
         file_data:    "/home",
 
         wstring: Components.classes["@mozilla.org/pref-localizedstring;1"]
                            .createInstance(Components.interfaces.nsIPrefLocalizedString),
+        unichar: Components.classes["@mozilla.org/supports-string;1"]
+                           .createInstance(Components.interfaces.nsISupportsString),
         file:    Components.classes["@mozilla.org/file/local;1"]
                            .createInstance(Components.interfaces.nsIFile)
     };
     kPrefValueSet2.wstring.data = kPrefValueSet2.wstring_data;
+    kPrefValueSet2.unichar.data = kPrefValueSet2.unichar_data;
     SafeFileInit(kPrefValueSet2.file, kPrefValueSet2.file_data);
 
 
     function SafeFileInit(aFile, aPath)
     {
       // set file path without dying for exceptions
       try
       {
@@ -65,57 +71,62 @@
 
     function CreateEmptyPrefValueSet()
     {
       var result =
       {
         int:          undefined,
         bool:         undefined,
         string:       undefined,
-        unichar:      undefined,
         wstring_data: undefined,
+        unichar_data: undefined,
         file_data:    undefined,
         wstring:      undefined,
+        unichar:      undefined,
         file:         undefined
       };
       return result;
     }
 
     function WritePrefsToSystem(aPrefValueSet)
     {
       // write preference data via XPCOM
       kPref.setIntPref ("tests.static_preference_int",    aPrefValueSet.int);
       kPref.setBoolPref("tests.static_preference_bool",   aPrefValueSet.bool);
       kPref.setCharPref("tests.static_preference_string", aPrefValueSet.string);
-      kPref.setStringPref("tests.static_preference_unichar", aPrefValueSet.unichar);
       kPref.setComplexValue("tests.static_preference_wstring",
                             Components.interfaces.nsIPrefLocalizedString,
                             aPrefValueSet.wstring);
+      kPref.setComplexValue("tests.static_preference_unichar",
+                            Components.interfaces.nsISupportsString,
+                            aPrefValueSet.unichar);
       kPref.setComplexValue("tests.static_preference_file",
                             Components.interfaces.nsIFile,
                             aPrefValueSet.file);
     }
 
     function ReadPrefsFromSystem()
     {
       // read preference data via XPCOM
       var result = CreateEmptyPrefValueSet();
       try {result.int    = kPref.getIntPref ("tests.static_preference_int")   } catch (ignored) {};
       try {result.bool   = kPref.getBoolPref("tests.static_preference_bool")  } catch (ignored) {};
       try {result.string = kPref.getCharPref("tests.static_preference_string")} catch (ignored) {};
       try
       {
-        result.unichar = kPref.getStringPref("tests.static_preference_unichar");
+        result.wstring = kPref.getComplexValue("tests.static_preference_wstring",
+                                               Components.interfaces.nsIPrefLocalizedString);
+        result.wstring_data = result.wstring.data;
       }
       catch (ignored) {};
       try
       {
-        result.wstring = kPref.getComplexValue("tests.static_preference_wstring",
-                                               Components.interfaces.nsIPrefLocalizedString);
-        result.wstring_data = result.wstring.data;
+        result.unichar = kPref.getComplexValue("tests.static_preference_unichar",
+                                               Components.interfaces.nsISupportsString);
+        result.unichar_data = result.unichar.data;
       }
       catch (ignored) {};
       try
       {
         result.file = kPref.getComplexValue("tests.static_preference_file",
                                             Components.interfaces.nsIFile);
         result.file_data    = result.file.data;
       }
@@ -129,170 +140,177 @@
     }
 
     function WritePrefsToPreferences(aPrefWindow, aPrefValueSet)
     {
       // write preference data into <preference>s
       GetXULElement(aPrefWindow, "tests.static_preference_int"    ).value = aPrefValueSet.int;
       GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).value = aPrefValueSet.bool;
       GetXULElement(aPrefWindow, "tests.static_preference_string" ).value = aPrefValueSet.string;
-      GetXULElement(aPrefWindow, "tests.static_preference_unichar").value = aPrefValueSet.unichar;
       GetXULElement(aPrefWindow, "tests.static_preference_wstring").value = aPrefValueSet.wstring_data;
+      GetXULElement(aPrefWindow, "tests.static_preference_unichar").value = aPrefValueSet.unichar_data;
       GetXULElement(aPrefWindow, "tests.static_preference_file"   ).value = aPrefValueSet.file_data;
     }
 
     function ReadPrefsFromPreferences(aPrefWindow)
     {
       // read preference data from <preference>s
       var result =
       {
         int:          GetXULElement(aPrefWindow, "tests.static_preference_int"    ).value,
         bool:         GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).value,
         string:       GetXULElement(aPrefWindow, "tests.static_preference_string" ).value,
-        unichar:      GetXULElement(aPrefWindow, "tests.static_preference_unichar").value,
         wstring_data: GetXULElement(aPrefWindow, "tests.static_preference_wstring").value,
+        unichar_data: GetXULElement(aPrefWindow, "tests.static_preference_unichar").value,
         file_data:    GetXULElement(aPrefWindow, "tests.static_preference_file"   ).value,
         wstring: Components.classes["@mozilla.org/pref-localizedstring;1"]
                            .createInstance(Components.interfaces.nsIPrefLocalizedString),
+        unichar: Components.classes["@mozilla.org/supports-string;1"]
+                           .createInstance(Components.interfaces.nsISupportsString),
         file:    Components.classes["@mozilla.org/file/local;1"]
                            .createInstance(Components.interfaces.nsIFile)
       }
       result.wstring.data = result.wstring_data;
+      result.unichar.data = result.unichar_data;
       SafeFileInit(result.file, result.file_data);
       return result;
     }
 
     function WritePrefsToUI(aPrefWindow, aPrefValueSet)
     {
       // write preference data into UI elements
       GetXULElement(aPrefWindow, "static_element_int"    ).value   = aPrefValueSet.int;
       GetXULElement(aPrefWindow, "static_element_bool"   ).checked = aPrefValueSet.bool;
       GetXULElement(aPrefWindow, "static_element_string" ).value   = aPrefValueSet.string;
-      GetXULElement(aPrefWindow, "static_element_unichar").value   = aPrefValueSet.unichar;
       GetXULElement(aPrefWindow, "static_element_wstring").value   = aPrefValueSet.wstring_data;
+      GetXULElement(aPrefWindow, "static_element_unichar").value   = aPrefValueSet.unichar_data;
       GetXULElement(aPrefWindow, "static_element_file"   ).value   = aPrefValueSet.file_data;
     }
 
     function ReadPrefsFromUI(aPrefWindow)
     {
       // read preference data from <preference>s
       var result =
       {
         int:          GetXULElement(aPrefWindow, "static_element_int"    ).value,
         bool:         GetXULElement(aPrefWindow, "static_element_bool"   ).checked,
         string:       GetXULElement(aPrefWindow, "static_element_string" ).value,
-        unichar:      GetXULElement(aPrefWindow, "static_element_unichar").value,
         wstring_data: GetXULElement(aPrefWindow, "static_element_wstring").value,
+        unichar_data: GetXULElement(aPrefWindow, "static_element_unichar").value,
         file_data:    GetXULElement(aPrefWindow, "static_element_file"   ).value,
         wstring: Components.classes["@mozilla.org/pref-localizedstring;1"]
                            .createInstance(Components.interfaces.nsIPrefLocalizedString),
+        unichar: Components.classes["@mozilla.org/supports-string;1"]
+                           .createInstance(Components.interfaces.nsISupportsString),
         file:    Components.classes["@mozilla.org/file/local;1"]
                            .createInstance(Components.interfaces.nsIFile)
       }
       result.wstring.data = result.wstring_data;
+      result.unichar.data = result.unichar_data;
       SafeFileInit(result.file, result.file_data);
       return result;
     }
 
 
     function RunInstantPrefTest(aPrefWindow)
     {
       // remark: there's currently no UI element binding for files
 
       // were all <preferences> correctly initialized?
       var expected = kPrefValueSet1;
       var found    = ReadPrefsFromPreferences(aPrefWindow);
       ok(found.int          === expected.int,          "instant pref init int"    );
       ok(found.bool         === expected.bool,         "instant pref init bool"   );
       ok(found.string       === expected.string,       "instant pref init string" );
-      ok(found.unichar      === expected.unichar,      "instant pref init unichar");
       ok(found.wstring_data === expected.wstring_data, "instant pref init wstring");
+      ok(found.unichar_data === expected.unichar_data, "instant pref init unichar");
       todo(found.file_data  === expected.file_data,    "instant pref init file"   );
 
       // were all elements correctly initialized? (loose check)
       found = ReadPrefsFromUI(aPrefWindow);
       ok(found.int          == expected.int,          "instant element init int"    );
       ok(found.bool         == expected.bool,         "instant element init bool"   );
       ok(found.string       == expected.string,       "instant element init string" );
-      ok(found.unichar      == expected.unichar,      "instant element init unichar");
       ok(found.wstring_data == expected.wstring_data, "instant element init wstring");
+      ok(found.unichar_data == expected.unichar_data, "instant element init unichar");
       todo(found.file_data  == expected.file_data,    "instant element init file"   );
 
       // do some changes in the UI
       expected = kPrefValueSet2;
       WritePrefsToUI(aPrefWindow, expected);
 
       // UI changes should get passed to the <preference>s,
       // but currently they aren't if the changes are made programmatically
       // (the handlers preference.change/prefpane.input and prefpane.change
       //  are called for manual changes, though).
       found = ReadPrefsFromPreferences(aPrefWindow);
       todo(found.int          === expected.int,          "instant change pref int"    );
       todo(found.bool         === expected.bool,         "instant change pref bool"   );
       todo(found.string       === expected.string,       "instant change pref string" );
-      todo(found.unichar      === expected.unichar,      "instant change pref unichar");
       todo(found.wstring_data === expected.wstring_data, "instant change pref wstring");
+      todo(found.unichar_data === expected.unichar_data, "instant change pref unichar");
       todo(found.file_data    === expected.file_data,    "instant change pref file"   );
 
       // and these changes should get passed to the system instantly
       // (which obviously can't pass with the above failing)
       found = ReadPrefsFromSystem();
       todo(found.int          === expected.int,          "instant change element int"    );
       todo(found.bool         === expected.bool,         "instant change element bool"   );
       todo(found.string       === expected.string,       "instant change element string" );
-      todo(found.unichar      === expected.unichar,      "instant change element unichar");
       todo(found.wstring_data === expected.wstring_data, "instant change element wstring");
+      todo(found.unichar_data === expected.unichar_data, "instant change element unichar");
       todo(found.file_data    === expected.file_data,    "instant change element file"   );
 
       // try resetting the prefs to default values (which should be empty here)
       GetXULElement(aPrefWindow, "tests.static_preference_int"    ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset();
+      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset();
-      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_file"   ).reset();
 
       // check system
       expected = CreateEmptyPrefValueSet();
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "instant reset system int"    );
       ok(found.bool         === expected.bool,         "instant reset system bool"   );
       ok(found.string       === expected.string,       "instant reset system string" );
-      ok(found.unichar      === expected.unichar,      "instant reset system unichar");
       ok(found.wstring_data === expected.wstring_data, "instant reset system wstring");
+      ok(found.unichar_data === expected.unichar_data, "instant reset system unichar");
       ok(found.file_data    === expected.file_data,    "instant reset system file"   );
 
       // check UI
       expected =
       {
         // alas, we don't have XUL elements with typeof(value) == int :(
         // int:         0,
         int:          "",
         bool:         false,
         string:       "",
-        unichar:      "",
         wstring_data: "",
+        unichar_data: "",
         file_data:    "",
         wstring:      {},
+        unichar:      {},
         file:         {}
       };
       found = ReadPrefsFromUI(aPrefWindow);
       ok(found.int          === expected.int,          "instant reset element int"    );
       ok(found.bool         === expected.bool,         "instant reset element bool"   );
       ok(found.string       === expected.string,       "instant reset element string" );
-      ok(found.unichar      === expected.unichar,      "instant reset element unichar");
       ok(found.wstring_data === expected.wstring_data, "instant reset element wstring");
+      ok(found.unichar_data === expected.unichar_data, "instant reset element unichar");
 //      ok(found.file_data    === expected.file_data,    "instant reset element file"   );
 
       // check hasUserValue
       ok(GetXULElement(aPrefWindow, "tests.static_preference_int"    ).hasUserValue === false, "instant reset hasUserValue int"    );
       ok(GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).hasUserValue === false, "instant reset hasUserValue bool"   );
       ok(GetXULElement(aPrefWindow, "tests.static_preference_string" ).hasUserValue === false, "instant reset hasUserValue string" );
+      ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "instant reset hasUserValue wstring");
       ok(GetXULElement(aPrefWindow, "tests.static_preference_unichar").hasUserValue === false, "instant reset hasUserValue unichar");
-      ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "instant reset hasUserValue wstring");
       ok(GetXULElement(aPrefWindow, "tests.static_preference_file"   ).hasUserValue === false, "instant reset hasUserValue file"   );
 
       // done with instant apply checks
     }
 
     function RunNonInstantPrefTestGeneral(aPrefWindow)
     {
       // Non-instant apply tests are harder: not only do we need to check that
@@ -302,102 +320,103 @@
       // remark: there's currently no UI element binding for files
 
       // were all <preferences> correctly initialized?
       var expected = kPrefValueSet1;
       var found    = ReadPrefsFromPreferences(aPrefWindow);
       ok(found.int          === expected.int,          "non-instant pref init int"    );
       ok(found.bool         === expected.bool,         "non-instant pref init bool"   );
       ok(found.string       === expected.string,       "non-instant pref init string" );
-      ok(found.unichar      === expected.unichar,      "non-instant pref init unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant pref init wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant pref init unichar");
       todo(found.file_data  === expected.file_data,    "non-instant pref init file"   );
 
       // were all elements correctly initialized? (loose check)
       found = ReadPrefsFromUI(aPrefWindow);
       ok(found.int          == expected.int,          "non-instant element init int"    );
       ok(found.bool         == expected.bool,         "non-instant element init bool"   );
       ok(found.string       == expected.string,       "non-instant element init string" );
-      ok(found.unichar      == expected.unichar,      "non-instant element init unichar");
       ok(found.wstring_data == expected.wstring_data, "non-instant element init wstring");
+      ok(found.unichar_data == expected.unichar_data, "non-instant element init unichar");
       todo(found.file_data  == expected.file_data,    "non-instant element init file"   );
 
       // do some changes in the UI
       expected = kPrefValueSet2;
       WritePrefsToUI(aPrefWindow, expected);
 
       // UI changes should get passed to the <preference>s,
       // but currently they aren't if the changes are made programmatically
       // (the handlers preference.change/prefpane.input and prefpane.change
       //  are called for manual changes, though).
       found = ReadPrefsFromPreferences(aPrefWindow);
       todo(found.int          === expected.int,          "non-instant change pref int"    );
       todo(found.bool         === expected.bool,         "non-instant change pref bool"   );
       todo(found.string       === expected.string,       "non-instant change pref string" );
-      todo(found.unichar      === expected.unichar,      "non-instant change pref unichar");
       todo(found.wstring_data === expected.wstring_data, "non-instant change pref wstring");
+      todo(found.unichar_data === expected.unichar_data, "non-instant change pref unichar");
       todo(found.file_data    === expected.file_data,    "non-instant change pref file"   );
 
       // and these changes should *NOT* get passed to the system
       // (which obviously always passes with the above failing)
       expected = kPrefValueSet1;
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "non-instant change element int"    );
       ok(found.bool         === expected.bool,         "non-instant change element bool"   );
       ok(found.string       === expected.string,       "non-instant change element string" );
-      ok(found.unichar      === expected.unichar,      "non-instant change element unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant change element wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant change element unichar");
       todo(found.file_data  === expected.file_data,    "non-instant change element file"   );
 
       // try resetting the prefs to default values (which should be empty here)
       GetXULElement(aPrefWindow, "tests.static_preference_int"    ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset();
+      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset();
-      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_file"   ).reset();
 
       // check system: the current values *MUST NOT* change
       expected = kPrefValueSet1;
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "non-instant reset system int"    );
       ok(found.bool         === expected.bool,         "non-instant reset system bool"   );
       ok(found.string       === expected.string,       "non-instant reset system string" );
-      ok(found.unichar      === expected.unichar,      "non-instant reset system unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant reset system wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant reset system unichar");
       todo(found.file_data  === expected.file_data,    "non-instant reset system file"   );
 
       // check UI: these values should be reset
       expected =
       {
         // alas, we don't have XUL elements with typeof(value) == int :(
         // int:         0,
         int:          "",
         bool:         false,
         string:       "",
-        unichar:      "",
         wstring_data: "",
+        unichar_data: "",
         file_data:    "",
         wstring:      {},
+        unichar:      {},
         file:         {}
       };
       found = ReadPrefsFromUI(aPrefWindow);
       ok(found.int          === expected.int,          "non-instant reset element int"    );
       ok(found.bool         === expected.bool,         "non-instant reset element bool"   );
       ok(found.string       === expected.string,       "non-instant reset element string" );
-      ok(found.unichar      === expected.unichar,      "non-instant reset element unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant reset element wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant reset element unichar");
 //      ok(found.file_data    === expected.file_data,    "non-instant reset element file"   );
 
       // check hasUserValue
       ok(GetXULElement(aPrefWindow, "tests.static_preference_int"    ).hasUserValue === false, "non-instant reset hasUserValue int"    );
       ok(GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).hasUserValue === false, "non-instant reset hasUserValue bool"   );
       ok(GetXULElement(aPrefWindow, "tests.static_preference_string" ).hasUserValue === false, "non-instant reset hasUserValue string" );
+      ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "non-instant reset hasUserValue wstring");
       ok(GetXULElement(aPrefWindow, "tests.static_preference_unichar").hasUserValue === false, "non-instant reset hasUserValue unichar");
-      ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "non-instant reset hasUserValue wstring");
       ok(GetXULElement(aPrefWindow, "tests.static_preference_file"   ).hasUserValue === false, "non-instant reset hasUserValue file"   );
     }
 
     function RunNonInstantPrefTestClose(aPrefWindow)
     {
       WritePrefsToPreferences(aPrefWindow, kPrefValueSet2);
     }
 
@@ -410,18 +429,18 @@
     }
 
     function RunResetPrefTest(aPrefWindow)
     {
       // try resetting the prefs to default values
       GetXULElement(aPrefWindow, "tests.static_preference_int"    ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_bool"   ).reset();
       GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset();
+      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset();
-      GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset();
       GetXULElement(aPrefWindow, "tests.static_preference_file"   ).reset();
     }
 
     function InitTestPrefs(aInstantApply)
     {
       // set instant apply mode and init prefs to set 1
       kPref.setBoolPref("browser.preferences.instantApply", aInstantApply);
       WritePrefsToSystem(kPrefValueSet1);
@@ -436,18 +455,18 @@
       // - test deferred reset in child window
       InitTestPrefs(true);
       openDialog("window_preferences2.xul", "", "modal", RunResetPrefTest, false);
       expected = kPrefValueSet1;
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "instant reset deferred int"    );
       ok(found.bool         === expected.bool,         "instant reset deferred bool"   );
       ok(found.string       === expected.string,       "instant reset deferred string" );
-      ok(found.unichar      === expected.unichar,      "instant reset deferred unichar");
       ok(found.wstring_data === expected.wstring_data, "instant reset deferred wstring");
+      ok(found.unichar_data === expected.unichar_data, "instant reset deferred unichar");
       todo(found.file_data  === expected.file_data,    "instant reset deferred file"   );
     }
 
     function RunTestNonInstant()
     {
       // test without instantApply
       // - general tests, similar to instant apply
       InitTestPrefs(false);
@@ -456,42 +475,42 @@
       // - test Cancel
       InitTestPrefs(false);
       openDialog("window_preferences.xul", "", "modal", RunNonInstantPrefTestClose, false);
       var expected = kPrefValueSet1;
       var found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "non-instant cancel system int"    );
       ok(found.bool         === expected.bool,         "non-instant cancel system bool"   );
       ok(found.string       === expected.string,       "non-instant cancel system string" );
-      ok(found.unichar      === expected.unichar,      "non-instant cancel system unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant cancel system wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant cancel system unichar");
       todo(found.file_data  === expected.file_data,    "non-instant cancel system file"   );
       
       // - test Accept
       InitTestPrefs(false);
       openDialog("window_preferences.xul", "", "modal", RunNonInstantPrefTestClose, true);
       expected = kPrefValueSet2;
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "non-instant accept system int"    );
       ok(found.bool         === expected.bool,         "non-instant accept system bool"   );
       ok(found.string       === expected.string,       "non-instant accept system string" );
-      ok(found.unichar      === expected.unichar,      "non-instant accept system unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant accept system wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant accept system unichar");
       todo(found.file_data  === expected.file_data,    "non-instant accept system file"   );
 
       // - test deferred reset in child window
       InitTestPrefs(false);
       openDialog("window_preferences2.xul", "", "modal", RunResetPrefTest, true);
       expected = CreateEmptyPrefValueSet();
       found    = ReadPrefsFromSystem();
       ok(found.int          === expected.int,          "non-instant reset deferred int"    );
       ok(found.bool         === expected.bool,         "non-instant reset deferred bool"   );
       ok(found.string       === expected.string,       "non-instant reset deferred string" );
-      ok(found.unichar      === expected.unichar,      "non-instant reset deferred unichar");
       ok(found.wstring_data === expected.wstring_data, "non-instant reset deferred wstring");
+      ok(found.unichar_data === expected.unichar_data, "non-instant reset deferred unichar");
       ok(found.file_data    === expected.file_data,    "non-instant reset deferred file"   );
     }
 
     function RunTestCommandRedirect()
     {
       openDialog("window_preferences_commandretarget.xul", "", "modal", RunCheckCommandRedirect, true);
     }
 
--- a/toolkit/modules/Preferences.jsm
+++ b/toolkit/modules/Preferences.jsm
@@ -42,33 +42,27 @@ this.Preferences =
  * @param   defaultValue
  *          the default value, if any, for prefs that don't have one
  *
  * @param   valueType
  *          the XPCOM interface of the pref's complex value type, if any
  *
  * @returns the value of the pref, if any; otherwise the default value
  */
-Preferences.get = function(prefName, defaultValue, valueType = null) {
+Preferences.get = function(prefName, defaultValue, valueType = Ci.nsISupportsString) {
   if (Array.isArray(prefName))
     return prefName.map(v => this.get(v, defaultValue));
 
   return this._get(prefName, defaultValue, valueType);
 };
 
 Preferences._get = function(prefName, defaultValue, valueType) {
   switch (this._prefBranch.getPrefType(prefName)) {
     case Ci.nsIPrefBranch.PREF_STRING:
-      if (valueType) {
-        let ifaces = ["nsIFile", "nsIPrefLocalizedString"];
-        if (ifaces.includes(valueType.name)) {
-          return this._prefBranch.getComplexValue(prefName, valueType).data;
-        }
-      }
-      return this._prefBranch.getStringPref(prefName);
+      return this._prefBranch.getComplexValue(prefName, valueType).data;
 
     case Ci.nsIPrefBranch.PREF_INT:
       return this._prefBranch.getIntPref(prefName);
 
     case Ci.nsIPrefBranch.PREF_BOOL:
       return this._prefBranch.getBoolPref(prefName);
 
     case Ci.nsIPrefBranch.PREF_INVALID:
--- a/toolkit/modules/Troubleshoot.jsm
+++ b/toolkit/modules/Troubleshoot.jsm
@@ -99,16 +99,17 @@ const PREFS_WHITELIST = [
 // The blacklist, unlike the whitelist, is a list of regular expressions.
 const PREFS_BLACKLIST = [
   /^network[.]proxy[.]/,
   /[.]print_to_filename$/,
   /^print[.]macosx[.]pagesetup/,
 ];
 
 // Table of getters for various preference types.
+// It's important to use getComplexValue for strings: it returns Unicode (wchars), getCharPref returns UTF-8 encoded chars.
 const PREFS_GETTERS = {};
 
 PREFS_GETTERS[Ci.nsIPrefBranch.PREF_STRING] = (prefs, name) => prefs.getStringPref(name);
 PREFS_GETTERS[Ci.nsIPrefBranch.PREF_INT] = (prefs, name) => prefs.getIntPref(name);
 PREFS_GETTERS[Ci.nsIPrefBranch.PREF_BOOL] = (prefs, name) => prefs.getBoolPref(name);
 
 // Return the preferences filtered by PREFS_BLACKLIST and PREFS_WHITELIST lists
 // and also by the custom 'filter'-ing function.
--- a/toolkit/modules/tests/xpcshell/test_Preferences.js
+++ b/toolkit/modules/tests/xpcshell/test_Preferences.js
@@ -107,17 +107,19 @@ add_test(function test_set_unsupported_p
     Preferences.set("test_set_unsupported_pref", []);
     // We expect this to throw, so the test is designed to fail if it doesn't.
     do_check_true(false);
   } catch (ex) {}
 
   run_next_test();
 });
 
-// Make sure that we can get a string pref that we didn't set ourselves.
+// Make sure that we can get a string pref that we didn't set ourselves
+// (i.e. that the way we get a string pref using getComplexValue doesn't
+// hork us getting a string pref that wasn't set using setComplexValue).
 add_test(function test_get_string_pref() {
   let svc = Cc["@mozilla.org/preferences-service;1"].
             getService(Ci.nsIPrefService).
             getBranch("");
   svc.setCharPref("test_get_string_pref", "a normal string");
   do_check_eq(Preferences.get("test_get_string_pref"), "a normal string");
 
   // Clean up.
--- a/tools/lint/docs/linters/eslint-plugin-mozilla.rst
+++ b/tools/lint/docs/linters/eslint-plugin-mozilla.rst
@@ -54,16 +54,21 @@ Often timing relative to the page load i
 be necessary.
 
 avoid-removeChild
 -----------------
 
 Rejects using element.parentNode.removeChild(element) when element.remove()
 can be used instead.
 
+avoid-nsISupportsString-preferences
+-----------------------------------
+
+Rejects using getComplexValue and setComplexValue with nsISupportsString.
+
 balanced-listeners
 ------------------
 
 Checks that for every occurence of 'addEventListener' or 'on' there is an
 occurence of 'removeEventListener' or 'off' with the same event name.
 
 import-browser-window-globals
 -----------------------------
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
@@ -132,16 +132,17 @@ module.exports = {
 
     // Don't enforce the maximum depth that blocks can be nested. The complexity
     // rule is a better rule to check this.
     "max-depth": "off",
 
     // Maximum depth callbacks can be nested.
     "max-nested-callbacks": ["error", 10],
 
+    "mozilla/avoid-nsISupportsString-preferences": "error",
     "mozilla/avoid-removeChild": "error",
     "mozilla/import-browser-window-globals": "error",
     "mozilla/import-globals": "error",
     "mozilla/no-import-into-var-and-global": "error",
     "mozilla/no-useless-parameters": "error",
     "mozilla/no-useless-removeEventListener": "error",
     "mozilla/use-default-preference-values": "error",
     "mozilla/use-ownerGlobal": "error",
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -27,16 +27,18 @@ module.exports = {
     "simpletest": require("../lib/environments/simpletest.js")
   },
   processors: {
     ".xml": require("../lib/processors/xbl-bindings")
   },
   rules: {
     "avoid-Date-timing": require("../lib/rules/avoid-Date-timing"),
     "avoid-removeChild": require("../lib/rules/avoid-removeChild"),
+    "avoid-nsISupportsString-preferences":
+      require("../lib/rules/avoid-nsISupportsString-preferences"),
     "balanced-listeners": require("../lib/rules/balanced-listeners"),
     "import-browser-window-globals":
       require("../lib/rules/import-browser-window-globals"),
     "import-content-task-globals":
       require("../lib/rules/import-content-task-globals"),
     "import-globals": require("../lib/rules/import-globals"),
     "import-headjs-globals": require("../lib/rules/import-headjs-globals"),
     "mark-test-function-used": require("../lib/rules/mark-test-function-used"),
@@ -59,16 +61,17 @@ module.exports = {
       require("../lib/rules/use-default-preference-values"),
     "use-ownerGlobal": require("../lib/rules/use-ownerGlobal"),
     "use-services": require("../lib/rules/use-services"),
     "var-only-at-top-level": require("../lib/rules/var-only-at-top-level")
   },
   rulesConfig: {
     "avoid-Date-timing": "off",
     "avoid-removeChild": "off",
+    "avoid-nsISupportsString-preferences": "off",
     "balanced-listeners": "off",
     "import-browser-window-globals": "off",
     "import-content-task-globals": "off",
     "import-globals": "off",
     "import-headjs-globals": "off",
     "mark-test-function-used": "off",
     "no-aArgs": "off",
     "no-arbitrary-setTimeout": "off",
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/avoid-nsISupportsString-preferences.js
@@ -0,0 +1,49 @@
+/**
+ * @fileoverview Rejects using getComplexValue and setComplexValue with
+ *               nsISupportsString.
+ *
+ * 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 strict";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+function isNsISupportsString(arg) {
+  let isNsISupportsStringIdentifier = obj =>
+    obj.type == "Identifier" && obj.name == "nsISupportsString";
+  return isNsISupportsStringIdentifier(arg) ||
+         (arg.type == "MemberExpression" &&
+          isNsISupportsStringIdentifier(arg.property));
+}
+
+module.exports = function(context) {
+
+  // ---------------------------------------------------------------------------
+  // Public
+  //  --------------------------------------------------------------------------
+
+  return {
+    "CallExpression": function(node) {
+      let callee = node.callee;
+      if (callee.type !== "MemberExpression" ||
+          callee.property.type !== "Identifier" ||
+          node.arguments.length < 2 ||
+          !isNsISupportsString(node.arguments[1])) {
+        return;
+      }
+
+      if (callee.property.name == "getComplexValue") {
+        context.report(node, "use getStringPref instead of " +
+                             "getComplexValue with nsISupportsString");
+      } else if (callee.property.name == "setComplexValue") {
+        context.report(node, "use setStringPref instead of " +
+                             "setComplexValue with nsISupportsString");
+      }
+    }
+  };
+};
--- a/tools/lint/eslint/eslint-plugin-mozilla/package.json
+++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json
@@ -1,11 +1,11 @@
 {
   "name": "eslint-plugin-mozilla",
-  "version": "0.4.7",
+  "version": "0.4.6",
   "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
   "keywords": [
     "eslint",
     "eslintplugin",
     "eslint-plugin",
     "mozilla",
     "firefox"
   ],
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-nsISupportsString-preferences.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require("../lib/rules/avoid-nsISupportsString-preferences");
+var RuleTester = require("eslint/lib/testers/rule-tester");
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+function invalidCode(code, accessType = "get") {
+  let message = "use " + accessType + "StringPref instead of " +
+                accessType + "ComplexValue with nsISupportsString";
+  return {code, errors: [{message, type: "CallExpression"}]};
+}
+
+ruleTester.run("avoid-nsISupportsString-preferences", rule, {
+  valid: [
+    "branch.getStringPref('name');",
+    "branch.getComplexValue('name', Ci.nsIPrefLocalizedString);",
+    "branch.setStringPref('name', 'blah');",
+    "branch.setComplexValue('name', Ci.nsIPrefLocalizedString, pref);"
+  ],
+  invalid: [
+    invalidCode("branch.getComplexValue('name', Ci.nsISupportsString);"),
+    invalidCode("branch.getComplexValue('name', nsISupportsString);"),
+    invalidCode("branch.getComplexValue('name', Ci.nsISupportsString).data;"),
+    invalidCode("branch.setComplexValue('name', Ci.nsISupportsString, str);",
+                "set"),
+    invalidCode("branch.setComplexValue('name', nsISupportsString, str);",
+                "set")
+  ]
+});
--- a/tools/profiler/lul/LulDwarf.cpp
+++ b/tools/profiler/lul/LulDwarf.cpp
@@ -287,21 +287,21 @@ uint64 ByteReader::ReadEncodedPointer(co
 // except that we need instances to be EqualityComparable, too.
 //
 // This could logically be nested within State, but then the qualified names
 // get horrendous.
 class CallFrameInfo::Rule {
  public:
   virtual ~Rule() { }
 
-  // Tell HANDLER that, at ADDRESS in the program, REGISTER can be
-  // recovered using this rule. If REGISTER is kCFARegister, then this rule
+  // Tell HANDLER that, at ADDRESS in the program, REG can be
+  // recovered using this rule. If REG is kCFARegister, then this rule
   // describes how to compute the canonical frame address. Return what the
   // HANDLER member function returned.
-  virtual bool Handle(Handler *handler, uint64 address, int register) const = 0;
+  virtual bool Handle(Handler *handler, uint64 address, int reg) const = 0;
 
   // Equality on rules. We use these to decide which rules we need
   // to report after a DW_CFA_restore_state instruction.
   virtual bool operator==(const Rule &rhs) const = 0;
 
   bool operator!=(const Rule &rhs) const { return ! (*this == rhs); }
 
   // Return a pointer to a copy of this rule.
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -1,13 +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 "InProcessCompositorWidget.h"
+
+#include "mozilla/VsyncDispatcher.h"
 #include "nsBaseWidget.h"
 
 #if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
 #include "mozilla/widget/AndroidCompositorWidget.h"
 #endif
 
 namespace mozilla {
 namespace widget {
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InputData.h"
 
 #include "mozilla/dom/Touch.h"
+#include "mozilla/TextEvents.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsThreadUtils.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "UnitTransforms.h"
 
 namespace mozilla {
--- a/widget/ScreenManager.cpp
+++ b/widget/ScreenManager.cpp
@@ -3,26 +3,27 @@
 /* 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 "ScreenManager.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/DOMTypes.h"
 #include "mozilla/Logging.h"
 #include "mozilla/StaticPtr.h"
 
-static LazyLogModule sScreenLog("WidgetScreen");
-
-NS_IMPL_ISUPPORTS(ScreenManager, nsIScreenManager)
+static mozilla::LazyLogModule sScreenLog("WidgetScreen");
 
 namespace mozilla {
 namespace widget {
 
+NS_IMPL_ISUPPORTS(ScreenManager, nsIScreenManager)
+
 ScreenManager::ScreenManager()
 {
 }
 
 ScreenManager::~ScreenManager()
 {
 }
 
@@ -73,31 +74,31 @@ ScreenManager::Refresh(nsTArray<mozilla:
 
   CopyScreensToAllRemotesIfIsParent();
 }
 
 template<class Range>
 void
 ScreenManager::CopyScreensToRemoteRange(Range aRemoteRange)
 {
-  AutoTArray<ScreenDetails, 4> screens;
+  AutoTArray<dom::ScreenDetails, 4> screens;
   for (auto& screen : mScreenList) {
     screens.AppendElement(screen->ToScreenDetails());
   }
   for (auto cp : aRemoteRange) {
     MOZ_LOG(sScreenLog, LogLevel::Debug, ("Send screens to [Pid %d]", cp->Pid()));
     if (!cp->SendRefreshScreens(screens)) {
       MOZ_LOG(sScreenLog, LogLevel::Error,
               ("SendRefreshScreens to [Pid %d] failed", cp->Pid()));
     }
   }
 }
 
 void
-ScreenManager::CopyScreensToRemote(ContentParent* aContentParent)
+ScreenManager::CopyScreensToRemote(dom::ContentParent* aContentParent)
 {
   MOZ_ASSERT(aContentParent);
   MOZ_ASSERT(XRE_IsParentProcess());
 
   auto range = { aContentParent };
   CopyScreensToRemoteRange(range);
 }
 
@@ -105,17 +106,17 @@ void
 ScreenManager::CopyScreensToAllRemotesIfIsParent()
 {
   if (XRE_IsContentProcess()) {
     return;
   }
 
   MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing all ContentParents"));
 
-  CopyScreensToRemoteRange(ContentParent::AllProcesses(ContentParent::eLive));
+  CopyScreensToRemoteRange(dom::ContentParent::AllProcesses(dom::ContentParent::eLive));
 }
 
 // Returns the screen that contains the rectangle. If the rect overlaps
 // multiple screens, it picks the screen with the greatest area of intersection.
 //
 // The coordinates are in desktop pixels.
 //
 NS_IMETHODIMP
--- a/widget/nsAutoRollup.h
+++ b/widget/nsAutoRollup.h
@@ -2,18 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsAutoRollup_h__
 #define nsAutoRollup_h__
 
 #include "mozilla/Attributes.h"     // for MOZ_RAII
 #include "mozilla/StaticPtr.h"      // for StaticRefPtr
-
-class nsIContent;
+#include "nsIContent.h"
 
 namespace mozilla {
 namespace widget {
 
 // A situation can occur when a mouse event occurs over a menu label while the
 // menu popup is already open. The expected behaviour is to close the popup.
 // This happens by calling nsIRollupListener::Rollup before the mouse event is
 // processed. However, in cases where the mouse event is not consumed, this
--- a/widget/nsBaseAppShell.cpp
+++ b/widget/nsBaseAppShell.cpp
@@ -8,16 +8,17 @@
 #include "nsBaseAppShell.h"
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #endif
 #include "nsThreadUtils.h"
 #include "nsIObserverService.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/Services.h"
+#include "nsXULAppAPI.h"
 
 // When processing the next thread event, the appshell may process native
 // events (if not in performance mode), which can result in suppressing the
 // next thread event for at most this many ticks:
 #define THREAD_EVENT_STARVATION_LIMIT PR_MillisecondsToInterval(10)
 
 NS_IMPL_ISUPPORTS(nsBaseAppShell, nsIAppShell, nsIThreadObserver, nsIObserver)
 
--- a/widget/nsBaseClipboard.h
+++ b/widget/nsBaseClipboard.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsBaseClipboard_h__
 #define nsBaseClipboard_h__
 
 #include "nsIClipboard.h"
 #include "nsITransferable.h"
+#include "nsCOMPtr.h"
 
 class nsITransferable;
 class nsIClipboardOwner;
 class nsIWidget;
 
 /**
  * Native Win32 BaseClipboard wrapper
  */
--- a/widget/nsDragServiceProxy.cpp
+++ b/widget/nsDragServiceProxy.cpp
@@ -11,16 +11,18 @@
 #include "mozilla/gfx/2D.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"
 
 using mozilla::ipc::Shmem;
 using mozilla::dom::TabChild;
 using mozilla::dom::OptionalShmem;
+using mozilla::LayoutDeviceIntRect;
+using mozilla::Maybe;
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsDragServiceProxy, nsBaseDragService)
 
 nsDragServiceProxy::nsDragServiceProxy()
 {
 }
 
 nsDragServiceProxy::~nsDragServiceProxy()