Merge inbound to mozilla-central. a=merge
authorMargareta Eliza Balazs <ebalazs@mozilla.com>
Fri, 17 Aug 2018 12:46:14 +0300
changeset 432090 b84213ec5a4d
parent 432089 d2ba1d6c76f2 (current diff)
parent 432056 5a0c5138ce9e (diff)
child 432091 7f8f670aefa5
child 432096 131363332762
child 432160 10d94a3e667f
push id106627
push userebalazs@mozilla.com
push dateFri, 17 Aug 2018 09:52:13 +0000
treeherdermozilla-inbound@b84213ec5a4d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
b84213ec5a4d / 63.0a1 / 20180817100105 / files
nightly linux64
b84213ec5a4d / 63.0a1 / 20180817100105 / files
nightly mac
b84213ec5a4d / 63.0a1 / 20180817100105 / files
nightly win32
b84213ec5a4d / 63.0a1 / 20180817100105 / files
nightly win64
b84213ec5a4d / 63.0a1 / 20180817100105 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
dom/interfaces/base/nsIDOMWindowUtils.idl
js/src/tests/test262/built-ins/Atomics/wake/bad-range.js
js/src/tests/test262/built-ins/Atomics/wake/count-boundary-cases.js
js/src/tests/test262/built-ins/Atomics/wake/count-defaults-to-infinity-missing.js
js/src/tests/test262/built-ins/Atomics/wake/count-defaults-to-infinity-undefined.js
js/src/tests/test262/built-ins/Atomics/wake/count-from-nans.js
js/src/tests/test262/built-ins/Atomics/wake/count-symbol-throws.js
js/src/tests/test262/built-ins/Atomics/wake/count-tointeger-throws-then-wake-throws.js
js/src/tests/test262/built-ins/Atomics/wake/descriptor.js
js/src/tests/test262/built-ins/Atomics/wake/length.js
js/src/tests/test262/built-ins/Atomics/wake/name.js
js/src/tests/test262/built-ins/Atomics/wake/negative-count.js
js/src/tests/test262/built-ins/Atomics/wake/negative-index-throws.js
js/src/tests/test262/built-ins/Atomics/wake/non-int32-typedarray-throws.js
js/src/tests/test262/built-ins/Atomics/wake/non-shared-bufferdata-throws.js
js/src/tests/test262/built-ins/Atomics/wake/non-views.js
js/src/tests/test262/built-ins/Atomics/wake/not-a-typedarray-throws.js
js/src/tests/test262/built-ins/Atomics/wake/not-an-object-throws.js
js/src/tests/test262/built-ins/Atomics/wake/null-bufferdata-throws.js
js/src/tests/test262/built-ins/Atomics/wake/out-of-range-index-throws.js
js/src/tests/test262/built-ins/Atomics/wake/shared-nonint-views.js
js/src/tests/test262/built-ins/Atomics/wake/shell.js
js/src/tests/test262/built-ins/Atomics/wake/symbol-for-index-throws.js
js/src/tests/test262/built-ins/Atomics/wake/undefined-index-defaults-to-zero.js
js/src/tests/test262/built-ins/Atomics/wake/wake-all-on-loc.js
js/src/tests/test262/built-ins/Atomics/wake/wake-all.js
js/src/tests/test262/built-ins/Atomics/wake/wake-in-order.js
js/src/tests/test262/built-ins/Atomics/wake/wake-nan.js
js/src/tests/test262/built-ins/Atomics/wake/wake-one.js
js/src/tests/test262/built-ins/Atomics/wake/wake-rewake-noop.js
js/src/tests/test262/built-ins/Atomics/wake/wake-two.js
js/src/tests/test262/built-ins/Atomics/wake/wake-with-no-agents-waiting.js
js/src/tests/test262/built-ins/Atomics/wake/wake-with-no-matching-agents-waiting.js
js/src/tests/test262/built-ins/Atomics/wake/wake-zero.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A1_T1.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A1_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A1_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A1_T4.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A1_T5.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A2_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A2_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A2_T4.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A2_T5.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A3_T1.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A3_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A3_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A3_T4.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A4_T1.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A4_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A4_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A4_T4.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A5_T1.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A5_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A5_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A5_T4.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A6_T1.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A6_T2.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A6_T3.js
js/src/tests/test262/built-ins/RegExp/S15.10.2.12_A6_T4.js
js/src/tests/test262/built-ins/RegExp/property-escapes/binary-properties-with-value.js
js/src/tests/test262/built-ins/RegExp/property-escapes/grammar-extensions.js
js/src/tests/test262/built-ins/RegExp/property-escapes/loose-matching.js
js/src/tests/test262/built-ins/RegExp/property-escapes/non-binary-properties-without-value.js
js/src/tests/test262/built-ins/RegExp/property-escapes/non-existent-properties.js
js/src/tests/test262/built-ins/RegExp/property-escapes/non-existent-property-values.js
js/src/tests/test262/built-ins/RegExp/property-escapes/unsupported-binary-properties.js
js/src/tests/test262/built-ins/RegExp/property-escapes/unsupported-properties.js
js/src/tests/test262/harness/assert-throws-early-not-early.js
js/src/tests/test262/language/literals/string/7.8.4-1gs-strict.js
layout/reftests/flexbox/flexbox-align-content-horizrev-001-ref.xhtml
layout/reftests/flexbox/flexbox-align-content-horizrev-001.xhtml
layout/reftests/flexbox/flexbox-align-content-vertrev-001-ref.xhtml
layout/reftests/flexbox/flexbox-align-content-vertrev-001.xhtml
modules/libpref/init/all.js
testing/web-platform/meta/css/css-transforms/transform-origin-in-shadow.html.ini
testing/web-platform/meta/dom/nodes/rootNode.html.ini
testing/web-platform/meta/html/editing/editing-0/contenteditable/contentEditable-slotted-inherit.html.ini
testing/web-platform/meta/html/semantics/document-metadata/the-link-element/link-rel-attribute.html.ini
testing/web-platform/meta/pointerlock/interfaces.window.js.ini
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1873,17 +1873,16 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "selectors"
 version = "0.19.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.1.1",
  "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/Makefile.in
+++ b/Makefile.in
@@ -306,21 +306,18 @@ package-generated-sources:
 # PGO support, but we can't do this test in client.mk
 # No point in clobbering if PGO has been explicitly disabled.
 ifdef NO_PROFILE_GUIDED_OPTIMIZE
 maybe_clobber_profiledbuild:
 else
 ifneq ($(CC_TYPE),msvc)
 maybe_clobber_profiledbuild: clean
 ifneq (,$(findstring clang,$(CC_TYPE)))
-# 32-bit Windows PGO is currently blocked by bug 1479800
-ifneq ($(CC_TYPE)_$(CPU_ARCH),clang-cl_x86)
 	$(LLVM_PROFDATA) merge -o $(DEPTH)/merged.profdata $(DEPTH)/*.profraw
 endif
-endif
 else
 maybe_clobber_profiledbuild:
 	$(RM) $(DIST)/bin/*.pgc
 	find $(DIST)/$(MOZ_APP_NAME) -name '*.pgc' -exec mv {} $(DIST)/bin \;
 endif # msvc
 endif # NO_PROFILE_GUIDED_OPTIMIZE
 
 .PHONY: maybe_clobber_profiledbuild
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -144,16 +144,17 @@ support-files =
 [browser_urlbar_search_no_speculative_connect_with_client_cert.js]
 [browser_urlbar_stop_pending.js]
 support-files =
   slow-page.sjs
 [browser_urlbar_remoteness_switch.js]
 run-if = e10s
 [browser_urlHighlight.js]
 [browser_urlOverflow.js]
+skip-if = true # Bug 1482557
 [browser_wyciwyg_urlbarCopying.js]
 subsuite = clipboard
 support-files =
   test_wyciwyg_copying.html
 [browser_urlbarStopSearchOnSelection.js]
 support-files =
   searchSuggestionEngineSlow.xml
   searchSuggestionEngine.sjs
--- a/browser/extensions/formautofill/api.js
+++ b/browser/extensions/formautofill/api.js
@@ -1,17 +1,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/. */
 
 "use strict";
 
 /* globals ExtensionAPI */
 
-const STYLESHEET_URI = "chrome://formautofill/content/formautofill.css";
 const CACHED_STYLESHEETS = new WeakMap();
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "FormAutofill",
                                "resource://formautofill/FormAutofill.jsm");
 ChromeUtils.defineModuleGetter(this, "formAutofillParent",
@@ -39,17 +38,19 @@ function insertStyleSheet(domWindow, url
 
 function onMaybeOpenPopup(evt) {
   let domWindow = evt.target.ownerGlobal;
   if (CACHED_STYLESHEETS.has(domWindow)) {
     // This window already has autofill stylesheets.
     return;
   }
 
-  insertStyleSheet(domWindow, STYLESHEET_URI);
+  insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css");
+  insertStyleSheet(domWindow, "resource://formautofill/autocomplete-item-shared.css");
+  insertStyleSheet(domWindow, "resource://formautofill/autocomplete-item.css");
 }
 
 function isAvailable() {
   let availablePref = Services.prefs.getCharPref("extensions.formautofill.available");
   if (availablePref == "on") {
     return true;
   } else if (availablePref == "detect") {
     let locale = Services.locale.getRequestedLocale();
--- a/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js
+++ b/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js
@@ -67,16 +67,18 @@ add_task(async function test_phishing_wa
   await BrowserTestUtils.withNewTab({gBrowser, url: URL}, async function(browser) {
     const {autoCompletePopup: {richlistbox: itemsBox}} = browser;
 
     await openPopupOn(browser, "#tel");
     const warningBox = itemsBox.querySelector(".autocomplete-richlistitem:last-child")._warningTextBox;
     ok(warningBox, "Got phishing warning box");
 
     await expectWarningText(browser, "Autofills phone");
+    is(warningBox.ownerGlobal.getComputedStyle(warningBox).backgroundColor,
+       "rgba(248, 232, 28, 0.2)", "Check warning text background color");
 
     await closePopup(browser);
   });
 });
 
 add_task(async function test_phishing_warning_complex_categories() {
   await BrowserTestUtils.withNewTab({gBrowser, url: URL}, async function(browser) {
     await openPopupOn(browser, "#street-address");
--- a/build/build-clang/build-clang.py
+++ b/build/build-clang/build-clang.py
@@ -58,16 +58,24 @@ def import_clang_tidy(source_dir):
     sys.path.append(clang_plugin_path)
     from import_mozilla_checks import do_import
     do_import(clang_plugin_path, clang_tidy_path)
 
 
 def build_package(package_build_dir, cmake_args):
     if not os.path.exists(package_build_dir):
         os.mkdir(package_build_dir)
+    # If CMake has already been run, it may have been run with different
+    # arguments, so we need to re-run it.  Make sure the cached copy of the
+    # previous CMake run is cleared before running it again.
+    if os.path.exists(package_build_dir + "/CMakeCache.txt"):
+        os.remove(package_build_dir + "/CMakeCache.txt")
+    if os.path.exists(package_build_dir + "/CMakeFiles"):
+        shutil.rmtree(package_build_dir + "/CMakeFiles")
+
     run_in(package_build_dir, ["cmake"] + cmake_args)
     run_in(package_build_dir, ["ninja", "install"])
 
 
 @contextmanager
 def updated_env(env):
     old_env = os.environ.copy()
     os.environ.update(env)
@@ -171,83 +179,125 @@ def is_linux():
 
 def is_windows():
     return platform.system() == "Windows"
 
 
 def build_one_stage(cc, cxx, asm, ld, ar, ranlib, libtool,
                     src_dir, stage_dir, build_libcxx,
                     osx_cross_compile, build_type, assertions,
-                    python_path, gcc_dir, libcxx_include_dir):
+                    python_path, gcc_dir, libcxx_include_dir,
+                    is_final_stage=False):
     if not os.path.exists(stage_dir):
         os.mkdir(stage_dir)
 
     build_dir = stage_dir + "/build"
     inst_dir = stage_dir + "/clang"
 
-    # If CMake has already been run, it may have been run with different
-    # arguments, so we need to re-run it.  Make sure the cached copy of the
-    # previous CMake run is cleared before running it again.
-    if os.path.exists(build_dir + "/CMakeCache.txt"):
-        os.remove(build_dir + "/CMakeCache.txt")
-    if os.path.exists(build_dir + "/CMakeFiles"):
-        shutil.rmtree(build_dir + "/CMakeFiles")
-
     # cmake doesn't deal well with backslashes in paths.
     def slashify_path(path):
         return path.replace('\\', '/')
 
-    cmake_args = ["-GNinja",
-                  "-DCMAKE_C_COMPILER=%s" % slashify_path(cc[0]),
-                  "-DCMAKE_CXX_COMPILER=%s" % slashify_path(cxx[0]),
-                  "-DCMAKE_ASM_COMPILER=%s" % slashify_path(asm[0]),
-                  "-DCMAKE_LINKER=%s" % slashify_path(ld[0]),
-                  "-DCMAKE_AR=%s" % slashify_path(ar),
-                  "-DCMAKE_C_FLAGS=%s" % ' '.join(cc[1:]),
-                  "-DCMAKE_CXX_FLAGS=%s" % ' '.join(cxx[1:]),
-                  "-DCMAKE_ASM_FLAGS=%s" % ' '.join(asm[1:]),
-                  "-DCMAKE_EXE_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
-                  "-DCMAKE_SHARED_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
-                  "-DCMAKE_BUILD_TYPE=%s" % build_type,
-                  "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64",
-                  "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
-                  "-DPYTHON_EXECUTABLE=%s" % slashify_path(python_path),
-                  "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
-                  "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"),
-                  "-DLIBCXX_LIBCPPABI_VERSION=\"\"",
-                  src_dir]
-    if is_windows():
-        cmake_args.insert(-1, "-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON")
-        cmake_args.insert(-1, "-DLLVM_USE_CRT_RELEASE=MT")
-    if ranlib is not None:
-        cmake_args += ["-DCMAKE_RANLIB=%s" % slashify_path(ranlib)]
-    if libtool is not None:
-        cmake_args += ["-DCMAKE_LIBTOOL=%s" % slashify_path(libtool)]
-    if osx_cross_compile:
-        cmake_args += ["-DCMAKE_SYSTEM_NAME=Darwin",
-                       "-DCMAKE_SYSTEM_VERSION=10.10",
-                       "-DLLVM_ENABLE_THREADS=OFF",
-                       "-DLIBCXXABI_LIBCXX_INCLUDES=%s" % libcxx_include_dir,
-                       "-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
-                       "-DCMAKE_FIND_ROOT_PATH=%s" % slashify_path(os.getenv("CROSS_CCTOOLS_PATH")), # noqa
-                       "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
-                       "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
-                       "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
-                       "-DCMAKE_MACOSX_RPATH=ON",
-                       "-DCMAKE_OSX_ARCHITECTURES=x86_64",
-                       "-DDARWIN_osx_ARCHS=x86_64",
-                       "-DDARWIN_osx_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
-                       "-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-apple-darwin11"]
+    def cmake_base_args(cc, cxx, asm, ld, ar, ranlib, libtool, inst_dir):
+        cmake_args = [
+            "-GNinja",
+            "-DCMAKE_C_COMPILER=%s" % slashify_path(cc[0]),
+            "-DCMAKE_CXX_COMPILER=%s" % slashify_path(cxx[0]),
+            "-DCMAKE_ASM_COMPILER=%s" % slashify_path(asm[0]),
+            "-DCMAKE_LINKER=%s" % slashify_path(ld[0]),
+            "-DCMAKE_AR=%s" % slashify_path(ar),
+            "-DCMAKE_C_FLAGS=%s" % ' '.join(cc[1:]),
+            "-DCMAKE_CXX_FLAGS=%s" % ' '.join(cxx[1:]),
+            "-DCMAKE_ASM_FLAGS=%s" % ' '.join(asm[1:]),
+            "-DCMAKE_EXE_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
+            "-DCMAKE_SHARED_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
+            "-DCMAKE_BUILD_TYPE=%s" % build_type,
+            "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
+            "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64",
+            "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
+            "-DPYTHON_EXECUTABLE=%s" % slashify_path(python_path),
+            "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"),
+            "-DLIBCXX_LIBCPPABI_VERSION=\"\"",
+        ]
+        if is_windows():
+            cmake_args.insert(-1, "-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON")
+            cmake_args.insert(-1, "-DLLVM_USE_CRT_RELEASE=MT")
+        if ranlib is not None:
+            cmake_args += ["-DCMAKE_RANLIB=%s" % slashify_path(ranlib)]
+        if libtool is not None:
+            cmake_args += ["-DCMAKE_LIBTOOL=%s" % slashify_path(libtool)]
+        if osx_cross_compile:
+            cmake_args += [
+                "-DCMAKE_SYSTEM_NAME=Darwin",
+                "-DCMAKE_SYSTEM_VERSION=10.10",
+                "-DLLVM_ENABLE_THREADS=OFF",
+                "-DLIBCXXABI_LIBCXX_INCLUDES=%s" % libcxx_include_dir,
+                "-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
+                "-DCMAKE_FIND_ROOT_PATH=%s" % slashify_path(os.getenv("CROSS_CCTOOLS_PATH")), # noqa
+                "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
+                "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
+                "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
+                "-DCMAKE_MACOSX_RPATH=ON",
+                "-DCMAKE_OSX_ARCHITECTURES=x86_64",
+                "-DDARWIN_osx_ARCHS=x86_64",
+                "-DDARWIN_osx_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
+                "-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-apple-darwin11"
+            ]
+        return cmake_args
+
+    cmake_args = cmake_base_args(
+        cc, cxx, asm, ld, ar, ranlib, libtool, inst_dir)
+    cmake_args += [
+        src_dir
+    ]
     build_package(build_dir, cmake_args)
 
     if is_linux():
         install_libgcc(gcc_dir, inst_dir)
     # For some reasons the import library clang.lib of clang.exe is not
     # installed, so we copy it by ourselves.
     if is_windows():
+        # The compiler-rt cmake scripts don't allow to build it for multiple
+        # targets at once on Windows, so manually build the 32-bits compiler-rt
+        # during the final stage.
+        build_32_bit = False
+        if is_final_stage:
+            # Only build the 32-bits compiler-rt when we originally built for
+            # 64-bits, which we detect through the contents of the LIB
+            # environment variable, which we also adjust for a 32-bits build
+            # at the same time.
+            old_lib = os.environ['LIB']
+            new_lib = []
+            for l in old_lib.split(os.pathsep):
+                if l.endswith('x64'):
+                    l = l[:-3] + 'x86'
+                    build_32_bit = True
+                elif l.endswith('amd64'):
+                    l = l[:-5]
+                    build_32_bit = True
+                new_lib.append(l)
+        if build_32_bit:
+            os.environ['LIB'] = os.pathsep.join(new_lib)
+            compiler_rt_build_dir = stage_dir + '/compiler-rt'
+            compiler_rt_inst_dir = inst_dir + '/lib/clang/'
+            subdirs = os.listdir(compiler_rt_inst_dir)
+            assert len(subdirs) == 1
+            compiler_rt_inst_dir += subdirs[0]
+            cmake_args = cmake_base_args(
+                [os.path.join(inst_dir, 'bin', 'clang-cl.exe'), '-m32'] + cc[1:],
+                [os.path.join(inst_dir, 'bin', 'clang-cl.exe'), '-m32'] + cxx[1:],
+                [os.path.join(inst_dir, 'bin', 'clang-cl.exe'), '-m32'] + asm[1:],
+                ld, ar, ranlib, libtool, compiler_rt_inst_dir)
+            cmake_args += [
+                '-DLLVM_CONFIG_PATH=%s' % slashify_path(
+                    os.path.join(inst_dir, 'bin', 'llvm-config')),
+                os.path.join(src_dir, 'projects', 'compiler-rt'),
+            ]
+            build_package(compiler_rt_build_dir, cmake_args)
+            os.environ['LIB'] = old_lib
         install_import_library(build_dir, inst_dir)
         install_asan_symbols(build_dir, inst_dir)
 
 
 # Return the absolute path of a build tool.  We first look to see if the
 # variable is defined in the config file, and if so we make sure it's an
 # absolute path to an existing tool, otherwise we look for a program in
 # $PATH named "key".
@@ -610,32 +660,34 @@ if __name__ == "__main__":
                 (cc_name, exe_ext)] + extra_cflags2,
             [stage1_inst_dir + "/bin/%s%s" %
                 (cxx_name, exe_ext)] + extra_cxxflags2,
             [stage1_inst_dir + "/bin/%s%s" %
                 (cc_name, exe_ext)] + extra_asmflags,
             [ld] + extra_ldflags,
             ar, ranlib, libtool,
             llvm_source_dir, stage2_dir, build_libcxx, osx_cross_compile,
-            build_type, assertions, python_path, gcc_dir, libcxx_include_dir)
+            build_type, assertions, python_path, gcc_dir, libcxx_include_dir,
+            stages == 2)
 
     if stages > 2:
         stage3_dir = build_dir + '/stage3'
         final_stage_dir = stage3_dir
         build_one_stage(
             [stage2_inst_dir + "/bin/%s%s" %
                 (cc_name, exe_ext)] + extra_cflags2,
             [stage2_inst_dir + "/bin/%s%s" %
                 (cxx_name, exe_ext)] + extra_cxxflags2,
             [stage2_inst_dir + "/bin/%s%s" %
                 (cc_name, exe_ext)] + extra_asmflags,
             [ld] + extra_ldflags,
             ar, ranlib, libtool,
             llvm_source_dir, stage3_dir, build_libcxx, osx_cross_compile,
-            build_type, assertions, python_path, gcc_dir, libcxx_include_dir)
+            build_type, assertions, python_path, gcc_dir, libcxx_include_dir,
+            stages == 3)
 
     package_name = "clang"
     if build_clang_tidy:
         prune_final_dir_for_clang_tidy(os.path.join(final_stage_dir, "clang"))
         package_name = "clang-tidy"
 
     if not args.skip_tar:
         ext = "bz2" if is_darwin() or is_windows() else "xz"
--- a/build/build-clang/clang-win64-st-an.json
+++ b/build/build-clang/clang-win64-st-an.json
@@ -11,12 +11,13 @@
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
       "r318309.patch",
       "r320462.patch",
+      "r327876.patch",
       "loosen-msvc-detection.patch",
       "fflush-before-unlocking.patch"
     ]
 }
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -10,11 +10,12 @@
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
       "loosen-msvc-detection.patch",
-      "r339636.patch"
+      "r339636.patch",
+      "workaround-issue38586.patch"
     ]
 }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/r327876.patch
@@ -0,0 +1,39 @@
+From 522a892efc2ff22a2fd421b1ef4d9d9739d78b2e Mon Sep 17 00:00:00 2001
+From: Vitaly Buka <vitalybuka@google.com>
+Date: Mon, 19 Mar 2018 18:22:35 +0000
+Subject: [PATCH] Fix CMake/MSVC when compiler-rt and llvm are built separately
+
+Summary:
+For some reason CMake can't find the `append` macro if LLVM is built separately and imported via `LLVM_CONFIG_PATH`.
+
+Patch by Loo Rong Jie
+
+Reviewers: rnk, vitalybuka
+
+Reviewed By: rnk, vitalybuka
+
+Subscribers: dberris, mgorny, llvm-commits, #sanitizers
+
+Differential Revision: https://reviews.llvm.org/D43458
+
+git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@327876 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
+index 4b953b212..a02ef9532 100644
+--- a/compiler-rt/CMakeLists.txt
++++ b/compiler-rt/CMakeLists.txt
+@@ -339,7 +339,7 @@ if (CMAKE_LINKER MATCHES "link.exe$")
+   # it, but CMake doesn't seem to have a way to set linker flags for
+   # individual static libraries, so we enable the suppression flag for
+   # the whole compiler-rt project.
+-  append("/IGNORE:4221" CMAKE_STATIC_LINKER_FLAGS)
++  set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
+ endif()
+ 
+ add_subdirectory(include)
+-- 
+2.18.0
+
new file mode 100644
--- /dev/null
+++ b/build/build-clang/workaround-issue38586.patch
@@ -0,0 +1,31 @@
+diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
+index 86ca2b3ef..f6ddd24eb 100644
+--- a/compiler-rt/CMakeLists.txt
++++ b/compiler-rt/CMakeLists.txt
+@@ -284,6 +284,26 @@ if(MSVC)
+   # warning from the MS linker complaining that it can't find the 'vc140.pdb'
+   # file used by our object library compilations.
+   list(APPEND SANITIZER_COMMON_CFLAGS /Z7)
++
++# Copied from llvm/cmake/modules/LLVMProcessSources.cmake
++function(llvm_replace_compiler_option var old new)
++  # Replaces a compiler option or switch `old' in `var' by `new'.
++  # If `old' is not in `var', appends `new' to `var'.
++  # Example: llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2")
++  # If the option already is on the variable, don't add it:
++  if( "${${var}}" MATCHES "(^| )${new}($| )" )
++    set(n "")
++  else()
++    set(n "${new}")
++  endif()
++  if( "${${var}}" MATCHES "(^| )${old}($| )" )
++    string( REGEX REPLACE "(^| )${old}($| )" " ${n} " ${var} "${${var}}" )
++  else()
++    set( ${var} "${${var}} ${n}" )
++  endif()
++  set( ${var} "${${var}}" PARENT_SCOPE )
++endfunction(llvm_replace_compiler_option)
++
+   llvm_replace_compiler_option(CMAKE_CXX_FLAGS "/Z[i7I]" "/Z7")
+   llvm_replace_compiler_option(CMAKE_CXX_FLAGS_DEBUG "/Z[i7I]" "/Z7")
+   llvm_replace_compiler_option(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Z[i7I]" "/Z7")
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1257,19 +1257,20 @@ def pgo_flags(compiler, build_env, targe
             use_cflags=['-fprofile-use', '-fprofile-correction',
                         '-Wcoverage-mismatch'],
             use_ldflags=['-fprofile-use'],
         )
 
     if compiler.type in ('clang-cl', 'clang'):
         profdata = os.path.join(topobjdir, 'merged.profdata')
         if compiler.type == 'clang-cl':
-            # 32-bit PGO is currently blocked by bug 1479800
             if target.cpu == 'x86_64':
                 gen_ldflags = ['clang_rt.profile-x86_64.lib']
+            elif target.cpu == 'x86':
+                gen_ldflags = ['clang_rt.profile-i386.lib']
             else:
                 gen_ldflags = None
         else:
             gen_ldflags = ['-fprofile-instr-generate']
 
         if gen_ldflags:
             return namespace(
                 gen_cflags=['-fprofile-instr-generate'],
--- a/devtools/client/aboutdebugging-new/src/actions/runtime.js
+++ b/devtools/client/aboutdebugging-new/src/actions/runtime.js
@@ -1,16 +1,18 @@
 /* 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";
 
+const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
 const { BrowserToolboxProcess } =
   require("resource://devtools/client/framework/ToolboxProcess.jsm");
+const { Cc, Ci } = require("chrome");
 const { DebuggerClient } = require("devtools/shared/client/debugger-client");
 const { DebuggerServer } = require("devtools/server/main");
 
 const {
   CONNECT_RUNTIME_FAILURE,
   CONNECT_RUNTIME_START,
   CONNECT_RUNTIME_SUCCESS,
   DEBUG_TARGETS,
@@ -82,16 +84,69 @@ function inspectDebugTarget(type, id) {
   } else {
     console.error(`Failed to inspect the debug target of type: ${ type } id: ${ id }`);
   }
 
   // We cancel the redux flow here since the inspection does not need to update the state.
   return () => {};
 }
 
+function installTemporaryExtension() {
+  const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+  fp.init(window, "Select Manifest File or Package (.xpi)", Ci.nsIFilePicker.modeOpen);
+  fp.open(async res => {
+    if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
+      return;
+    }
+
+    let file = fp.file;
+
+    // AddonManager.installTemporaryAddon accepts either
+    // addon directory or final xpi file.
+    if (!file.isDirectory() &&
+        !file.leafName.endsWith(".xpi") && !file.leafName.endsWith(".zip")) {
+      file = file.parent;
+    }
+
+    try {
+      await AddonManager.installTemporaryAddon(file);
+    } catch (e) {
+      console.error(e);
+    }
+  });
+
+  return () => {};
+}
+
+function reloadTemporaryExtension(actor) {
+  return async (_, getState) => {
+    const client = getState().runtime.client;
+
+    try {
+      await client.request({ to: actor, type: "reload" });
+    } catch (e) {
+      console.error(e);
+    }
+  };
+}
+
+function removeTemporaryExtension(id) {
+  return async () => {
+    try {
+      const addon = await AddonManager.getAddonByID(id);
+
+      if (addon) {
+        await addon.uninstall();
+      }
+    } catch (e) {
+      console.error(e);
+    }
+  };
+}
+
 function requestTabs() {
   return async (dispatch, getState) => {
     dispatch({ type: REQUEST_TABS_START });
 
     const client = getState().runtime.client;
 
     try {
       const { tabs } = await client.listTabs({ favicons: true });
@@ -125,11 +180,14 @@ function requestExtensions() {
     }
   };
 }
 
 module.exports = {
   connectRuntime,
   disconnectRuntime,
   inspectDebugTarget,
+  installTemporaryExtension,
+  reloadTemporaryExtension,
+  removeTemporaryExtension,
   requestTabs,
   requestExtensions,
 };
--- a/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js
+++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js
@@ -5,16 +5,18 @@
 "use strict";
 
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail"));
 const TabDetail = createFactory(require("./debugtarget/TabDetail"));
+const TemporaryExtensionAction =
+  createFactory(require("./debugtarget/TemporaryExtensionAction"));
 
 const Actions = require("../actions/index");
 const { DEBUG_TARGETS } = require("../constants");
 
 /**
  * This component displays debug target.
  */
 class DebugTargetItem extends PureComponent {
@@ -25,16 +27,33 @@ class DebugTargetItem extends PureCompon
     };
   }
 
   inspect() {
     const { dispatch, target } = this.props;
     dispatch(Actions.inspectDebugTarget(target.type, target.id));
   }
 
+  renderAction() {
+    const { dispatch, target } = this.props;
+
+    return dom.div(
+      {},
+      dom.button(
+        {
+          onClick: e => this.inspect(),
+          className: "aboutdebugging-button",
+        },
+        "Inspect"
+      ),
+      target.details.temporarilyInstalled
+        ? TemporaryExtensionAction({ dispatch, target }) : null,
+    );
+  }
+
   renderDetail() {
     const { target } = this.props;
 
     switch (target.type) {
       case DEBUG_TARGETS.EXTENSION:
         return ExtensionDetail({ target });
       case DEBUG_TARGETS.TAB:
         return TabDetail({ target });
@@ -64,31 +83,21 @@ class DebugTargetItem extends PureCompon
           title: target.name,
         },
         target.name
       ),
       this.renderDetail(),
     );
   }
 
-  renderInspectButton() {
-    return dom.button(
-      {
-        onClick: e => this.inspect(),
-        className: "aboutdebugging-button",
-      },
-      "Inspect"
-    );
-  }
-
   render() {
     return dom.li(
       {
         className: "debug-target-item",
       },
       this.renderIcon(),
       this.renderInfo(),
-      this.renderInspectButton(),
+      this.renderAction(),
     );
   }
 }
 
 module.exports = DebugTargetItem;
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
@@ -6,16 +6,18 @@
 
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const DebugTargetPane = createFactory(require("./DebugTargetPane"));
 const RuntimeInfo = createFactory(require("./RuntimeInfo"));
+const TemporaryExtensionInstaller =
+  createFactory(require("./debugtarget/TemporaryExtensionInstaller"));
 
 const Services = require("Services");
 
 class RuntimePage extends PureComponent {
   static get propTypes() {
     return {
       dispatch: PropTypes.func.isRequired,
       installedExtensions: PropTypes.arrayOf(PropTypes.object).isRequired,
@@ -31,16 +33,17 @@ class RuntimePage extends PureComponent 
       {
         className: "page",
       },
       RuntimeInfo({
         icon: "chrome://branding/content/icon64.png",
         name: Services.appinfo.name,
         version: Services.appinfo.version,
       }),
+      TemporaryExtensionInstaller({ dispatch }),
       DebugTargetPane({
         dispatch,
         name: "Temporary Extensions",
         targets: temporaryExtensions,
       }),
       DebugTargetPane({
         dispatch,
         name: "Extensions",
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js
@@ -28,17 +28,17 @@ class ExtensionDetail extends PureCompon
         },
         value,
       ),
     ];
   }
 
   renderUUID() {
     const { target } = this.props;
-    const { manifestURL, uuid } = target;
+    const { manifestURL, uuid } = target.details;
 
     const value = [
       uuid,
       dom.a(
         {
           className: "extension-detail__manifest",
           href: manifestURL,
           target: "_blank",
@@ -47,17 +47,18 @@ class ExtensionDetail extends PureCompon
       )
     ];
 
     return this.renderField("Internal UUID", value, uuid);
   }
 
   render() {
     const { target } = this.props;
-    const { id, location, uuid } = target;
+    const { id, details } = target;
+    const { location, uuid } = details;
 
     return dom.dl(
       {
         className: "extension-detail",
       },
       location ? this.renderField("Location", location) : null,
       this.renderField("Extension ID", id),
       uuid ? this.renderUUID() : null,
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js
@@ -14,13 +14,13 @@ const PropTypes = require("devtools/clie
 class TabDetail extends PureComponent {
   static get propTypes() {
     return {
       target: PropTypes.object.isRequired,
     };
   }
 
   render() {
-    return dom.div({ className: "ellipsis-text" }, this.props.target.url);
+    return dom.div({ className: "ellipsis-text" }, this.props.target.details.url);
   }
 }
 
 module.exports = TabDetail;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionAction.js
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
+const Actions = require("../../actions/index");
+
+/**
+ * This component provides components that reload/remove temporary extension.
+ */
+class TemporaryExtensionAction extends PureComponent {
+  static get propTypes() {
+    return {
+      dispatch: PropTypes.func.isRequired,
+      target: PropTypes.object.isRequired,
+    };
+  }
+
+  reload() {
+    const { dispatch, target } = this.props;
+    dispatch(Actions.reloadTemporaryExtension(target.details.actor));
+  }
+
+  remove() {
+    const { dispatch, target } = this.props;
+    dispatch(Actions.removeTemporaryExtension(target.id));
+  }
+
+  render() {
+    return [
+      dom.button(
+        {
+          className: "aboutdebugging-button",
+          onClick: e => this.reload()
+        },
+        "Reload",
+      ),
+      dom.button(
+        {
+          className: "aboutdebugging-button",
+          onClick: e => this.remove()
+        },
+        "Remove",
+      ),
+    ];
+  }
+}
+
+module.exports = TemporaryExtensionAction;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
@@ -0,0 +1,38 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
+const Actions = require("../../actions/index");
+
+/**
+ * This component provides an installer for temporary extension.
+ */
+class TemporaryExtensionInstaller extends PureComponent {
+  static get propTypes() {
+    return {
+      dispatch: PropTypes.func.isRequired,
+    };
+  }
+
+  install() {
+    this.props.dispatch(Actions.installTemporaryExtension());
+  }
+
+  render() {
+    return dom.button(
+      {
+        className: "aboutdebugging-button",
+        onClick: e => this.install()
+      },
+      "Load Temporary Add-on…"
+    );
+  }
+}
+
+module.exports = TemporaryExtensionInstaller;
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
@@ -1,9 +1,11 @@
 # 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/.
 
 DevToolsModules(
     'ExtensionDetail.css',
     'ExtensionDetail.js',
     'TabDetail.js',
+    'TemporaryExtensionAction.js',
+    'TemporaryExtensionInstaller.js',
 )
--- a/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js
+++ b/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js
@@ -65,33 +65,53 @@ function getExtensionFilePath(extension)
   }
 
   return extension.url.slice("file://".length);
 }
 
 function toExtensionComponentData(extensions) {
   return extensions.map(extension => {
     const type = DEBUG_TARGETS.EXTENSION;
-    const { iconURL, id, manifestURL, name } = extension;
+    const { actor, iconURL, id, manifestURL, name, temporarilyInstalled } = extension;
     const icon = iconURL || "chrome://mozapps/skin/extensions/extensionGeneric.svg";
     const location = getExtensionFilePath(extension);
     const uuid = manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null;
-    return { type, id, icon, location, manifestURL, name, uuid };
+    return {
+      name,
+      icon,
+      id,
+      type,
+      details: {
+        actor,
+        location,
+        manifestURL,
+        temporarilyInstalled,
+        uuid,
+      },
+    };
   });
 }
 
 function toTabComponentData(tabs) {
   return tabs.map(tab => {
     const type = DEBUG_TARGETS.TAB;
     const id = tab.outerWindowID;
     const icon = tab.favicon
       ? `data:image/png;base64,${ btoa(String.fromCharCode.apply(String, tab.favicon)) }`
       : "chrome://devtools/skin/images/globe.svg";
     const name = tab.title || tab.url;
     const url = tab.url;
-    return { type, id, icon, name, url };
+    return {
+      name,
+      icon,
+      id,
+      type,
+      details: {
+        url,
+      },
+    };
   });
 }
 
 module.exports = {
   RuntimeState,
   runtimeReducer,
 };
--- a/devtools/shared/adb/adb-binary.js
+++ b/devtools/shared/adb/adb-binary.js
@@ -211,12 +211,17 @@ async function isUnpacked() {
  * @return {nsIFile}
  *        File object for the binary.
  */
 async function getFileForBinary() {
   if (!await isUnpacked() &&
       !await extractFiles()) {
     return null;
   }
-  return new FileUtils.File(ADB_BINARY_PATH);
+
+  const file = new FileUtils.File(ADB_BINARY_PATH);
+  if (!file.exists()) {
+    return null;
+  }
+  return file;
 }
 
 exports.getFileForBinary = getFileForBinary;
--- a/devtools/shared/adb/test/test_adb.js
+++ b/devtools/shared/adb/test/test_adb.js
@@ -96,19 +96,17 @@ add_task(async function testNoAdbJSON() 
   await extension.startup();
 
   const adbBinary = await getFileForBinary();
   equal(adbBinary, null);
 
   await extension.unload();
 });
 
-add_task({
-  skip_if: () => mozinfo.os == "win" // bug 1482008
-}, async function testNoTargetBinaries() {
+add_task(async function testNoTargetBinaries() {
   const extension = ExtensionTestUtils.loadExtension({
     manifest: {
       version: (extension_version++).toString(),
       applications: {
         gecko: { id: "adb@mozilla.org" }
       }
     },
     files: {
@@ -141,17 +139,17 @@ add_task(async function testExtract() {
       "win32/AdbWinApi.dll": "AdbWinApi.dll",
       "win32/AdbWinUsbApi.dll": "AdbWinUsbApi.dll"
     },
   });
 
   await extension.startup();
 
   const adbBinary = await getFileForBinary();
-  ok(await adbBinary.exists);
+  ok(await adbBinary.exists());
 
   await extension.unload();
 });
 
 add_task({
   skip_if: () => mozinfo.os == "win" // bug 1482008
 }, async function testStartAndStop() {
   const extension = ExtensionTestUtils.loadExtension({
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1270,31 +1270,38 @@ Element::AttachShadowWithoutNameChecks(S
    * 6. Return shadow.
    */
   return shadowRoot.forget();
 }
 
 void
 Element::UnattachShadow()
 {
-  if (!GetShadowRoot()) {
+  RefPtr<ShadowRoot> shadowRoot = GetShadowRoot();
+  if (!shadowRoot) {
     return;
   }
 
   nsAutoScriptBlocker scriptBlocker;
 
   if (nsIDocument* doc = GetComposedDoc()) {
     if (nsIPresShell* shell = doc->GetShell()) {
       shell->DestroyFramesForAndRestyle(this);
     }
   }
   MOZ_ASSERT(!GetPrimaryFrame());
 
   // Simply unhook the shadow root from the element.
   MOZ_ASSERT(!GetShadowRoot()->HasSlots(), "Won't work when shadow root has slots!");
+  for (nsIContent* child = shadowRoot->GetFirstChild(); child;
+       child = child->GetNextSibling()) {
+    child->UnbindFromTree(true, false);
+  }
+
+  shadowRoot->SetIsComposedDocParticipant(false);
   SetShadowRoot(nullptr);
 }
 
 void
 Element::GetAttribute(const nsAString& aName, DOMString& aReturn)
 {
   const nsAttrValue* val =
     mAttrs.GetAttr(aName,
--- a/dom/base/IndexedDBHelper.jsm
+++ b/dom/base/IndexedDBHelper.jsm
@@ -155,31 +155,31 @@ IndexedDBHelper.prototype = {
         stores = [];
         for (let i = 0; i < store_name.length; ++i) {
           stores.push(txn.objectStore(store_name[i]));
         }
       } else {
         stores = txn.objectStore(store_name);
       }
 
-      txn.oncomplete = function (event) {
+      txn.oncomplete = function () {
         if (DEBUG) debug("Transaction complete. Returning to callback.");
         if (successCb) {
-          successCb(txn.result);
+          if ("result" in txn) {
+            successCb(txn.result);
+          } else {
+            successCb();
+          }
         }
       };
 
-      txn.onabort = function (event) {
+      txn.onabort = function () {
         if (DEBUG) debug("Caught error on transaction");
-        /*
-         * event.target.error may be null
-         * if txn was aborted by calling txn.abort()
-         */
         if (failureCb) {
-          failureCb(getErrorName(event.target.error));
+          failureCb(getErrorName(txn.error));
         }
       };
       callback(txn, stores);
     }, failureCb);
   },
 
   /**
    * Initialize the DB. Does not call open.
--- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini
+++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
@@ -27,17 +27,16 @@ support-files =
   snappyUpgrade_profile.zip
   storagePersistentUpgrade_profile.zip
   wasm_recompile_profile.zip
   xpcshell-shared.ini
 
 [include:xpcshell-shared.ini]
 
 [test_bad_origin_directory.js]
-skip-if = release_or_beta
 [test_obsoleteOriginAttributesUpgrade.js]
 [test_blob_file_backed.js]
 [test_bug1056939.js]
 [test_cleanup_transaction.js]
 [test_database_close_without_onclose.js]
 [test_database_onclose.js]
 [test_defaultStorageUpgrade.js]
 [test_file_copy_failure.js]
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -682,30 +682,26 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Force a garbage collection followed by a cycle collection.
    *
    * Will throw a DOM security error if called without chrome privileges in
    * non-debug builds. Available to all callers in debug builds.
    *
    * @param aListener listener that receives information about the CC graph
-   *                  (see @mozilla.org/cycle-collector-logger;1 for a logger
-   *                   component)
    */
   void garbageCollect([optional] in nsICycleCollectorListener aListener);
 
   /**
    * Force a cycle collection without garbage collection.
    *
    * Will throw a DOM security error if called without chrome privileges in
    * non-debug builds. Available to all callers in debug builds.
    *
    * @param aListener listener that receives information about the CC graph
-   *                  (see @mozilla.org/cycle-collector-logger;1 for a logger
-   *                   component)
    */
   void cycleCollect([optional] in nsICycleCollectorListener aListener);
 
   /**
    * Trigger whichever GC or CC timer is currently active and waiting to fire.
    * Don't do this too much for initiating heavy actions, like the start of a IGC.
    */
   void runNextCollectorTimer();
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -2026,62 +2026,16 @@ EnsureDirectory(nsIFile* aDirectory, boo
     NS_ENSURE_SUCCESS(rv, rv);
 
     *aCreated = true;
   }
 
   return NS_OK;
 }
 
-nsresult
-EnsureOriginDirectory(nsIFile* aDirectory, bool* aCreated)
-{
-  AssertIsOnIOThread();
-
-  nsresult rv;
-
-#ifndef RELEASE_OR_BETA
-  bool exists;
-  rv = aDirectory->Exists(&exists);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!exists) {
-    nsString leafName;
-    nsresult rv = aDirectory->GetLeafName(leafName);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!leafName.EqualsLiteral(kChromeOrigin)) {
-      nsCString spec;
-      OriginAttributes attrs;
-      OriginParser::ResultType result =
-        OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName),
-                                  spec,
-                                  &attrs);
-      if (NS_WARN_IF(result != OriginParser::ValidOrigin)) {
-        QM_WARNING("Preventing creation of a new origin directory which is not "
-                   "supported by our origin parser or is obsolete!");
-
-        return NS_ERROR_FAILURE;
-      }
-    }
-  }
-#endif
-
-  rv = EnsureDirectory(aDirectory, aCreated);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
 enum FileFlag {
   kTruncateFileFlag,
   kUpdateFileFlag,
   kAppendFileFlag
 };
 
 nsresult
 GetOutputStream(nsIFile* aFile,
@@ -5472,16 +5426,53 @@ QuotaManager::EnsureTemporaryStorageIsIn
 
   mTemporaryStorageInitialized = true;
 
   CheckTemporaryStorageLimits();
 
   return rv;
 }
 
+nsresult
+QuotaManager::EnsureOriginDirectory(nsIFile* aDirectory,
+                                    bool* aCreated)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aDirectory);
+  MOZ_ASSERT(aCreated);
+
+  bool exists;
+  nsresult rv = aDirectory->Exists(&exists);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (!exists) {
+    nsString leafName;
+    rv = aDirectory->GetLeafName(leafName);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    if (!leafName.EqualsLiteral(kChromeOrigin) &&
+        !IsSanitizedOriginValid(NS_ConvertUTF16toUTF8(leafName))) {
+      QM_WARNING("Preventing creation of a new origin directory which is not "
+                 "supported by our origin parser or is obsolete!");
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  rv = EnsureDirectory(aDirectory, aCreated);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return NS_OK;
+}
+
 void
 QuotaManager::OriginClearCompleted(PersistenceType aPersistenceType,
                                    const nsACString& aOrigin)
 {
   AssertIsOnIOThread();
 
   if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
     mInitializedOrigins.RemoveElement(aOrigin);
@@ -6030,16 +6021,39 @@ QuotaManager::GetDirectoryLockTable(Pers
 
     case PERSISTENCE_TYPE_PERSISTENT:
     case PERSISTENCE_TYPE_INVALID:
     default:
       MOZ_CRASH("Bad persistence type value!");
   }
 }
 
+bool
+QuotaManager::IsSanitizedOriginValid(const nsACString& aSanitizedOrigin)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(!aSanitizedOrigin.Equals(kChromeOrigin));
+
+  bool valid;
+  if (auto entry = mValidOrigins.LookupForAdd(aSanitizedOrigin)) {
+    // We already parsed this sanitized origin string.
+    valid = entry.Data();
+  } else {
+    nsCString spec;
+    OriginAttributes attrs;
+    OriginParser::ResultType result =
+      OriginParser::ParseOrigin(aSanitizedOrigin, spec, &attrs);
+
+    valid = result == OriginParser::ValidOrigin;
+    entry.OrInsert([valid]() { return valid; });
+  }
+
+  return valid;
+}
+
 /*******************************************************************************
  * Local class implementations
  ******************************************************************************/
 
 OriginInfo::OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
                        uint64_t aUsage, int64_t aAccessTime, bool aPersisted)
   : mGroupInfo(aGroupInfo), mOrigin(aOrigin), mUsage(aUsage),
     mAccessTime(aAccessTime), mPersisted(aPersisted)
@@ -7932,17 +7946,17 @@ PersistOp::DoDirectoryWork(QuotaManager*
   nsresult rv = aQuotaManager->GetDirectoryForOrigin(mPersistenceType.Value(),
                                                      mOriginScope.GetOrigin(),
                                                      getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool created;
-  rv = EnsureOriginDirectory(directory, &created);
+  rv = aQuotaManager->EnsureOriginDirectory(directory, &created);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (created) {
     int64_t timestamp;
     rv = CreateDirectoryMetadataFiles(directory,
                                       /* aPersisted */ true,
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -296,16 +296,20 @@ public:
                                     const nsACString& aGroup,
                                     const nsACString& aOrigin,
                                     nsIFile** aDirectory,
                                     bool* aCreated);
 
   nsresult
   EnsureTemporaryStorageIsInitialized();
 
+  nsresult
+  EnsureOriginDirectory(nsIFile* aDirectory,
+                        bool* aCreated);
+
   void
   OriginClearCompleted(PersistenceType aPersistenceType,
                        const nsACString& aOrigin);
 
   void
   ResetOrClearCompleted();
 
   void
@@ -517,16 +521,19 @@ private:
     for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
       mClients[index]->ReleaseIOThreadObjects();
     }
   }
 
   DirectoryLockTable&
   GetDirectoryLockTable(PersistenceType aPersistenceType);
 
+  bool
+  IsSanitizedOriginValid(const nsACString& aSanitizedOrigin);
+
   static void
   ShutdownTimerCallback(nsITimer* aTimer, void* aClosure);
 
   mozilla::Mutex mQuotaMutex;
 
   nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
 
   // Maintains a list of directory locks that are queued.
@@ -540,20 +547,25 @@ private:
   DirectoryLockTable mDefaultDirectoryLockTable;
 
   // Thread on which IO is performed.
   nsCOMPtr<nsIThread> mIOThread;
 
   // A timer that gets activated at shutdown to ensure we close all storages.
   nsCOMPtr<nsITimer> mShutdownTimer;
 
-  // A list of all successfully initialized origins. This list isn't protected
-  // by any mutex but it is only ever touched on the IO thread.
+  // A list of all successfully initialized persistent origins. This list isn't
+  // protected by any mutex but it is only ever touched on the IO thread.
   nsTArray<nsCString> mInitializedOrigins;
 
+  // A hash table that is used to cache origin parser results for given
+  // sanitized origin strings. This hash table isn't protected by any mutex but
+  // it is only ever touched on the IO thread.
+  nsDataHashtable<nsCStringHashKey, bool> mValidOrigins;
+
   // This array is populated at initialization time and then never modified, so
   // it can be iterated on any thread.
   AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
 
   nsString mBasePath;
   nsString mIndexedDBPath;
   nsString mStoragePath;
   nsString mPermanentStoragePath;
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -513,17 +513,17 @@ var interfaceNamesInGlobalScope =
     {name: "HTMLProgressElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLQuoteElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLScriptElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLSelectElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "HTMLSlotElement", insecureContext: true, disabled: true},
+    {name: "HTMLSlotElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLSourceElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLSpanElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLStyleElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLTableCaptionElement", insecureContext: true},
@@ -867,17 +867,17 @@ var interfaceNamesInGlobalScope =
     {name: "ServiceWorkerContainer", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ServiceWorkerRegistration", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ScopedCredential", insecureContext: true, disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ScopedCredentialInfo", insecureContext: true, disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "ShadowRoot", insecureContext: true, disabled: true},
+    {name: "ShadowRoot", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SharedWorker", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SimpleGestureEvent", insecureContext: true, xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SimpleTest", insecureContext: true, xbl: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SourceBuffer", insecureContext: true},
--- a/js/src/devtools/automation/cgc-jstests-slow.txt
+++ b/js/src/devtools/automation/cgc-jstests-slow.txt
@@ -58,8 +58,20 @@ non262/regress/regress-360969-02.js
 non262/regress/regress-360969-03.js
 non262/regress/regress-360969-04.js
 non262/regress/regress-360969-05.js
 non262/regress/regress-360969-06.js
 non262/extensions/regress-477187.js
 non262/regress/regress-452498-052-a.js
 non262/extensions/clone-complex-object.js
 non262/extensions/clone-object-deep.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js
+test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -292,16 +292,24 @@ interface nsIXPCComponents_Utils : nsISu
     /*
      * To be called from JS only.
      *
      * Force an immediate cycle collection cycle.
      */
     void forceCC([optional] in nsICycleCollectorListener aListener);
 
     /*
+     * To be called from JS only.  C++ callers should use the
+     * nsCycleCollector_createLogger() function instead.
+     *
+     * Create an instance of the built-in cycle collector logger object.
+     */
+    nsICycleCollectorListener createCCLogger();
+
+    /*
      * To be called from JS only.
      *
      * If any incremental CC is in progress, finish it. For testing.
      */
     void finishCC();
 
     /*
      * To be called from JS only.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -26,16 +26,17 @@
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/Scheduler.h"
 #include "nsZipArchive.h"
 #include "nsWindowMemoryReporter.h"
+#include "nsICycleCollectorListener.h"
 #include "nsIException.h"
 #include "nsIScriptError.h"
 #include "nsISimpleEnumerator.h"
 #include "nsPIDOMWindow.h"
 #include "nsGlobalWindow.h"
 #include "nsScriptError.h"
 #include "GeckoProfiler.h"
 
@@ -2313,16 +2314,26 @@ nsXPCComponents_Utils::ForceGC()
 NS_IMETHODIMP
 nsXPCComponents_Utils::ForceCC(nsICycleCollectorListener* listener)
 {
     nsJSContext::CycleCollectNow(listener);
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsXPCComponents_Utils::CreateCCLogger(nsICycleCollectorListener** aListener)
+{
+    NS_ENSURE_ARG_POINTER(aListener);
+    nsCOMPtr<nsICycleCollectorListener> logger =
+      nsCycleCollector_createLogger();
+    logger.forget(aListener);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsXPCComponents_Utils::FinishCC()
 {
     nsCycleCollector_finishAnyCurrentCollection();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::CcSlice(int64_t budget)
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -27,16 +27,17 @@
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
 
 #include "nsDOMMutationObserver.h"
 #include "nsICycleCollectorListener.h"
+#include "nsCycleCollector.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsScriptSecurityManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptError.h"
 #include "nsContentUtils.h"
 #include "nsScriptError.h"
 
@@ -1106,22 +1107,18 @@ MOZ_EXPORT void
 DumpJSStack()
 {
     xpc_DumpJSStack(true, true, false);
 }
 
 MOZ_EXPORT void
 DumpCompleteHeap()
 {
-    nsCOMPtr<nsICycleCollectorListener> listener =
-      do_CreateInstance("@mozilla.org/cycle-collector-logger;1");
-    if (!listener) {
-      NS_WARNING("Failed to create CC logger");
-      return;
-    }
+    nsCOMPtr<nsICycleCollectorListener> listener = nsCycleCollector_createLogger();
+    MOZ_ASSERT(listener);
 
     nsCOMPtr<nsICycleCollectorListener> alltracesListener;
     listener->AllTraces(getter_AddRefs(alltracesListener));
     if (!alltracesListener) {
       NS_WARNING("Failed to get all traces logger");
       return;
     }
 
--- a/layout/reftests/flexbox/reftest.list
+++ b/layout/reftests/flexbox/reftest.list
@@ -7,22 +7,16 @@
 #
 # Where possible & practical, we should try to address these so we can migrate
 # tests over to the w3c-css directory, so that they can become part of the
 # W3C's test suite.
 
 # SUBDIRECTORY: Reftests for paginated flex containers
 include pagination/reftest.list
 
-# XXXdholbert These tests should move to w3c-css/submitted once we've closed
-# out bug 1207698 and updated these tests' expectations & alignment keyword
-# usage accordingly:
-== flexbox-align-content-horizrev-001.xhtml flexbox-align-content-horizrev-001-ref.xhtml
-== flexbox-align-content-vertrev-001.xhtml flexbox-align-content-vertrev-001-ref.xhtml
-
 # Tests for cross-axis alignment (align-self / align-items properties)
 fails == flexbox-align-self-baseline-horiz-2.xhtml  flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others
 # This one fails on windows R (but not Ru, strangely) and GTK.
 # On Windows R and GTK, the single-line <label> flex item has a different
 # background size in test vs. ref
 fuzzy-if(cocoaWidget,0-1,0-2) random-if(winWidget||gtkWidget) skip-if(Android) == flexbox-align-self-baseline-horiz-3.xhtml  flexbox-align-self-baseline-horiz-3-ref.xhtml # XXXdholbert investigate the random-if. The skip-if(Android) is because checkbox/radio appearance:none doesn't work as expected.
 == flexbox-align-self-baseline-horiz-4.xhtml flexbox-align-self-baseline-horiz-4-ref.xhtml
 == flexbox-item-align-self-dynamic-pos-001.html flexbox-item-align-self-dynamic-pos-001-ref.html
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001-ref.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001-ref.xhtml
@@ -139,32 +139,32 @@
       <div class="c" style="margin-top: 30px"/>
     </div>
 
     <!-- start -->
     <div class="flexbox">
       <div class="a"/>
     </div>
     <div class="flexbox">
+      <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
     </div>
     <div class="flexbox">
-      <div class="c"/>
+      <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="c"/>
     </div>
 
     <!-- end -->
     <div class="flexbox">
       <div class="a" style="margin-top: 190px"/>
     </div>
     <div class="flexbox">
-      <div class="b" style="margin-top: 160px"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="a" style="margin-top: 160px"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
     </div>
     <div class="flexbox">
-      <div class="c" style="margin-top: 120px"/>
+      <div class="a" style="margin-top: 120px"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="c"/>
     </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001a.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001a.xhtml
@@ -144,36 +144,36 @@
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- start -->
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- end -->
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001b.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-001b.xhtml
@@ -145,36 +145,36 @@
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- start -->
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- end -->
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
   </body>
 </html>
rename from layout/reftests/flexbox/flexbox-align-content-horizrev-001-ref.xhtml
rename to layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-002-ref.xhtml
--- a/layout/reftests/flexbox/flexbox-align-content-horizrev-001-ref.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-002-ref.xhtml
@@ -133,10 +133,38 @@
       <div class="b" style="margin-top: calc(160px / 3)"><div class="fixedSizeChild"/></div>
       <div class="a" style="margin-top: calc(160px / 3)"/>
     </div>
     <div class="flexbox">
       <div class="c" style="margin-top: 30px"/>
       <div class="b" style="margin-top: 30px"><div class="fixedSizeChild"/></div>
       <div class="a" style="margin-top: 30px"/>
     </div>
+
+    <!-- start -->
+    <div class="flexbox">
+      <div class="a"/>
+    </div>
+    <div class="flexbox">
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="a"/>
+    </div>
+    <div class="flexbox">
+      <div class="c"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="a"/>
+    </div>
+
+    <!-- end -->
+    <div class="flexbox">
+      <div class="a" style="margin-top: 190px"/>
+    </div>
+    <div class="flexbox">
+      <div class="b" style="margin-top: 160px"><div class="fixedSizeChild"/></div>
+      <div class="a"/>
+    </div>
+    <div class="flexbox">
+      <div class="c" style="margin-top: 120px"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="a"/>
+    </div>
   </body>
 </html>
rename from layout/reftests/flexbox/flexbox-align-content-horizrev-001.xhtml
rename to layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-002.xhtml
--- a/layout/reftests/flexbox/flexbox-align-content-horizrev-001.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-002.xhtml
@@ -5,17 +5,17 @@
 -->
 <!-- Testcase with a series of row wrap-reverse flex containers, with 1-3 flex lines,
      testing each possible value of the 'align-content' property. -->
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>CSS Test: Testing 'align-content' in a row wrap-reverse flex container</title>
     <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
     <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-content-property"/>
-    <link rel="match" href="flexbox-align-content-horizrev-001-ref.xhtml"/>
+    <link rel="match" href="flexbox-align-content-horiz-002-ref.xhtml"/>
     <style>
       div.flexbox {
         width: 20px; /* Skinny, to force us to wrap */
         height: 200px;
         display: flex;
         flex-wrap: wrap-reverse;
         margin-right: 2px;
         float: left;
@@ -142,10 +142,38 @@
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
+
+    <!-- start -->
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+    </div>
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
+
+    <!-- end -->
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+    </div>
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001-ref.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001-ref.xhtml
@@ -142,32 +142,32 @@
       <div class="c" style="margin-left: 30px"/>
     </div>
 
     <!-- start -->
     <div class="flexbox">
       <div class="a"/>
     </div>
     <div class="flexbox">
+      <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
     </div>
     <div class="flexbox">
-      <div class="c"/>
+      <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="c"/>
     </div>
 
     <!-- end -->
     <div class="flexbox">
       <div class="a" style="margin-left: 190px"/>
     </div>
     <div class="flexbox">
-      <div class="b" style="margin-left: 160px"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="a" style="margin-left: 160px"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
     </div>
     <div class="flexbox">
-      <div class="c" style="margin-left: 120px"/>
+      <div class="a" style="margin-left: 120px"/>
       <div class="b"><div class="fixedSizeChild"/></div>
-      <div class="a"/>
+      <div class="c"/>
     </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001a.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001a.xhtml
@@ -144,36 +144,36 @@
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- start -->
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- end -->
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001b.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-001b.xhtml
@@ -145,36 +145,36 @@
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- start -->
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: start; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: start">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
 
     <!-- end -->
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
-    <div class="flexbox" style="align-content: end; flex-wrap: wrap-reverse">
+    <div class="flexbox" style="align-content: end">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
   </body>
 </html>
rename from layout/reftests/flexbox/flexbox-align-content-vertrev-001-ref.xhtml
rename to layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-002-ref.xhtml
--- a/layout/reftests/flexbox/flexbox-align-content-vertrev-001-ref.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-002-ref.xhtml
@@ -136,10 +136,38 @@
       <div class="a" style="margin-right: calc(160px / 3)"/>
       <div class="b" style="margin-right: calc(160px / 3)"><div class="fixedSizeChild"/></div>
     </div>
     <div class="flexbox">
       <div class="a" style="margin-right: 30px"/>
       <div class="b" style="margin-right: 30px"><div class="fixedSizeChild"/></div>
       <div class="c" style="margin-right: 30px"/>
     </div>
+
+    <!-- start -->
+    <div class="flexbox">
+      <div class="a" style="margin-right: 190px"/>
+    </div>
+    <div class="flexbox">
+      <div class="a" style="margin-right: 160px"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox">
+      <div class="a" style="margin-right: 120px"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
+
+    <!-- end -->
+    <div class="flexbox">
+      <div class="a"/>
+    </div>
+    <div class="flexbox">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
   </body>
 </html>
rename from layout/reftests/flexbox/flexbox-align-content-vertrev-001.xhtml
rename to layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-002.xhtml
--- a/layout/reftests/flexbox/flexbox-align-content-vertrev-001.xhtml
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-002.xhtml
@@ -5,17 +5,17 @@
 -->
 <!-- Testcase with a series of column wrap-reverse flex containers, with 1-3 flex lines,
      testing each possible value of the 'align-content' property. -->
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>CSS Test: Testing 'align-content' in a column wrap-reverse flex container</title>
     <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
     <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#align-content-property"/>
-    <link rel="match" href="flexbox-align-content-vertrev-001-ref.xhtml"/>
+    <link rel="match" href="flexbox-align-content-vert-002-ref.xhtml"/>
     <style>
       div.flexbox {
         width: 200px;
         height: 20px; /* Short, to force us to wrap */
         display: flex;
         flex-direction: column;
         flex-wrap: wrap-reverse;
         margin-bottom: 2px;
@@ -142,10 +142,38 @@
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
     </div>
     <div class="flexbox" style="align-content: space-evenly">
       <div class="a"/>
       <div class="b"><div class="fixedSizeChild"/></div>
       <div class="c"/>
     </div>
+
+    <!-- start -->
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+    </div>
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox" style="align-content: start">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
+
+    <!-- end -->
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+    </div>
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+    </div>
+    <div class="flexbox" style="align-content: end">
+      <div class="a"/>
+      <div class="b"><div class="fixedSizeChild"/></div>
+      <div class="c"/>
+    </div>
   </body>
 </html>
--- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list
+++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list
@@ -4,18 +4,20 @@
 == flexbox-abspos-child-002.html flexbox-abspos-child-002-ref.html
 
 # Tests for handling anonymous flex items
 == flexbox-anonymous-items-001.html flexbox-anonymous-items-001-ref.html
 
 # Tests for alignment of flex lines (align-content property)
 == flexbox-align-content-horiz-001a.xhtml flexbox-align-content-horiz-001-ref.xhtml
 == flexbox-align-content-horiz-001b.xhtml flexbox-align-content-horiz-001-ref.xhtml
+== flexbox-align-content-horiz-002.xhtml flexbox-align-content-horiz-002-ref.xhtml
 == flexbox-align-content-vert-001a.xhtml  flexbox-align-content-vert-001-ref.xhtml
 == flexbox-align-content-vert-001b.xhtml  flexbox-align-content-vert-001-ref.xhtml
+== flexbox-align-content-vert-002.xhtml flexbox-align-content-vert-002-ref.xhtml
 == flexbox-align-content-wmvert-001.xhtml  flexbox-align-content-wmvert-001-ref.xhtml
 
 # Tests for cross-axis alignment (align-self / align-items properties)
 == flexbox-align-self-baseline-horiz-001a.xhtml flexbox-align-self-baseline-horiz-001-ref.xhtml
 == flexbox-align-self-baseline-horiz-001b.xhtml flexbox-align-self-baseline-horiz-001-ref.xhtml
 == flexbox-align-self-baseline-horiz-002.xhtml flexbox-align-self-baseline-horiz-002-ref.xhtml
 == flexbox-align-self-baseline-horiz-003.xhtml flexbox-align-self-baseline-horiz-003-ref.xhtml
 == flexbox-align-self-baseline-horiz-004.xhtml flexbox-align-self-baseline-horiz-004-ref.xhtml
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -49,16 +49,17 @@ import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.StrictMode;
@@ -2235,18 +2236,19 @@ public abstract class GeckoApp extends G
             final Context context = GeckoAppShell.getApplicationContext();
             long cleanupVersion = GeckoSharedPrefs.forApp(context).getInt(CLEANUP_VERSION, 0);
 
             if (cleanupVersion < 1) {
                 // Reduce device storage footprint by removing .ttf files from
                 // the res/fonts directory: we no longer need to copy our
                 // bundled fonts out of the APK in order to use them.
                 // See https://bugzilla.mozilla.org/show_bug.cgi?id=878674.
-                File dir = new File("res/fonts");
-                if (dir.exists() && dir.isDirectory()) {
+                final File dataDir = new File(context.getApplicationInfo().dataDir);
+                final File dir = new File(dataDir, "res/fonts");
+                if (dir.exists() && dir.isDirectory() && dir.listFiles() != null) {
                     for (File file : dir.listFiles()) {
                         if (file.isFile() && file.getName().endsWith(".ttf")) {
                             file.delete();
                         }
                     }
                     if (!dir.delete()) {
                         Log.w(LOGTAG, "unable to delete res/fonts directory (not empty?)");
                     }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -337,17 +337,22 @@ public class GeckoView extends FrameLayo
     public void onAttachedToWindow() {
         if (mSession == null) {
             setSession(new GeckoSession(), GeckoRuntime.getDefault(getContext()));
         }
 
         if (!mSession.isOpen()) {
             mSession.open(mRuntime);
         }
-        mRuntime.orientationChanged();
+        // Temporary solution until we find out why mRuntime can end up as null here. It means we
+        // might miss an orientation change if we were background OOM-killed, but it's better than
+        // crashing. See bug 1484001.
+        if (mRuntime != null) {
+            mRuntime.orientationChanged();
+        }
 
         super.onAttachedToWindow();
     }
 
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1374,23 +1374,18 @@ pref("dom.event.highrestimestamp.enabled
 pref("dom.event.coalesce_mouse_move",       true);
 
 #if defined(NIGHTLY_BUILD) && !defined(ANDROID)
 pref("dom.ua_widget.enabled", false);
 #else
 pref("dom.ua_widget.enabled", false);
 #endif
 
-#ifdef NIGHTLY_BUILD
 pref("dom.webcomponents.shadowdom.enabled", true);
 pref("dom.webcomponents.customelements.enabled", true);
-#else
-pref("dom.webcomponents.shadowdom.enabled", false);
-pref("dom.webcomponents.customelements.enabled", false);
-#endif
 
 pref("javascript.enabled",                  true);
 pref("javascript.options.strict",           false);
 #ifdef DEBUG
 pref("javascript.options.strict.debug",     false);
 #endif
 pref("javascript.options.baselinejit",      true);
 pref("javascript.options.ion",              true);
--- a/servo/components/selectors/Cargo.toml
+++ b/servo/components/selectors/Cargo.toml
@@ -19,17 +19,16 @@ path = "lib.rs"
 [features]
 bench = []
 
 [dependencies]
 bitflags = "1.0"
 matches = "0.1"
 cssparser = "0.24.0"
 log = "0.4"
-fnv = "1.0"
 fxhash = "0.2"
 phf = "0.7.18"
 precomputed-hash = "0.1"
 servo_arc = { version = "0.1", path = "../servo_arc" }
 smallvec = "0.6.2"
 thin-slice = "0.1.0"
 
 [build-dependencies]
--- a/servo/components/selectors/bloom.rs
+++ b/servo/components/selectors/bloom.rs
@@ -1,18 +1,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/. */
 
 //! Counting and non-counting Bloom filters tuned for use as ancestor filters
 //! for selector matching.
 
-use fnv::FnvHasher;
 use std::fmt::{self, Debug};
-use std::hash::{Hash, Hasher};
 
 // The top 8 bits of the 32-bit hash value are not used by the bloom filter.
 // Consumers may rely on this to pack hashes more efficiently.
 pub const BLOOM_HASH_MASK: u32 = 0x00ffffff;
 const KEY_SIZE: usize = 12;
 
 const ARRAY_SIZE: usize = 1 << KEY_SIZE;
 const KEY_MASK: u32 = (1 << KEY_SIZE) - 1;
@@ -103,53 +101,37 @@ where
         self.storage.is_zeroed()
     }
 
     #[cfg(not(debug_assertions))]
     pub fn is_zeroed(&self) -> bool {
         unreachable!()
     }
 
+    /// Inserts an item with a particular hash into the bloom filter.
     #[inline]
     pub fn insert_hash(&mut self, hash: u32) {
         self.storage.adjust_first_slot(hash, true);
         self.storage.adjust_second_slot(hash, true);
     }
 
-    /// Inserts an item into the bloom filter.
-    #[inline]
-    pub fn insert<T: Hash>(&mut self, elem: &T) {
-        self.insert_hash(hash(elem))
-    }
-
+    /// Removes an item with a particular hash from the bloom filter.
     #[inline]
     pub fn remove_hash(&mut self, hash: u32) {
         self.storage.adjust_first_slot(hash, false);
         self.storage.adjust_second_slot(hash, false);
     }
 
-    /// Removes an item from the bloom filter.
-    #[inline]
-    pub fn remove<T: Hash>(&mut self, elem: &T) {
-        self.remove_hash(hash(elem))
-    }
-
+    /// Check whether the filter might contain an item with the given hash.
+    /// This can sometimes return true even if the item is not in the filter,
+    /// but will never return false for items that are actually in the filter.
     #[inline]
     pub fn might_contain_hash(&self, hash: u32) -> bool {
         !self.storage.first_slot_is_empty(hash) && !self.storage.second_slot_is_empty(hash)
     }
-
-    /// Check whether the filter might contain an item.  This can
-    /// sometimes return true even if the item is not in the filter,
-    /// but will never return false for items that are actually in the
-    /// filter.
-    #[inline]
-    pub fn might_contain<T: Hash>(&self, elem: &T) -> bool {
-        self.might_contain_hash(hash(elem))
-    }
 }
 
 impl<S> Debug for CountingBloomFilter<S>
 where
     S: BloomStorage,
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut slots_used = 0;
@@ -291,76 +273,77 @@ impl Default for BloomStorageBool {
 impl Clone for BloomStorageBool {
     fn clone(&self) -> Self {
         BloomStorageBool {
             counters: self.counters,
         }
     }
 }
 
-fn hash<T: Hash>(elem: &T) -> u32 {
-    // We generally use FxHasher in Stylo because it's faster than FnvHasher,
-    // but the increased collision rate has outsized effect on the bloom
-    // filter, so we use FnvHasher instead here.
-    let mut hasher = FnvHasher::default();
-    elem.hash(&mut hasher);
-    let hash: u64 = hasher.finish();
-    (hash >> 32) as u32 ^ (hash as u32)
-}
-
 #[inline]
 fn hash1(hash: u32) -> u32 {
     hash & KEY_MASK
 }
 
 #[inline]
 fn hash2(hash: u32) -> u32 {
     (hash >> KEY_SIZE) & KEY_MASK
 }
 
 #[test]
 fn create_and_insert_some_stuff() {
+    use fxhash::FxHasher;
+    use std::hash::{Hash, Hasher};
     use std::mem::transmute;
 
+    fn hash_as_str(i: usize) -> u32 {
+        let mut hasher = FxHasher::default();
+        let s = i.to_string();
+        s.hash(&mut hasher);
+        let hash: u64 = hasher.finish();
+        (hash >> 32) as u32 ^ (hash as u32)
+    }
+
     let mut bf = BloomFilter::new();
 
     // Statically assert that ARRAY_SIZE is a multiple of 8, which
     // BloomStorageBool relies on.
     unsafe {
         transmute::<[u8; ARRAY_SIZE % 8], [u8; 0]>([]);
     }
 
     for i in 0_usize..1000 {
-        bf.insert(&i);
+        bf.insert_hash(hash_as_str(i));
     }
 
     for i in 0_usize..1000 {
-        assert!(bf.might_contain(&i));
+        assert!(bf.might_contain_hash(hash_as_str(i)));
     }
 
-    let false_positives = (1001_usize..2000).filter(|i| bf.might_contain(i)).count();
+    let false_positives =
+        (1001_usize..2000).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count();
 
-    assert!(false_positives < 160, "{} is not < 160", false_positives); // 16%.
+    assert!(false_positives < 190, "{} is not < 190", false_positives); // 19%.
 
     for i in 0_usize..100 {
-        bf.remove(&i);
+        bf.remove_hash(hash_as_str(i));
     }
 
     for i in 100_usize..1000 {
-        assert!(bf.might_contain(&i));
+        assert!(bf.might_contain_hash(hash_as_str(i)));
     }
 
-    let false_positives = (0_usize..100).filter(|i| bf.might_contain(i)).count();
+    let false_positives = (0_usize..100).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count();
 
     assert!(false_positives < 20, "{} is not < 20", false_positives); // 20%.
 
     bf.clear();
 
     for i in 0_usize..2000 {
-        assert!(!bf.might_contain(&i));
+        assert!(!bf.might_contain_hash(hash_as_str(i)));
     }
 }
 
 #[cfg(feature = "bench")]
 #[cfg(test)]
 mod bench {
     extern crate test;
     use super::BloomFilter;
--- a/servo/components/selectors/lib.rs
+++ b/servo/components/selectors/lib.rs
@@ -4,17 +4,16 @@
 
 // Make |cargo bench| work.
 #![cfg_attr(feature = "bench", feature(test))]
 
 #[macro_use]
 extern crate bitflags;
 #[macro_use]
 extern crate cssparser;
-extern crate fnv;
 extern crate fxhash;
 #[macro_use]
 extern crate log;
 #[macro_use]
 extern crate matches;
 extern crate phf;
 extern crate precomputed_hash;
 extern crate servo_arc;
--- a/testing/profiles/unittest/user.js
+++ b/testing/profiles/unittest/user.js
@@ -113,17 +113,17 @@ user_pref("dom.successive_dialog_time_li
 // domains whitelisted for remote XUL, so that intranet apps and such continue
 // to work without major rewrites. However, we also use the whitelist mechanism
 // to run our XBL tests in automation, in which case we really want to be testing
 // the configuration that we ship to users without special whitelisting. So we
 // use an additional pref here to allow automation to use the "normal" behavior.
 user_pref("dom.use_xbl_scopes_for_remote_xul", true);
 user_pref("dom.w3c_touch_events.enabled", 1);
 user_pref("dom.webcomponents.customelements.enabled", true);
-user_pref("dom.webcomponents.shadowdom.enabled", false);
+user_pref("dom.webcomponents.shadowdom.enabled", true);
 user_pref("extensions.autoDisableScopes", 0);
 user_pref("extensions.blocklist.detailsURL", "http://{server}/extensions-dummy/blocklistDetailsURL");
 user_pref("extensions.blocklist.itemURL", "http://{server}/extensions-dummy/blocklistItemURL");
 user_pref("extensions.blocklist.url", "http://{server}/extensions-dummy/blocklistURL");
 // XPI extensions are required for test harnesses to load
 user_pref("extensions.defaultProviders.enabled", true);
 // Enable form autofill feature testing.
 user_pref("extensions.formautofill.available", "on");
--- a/testing/web-platform/meta/css/css-shadow-parts/all-hosts.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/all-hosts.html.ini
@@ -1,4 +1,6 @@
 [all-hosts.html]
-  [CSS Shadow Parts - All Hosts]
+  [::part with host selector styles in first host]
     expected: FAIL
 
+  [::part with host selector styles in second host]
+    expected: FAIL
--- a/testing/web-platform/meta/css/css-shadow-parts/complex-matching.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/complex-matching.html.ini
@@ -1,4 +1,4 @@
 [complex-matching.html]
-  [CSS Shadow Parts - Complex Matching]
+  [Complex selector for host works]
     expected: FAIL
 
--- a/testing/web-platform/meta/css/css-shadow-parts/inner-host.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/inner-host.html.ini
@@ -1,4 +1,4 @@
 [inner-host.html]
-  [CSS Shadow Parts - Inner Host]
+  [Part in outer host is styled by document style sheet]
     expected: FAIL
 
--- a/testing/web-platform/meta/css/css-shadow-parts/invalidation-change-part-name.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/invalidation-change-part-name.html.ini
@@ -1,4 +1,4 @@
 [invalidation-change-part-name.html]
-  [CSS Shadow Parts - Invalidation Change Part Name]
+  [Part in selected host changed color]
     expected: FAIL
 
--- a/testing/web-platform/meta/css/css-shadow-parts/invalidation-complex-selector.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/invalidation-complex-selector.html.ini
@@ -1,4 +1,4 @@
 [invalidation-complex-selector.html]
-  [CSS Shadow Parts - Invalidation Complex Selector]
+  [Part in selected host changed color]
     expected: FAIL
 
--- a/testing/web-platform/meta/css/css-shadow-parts/simple.html.ini
+++ b/testing/web-platform/meta/css/css-shadow-parts/simple.html.ini
@@ -1,4 +1,4 @@
 [simple.html]
-  [CSS Shadow Parts - Simple]
+  [Part in selected host is styled]
     expected: FAIL
 
deleted file mode 100644
--- a/testing/web-platform/meta/css/css-transforms/transform-origin-in-shadow.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[transform-origin-in-shadow.html]
-  expected: ERROR
-  ['transform-origin' on <svg> being direct descendant of shadow root]
-    expected: FAIL
-
--- a/testing/web-platform/meta/css/cssom/getComputedStyle-detached-subtree.html.ini
+++ b/testing/web-platform/meta/css/cssom/getComputedStyle-detached-subtree.html.ini
@@ -1,8 +1,15 @@
 [getComputedStyle-detached-subtree.html]
-  expected: ERROR
   [getComputedStyle returns no style for detached element]
     expected: FAIL
 
   [getComputedStyle returns no style for element in non-rendered iframe (display: none)]
     expected: FAIL
 
+  [getComputedStyle returns no style for element outside the flat tree]
+    expected: FAIL
+
+  [getComputedStyle returns no style for descendant outside the flat tree]
+    expected: FAIL
+
+  [getComputedStyle returns no style for shadow tree outside of flattened tree]
+    expected: FAIL
--- a/testing/web-platform/meta/dom/interfaces.html.ini
+++ b/testing/web-platform/meta/dom/interfaces.html.ini
@@ -132,73 +132,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "origin" with the proper type]
     expected: FAIL
 
   [Document interface: xmlDoc must inherit property "origin" with the proper type]
     expected: FAIL
 
-  [ShadowRoot interface: existence and properties of interface object]
-    expected: FAIL
-
-  [ShadowRoot interface object length]
-    expected: FAIL
-
-  [ShadowRoot interface object name]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
-
-  [ShadowRoot interface: attribute mode]
-    expected: FAIL
-
-  [ShadowRoot interface: attribute host]
-    expected: FAIL
-
-  [Element interface: attribute slot]
-    expected: FAIL
-
-  [Element interface: operation attachShadow(ShadowRootInit)]
-    expected: FAIL
-
-  [Element interface: attribute shadowRoot]
-    expected: FAIL
-
-  [Element interface: attribute assignedSlot]
-    expected: FAIL
-
-  [Element interface: element must inherit property "slot" with the proper type]
-    expected: FAIL
-
-  [Element interface: element must inherit property "attachShadow(ShadowRootInit)" with the proper type]
-    expected: FAIL
-
-  [Element interface: calling attachShadow(ShadowRootInit) on element with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [Element interface: element must inherit property "shadowRoot" with the proper type]
-    expected: FAIL
-
-  [Element interface: element must inherit property "assignedSlot" with the proper type]
-    expected: FAIL
-
-  [Text interface: attribute assignedSlot]
-    expected: FAIL
-
-  [Text interface: document.createTextNode("abc") must inherit property "assignedSlot" with the proper type]
-    expected: FAIL
-
   [AbstractRange interface: existence and properties of interface object]
     expected: FAIL
 
   [AbstractRange interface object length]
     expected: FAIL
 
   [AbstractRange interface object name]
     expected: FAIL
@@ -271,73 +214,16 @@
     expected: FAIL
 
   [Document interface: new Document() must inherit property "origin" with the proper type]
     expected: FAIL
 
   [Document interface: xmlDoc must inherit property "origin" with the proper type]
     expected: FAIL
 
-  [ShadowRoot interface: existence and properties of interface object]
-    expected: FAIL
-
-  [ShadowRoot interface object length]
-    expected: FAIL
-
-  [ShadowRoot interface object name]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
-
-  [ShadowRoot interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
-
-  [ShadowRoot interface: attribute mode]
-    expected: FAIL
-
-  [ShadowRoot interface: attribute host]
-    expected: FAIL
-
-  [Element interface: attribute slot]
-    expected: FAIL
-
-  [Element interface: operation attachShadow(ShadowRootInit)]
-    expected: FAIL
-
-  [Element interface: attribute shadowRoot]
-    expected: FAIL
-
-  [Element interface: attribute assignedSlot]
-    expected: FAIL
-
-  [Element interface: element must inherit property "slot" with the proper type]
-    expected: FAIL
-
-  [Element interface: element must inherit property "attachShadow(ShadowRootInit)" with the proper type]
-    expected: FAIL
-
-  [Element interface: calling attachShadow(ShadowRootInit) on element with too few arguments must throw TypeError]
-    expected: FAIL
-
-  [Element interface: element must inherit property "shadowRoot" with the proper type]
-    expected: FAIL
-
-  [Element interface: element must inherit property "assignedSlot" with the proper type]
-    expected: FAIL
-
-  [Text interface: attribute assignedSlot]
-    expected: FAIL
-
-  [Text interface: document.createTextNode("abc") must inherit property "assignedSlot" with the proper type]
-    expected: FAIL
-
   [AbstractRange interface: existence and properties of interface object]
     expected: FAIL
 
   [AbstractRange interface object length]
     expected: FAIL
 
   [AbstractRange interface object name]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/dom/nodes/rootNode.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[rootNode.html]
-  [getRootNode() must return context object's shadow-including root if options's composed is true, and context object's root otherwise]
-    expected: FAIL
-
--- a/testing/web-platform/meta/fullscreen/idlharness.window.js.ini
+++ b/testing/web-platform/meta/fullscreen/idlharness.window.js.ini
@@ -3,19 +3,16 @@
     expected: FAIL
 
   [Document interface: operation exitFullscreen()]
     expected: FAIL
 
   [Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenerror" with the proper type]
     expected: FAIL
 
-  [ShadowRoot interface: attribute fullscreenElement]
-    expected: FAIL
-
   [Element interface: attribute onfullscreenerror]
     expected: FAIL
 
   [Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenchange" with the proper type]
     expected: FAIL
 
   [Element interface: attribute onfullscreenchange]
     expected: FAIL
--- a/testing/web-platform/meta/fullscreen/interfaces.html.ini
+++ b/testing/web-platform/meta/fullscreen/interfaces.html.ini
@@ -1,15 +1,12 @@
 [interfaces.html]
   [Document interface: operation exitFullscreen()]
     expected: FAIL
 
-  [ShadowRoot interface: attribute fullscreenElement]
-    expected: FAIL
-
   [Element interface: operation requestFullscreen()]
     expected: FAIL
 
   [Element interface: attribute onfullscreenchange]
     expected: FAIL
 
   [Element interface: attribute onfullscreenerror]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/html/editing/editing-0/contenteditable/contentEditable-slotted-inherit.html.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[contentEditable-slotted-inherit.html]
-  [Slotted child of contenteditable host should be editable - slot direct child of shadow root]
-    expected: FAIL
-
-  [Slotted child of contenteditable host should be editable - slot wrapped in shadow tree ancestor]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/document-metadata/the-link-element/link-rel-attribute.html.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[link-rel-attribute.html]
-  [Untitled]
-    expected: FAIL
-
-  [Removing stylesheet from link rel attribute should remove the stylesheet for shadow DOM]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/pointerlock/interfaces.window.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[interfaces.window.html]
-  [ShadowRoot interface: attribute pointerLockElement]
-    expected: FAIL
-
--- a/toolkit/components/extensions/schemas/manifest.json
+++ b/toolkit/components/extensions/schemas/manifest.json
@@ -214,18 +214,23 @@
                 "preprocess": "localize"
               },
               "url": {
                 "type": "string",
                 "optional": true,
                 "preprocess": "localize"
               }
             }
+          },
+
+          "hidden": {
+            "type": "boolean",
+            "optional": true,
+            "default": false
           }
-
         },
 
         "additionalProperties": { "$ref": "UnrecognizedProperty" }
       },
       {
         "id": "WebExtensionLangpackManifest",
         "type": "object",
         "description": "Represents a WebExtension language pack manifest.json file",
--- a/toolkit/content/widgets.css
+++ b/toolkit/content/widgets.css
@@ -3,18 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* ===== widgets.css =====================================================
    == Styles ported from XBL <resources>, loaded by "global.css".
    ======================================================================= */
 
 @import url("chrome://global/content/autocomplete.css");
 @import url("chrome://global/skin/autocomplete.css");
-@import url("resource://formautofill/autocomplete-item-shared.css");
-@import url("resource://formautofill/autocomplete-item.css");
 @import url("chrome://global/skin/dialog.css");
 @import url("chrome://global/skin/dropmarker.css");
 @import url("chrome://global/skin/groupbox.css");
 @import url("chrome://global/skin/menu.css");
 @import url("chrome://global/skin/menulist.css");
 @import url("chrome://global/skin/notification.css");
 @import url("chrome://global/skin/popup.css");
 @import url("chrome://global/skin/progressmeter.css");
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -111,17 +111,17 @@ const PROP_JSON_FIELDS = ["id", "syncGUI
                           "updateDate", "applyBackgroundUpdates", "path",
                           "skinnable", "sourceURI", "releaseNotesURI",
                           "softDisabled", "foreignInstall",
                           "strictCompatibility", "locales", "targetApplications",
                           "targetPlatforms", "signedState",
                           "seen", "dependencies", "hasEmbeddedWebExtension",
                           "userPermissions", "icons", "iconURL", "icon64URL",
                           "blocklistState", "blocklistURL", "startupData",
-                          "previewImage"];
+                          "previewImage", "hidden"];
 
 const LEGACY_TYPES = new Set([
   "extension",
 ]);
 
 // Some add-on types that we track internally are presented as other types
 // externally
 const TYPE_ALIASES = {
@@ -283,16 +283,17 @@ class AddonInternal {
     this.blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
     this.blocklistURL = null;
     this.sourceURI = null;
     this.releaseNotesURI = null;
     this.foreignInstall = false;
     this.seen = true;
     this.skinnable = false;
     this.startupData = null;
+    this._hidden = false;
 
     this.inDatabase = false;
 
     /**
      * @property {Array<string>} dependencies
      *   An array of bootstrapped add-on IDs on which this add-on depends.
      *   The add-on will remain appDisabled if any of the dependent
      *   add-ons is not installed and enabled.
@@ -411,17 +412,22 @@ class AddonInternal {
     return this.signedState > AddonManager.SIGNEDSTATE_MISSING;
   }
 
   get isCompatible() {
     return this.isCompatibleWith();
   }
 
   get hidden() {
-    return this.location.isSystem;
+    return this.location.isSystem ||
+           (this._hidden && this.signedState == AddonManager.SIGNEDSTATE_PRIVILEGED);
+  }
+
+  set hidden(val) {
+    this._hidden = val;
   }
 
   get disabled() {
     return (this.userDisabled || this.appDisabled || this.softDisabled);
   }
 
   get isPlatformCompatible() {
     if (this.targetPlatforms.length == 0)
@@ -572,20 +578,20 @@ class AddonInternal {
   }
 
   async setUserDisabled(val) {
     if (val == (this.userDisabled || this.softDisabled)) {
       return;
     }
 
     if (this.inDatabase) {
-      // hidden and system add-ons should not be user disabled,
-      // as there is no UI to re-enable them.
-      if (this.hidden) {
-        throw new Error(`Cannot disable hidden add-on ${this.id}`);
+      // System add-ons should not be user disabled, as there is no UI to
+      // re-enable them.
+      if (this.location.isSystem) {
+        throw new Error(`Cannot disable system add-on ${this.id}`);
       }
       await XPIDatabase.updateAddonDisabledState(this, val);
     } else {
       this.userDisabled = val;
       // When enabling remove the softDisabled flag
       if (!val)
         this.softDisabled = false;
     }
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -461,16 +461,17 @@ async function loadManifestFromWebManife
   addon.internalName = null;
   addon.updateURL = bss.update_url;
   addon.optionsBrowserStyle = true;
   addon.optionsURL = null;
   addon.optionsType = null;
   addon.aboutURL = null;
   addon.dependencies = Object.freeze(Array.from(extension.dependencies));
   addon.startupData = extension.startupData;
+  addon.hidden = manifest.hidden;
 
   if (isTheme(addon.type) && await aPackage.hasResource("preview.png")) {
     addon.previewImage = "preview.png";
   }
 
   if (manifest.options_ui) {
     // Store just the relative path here, the AddonWrapper getURL
     // wrapper maps this to a full URL.
@@ -807,16 +808,19 @@ var loadManifest = async function(aPacka
               await loadManifestFromWebManifest(aPackage.rootURI, aPackage) :
               await loadFromRDF(aPackage.getURI("install.rdf"));
 
   addon._sourceBundle = aPackage.file;
   addon.location = aLocation;
 
   let {signedState, cert} = await aPackage.verifySignedState(addon);
   addon.signedState = signedState;
+  if (signedState != AddonManager.SIGNEDSTATE_PRIVILEGED) {
+    addon.hidden = false;
+  }
 
   if (isWebExtension && !addon.id) {
     if (cert) {
       addon.id = cert.commonName;
       if (!gIDTest.test(addon.id)) {
         throw new Error(`Webextension is signed with an invalid id (${addon.id})`);
       }
     }
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_hidden.js
@@ -0,0 +1,51 @@
+
+add_task(async function test_hidden() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2");
+  AddonTestUtils.usePrivilegedSignatures = id => id.startsWith("privileged");
+
+  await promiseStartupManager();
+
+  let xpi1 = createTempWebExtensionFile({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "privileged@tests.mozilla.org",
+        },
+      },
+
+      name: "Hidden Extension",
+      hidden: true,
+    },
+  });
+
+  let xpi2 = createTempWebExtensionFile({
+    manifest: {
+      applications: {
+        gecko: {
+          id: "unprivileged@tests.mozilla.org",
+        },
+      },
+
+      name: "Non-Hidden Extension",
+      hidden: true,
+    },
+  });
+
+  await promiseInstallAllFiles([xpi1, xpi2]);
+
+  let [addon1, addon2] = await promiseAddonsByIDs(["privileged@tests.mozilla.org",
+                                                   "unprivileged@tests.mozilla.org"]);
+
+  ok(addon1.hidden, "Privileged extension should be hidden");
+  ok(!addon2.hidden, "Unprivileged extension should not be hidden");
+
+  await promiseRestartManager();
+
+  ([addon1, addon2] = await promiseAddonsByIDs(["privileged@tests.mozilla.org",
+                                                "unprivileged@tests.mozilla.org"]));
+
+  ok(addon1.hidden, "Privileged extension should be hidden");
+  ok(!addon2.hidden, "Unprivileged extension should not be hidden");
+
+  await promiseShutdownManager();
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_nodisable_hidden.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_nodisable_hidden.js
@@ -88,17 +88,17 @@ add_task(async function() {
   Assert.ok(addon.isActive);
   Assert.equal(addon.type, "extension");
 
   // system add-ons cannot be disabled by the user.
   try {
     await addon.disable();
     do_throw("Expected addon.userDisabled on a hidden add-on to throw!");
   } catch (e) {
-    Assert.equal(e.message, `Cannot disable hidden add-on ${SYSTEM_ID}`);
+    Assert.equal(e.message, `Cannot disable system add-on ${SYSTEM_ID}`);
   }
 
   Assert.notEqual(addon, null);
   Assert.equal(addon.version, "1.0");
   Assert.equal(addon.name, "Test disabling hidden add-ons, hidden system add-on case.");
   Assert.ok(addon.isCompatible);
   Assert.ok(!addon.appDisabled);
   Assert.ok(!addon.userDisabled);
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -129,16 +129,17 @@ tags = blocklist
 tags = blocklist
 [test_gfxBlacklist_prefs.js]
 # Bug 1248787 - consistently fails
 skip-if = true
 tags = blocklist
 [test_gmpProvider.js]
 skip-if = appname != "firefox"
 [test_harness.js]
+[test_hidden.js]
 [test_install.js]
 [test_install_icons.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_invalid_install_rdf.js]
 [test_isDebuggable.js]
 [test_isReady.js]
 [test_json_updatecheck.js]
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2045,28 +2045,21 @@ private:
   bool mWantAfterProcessing;
   nsCString mCurrentAddress;
   mozilla::LinkedList<CCGraphDescriber> mDescribers;
   FILE* mCCLog;
 };
 
 NS_IMPL_ISUPPORTS(nsCycleCollectorLogger, nsICycleCollectorListener)
 
-nsresult
-nsCycleCollectorLoggerConstructor(nsISupports* aOuter,
-                                  const nsIID& aIID,
-                                  void** aInstancePtr)
+already_AddRefed<nsICycleCollectorListener>
+nsCycleCollector_createLogger()
 {
-  if (NS_WARN_IF(aOuter)) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-
-  nsISupports* logger = new nsCycleCollectorLogger();
-
-  return logger->QueryInterface(aIID, aInstancePtr);
+  nsCOMPtr<nsICycleCollectorListener> logger = new nsCycleCollectorLogger();
+  return logger.forget();
 }
 
 static bool
 GCThingIsGrayCCThing(JS::GCCellPtr thing)
 {
     return AddToCCKind(thing.kind()) &&
            JS::GCThingIsMarkedGray(thing);
 }
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -41,16 +41,17 @@ void nsCycleCollector_prepareForGarbageC
 void nsCycleCollector_finishAnyCurrentCollection();
 
 void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false,
                                                bool aPurge = false);
 bool nsCycleCollector_doDeferredDeletion();
 bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget);
 
 already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink();
+already_AddRefed<nsICycleCollectorListener> nsCycleCollector_createLogger();
 
 void nsCycleCollector_collect(nsICycleCollectorListener* aManualListener);
 
 void nsCycleCollector_collectSlice(js::SliceBudget& budget,
                                    bool aPreferShorterSlices = false);
 
 uint32_t nsCycleCollector_suspectedCount();
 
@@ -61,18 +62,9 @@ void nsCycleCollector_shutdown(bool aDoC
 // Helpers for interacting with JS
 void nsCycleCollector_registerJSContext(mozilla::CycleCollectedJSContext* aCx);
 void nsCycleCollector_forgetJSContext();
 
 // Helpers for cooperative threads.
 void nsCycleCollector_registerNonPrimaryContext(mozilla::CycleCollectedJSContext* aCx);
 void nsCycleCollector_forgetNonPrimaryContext();
 
-#define NS_CYCLE_COLLECTOR_LOGGER_CID \
-{ 0x58be81b4, 0x39d2, 0x437c, \
-{ 0x94, 0xea, 0xae, 0xde, 0x2c, 0x62, 0x08, 0xd3 } }
-
-extern nsresult
-nsCycleCollectorLoggerConstructor(nsISupports* aOuter,
-                                  const nsIID& aIID,
-                                  void** aInstancePtr);
-
 #endif // nsCycleCollector_h__
--- a/xpcom/base/nsICycleCollectorListener.idl
+++ b/xpcom/base/nsICycleCollectorListener.idl
@@ -11,25 +11,25 @@ class nsCycleCollectorLogger;
 %}
 
 [ptr] native FILE(FILE);
 [ptr] native nsCycleCollectorLoggerPtr (nsCycleCollectorLogger);
 interface nsIFile;
 
 /**
  * A set of interfaces for recording the cycle collector's work. An instance
- * of @mozilla.org/cycle-collector-logger;1 can be configured to enable various
+ * of nsICycleCollectorListener can be configured to enable various
  * options, then passed to the cycle collector when it runs.
  * Note that additional logging options are available by setting environment
  * variables, as described at the top of nsCycleCollector.cpp.
  */
 
 /**
  * nsICycleCollectorHandler is the interface JS code should implement to
- * receive the results logged by a @mozilla.org/cycle-collector-logger;1
+ * receive the results logged by an nsICycleCollectorListener
  * instance. Pass an instance of this to the logger's 'processNext' method
  * after the collection has run. This will describe the objects the cycle
  * collector visited, the edges it found, and the conclusions it reached
  * about the liveness of objects.
  *
  * In more detail:
  * - For each node in the graph:
  *   - a call is made to either |noteRefCountedObject| or |noteGCedObject|, to
@@ -93,18 +93,20 @@ interface nsICycleCollectorLogSink : nsI
 
 /**
  * This interface is used to configure some reporting options for the cycle
  * collector. This interface cannot be implemented by JavaScript code, as it
  * is called while the cycle collector is running.
  *
  * To analyze cycle collection data in JS:
  *
- * - Create an instance of @mozilla.org/cycle-collector-logger;1, which
- *   implements this interface.
+ * - Create an instance of nsICycleCollectorListener, which implements this
+ *   interface. In C++, this can be done by calling
+ *   nsCycleCollector_createLogger(). In JS, this can be done by calling
+ *   Components.utils.createCCLogger().
  *
  * - Set its |disableLog| property to true. This prevents the logger from
  *   printing messages about each method call to a temporary log file.
  *
  * - Set its |wantAfterProcessing| property to true. This tells the logger
  *   to record calls to its methods in memory. The |processNext| method
  *   returns events from this record.
  *
--- a/xpcom/base/nsMemoryInfoDumper.cpp
+++ b/xpcom/base/nsMemoryInfoDumper.cpp
@@ -379,18 +379,17 @@ nsMemoryInfoDumper::DumpGCAndCCLogsToFil
       logSink->SetFilenameIdentifier(identifier);
       logSink->SetProcessIdentifier(cp->Pid());
 
       Unused << cp->CycleCollectWithLogs(aDumpAllTraces, logSink,
                                          callbackHolder);
     }
   }
 
-  nsCOMPtr<nsICycleCollectorListener> logger =
-    do_CreateInstance("@mozilla.org/cycle-collector-logger;1");
+  nsCOMPtr<nsICycleCollectorListener> logger = nsCycleCollector_createLogger();
 
   if (aDumpAllTraces) {
     nsCOMPtr<nsICycleCollectorListener> allTracesLogger;
     logger->AllTraces(getter_AddRefs(allTracesLogger));
     logger = allTracesLogger;
   }
 
   nsCOMPtr<nsICycleCollectorLogSink> logSink;
@@ -407,18 +406,17 @@ nsMemoryInfoDumper::DumpGCAndCCLogsToFil
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMemoryInfoDumper::DumpGCAndCCLogsToSink(bool aDumpAllTraces,
                                           nsICycleCollectorLogSink* aSink)
 {
-  nsCOMPtr<nsICycleCollectorListener> logger =
-    do_CreateInstance("@mozilla.org/cycle-collector-logger;1");
+  nsCOMPtr<nsICycleCollectorListener> logger = nsCycleCollector_createLogger();
 
   if (aDumpAllTraces) {
     nsCOMPtr<nsICycleCollectorListener> allTracesLogger;
     logger->AllTraces(getter_AddRefs(allTracesLogger));
     logger = allTracesLogger;
   }
 
   logger->SetLogSink(aSink);
--- a/xpcom/build/XPCOMModule.inc
+++ b/xpcom/build/XPCOMModule.inc
@@ -67,10 +67,9 @@
 #if defined(MOZ_WIDGET_COCOA)
     COMPONENT(MACUTILSIMPL, nsMacUtilsImplConstructor)
 #endif
 
     COMPONENT(SYSTEMINFO, nsSystemInfoConstructor)
     COMPONENT_M(MEMORY_REPORTER_MANAGER, nsMemoryReporterManagerConstructor, Module::ALLOW_IN_GPU_PROCESS)
     COMPONENT(MEMORY_INFO_DUMPER, nsMemoryInfoDumperConstructor)
     COMPONENT(IOUTIL, nsIOUtilConstructor)
-    COMPONENT(CYCLE_COLLECTOR_LOGGER, nsCycleCollectorLoggerConstructor)
     COMPONENT(MESSAGE_LOOP, nsMessageLoopConstructor)
--- a/xpcom/build/nsXPCOMCID.h
+++ b/xpcom/build/nsXPCOMCID.h
@@ -72,21 +72,16 @@
 #define NS_MEMORY_REPORTER_MANAGER_CONTRACTID "@mozilla.org/memory-reporter-manager;1"
 
 /**
  * Memory info dumper service CID
  */
 #define NS_MEMORY_INFO_DUMPER_CONTRACTID "@mozilla.org/memory-info-dumper;1"
 
 /**
- * Cycle collector logger contract id
- */
-#define NS_CYCLE_COLLECTOR_LOGGER_CONTRACTID "@mozilla.org/cycle-collector-logger;1"
-
-/**
  * nsMessageLoop contract id
  */
 #define NS_MESSAGE_LOOP_CONTRACTID "@mozilla.org/message-loop;1"
 
 #define NS_COMPARTMENT_INFO_CONTRACTID "@mozilla.org/compartment-info;1"
 
 /**
  * The following are the CIDs and Contract IDs of the nsISupports wrappers for