Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 26 Jul 2017 11:16:03 +0200
changeset 419984 e9224528ba04e008087766d6bc2d0e10eea4c195
parent 419983 71511633aae746122e6345797486250dfe292503 (current diff)
parent 419742 e8400551c2e39f24c75a009ebed496c7acd7bf47 (diff)
child 419985 68a7ead060bfd1fa8d453286362a7377d9887f42
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
gfx/thebes/DeviceManagerDx.cpp
tools/profiler/core/platform.cpp
--- a/Makefile.in
+++ b/Makefile.in
@@ -243,20 +243,22 @@ default all::
 include $(topsrcdir)/config/rules.mk
 
 ifdef SCCACHE_VERBOSE_STATS
 default::
 	-$(CCACHE) --show-stats --stats-format=json > sccache-stats.json
 	@echo "===SCCACHE STATS==="
 	-$(CCACHE) --show-stats
 	@echo "==================="
+ifndef MOZ_PROFILE_GENERATE
 # Ideally we'd do that in the same file as we set the sccache.log location for
 # sccache, but it's too late in the build.
 	-gzip -9 $(DIST)/sccache.log
 endif
+endif
 
 distclean::
 	$(RM) $(DIST_GARBAGE)
 
 ifdef MOZ_CRASHREPORTER
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 endif
--- a/accessible/tests/mochitest/elm/a11y.ini
+++ b/accessible/tests/mochitest/elm/a11y.ini
@@ -9,8 +9,9 @@ skip-if = buildapp == 'mulet'
 [test_figure.html]
 [test_listbox.xul]
 [test_MathMLSpec.html]
 [test_nsApplicationAcc.html]
 [test_plugin.html]
 skip-if = buildapp == 'mulet'
 [test_canvas.html]
 [test_shadowroot.html]
+skip-if = stylo # bug 1293844
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -38,20 +38,16 @@ var whitelist = [
   {file: "chrome://pdf.js/locale/viewer.properties"},
 
   // security/manager/pki/resources/content/device_manager.js
   {file: "chrome://pippki/content/load_device.xul"},
 
   // Used by setting this url as a pref in about:config
   {file: "chrome://browser/content/newtab/alternativeDefaultSites.json"},
 
-  // Temporary whitelisted while WebPayments in construction
-  // See Bug 1381141
-  {file: "chrome://payments/content/paymentRequest.xhtml"},
-
   // Add-on compat
   {file: "chrome://browser/skin/devtools/common.css"},
   {file: "chrome://global/content/XPCNativeWrapper.js"},
   {file: "chrome://global/locale/brand.dtd"},
 
   // The l10n build system can't package string files only for some platforms.
   // See bug 1339424 for why this is hard to fix.
   {file: "chrome://global/locale/fallbackMenubar.properties",
@@ -170,16 +166,24 @@ var whitelist = [
   {file: "resource://gre/modules/Manifest.jsm"},
   // Bug 1351097
   {file: "resource://gre/modules/accessibility/AccessFu.jsm"},
   // Bug 1351637
   {file: "resource://gre/modules/sdk/bootstrap.js"},
 
 ];
 
+// Temporary whitelisted while WebPayments in construction
+// See Bug 1381141
+if (AppConstants.NIGHTLY_BUILD && AppConstants.MOZ_BUILD_APP == "browser") {
+  whitelist.push(
+    {file: "chrome://payments/content/paymentRequest.xhtml"}
+  );
+}
+
 if (!AppConstants.MOZ_PHOTON_THEME) {
   whitelist.push(
     // Bug 1343824
     {file: "chrome://browser/skin/customizableui/customize-illustration-rtl@2x.png",
      platforms: ["linux", "win"]},
     {file: "chrome://browser/skin/customizableui/customize-illustration@2x.png",
      platforms: ["linux", "win"]},
     {file: "chrome://browser/skin/customizableui/info-icon-customizeTip@2x.png",
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -446,24 +446,31 @@
        context="toolbar-context-menu"
 #endif
        hidden="true">
 #ifdef MOZ_PHOTON_THEME
   <photonpanelmultiview mainViewId="widget-overflow-mainView">
     <panelview id="widget-overflow-mainView"
                context="toolbar-context-menu">
 #endif
-      <vbox id="widget-overflow-scroller">
-        <vbox id="widget-overflow-list" class="widget-overflow-list"
-              overflowfortoolbar="nav-bar"/>
-        <toolbarseparator id="widget-overflow-fixed-separator" hidden="true"/>
-        <vbox id="widget-overflow-fixed-list" class="widget-overflow-list" hidden="true"
-              emptylabel="&customizeMode.emptyOverflowList.description;"/>
+      <vbox class="panel-subview-body">
+        <vbox id="widget-overflow-scroller">
+          <vbox id="widget-overflow-list" class="widget-overflow-list"
+                overflowfortoolbar="nav-bar"/>
+          <toolbarseparator id="widget-overflow-fixed-separator" hidden="true"/>
+          <vbox id="widget-overflow-fixed-list" class="widget-overflow-list" hidden="true"
+                emptylabel="&customizeMode.emptyOverflowList.description;"/>
+        </vbox>
       </vbox>
 #ifdef MOZ_PHOTON_THEME
+      <toolbarbutton command="cmd_CustomizeToolbars"
+                      id="overflowMenu-customize-button"
+                      class="subviewbutton panel-subview-footer"
+                      accesskey="&overflowCustomizeToolbar.accesskey;"
+                      label="&overflowCustomizeToolbar.label;"/>
     </panelview>
   </photonpanelmultiview>
 #endif
 </panel>
 
 <panel id="customization-tipPanel"
        type="arrow"
        flip="none"
--- a/browser/components/extensions/ext-history.js
+++ b/browser/components/extensions/ext-history.js
@@ -60,19 +60,19 @@ const convertNodeToHistoryItem = node =>
 /*
  * Converts a nsINavHistoryResultNode into a VisitItem
  *
  * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode
  */
 const convertNodeToVisitItem = node => {
   return {
     id: node.pageGuid,
-    visitId: node.visitId,
+    visitId: String(node.visitId),
     visitTime: PlacesUtils.toDate(node.time).getTime(),
-    referringVisitId: node.fromVisitId,
+    referringVisitId: String(node.fromVisitId),
     transition: getTransition(node.visitType),
   };
 };
 
 /*
  * Converts a nsINavHistoryContainerResultNode into an array of objects
  *
  * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryContainerResultNode
--- a/browser/components/extensions/schemas/devtools_inspected_window.json
+++ b/browser/components/extensions/schemas/devtools_inspected_window.json
@@ -131,23 +131,23 @@
           {
             "name": "callback",
             "type": "function",
             "description": "A function called when evaluation completes.",
             "optional": true,
             "parameters": [
               {
                 "name": "result",
-                "type": "object",
-                "additionalProperties": {"type": "any"},
+                "type": "any",
                 "description": "The result of evaluation."
               },
               {
                 "name": "exceptionInfo",
                 "type": "object",
+                "optional": true,
                 "description": "An object providing details if an exception occurred while evaluating the expression.",
                 "properties": {
                   "isError": {
                     "type": "boolean",
                     "description": "Set if the error occurred on the DevTools side before the expression is evaluated."
                   },
                   "code": {
                     "type": "string",
--- a/browser/components/extensions/schemas/tabs.json
+++ b/browser/components/extensions/schemas/tabs.json
@@ -53,34 +53,34 @@
         }
       },
       {
         "id": "Tab",
         "type": "object",
         "properties": {
           "id": {"type": "integer", "minimum": -1, "optional": true, "description": "The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a Tab may not be assigned an ID, for example when querying foreign tabs using the $(ref:sessions) API, in which case a session ID may be present. Tab ID can also be set to $(ref:tabs.TAB_ID_NONE) for apps and devtools windows."},
           "index": {"type": "integer", "minimum": -1, "description": "The zero-based index of the tab within its window."},
-          "windowId": {"type": "integer", "minimum": 0, "description": "The ID of the window the tab is contained within."},
+          "windowId": {"type": "integer", "optional": true, "minimum": 0, "description": "The ID of the window the tab is contained within."},
           "openerTabId": {"unsupported": true, "type": "integer", "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists."},
           "selected": {"type": "boolean", "description": "Whether the tab is selected.", "deprecated": "Please use $(ref:tabs.Tab.highlighted).", "unsupported": true},
           "highlighted": {"type": "boolean", "description": "Whether the tab is highlighted. Works as an alias of active"},
           "active": {"type": "boolean", "description": "Whether the tab is active in its window. (Does not necessarily mean the window is focused.)"},
           "pinned": {"type": "boolean", "description": "Whether the tab is pinned."},
           "lastAccessed": {"type": "integer", "optional": true, "description": "The last time the tab was accessed as the number of milliseconds since epoch."},
           "audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the speaker audio indicator is showing."},
           "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."},
           "url": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "title": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "favIconUrl": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."},
           "status": {"type": "string", "optional": true, "description": "Either <em>loading</em> or <em>complete</em>."},
           "incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."},
           "width": {"type": "integer", "optional": true, "description": "The width of the tab in pixels."},
           "height": {"type": "integer", "optional": true, "description": "The height of the tab in pixels."},
-          "sessionId": {"unsupported": true, "type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."},
-          "cookieStoreId": {"type": "string", "description": "The CookieStoreId used for the tab."}
+          "sessionId": {"type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."},
+          "cookieStoreId": {"type": "string", "optional": true, "description": "The CookieStoreId used for the tab."}
         }
       },
       {
         "id": "ZoomSettingsMode",
         "type": "string",
         "description": "Defines how zoom changes are handled, i.e. which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.",
         "enum": [
           {
@@ -501,16 +501,17 @@
           {
             "type": "function",
             "name": "callback",
             "optional": true,
             "parameters": [
               {
                 "name": "tab",
                 "$ref": "Tab",
+                "optional": true,
                 "description": "Details about the created tab. Will contain the ID of the new tab."
               }
             ]
           }
         ]
       },
       {
         "name": "duplicate",
--- a/browser/components/preferences/in-content-new/main.xul
+++ b/browser/components/preferences/in-content-new/main.xul
@@ -384,18 +384,16 @@
                 label="&restoreDefault.label;"
                 accesskey="&restoreDefault.accesskey;"
                 preference="pref.browser.homepage.disable_button.restore_default"/>
       </html:td>
     </html:tr>
   </html:table>
 </groupbox>
 
-  <caption><label>&defaultSearchEngine.label;</label></caption>
-  <caption><label>&oneClickSearchEngines.label;</label></caption>
 <!-- Tab preferences -->
 <groupbox data-category="paneGeneral"
           hidden="true">
     <caption><label>&tabsGroup.label;</label></caption>
 
     <checkbox id="ctrlTabRecentlyUsedOrder" label="&ctrlTabRecentlyUsedOrder.label;"
               accesskey="&ctrlTabRecentlyUsedOrder.accesskey;"
               preference="browser.ctrlTab.previews"/>
@@ -452,19 +450,19 @@
 </hbox>
 
 <!-- Fonts and Colors -->
 <groupbox id="fontsGroup" data-category="paneGeneral" hidden="true">
   <caption><label>&fontsAndColors.label;</label></caption>
 
   <vbox>
     <hbox id="fontSettings">
-      <hbox align="center">
+      <hbox align="center" flex="1">
         <label control="defaultFont" accesskey="&defaultFont2.accesskey;">&defaultFont2.label;</label>
-        <menulist id="defaultFont" delayprefsave="true" onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
+        <menulist id="defaultFont" flex="1" delayprefsave="true" onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
         <label id="defaultFontSizeLabel" control="defaultFontSize" accesskey="&defaultSize2.accesskey;">&defaultSize2.label;</label>
         <menulist id="defaultFontSize" delayprefsave="true">
           <menupopup>
             <menuitem value="9" label="9"/>
             <menuitem value="10" label="10"/>
             <menuitem value="11" label="11"/>
             <menuitem value="12" label="12"/>
             <menuitem value="13" label="13"/>
@@ -729,16 +727,18 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1">&updateApplication.label;</label>
 </hbox>
 
 <!-- Update -->
 <groupbox id="updateApp" data-category="paneGeneral" hidden="true">
+  <label>&updateApplicationDescription.label;</label>
+  <separator/>
   <hbox align="start">
     <vbox flex="1">
       <description>
         &updateApplication.version.pre;<label id="version"/>&updateApplication.version.post;
         <label id="releasenotes" class="learnMore text-link" hidden="true">&releaseNotes.link;</label>
       </description>
       <description id="distribution" class="text-blurb" hidden="true"/>
       <description id="distributionId" class="text-blurb" hidden="true"/>
@@ -822,17 +822,19 @@
       <hbox id="manualUpdate" align="center">
         <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
         <spacer flex="1"/>
         <button label="&update.checkForUpdatesButton.label;"
                 accesskey="&update.checkForUpdatesButton.accesskey;"
                 disabled="true"/>
       </hbox>
       <hbox id="unsupportedSystem" align="center">
-        <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
+        <description flex="1">
+          <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
+        </description>
         <spacer flex="1"/>
         <button label="&update.checkForUpdatesButton.label;"
                 accesskey="&update.checkForUpdatesButton.accesskey;"
                 disabled="true"/>
       </hbox>
       <hbox id="restarting" align="center">
         <image class="update-throbber"/><label>&update.restarting;</label>
         <spacer flex="1"/>
@@ -845,18 +847,18 @@
 #endif
 
   <separator/>
 #ifdef MOZ_UPDATER
   <description>&updateApplication.description;</description>
   <radiogroup id="updateRadioGroup">
     <radio id="autoDesktop"
            value="auto"
-           label="&updateAuto2.label;"
-           accesskey="&updateAuto2.accesskey;"/>
+           label="&updateAuto3.label;"
+           accesskey="&updateAuto3.accesskey;"/>
     <radio value="checkOnly"
           label="&updateCheckChoose2.label;"
           accesskey="&updateCheckChoose2.accesskey;"/>
     <radio value="manual"
           label="&updateManual2.label;"
           accesskey="&updateManual2.accesskey;"/>
   </radiogroup>
 #ifdef MOZ_MAINTENANCE_SERVICE
--- a/browser/components/preferences/in-content-new/privacy.js
+++ b/browser/components/preferences/in-content-new/privacy.js
@@ -1217,26 +1217,26 @@ var gPrivacyPane = {
     this.observer = {
       onNetworkCacheDiskConsumption(consumption) {
         var size = DownloadUtils.convertByteUnits(consumption);
         // The XBL binding for the string bundle may have been destroyed if
         // the page was closed before this callback was executed.
         if (!prefStrBundle.getFormattedString) {
           return;
         }
-        actualSizeLabel.value = prefStrBundle.getFormattedString("actualDiskCacheSize", size);
+        actualSizeLabel.textContent = prefStrBundle.getFormattedString("actualDiskCacheSize", size);
       },
 
       QueryInterface: XPCOMUtils.generateQI([
         Components.interfaces.nsICacheStorageConsumptionObserver,
         Components.interfaces.nsISupportsWeakReference
       ])
     };
 
-    actualSizeLabel.value = prefStrBundle.getString("actualDiskCacheSizeCalculated");
+    actualSizeLabel.textContent = prefStrBundle.getString("actualDiskCacheSizeCalculated");
 
     try {
       var cacheService =
         Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
                   .getService(Components.interfaces.nsICacheStorageService);
       cacheService.asyncGetDiskConsumption(this.observer);
     } catch (e) {}
   },
--- a/browser/components/preferences/in-content-new/privacy.xul
+++ b/browser/components/preferences/in-content-new/privacy.xul
@@ -370,17 +370,17 @@
             accesskey="&locbar.history.accesskey;"
             preference="browser.urlbar.suggest.history"/>
   <checkbox id="bookmarkSuggestion" label="&locbar.bookmarks.label;"
             accesskey="&locbar.bookmarks.accesskey;"
             preference="browser.urlbar.suggest.bookmark"/>
   <checkbox id="openpageSuggestion" label="&locbar.openpage.label;"
             accesskey="&locbar.openpage.accesskey;"
             preference="browser.urlbar.suggest.openpage"/>
-  <label class="text-link" onclick="gotoPref('general')">
+  <label class="text-link" onclick="gotoPref('search')">
     &suggestionSettings2.label;
   </label>
 </groupbox>
 
 <!-- Cache -->
 <groupbox id="cacheGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&httpCache.label;</label></caption>
 
@@ -407,34 +407,37 @@
   </hbox>
 </groupbox>
 
 <!-- Site Data -->
 <groupbox id="siteDataGroup" hidden="true" data-category="panePrivacy" data-hidden-from-search="true">
   <caption><label>&siteData.label;</label></caption>
 
   <hbox align="baseline">
-    <label id="totalSiteDataSize"></label>
-    <label id="siteDataLearnMoreLink" class="learnMore text-link" value="&siteDataLearnMoreLink.label;"></label>
-    <spacer flex="1" />
-    <button id="clearSiteDataButton"
-            class="accessory-button"
-            icon="clear"
-            label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
+    <vbox flex="1">
+      <description flex="1">
+        <label id="totalSiteDataSize"></label>
+        <label id="siteDataLearnMoreLink" class="learnMore text-link" value="&siteDataLearnMoreLink.label;"></label>
+      </description>
+    </vbox>
+    <vbox align="end">
+      <button id="siteDataSettings"
+              class="accessory-button"
+              label="&siteDataSettings.label;"
+              accesskey="&siteDataSettings.accesskey;"
+              searchkeywords="&window.title;
+                              &hostCol.label;
+                              &statusCol.label;
+                              &usageCol.label;"/>
+      <button id="clearSiteDataButton"
+          class="accessory-button"
+          icon="clear"
+          label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
+    </vbox>
   </hbox>
-  <vbox align="end">
-    <button id="siteDataSettings"
-            class="accessory-button"
-            label="&siteDataSettings.label;"
-            accesskey="&siteDataSettings.accesskey;"
-            searchkeywords="&window.title;
-                            &hostCol.label;
-                            &statusCol.label;
-                            &usageCol.label;"/>
-  </vbox>
 </groupbox>
 
 <!-- Tracking -->
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&trackingProtectionHeader2.label;</label></caption>
   <vbox>
     <hbox align="start">
       <vbox flex="1">
@@ -515,21 +518,21 @@
 <groupbox id="permissionsGroup" data-category="panePrivacy" hidden="true">
   <grid>
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows>
       <row id="notificationsPolicyRow" align="center">
-        <hbox flex="1">
+        <description flex="1">
           <label id="notificationsPolicy">&notificationsPolicyDesc3.label;</label>
           <label id="notificationsPolicyLearnMore"
                  class="learnMore text-link">&notificationsPolicyLearnMore.label;</label>
-        </hbox>
+        </description>
         <hbox pack="end">
           <button id="notificationsPolicyButton"
                   class="accessory-button"
                   label="&notificationsPolicyButton.label;"
                   accesskey="&notificationsPolicyButton.accesskey;"
                   searchkeywords="&removepermission.label;
                                   &removeallpermissions.label;
                                   &button.cancel.label;
@@ -588,32 +591,32 @@
 <!-- Firefox Data Collection and Use -->
 #ifdef MOZ_DATA_REPORTING
 <groupbox id="dataCollectionGroup" data-category="panePrivacy" data-subcategory="reports" hidden="true">
   <description>
     &dataCollectionDesc.label;<label id="dataCollectionPrivacyNotice" class="learnMore text-link">&dataCollectionPrivacyNotice.label;</label>
   </description>
 
   <vbox>
-    <hbox align="center">
+    <description flex="1">
       <checkbox id="submitHealthReportBox" label="&enableHealthReport1.label;"
-                accesskey="&enableHealthReport1.accesskey;"/>
+                accesskey="&enableHealthReport1.accesskey;" flex="1" />
       <label id="FHRLearnMore"
              class="learnMore text-link">&healthReportLearnMore.label;</label>
-    </hbox>
+    </description>
 #ifndef MOZ_TELEMETRY_REPORTING
     <description id="TelemetryDisabledDesc" class="indent" control="telemetryGroup">&healthReportingDisabled.label;</description>
 #endif
   </vbox>
 #ifdef MOZ_CRASHREPORTER
   <hbox align="center">
     <checkbox id="automaticallySubmitCrashesBox"
               preference="browser.crashReports.unsubmittedCheck.autoSubmit"
               label="&alwaysSubmitCrashReports1.label;"
-              accesskey="&alwaysSubmitCrashReports1.accesskey;"/>
+              accesskey="&alwaysSubmitCrashReports1.accesskey;" flex="1" />
     <label id="crashReporterLearnMore"
            class="learnMore text-link">&crashReporterLearnMore.label;</label>
   </hbox>
 #endif
 </groupbox>
 #endif
 
 <hbox id="securityCategory"
--- a/browser/components/preferences/in-content-new/search.xul
+++ b/browser/components/preferences/in-content-new/search.xul
@@ -22,17 +22,17 @@
     <hbox id="searchCategory"
           class="subcategory"
           hidden="true"
           data-category="paneSearch">
       <label class="header-name" flex="1">&paneSearch.title;</label>
     </hbox>
 
     <!-- Default Search Engine -->
-    <groupbox id="defaultEngineGroup" align="start" data-category="paneSearch">
+    <groupbox id="defaultEngineGroup" data-category="paneSearch">
       <caption label="&defaultSearchEngine.label;"/>
       <label>&chooseYourDefaultSearchEngine2.label;</label>
       <menulist id="defaultEngine">
         <menupopup/>
       </menulist>
       <checkbox id="suggestionsInSearchFieldsCheckbox"
                 label="&provideSearchSuggestions.label;"
                 accesskey="&provideSearchSuggestions.accesskey;"
--- a/browser/components/preferences/in-content-new/sync.xul
+++ b/browser/components/preferences/in-content-new/sync.xul
@@ -152,31 +152,31 @@
               </vbox>
             </hbox>
           </deck>
         </groupbox>
         <groupbox id="syncOptions">
           <caption><label>&signedIn.settings.label;</label></caption>
           <description>&signedIn.settings.description;</description>
           <hbox id="fxaSyncEngines">
-            <vbox align="start" flex="1">
+            <vbox flex="1">
               <checkbox label="&engine.tabs.label2;"
                         accesskey="&engine.tabs.accesskey;"
                         preference="engine.tabs"/>
               <checkbox label="&engine.bookmarks.label;"
                         accesskey="&engine.bookmarks.accesskey;"
                         preference="engine.bookmarks"/>
               <checkbox label="&engine.logins.label;"
                         accesskey="&engine.logins.accesskey;"
                         preference="engine.passwords"/>
               <checkbox label="&engine.history.label;"
                         accesskey="&engine.history.accesskey;"
                         preference="engine.history"/>
             </vbox>
-            <vbox align="start" flex="1">
+            <vbox flex="1">
               <checkbox label="&engine.addons.label;"
                         accesskey="&engine.addons.accesskey;"
                         preference="engine.addons"/>
               <checkbox label="&engine.prefs.label;"
                         accesskey="&engine.prefs.accesskey;"
                         preference="engine.prefs"/>
               <checkbox label="&engine.addresses.label;"
                         accesskey="&engine.addresses.accesskey;"
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -15,9 +15,8 @@ export MOZ_TELEMETRY_REPORTING=1
 #Use ccache
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux32/devedition
+++ b/browser/config/mozconfigs/linux32/devedition
@@ -15,9 +15,8 @@ ac_add_options --enable-verify-mar
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/aurora
 
 mk_add_options MOZ_PGO=1
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -1,10 +1,8 @@
-no_sccache=1
-
 ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.no-compile"
 
 if test `uname -m` = "x86_64"; then
   ac_add_options --target=i686-pc-linux
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig-devedition
@@ -1,10 +1,8 @@
-no_sccache=1
-
 ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --with-branding=browser/branding/aurora
 
 . "$topsrcdir/build/mozconfig.no-compile"
 
 if test `uname -m` = "x86_64"; then
   ac_add_options --target=i686-pc-linux
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -6,9 +6,8 @@ ac_add_options --enable-verify-mar
 # This will overwrite the default of stripping everything and keep the symbol table.
 # This is useful for profiling and debugging and only increases the package size
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -15,9 +15,8 @@ export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/debug-static-analysis-clang
+++ b/browser/config/mozconfigs/linux64/debug-static-analysis-clang
@@ -19,9 +19,8 @@ export CXX="$topsrcdir/clang/bin/clang++
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
 export PKG_CONFIG_LIBDIR=/usr/lib64/pkgconfig:/usr/share/pkgconfig
 . $topsrcdir/build/unix/mozconfig.gtk
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/devedition
+++ b/browser/config/mozconfigs/linux64/devedition
@@ -15,9 +15,8 @@ ac_add_options --enable-verify-mar
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/aurora
 
 mk_add_options MOZ_PGO=1
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -1,10 +1,8 @@
-no_sccache=1
-
 ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.no-compile"
 
 export MOZILLA_OFFICIAL=1
 
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig-devedition
@@ -1,10 +1,8 @@
-no_sccache=1
-
 ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --with-branding=browser/branding/aurora
 
 . "$topsrcdir/build/mozconfig.no-compile"
 
 export MOZILLA_OFFICIAL=1
 
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -6,9 +6,8 @@ ac_add_options --enable-verify-mar
 # This will overwrite the default of stripping everything and keep the symbol table.
 # This is useful for profiling and debugging and only increases the package size
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/opt-static-analysis-clang
+++ b/browser/config/mozconfigs/linux64/opt-static-analysis-clang
@@ -18,9 +18,8 @@ CXX="$topsrcdir/clang/bin/clang++"
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
 export PKG_CONFIG_LIBDIR=/usr/lib64/pkgconfig:/usr/share/pkgconfig
 . $topsrcdir/build/unix/mozconfig.gtk
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/beta
+++ b/browser/config/mozconfigs/macosx64/beta
@@ -4,9 +4,8 @@ if [ -n "$ENABLE_RELEASE_PROMOTION" ]; t
 fi
 
 . "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt"
 
 ac_add_options --enable-official-branding
 ac_add_options --enable-verify-mar
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64/debug
@@ -15,9 +15,8 @@ ac_add_options --with-macbundlename-pref
 fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/debug-static-analysis
+++ b/browser/config/mozconfigs/macosx64/debug-static-analysis
@@ -5,9 +5,8 @@ MOZ_AUTOMATION_L10N_CHECK=0
 . $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-debug
 ac_add_options --enable-dmd
 
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/devedition
+++ b/browser/config/mozconfigs/macosx64/devedition
@@ -20,9 +20,8 @@ fi
 
 if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
 ac_add_options --with-macbundlename-prefix=Firefox
 fi
 
 ac_add_options --with-branding=browser/branding/aurora
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/nightly
+++ b/browser/config/mozconfigs/macosx64/nightly
@@ -12,9 +12,8 @@ fi
 
 if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
 ac_add_options --with-macbundlename-prefix=Firefox
 fi
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/opt-static-analysis
+++ b/browser/config/mozconfigs/macosx64/opt-static-analysis
@@ -6,10 +6,9 @@ MOZ_AUTOMATION_L10N_CHECK=0
 
 ac_add_options --disable-debug
 ac_add_options --enable-optimize
 ac_add_options --enable-dmd
 
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
 
--- a/browser/config/mozconfigs/macosx64/release
+++ b/browser/config/mozconfigs/macosx64/release
@@ -11,9 +11,8 @@ fi
 ac_add_options --enable-official-branding
 ac_add_options --enable-verify-mar
 
 # safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
 # defines.sh during the beta cycle
 export BUILDING_RELEASE=1
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/whitelist
+++ b/browser/config/mozconfigs/whitelist
@@ -21,56 +21,51 @@ for platform in ['linux32', 'linux64', '
     ]
 
 whitelist['nightly']['linux32'] += [
     'CXX=$REAL_CXX',
     'CXX="ccache $REAL_CXX"',
     'CC="ccache $REAL_CC"',
     'mk_add_options PROFILE_GEN_SCRIPT=@TOPSRCDIR@/build/profile_pageloader.pl',
     'ac_add_options --with-ccache=/usr/bin/ccache',
-    '. "$topsrcdir/build/mozconfig.cache"',
     'export MOZILLA_OFFICIAL=1',
     'export MOZ_TELEMETRY_REPORTING=1',
     "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
     'STRIP_FLAGS="--strip-debug"',
 ]
 
 whitelist['nightly']['linux64'] += [
     'export MOZILLA_OFFICIAL=1',
     'export MOZ_TELEMETRY_REPORTING=1',
     "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
     'STRIP_FLAGS="--strip-debug"',
     'ac_add_options --with-ccache=/usr/bin/ccache',
-    '. "$topsrcdir/build/mozconfig.cache"',
 ]
 
 whitelist['nightly']['macosx64'] += [
     'if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then',
     'ac_add_options --with-macbundlename-prefix=Firefox',
     'fi',
     'mk_add_options MOZ_MAKE_FLAGS="-j12"',
     'ac_add_options --with-ccache',
-    '. "$topsrcdir/build/mozconfig.cache"',
     'ac_add_options --disable-install-strip',
     'ac_add_options --enable-instruments',
     'ac_add_options --enable-dtrace',
     'if test `uname -s` != Linux; then',
 ]
 
 whitelist['nightly']['win32'] += [
     '. $topsrcdir/configs/mozilla2/win32/include/choose-make-flags',
     'mk_add_options MOZ_MAKE_FLAGS=-j1',
-    '. "$topsrcdir/build/mozconfig.cache"',
     'if test "$IS_NIGHTLY" != ""; then',
     'ac_add_options --disable-auto-deps',
     'fi',
 ]
 whitelist['nightly']['win64'] += [
     '. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"',
-    '. "$topsrcdir/build/mozconfig.cache"',
 ]
 
 for platform in all_platforms:
     whitelist['release'][platform] = [
         'ac_add_options --enable-update-channel=release',
         'ac_add_options --enable-official-branding',
         'mk_add_options MOZ_MAKE_FLAGS="-j4"',
         'export BUILDING_RELEASE=1',
--- a/browser/config/mozconfigs/win32/debug
+++ b/browser/config/mozconfigs/win32/debug
@@ -18,9 +18,8 @@ export MOZ_TELEMETRY_REPORTING=1
 . $topsrcdir/build/win32/mozconfig.vs-latest
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win32/devedition
+++ b/browser/config/mozconfigs/win32/devedition
@@ -11,9 +11,8 @@ MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/aurora
 
 mk_add_options MOZ_PGO=1
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win32/nightly
+++ b/browser/config/mozconfigs/win32/nightly
@@ -2,9 +2,8 @@
 . "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
 
 ac_add_options --enable-profiling
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win64/debug
+++ b/browser/config/mozconfigs/win64/debug
@@ -21,9 +21,8 @@ export MOZ_TELEMETRY_REPORTING=1
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . $topsrcdir/build/win64/mozconfig.vs-latest
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win64/devedition
+++ b/browser/config/mozconfigs/win64/devedition
@@ -12,9 +12,8 @@ MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/aurora
 
 mk_add_options MOZ_PGO=1
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win64/nightly
+++ b/browser/config/mozconfigs/win64/nightly
@@ -3,9 +3,8 @@
 . "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
 
 ac_add_options --enable-profiling
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/nightly
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/tooltool-manifests/linux32/releng.manifest
+++ b/browser/config/tooltool-manifests/linux32/releng.manifest
@@ -11,19 +11,19 @@
     "size": 11189216,
     "digest": "18bc52b0599b1308b667e282abb45f47597bfc98a5140cfcab8da71dacf89dd76d0dee22a04ce26fe7ad1f04e2d6596991f9e5b01fd2aaaab5542965f596b0e6",
     "algorithm": "sha512",
     "filename": "gtk3.tar.xz",
     "setup": "setup.sh",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/linux64/asan.manifest
+++ b/browser/config/tooltool-manifests/linux64/asan.manifest
@@ -11,19 +11,28 @@
     "version": "clang 3.9.0, libgcc 4.9.4",
     "size": 166261192,
     "digest": "52f3fc23f0f5c98050f8b0ac7c92a6752d067582a16f712a5a58074be98975d594f9e36249fc2be7f1cc2ca6d509c663faaf2bea66f949243cc1f41651638ba6",
     "algorithm": "sha512",
     "filename": "clang.tar.xz",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
+    "algorithm": "sha512",
+    "visibility": "public",
+    "filename": "sccache2.tar.xz",
+    "unpack": true,
+    "digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
+    "size": 2191380
+  },
+  {
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "size": 12072532,
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/linux64/clang.manifest
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest
@@ -11,19 +11,19 @@
     "size": 12072532,
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "algorithm": "sha512",
     "filename": "gtk3.tar.xz",
     "setup": "setup.sh",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/linux64/clang.manifest.centos6
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest.centos6
@@ -11,19 +11,19 @@
     "size": 12072532,
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "algorithm": "sha512",
     "filename": "gtk3.tar.xz",
     "setup": "setup.sh",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/linux64/fuzzing.manifest
+++ b/browser/config/tooltool-manifests/linux64/fuzzing.manifest
@@ -12,16 +12,25 @@
     "size": 215309284,
     "visibility": "public",
     "digest": "8f6d386ca1d4606526dd24f366b1dbc1914c6c6d7f54c69c2a2ca0e7cfabe641c1168952d606295feffa9f38ad687084de5efb1e80be3ed2f431ac91de80039b",
     "algorithm": "sha512",
     "filename": "clang.tar.xz",
     "unpack": true
   },
   {
+    "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
+    "algorithm": "sha512",
+    "visibility": "public",
+    "filename": "sccache2.tar.xz",
+    "unpack": true,
+    "digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
+    "size": 2191380
+  },
+  {
     "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
     "size": 146886764,
     "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
--- a/browser/config/tooltool-manifests/linux64/hazard.manifest
+++ b/browser/config/tooltool-manifests/linux64/hazard.manifest
@@ -19,19 +19,19 @@
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "unpack": true,
     "setup": "setup.sh",
     "algorithm": "sha512",
     "filename": "gtk3.tar.xz",
     "size": 12072532
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/linux64/msan.manifest
+++ b/browser/config/tooltool-manifests/linux64/msan.manifest
@@ -11,19 +11,19 @@
     "version": "clang 3.9.0, libgcc 4.9.4",
     "size": 166261192,
     "digest": "52f3fc23f0f5c98050f8b0ac7c92a6752d067582a16f712a5a58074be98975d594f9e36249fc2be7f1cc2ca6d509c663faaf2bea66f949243cc1f41651638ba6",
     "algorithm": "sha512",
     "filename": "clang.tar.xz",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "size": 12072532,
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/linux64/releng.manifest
+++ b/browser/config/tooltool-manifests/linux64/releng.manifest
@@ -11,19 +11,19 @@
     "size": 12072532,
     "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
     "algorithm": "sha512",
     "filename": "gtk3.tar.xz",
     "setup": "setup.sh",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 146886764,
-    "digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 161014632,
+    "digest": "65bebcf94fc66ea618c58c9ac33f0f206095ecfe3931cc6edb301f4b40480e3b44b0f39aea7a25fed8eef47e63523e7e670082947a3662cdc04c68ebbe5dfc89",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/macosx64/clang.manifest
+++ b/browser/config/tooltool-manifests/macosx64/clang.manifest
@@ -3,19 +3,19 @@
     "version": "clang 3.9.0",
     "size": 185632474,
     "digest": "0e1a556b65d6398fa812b9ceb5ce5e2dec3eda77d4a032a818182b34fc8ce602412f42388bb1fda6bea265d35c1dde3847a730b264fec01cd7e3dcfd39941660",
     "algorithm": "sha512",
     "filename": "clang.tar.bz2",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 97110232,
-    "digest": "7df456b9f86a0f11b81700b6bbb9451137beb5a4035fe2330dc507c804fe8230573636720dba60308eee5305b7c04bc041c025ca0ca98bef54f98f98b48dd8d7",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 109162660,
+    "digest": "3335320fe950c75fd02c0828d062f633a0eadd77482c5c5f096d5faddc1826e500a557129ef89f5cdb0b5f1778b74bd0b569c996b9f54bdb105ef2bff7e628eb",
     "algorithm": "sha512",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
@@ -37,19 +37,19 @@
     "size": 57060,
     "visibility": "public",
     "digest": "0c96f0d3ace71c4110abec6f7ead013600b0a73c89465d840276090d849279e555d977fb2aa6bbabb7891d7191fc8cc8a4e8242be888114be52346b77a512fcc",
     "algorithm": "sha512",
     "unpack": true,
     "filename": "dmg.tar.xz"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 141005088,
-    "digest": "8c915059da3df885c4b26efa25431719a41a108adbc900f49ca51419fee30480e32ac99aeb398954722c10b72dea6d1d39fc122846c86194b12063c9b85da47d",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 155690216,
+    "digest": "379f542ea16c775e7bcad36823f0068ca6a1f17c2b25e42ef978d51865298ba4207dc89bbb614805f81a123d12e339209a447afbd12c1122e16f4c7c41e7d92b",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "size": 281576,
     "visibility": "public",
     "digest": "71616564533d138fb12f08e761c2638d054814fdf9c9439638ec57b201e100445c364d73d8d7a4f0e3b784898d5fe6264e8242863fc5ac40163f1791468bbc46",
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -3,19 +3,19 @@
     "version": "clang 3.9.0",
     "size": 185632474,
     "digest": "0e1a556b65d6398fa812b9ceb5ce5e2dec3eda77d4a032a818182b34fc8ce602412f42388bb1fda6bea265d35c1dde3847a730b264fec01cd7e3dcfd39941660",
     "algorithm": "sha512",
     "filename": "clang.tar.bz2",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 97110232,
-    "digest": "7df456b9f86a0f11b81700b6bbb9451137beb5a4035fe2330dc507c804fe8230573636720dba60308eee5305b7c04bc041c025ca0ca98bef54f98f98b48dd8d7",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 109162660,
+    "digest": "3335320fe950c75fd02c0828d062f633a0eadd77482c5c5f096d5faddc1826e500a557129ef89f5cdb0b5f1778b74bd0b569c996b9f54bdb105ef2bff7e628eb",
     "algorithm": "sha512",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "cctools port from commit hash 8e9c3f2506b51",
     "size": 2233376,
     "digest": "d632ef587f0253f016aa5323999a3d9576284c04e66b5243a5780af9a55f474ac91ad8dee5bd86a6ee4e2593e2b345e2fd0aa4e8838b3686f84c5c5ac5c9c418",
--- a/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
+++ b/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
@@ -1,19 +1,19 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 90954208,
-    "digest": "6ee6ab72521c1f476fd15a3f2787f3046a1648f34cbc43380c2ba3915c2207b29c942fefe4b56426f5bafe47937c6a8074201d61a79d02ad366dace41d5cb717",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 97017057,
+    "digest": "b726645f9d26c5a3048720b3839166021c1cf91a02d2ff2f10c49adced7455c7352e18b5052084d80bf9d1c40ec1bf72d0397921b8cd23262f89fdbd10def58f",
     "algorithm": "sha512",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/win32/clang.manifest
+++ b/browser/config/tooltool-manifests/win32/clang.manifest
@@ -1,19 +1,19 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 90954208,
-    "digest": "6ee6ab72521c1f476fd15a3f2787f3046a1648f34cbc43380c2ba3915c2207b29c942fefe4b56426f5bafe47937c6a8074201d61a79d02ad366dace41d5cb717",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 97017057,
+    "digest": "b726645f9d26c5a3048720b3839166021c1cf91a02d2ff2f10c49adced7455c7352e18b5052084d80bf9d1c40ec1bf72d0397921b8cd23262f89fdbd10def58f",
     "algorithm": "sha512",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/win32/releng.manifest
+++ b/browser/config/tooltool-manifests/win32/releng.manifest
@@ -1,19 +1,19 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 90954208,
-    "digest": "6ee6ab72521c1f476fd15a3f2787f3046a1648f34cbc43380c2ba3915c2207b29c942fefe4b56426f5bafe47937c6a8074201d61a79d02ad366dace41d5cb717",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 97017057,
+    "digest": "b726645f9d26c5a3048720b3839166021c1cf91a02d2ff2f10c49adced7455c7352e18b5052084d80bf9d1c40ec1bf72d0397921b8cd23262f89fdbd10def58f",
     "algorithm": "sha512",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/browser/config/tooltool-manifests/win64/clang.manifest
+++ b/browser/config/tooltool-manifests/win64/clang.manifest
@@ -1,19 +1,19 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 98336380,
-    "digest": "92091d92ce135ee52486c31ae670735dd140ab5b1389f14582c4d9b14cbb393f7180399b9232564a3eb96443b568323070a3c1329deb07b145b28476e8271175",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 103602526,
+    "digest": "558d2d18991ad8b250a5d6b46a55e1ffdffc50d6bdd9cb4b3a945dd3d1143836b32e47f1df612bfea97ca2c02333ed43055b6c3030ecb1632385fb6940c1d246",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/win64/releng.manifest
+++ b/browser/config/tooltool-manifests/win64/releng.manifest
@@ -1,19 +1,19 @@
 [
   {
     "size": 266240,
     "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
     "algorithm": "sha512",
     "filename": "mozmake.exe"
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 98336380,
-    "digest": "92091d92ce135ee52486c31ae670735dd140ab5b1389f14582c4d9b14cbb393f7180399b9232564a3eb96443b568323070a3c1329deb07b145b28476e8271175",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 103602526,
+    "digest": "558d2d18991ad8b250a5d6b46a55e1ffdffc50d6bdd9cb4b3a945dd3d1143836b32e47f1df612bfea97ca2c02333ed43055b6c3030ecb1632385fb6940c1d246",
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "rustc.tar.bz2",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/win64/sccache-build.manifest
@@ -0,0 +1,27 @@
+[
+  {
+    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
+    "size": 98336380,
+    "digest": "92091d92ce135ee52486c31ae670735dd140ab5b1389f14582c4d9b14cbb393f7180399b9232564a3eb96443b568323070a3c1329deb07b145b28476e8271175",
+    "algorithm": "sha512",
+    "visibility": "public",
+    "filename": "rustc.tar.bz2",
+    "unpack": true
+  },
+  {
+    "version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",
+    "size": 326656969,
+    "digest": "babc414ffc0457d27f5a1ed24a8e4873afbe2f1c1a4075469a27c005e1babc3b2a788f643f825efedff95b79686664c67ec4340ed535487168a3482e68559bc7",
+    "algorithm": "sha512",
+    "filename": "vs2015u3.zip",
+    "unpack": true
+  },
+  {
+    "version": "MinGit-2.13.3-64-bit",
+    "size": 21482885,
+    "digest": "929bb3c07be8487ee519422a312bdbfeec8f4db4b62c49d02f9aad9fd2a66c0ee5fad63d2b06c8744c336dc9d50446fa4457897333ad17ffd783ecabd1e2ddbb",
+    "algorithm": "sha512",
+    "filename": "git.zip",
+    "unpack": true
+  }
+]
--- a/browser/extensions/formautofill/test/browser/browser.ini
+++ b/browser/extensions/formautofill/test/browser/browser.ini
@@ -1,14 +1,16 @@
 [DEFAULT]
 head = head.js
 
 support-files =
   ../fixtures/autocomplete_basic.html
 
 [browser_autocomplete_footer.js]
+[browser_autocomplete_marked_back_forward.js]
+[browser_autocomplete_marked_detached_tab.js]
 [browser_check_installed.js]
 [browser_editProfileDialog.js]
 [browser_first_time_use_doorhanger.js]
 [browser_privacyPreferences.js]
 [browser_manageProfilesDialog.js]
 [browser_submission_in_private_mode.js]
 [browser_update_doorhanger.js]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/browser_autocomplete_marked_back_forward.js
@@ -0,0 +1,61 @@
+/**
+ * Test that autofill autocomplete works after back/forward navigation
+ */
+
+"use strict";
+
+const URL = BASE_URL + "autocomplete_basic.html";
+
+function checkPopup(autoCompletePopup) {
+  let first = autoCompletePopup.view.results[0];
+  const {primary, secondary} = JSON.parse(first.label);
+  ok(primary.startsWith(TEST_ADDRESS_1["street-address"].split("\n")[0]),
+     "Check primary label is street address");
+  is(secondary, TEST_ADDRESS_1["address-level2"], "Check secondary label is address-level2");
+}
+
+add_task(async function setup_storage() {
+  await saveAddress(TEST_ADDRESS_1);
+  await saveAddress(TEST_ADDRESS_2);
+  await saveAddress(TEST_ADDRESS_3);
+});
+
+add_task(async function test_back_forward() {
+  await BrowserTestUtils.withNewTab({gBrowser, url: URL}, async function(browser) {
+    const {autoCompletePopup} = browser;
+
+    // Check the page after the initial load
+    await openPopupOn(browser, "#street-address");
+    checkPopup(autoCompletePopup);
+
+    // Now navigate forward and make sure autofill autocomplete results are still attached
+    let loadPromise = BrowserTestUtils.browserLoaded(browser);
+    await BrowserTestUtils.loadURI(browser, `${URL}?load=2`);
+    await loadPromise;
+
+    // Check the second page
+    await openPopupOn(browser, "#street-address");
+    checkPopup(autoCompletePopup);
+
+    // Check after hitting back to the first page
+    let stoppedPromise = BrowserTestUtils.browserStopped(browser);
+    browser.goBack();
+    await stoppedPromise;
+    await openPopupOn(browser, "#street-address");
+    checkPopup(autoCompletePopup);
+
+    // Check after hitting forward to the second page
+    stoppedPromise = BrowserTestUtils.browserStopped(browser);
+    browser.goForward();
+    await stoppedPromise;
+    await openPopupOn(browser, "#street-address");
+    checkPopup(autoCompletePopup);
+
+    // Ensure the popup is closed before entering the next test.
+    await ContentTask.spawn(browser, {}, async function() {
+      content.document.getElementById("street-address").blur();
+    });
+    await BrowserTestUtils.waitForCondition(() => !autoCompletePopup.popupOpen,
+                                            "popup should have closed");
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/browser_autocomplete_marked_detached_tab.js
@@ -0,0 +1,54 @@
+/**
+ * Test that autofill autocomplete works after detaching a tab
+ */
+
+"use strict";
+
+const URL = BASE_URL + "autocomplete_basic.html";
+
+function checkPopup(autoCompletePopup) {
+  let first = autoCompletePopup.view.results[0];
+  const {primary, secondary} = JSON.parse(first.label);
+  ok(primary.startsWith(TEST_ADDRESS_1["street-address"].split("\n")[0]),
+     "Check primary label is street address");
+  is(secondary, TEST_ADDRESS_1["address-level2"], "Check secondary label is address-level2");
+}
+
+add_task(async function setup_storage() {
+  await saveAddress(TEST_ADDRESS_1);
+  await saveAddress(TEST_ADDRESS_2);
+  await saveAddress(TEST_ADDRESS_3);
+});
+
+add_task(async function test_detach_tab_marked() {
+  await BrowserTestUtils.withNewTab({gBrowser, url: URL}, async function(browser) {
+    const {autoCompletePopup} = browser;
+
+    // Check the page after the initial load
+    await openPopupOn(browser, "#street-address");
+    checkPopup(autoCompletePopup);
+
+    // Detach the tab to a new window
+    let newWin = gBrowser.replaceTabWithWindow(gBrowser.getTabForBrowser(browser));
+    await TestUtils.topicObserved("browser-delayed-startup-finished", subject => {
+      return subject == newWin;
+    });
+
+    info("tab was detached");
+    let newBrowser = newWin.gBrowser.selectedBrowser;
+    ok(newBrowser, "Found new <browser>");
+    let newAutoCompletePopup = newBrowser.autoCompletePopup;
+    ok(newAutoCompletePopup, "Found new autocomplete popup");
+
+    await openPopupOn(newBrowser, "#street-address");
+    checkPopup(newAutoCompletePopup);
+
+    // Ensure the popup is closed before entering the next test.
+    await ContentTask.spawn(newBrowser, {}, async function() {
+      content.document.getElementById("street-address").blur();
+    });
+    await BrowserTestUtils.waitForCondition(() => !newAutoCompletePopup.popupOpen,
+                                           "popup should have closed");
+    await BrowserTestUtils.closeWindow(newWin);
+  });
+});
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -39,27 +39,29 @@ const SECONDARY_BUTTON_INDEX = 1;
 async function sleep(ms = 500) {
   await new Promise(resolve => setTimeout(resolve, ms));
 }
 
 async function expectPopupOpen(browser) {
   const {autoCompletePopup, autoCompletePopup: {richlistbox: itemsBox}} = browser;
   const listItemElems = itemsBox.querySelectorAll(".autocomplete-richlistitem");
 
-  await BrowserTestUtils.waitForCondition(() => autoCompletePopup.popupOpen);
+  await BrowserTestUtils.waitForCondition(() => autoCompletePopup.popupOpen,
+                                         "popup should be open");
   await BrowserTestUtils.waitForCondition(() => {
     return [...listItemElems].every(item => {
       return (item.getAttribute("originaltype") == "autofill-profile" ||
              item.getAttribute("originaltype") == "autofill-footer") &&
              item.hasAttribute("formautofillattached");
     });
-  });
+  }, "The popup should be a form autofill one");
 }
 
 async function openPopupOn(browser, selector) {
+  await SimpleTest.promiseFocus(browser);
   /* eslint no-shadow: ["error", { "allow": ["selector"] }] */
   await ContentTask.spawn(browser, {selector}, async function({selector}) {
     content.document.querySelector(selector).focus();
   });
   await sleep(2000);
   await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
   await expectPopupOpen(browser);
 }
--- a/browser/extensions/screenshots/install.rdf
+++ b/browser/extensions/screenshots/install.rdf
@@ -7,14 +7,14 @@
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!--Firefox-->
         <em:minVersion>51.0a1</em:minVersion>
         <em:maxVersion>*</em:maxVersion>
       </Description>
     </em:targetApplication>
     <em:type>2</em:type>
-    <em:version>10.8.0</em:version>
+    <em:version>10.9.0</em:version>
     <em:bootstrap>true</em:bootstrap>
     <em:homepageURL>https://pageshot.net/</em:homepageURL>
     <em:multiprocessCompatible>true</em:multiprocessCompatible>
   </Description>
 </RDF>
--- a/browser/extensions/screenshots/webextension/build/inlineSelectionCss.js
+++ b/browser/extensions/screenshots/webextension/build/inlineSelectionCss.js
@@ -424,17 +424,17 @@ window.inlineSelectionCss = `
   text-align: center;
   padding-top: 20px;
   width: 400px; }
 
 .myshots-all-buttons-container {
   display: flex;
   flex-direction: row-reverse;
   background: #f5f5f5;
-  border-radius: 1px;
+  border-radius: 2px;
   box-sizing: border-box;
   height: 80px;
   padding: 8px;
   position: absolute;
   right: 5px;
   top: 5px; }
   html[dir="rtl"] .myshots-all-buttons-container {
     left: 5px;
--- a/browser/extensions/screenshots/webextension/build/onboardingCss.js
+++ b/browser/extensions/screenshots/webextension/build/onboardingCss.js
@@ -226,24 +226,24 @@ body {
   top: 50%;
   transition: opacity 100ms cubic-bezier(0.07, 0.95, 0, 1);
   z-index: 10; }
 
 #skip:hover {
   opacity: 1; }
 
 .active-slide-1 #prev,
-.active-slide-4 #next {
+.active-slide-3 #next {
   display: none; }
 
 #done {
   background-image: url("MOZ_EXTENSION/icons/done.svg");
   display: none; }
 
-.active-slide-4 #done {
+.active-slide-3 #done {
   display: inline-block; }
 
 /* for smaller screen sizes */
 @media screen and (max-width: 768px) {
   .slide {
     height: 360px;
     width: 450px; }
     .slide .slide-image {
--- a/browser/extensions/screenshots/webextension/build/onboardingHtml.js
+++ b/browser/extensions/screenshots/webextension/build/onboardingHtml.js
@@ -5,17 +5,17 @@ window.onboardingHtml = `
   <head>
     <!-- onboarding.scss is automatically inserted here: -->
     <style></style>
     <!-- Here and in onboarding.scss use MOZ_EXTENSION/path to refer to local files -->
   </head>
   <body>
     <div id="slide-overlay">
       <!-- The current slide is set by having .active-slide-1, .active-slide-2, etc on #slide element: -->
-      <div id="slide-container" data-number-of-slides="4" class="active-slide-1">
+      <div id="slide-container" data-number-of-slides="3" class="active-slide-1">
         <div class="slide slide-1">
           <!-- Note: all images must be listed in manifest.json.template under web_accessible_resources -->
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-1.png');"></div>
           <div class="slide-content">
             <div class="slide-content-aligner">
               <h1><span><strong>Firefox</strong> Screenshots</span><sup>Beta</sup></h1>
               <p data-l10n-id="tourBodyOne"></p>
             </div>
@@ -25,40 +25,32 @@ window.onboardingHtml = `
         <div class="slide slide-2">
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-2.png');"></div>
           <div class="slide-content">
             <h1 data-l10n-id="tourHeaderTwo"></h1>
             <p data-l10n-id="tourBodyTwo"></p>
           </div>
         </div>
         <div class="slide slide-3">
-          <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-3.png');"></div>
-          <div class="slide-content">
-            <h1 data-l10n-id="tourHeaderThree"></h1>
-            <p data-l10n-id="tourBodyThree"></p>
-          </div>
-        </div>
-        <div class="slide slide-4">
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-4.png');"></div>
           <div class="slide-content">
             <h1 data-l10n-id="tourHeaderFour"></h1>
             <p data-l10n-id="tourBodyFour"></p>
           </div>
         </div>
 
         <!-- Clickable elements should be buttons for accessibility -->
         <button id="skip" data-l10n-id="tourSkip" tabindex=1>Skip</button>
         <button id="prev" tabindex=2 data-l10n-label-id="tourPrevious"></button>
         <button id="next" tabindex=3 data-l10n-label-id="tourNext"></button>
         <button id="done" tabindex=4 data-l10n-label-id="tourDone"></button>
         <div id="slide-status-container">
           <button class="goto-slide goto-slide-1" data-number="1" tabindex=4></button>
           <button class="goto-slide goto-slide-2" data-number="2" tabindex=5></button>
           <button class="goto-slide goto-slide-3" data-number="3" tabindex=6></button>
-          <button class="goto-slide goto-slide-4" data-number="4" tabindex=7></button>
         </div>
         <!-- FIXME: Need to put in privacy / etc links -->
       </div>
     </div>
   </body>
 </html>
 
 `;
--- a/browser/extensions/screenshots/webextension/manifest.json
+++ b/browser/extensions/screenshots/webextension/manifest.json
@@ -1,12 +1,12 @@
 {
   "manifest_version": 2,
   "name": "Firefox Screenshots",
-  "version": "10.8.0",
+  "version": "10.9.0",
   "description": "__MSG_addonDescription__",
   "author": "__MSG_addonAuthorsList__",
   "homepage_url": "https://github.com/mozilla-services/screenshots",
   "applications": {
     "gecko": {
       "id": "screenshots@mozilla.org"
     }
   },
--- a/browser/extensions/screenshots/webextension/onboarding/slides.html
+++ b/browser/extensions/screenshots/webextension/onboarding/slides.html
@@ -3,17 +3,17 @@
   <head>
     <!-- onboarding.scss is automatically inserted here: -->
     <style></style>
     <!-- Here and in onboarding.scss use MOZ_EXTENSION/path to refer to local files -->
   </head>
   <body>
     <div id="slide-overlay">
       <!-- The current slide is set by having .active-slide-1, .active-slide-2, etc on #slide element: -->
-      <div id="slide-container" data-number-of-slides="4" class="active-slide-1">
+      <div id="slide-container" data-number-of-slides="3" class="active-slide-1">
         <div class="slide slide-1">
           <!-- Note: all images must be listed in manifest.json.template under web_accessible_resources -->
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-1.png');"></div>
           <div class="slide-content">
             <div class="slide-content-aligner">
               <h1><span><strong>Firefox</strong> Screenshots</span><sup>Beta</sup></h1>
               <p data-l10n-id="tourBodyOne"></p>
             </div>
@@ -23,38 +23,30 @@
         <div class="slide slide-2">
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-2.png');"></div>
           <div class="slide-content">
             <h1 data-l10n-id="tourHeaderTwo"></h1>
             <p data-l10n-id="tourBodyTwo"></p>
           </div>
         </div>
         <div class="slide slide-3">
-          <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-3.png');"></div>
-          <div class="slide-content">
-            <h1 data-l10n-id="tourHeaderThree"></h1>
-            <p data-l10n-id="tourBodyThree"></p>
-          </div>
-        </div>
-        <div class="slide slide-4">
           <div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-4.png');"></div>
           <div class="slide-content">
             <h1 data-l10n-id="tourHeaderFour"></h1>
             <p data-l10n-id="tourBodyFour"></p>
           </div>
         </div>
 
         <!-- Clickable elements should be buttons for accessibility -->
         <button id="skip" data-l10n-id="tourSkip" tabindex=1>Skip</button>
         <button id="prev" tabindex=2 data-l10n-label-id="tourPrevious"></button>
         <button id="next" tabindex=3 data-l10n-label-id="tourNext"></button>
         <button id="done" tabindex=4 data-l10n-label-id="tourDone"></button>
         <div id="slide-status-container">
           <button class="goto-slide goto-slide-1" data-number="1" tabindex=4></button>
           <button class="goto-slide goto-slide-2" data-number="2" tabindex=5></button>
           <button class="goto-slide goto-slide-3" data-number="3" tabindex=6></button>
-          <button class="goto-slide goto-slide-4" data-number="4" tabindex=7></button>
         </div>
         <!-- FIXME: Need to put in privacy / etc links -->
       </div>
     </div>
   </body>
 </html>
--- a/browser/extensions/screenshots/webextension/selector/ui.js
+++ b/browser/extensions/screenshots/webextension/selector/ui.js
@@ -234,40 +234,31 @@ this.ui = (function() { // eslint-disabl
                      <div class="face-container">
                        <div class="eye left"><div class="eyeball"></div></div>
                        <div class="eye right"><div class="eyeball"></div></div>
                        <div class="face"></div>
                      </div>
                      <div class="preview-instructions"></div>
                      <div class="myshots-all-buttons-container">
                        <button class="myshots-button myshots-link" tabindex="1"></button>
-                       <div class="spacer"></div>
-                       <button class="myshots-button visible" tabindex="2"></button>
-                       <button class="myshots-button full-page" tabindex="3"></button>
                      </div>
                    </div>
                  </div>
                </body>`;
             installHandlerOnDocument(this.document);
             if (this.addClassName) {
               this.document.body.className = this.addClassName;
             }
             this.document.documentElement.dir = browser.i18n.getMessage("@@bidi_dir");
             this.document.documentElement.lang = browser.i18n.getMessage("@@ui_locale");
             const overlay = this.document.querySelector(".preview-overlay");
             overlay.querySelector(".preview-instructions").textContent = browser.i18n.getMessage("screenshotInstructions");
             overlay.querySelector(".myshots-link").textContent = browser.i18n.getMessage("myShotsLink");
-            overlay.querySelector(".visible").textContent = browser.i18n.getMessage("saveScreenshotVisibleArea");
-            overlay.querySelector(".full-page").textContent = browser.i18n.getMessage("saveScreenshotFullPage");
             overlay.querySelector(".myshots-button").addEventListener(
               "click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onOpenMyShots)));
-            overlay.querySelector(".visible").addEventListener(
-              "click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onClickVisible)));
-            overlay.querySelector(".full-page").addEventListener(
-              "click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onClickFullPage)));
             resolve();
           }), {once: true});
           document.body.appendChild(this.element);
           this.unhide();
         } else {
           resolve();
         }
       });
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -327,16 +327,18 @@ These should match what Safari and other
 <!ENTITY viewMenu.label         "View"> 
 <!ENTITY viewMenu.accesskey       "V"> 
 <!ENTITY viewToolbarsMenu.label       "Toolbars"> 
 <!ENTITY viewToolbarsMenu.accesskey     "T"> 
 <!ENTITY viewSidebarMenu.label "Sidebar">
 <!ENTITY viewSidebarMenu.accesskey "e">
 <!ENTITY viewCustomizeToolbar.label       "Customize…"> 
 <!ENTITY viewCustomizeToolbar.accesskey     "C">
+<!ENTITY overflowCustomizeToolbar.label       "Customize Toolbar…">
+<!ENTITY overflowCustomizeToolbar.accesskey   "C">
 
 <!ENTITY historyMenu.label "History">
 <!ENTITY historyMenu.accesskey "s">
 <!ENTITY historyUndoMenu.label "Recently Closed Tabs">
 <!-- LOCALIZATION NOTE (historyUndoWindowMenu): see bug 394759 -->
 <!ENTITY historyUndoWindowMenu.label "Recently Closed Windows">
 <!ENTITY historyRestoreLastSession.label "Restore Previous Session">
 
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -85,21 +85,23 @@ available. -->
 -->
 <!ENTITY updateApplication.label         "&brandShortName; Updates">
 <!-- LOCALIZATION NOTE (updateApplication.version.*): updateApplication.version.pre
 # is followed by a version number, keep the trailing space or replace it with a
 # different character as needed. updateApplication.version.post is displayed
 # after the version number, and is empty on purpose for English. You can use it
 # if required by your language.
  -->
+<!ENTITY updateApplicationDescription.label
+                                         "Keep &brandShortName; up to date for the best performance, stability, and security.">
 <!ENTITY updateApplication.version.pre   "Version ">
 <!ENTITY updateApplication.version.post  "">
 <!ENTITY updateApplication.description   "Allow &brandShortName; to">
-<!ENTITY updateAuto2.label               "Automatically install updates (recommended for improved security)">
-<!ENTITY updateAuto2.accesskey           "A">
+<!ENTITY updateAuto3.label               "Automatically install updates (recommended)">
+<!ENTITY updateAuto3.accesskey           "A">
 <!ENTITY updateCheckChoose2.label        "Check for updates but let you choose to install them">
 <!ENTITY updateCheckChoose2.accesskey    "C">
 <!ENTITY updateManual2.label             "Never check for updates (not recommended)">
 <!ENTITY updateManual2.accesskey         "N">
 
 <!ENTITY updateHistory2.label            "Show Update History…">
 <!ENTITY updateHistory2.accesskey        "p">
 
--- a/browser/locales/en-US/chrome/browser/preferences/sync.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/sync.dtd
@@ -49,17 +49,17 @@ both, to better adapt this sentence to t
 -->
 <!ENTITY signedInLoginFailure.beforename.label "Please sign in to reconnect">
 <!ENTITY signedInLoginFailure.aftername.label "">
 
 <!ENTITY notSignedIn.label           "You are not signed in.">
 <!ENTITY signIn.label                "Sign in">
 <!ENTITY signIn.accesskey            "g">
 <!ENTITY profilePicture.tooltip      "Change profile picture">
-<!ENTITY verifiedManage.label        "Manage Account">
+<!ENTITY verifiedManage.label        "Manage account">
 <!ENTITY verifiedManage.accesskey    "o">
 <!ENTITY disconnect3.label           "Disconnect…">
 <!ENTITY disconnect3.accesskey       "D">
 <!ENTITY verify.label                "Verify Email">
 <!ENTITY verify.accesskey            "V">
 <!ENTITY forget.label                "Forget this Email">
 <!ENTITY forget.accesskey            "F">
 
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -1728,17 +1728,17 @@ toolbarpaletteitem[place=panel] > .toolb
 #widget-overflow > .panel-arrowcontainer > .panel-arrowcontent {
   padding: 0;
 }
 
 .cui-widget-panelview,
 %ifndef MOZ_PHOTON_THEME
 #widget-overflow-scroller {
 %else
-#widget-overflow-mainView {
+#widget-overflow-mainView .panel-subview-body {
 %endif
   overflow-y: auto;
   overflow-x: hidden;
 }
 
 #widget-overflow-scroller {
 %ifdef MOZ_PHOTON_THEME
   margin-top: 4px;
--- a/browser/themes/shared/incontentprefs-old/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs-old/preferences.inc.css
@@ -377,26 +377,28 @@ description > html|a {
   min-width: 30ch;
 }
 
 /**
  * Sync
  */
 
 #fxaProfileImage {
-  max-width: 60px;
+  width: 60px;
+  height: 60px;
   border-radius: 50%;
   list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg);
   margin-inline-end: 15px;
   image-rendering: auto;
   border: 1px solid transparent;
 }
 
 #fxaLoginStatus[hasName] #fxaProfileImage {
-  max-width: 80px;
+  width: 80px;
+  height: 80px;
 }
 
 #fxaProfileImage.actionable {
   cursor: pointer;
 }
 
 #fxaProfileImage.actionable:hover {
   border-color: #0095DD;
@@ -513,17 +515,18 @@ description > html|a {
 #fxaEmailAddress1,
 #fxaEmailAddress2,
 #fxaEmailAddress3 {
   word-break: break-all;
 }
 
 .fxaFirefoxLogo {
   list-style-image: url(chrome://browser/skin/fxa/logo.png);
-  max-width: 64px;
+  width: 64px;
+  height: 64px;
   margin-inline-end: 14px;
 }
 
 .fxaMobilePromo {
   margin-bottom: 20px;
   margin-top: 25px;
 }
 
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -274,16 +274,20 @@ html|option {
 }
 
 /* XXX This style is for bug 740213 and should be removed once that
    bug has a solution. */
 description > html|a {
   cursor: pointer;
 }
 
+description > checkbox {
+  vertical-align: middle;
+}
+
 #weavePrefsDeck > vbox > label,
 #weavePrefsDeck > vbox > groupbox,
 #weavePrefsDeck > vbox > description,
 #weavePrefsDeck > #hasFxaAccount > vbox > label,
 #weavePrefsDeck > #hasFxaAccount > hbox > label {
   /* no margin-inline-start for elements at the beginning of a line */
   margin-inline-start: 0;
 }
@@ -397,26 +401,28 @@ groupbox {
   min-width: 30ch;
 }
 
 /**
  * Sync
  */
 
 #fxaProfileImage {
-  max-width: 60px;
+  width: 60px;
+  height: 60px;
   border-radius: 50%;
   list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg);
   margin-inline-end: 15px;
   image-rendering: auto;
   border: 1px solid transparent;
 }
 
 #fxaLoginStatus[hasName] #fxaProfileImage {
-  max-width: 80px;
+  width: 80px;
+  height: 80px;
 }
 
 #fxaProfileImage.actionable {
   cursor: pointer;
 }
 
 #fxaProfileImage.actionable:hover {
   border-color: #0095DD;
@@ -533,17 +539,18 @@ groupbox {
 #fxaEmailAddress1,
 #fxaEmailAddress2,
 #fxaEmailAddress3 {
   word-break: break-all;
 }
 
 .fxaFirefoxLogo {
   list-style-image: url(chrome://browser/skin/fxa/logo.png);
-  max-width: 64px;
+  width: 64px;
+  height: 64px;
   margin-inline-end: 14px;
 }
 
 .fxaMobilePromo {
   margin-bottom: 20px;
   margin-top: 25px;
 }
 
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -196,21 +196,17 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
     else
         DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
     fi
 fi
 
 # bionic in Android < 4.1 doesn't support PIE
 # On OSX, the linker defaults to building PIE programs when targeting OSX 10.7.
 # On other Unix systems, some file managers (Nautilus) can't start PIE programs
-if test -n "$gonkdir" && test "$ANDROID_VERSION" -ge 16; then
-    MOZ_PIE=1
-else
-    MOZ_PIE=
-fi
+MOZ_PIE=
 
 MOZ_ARG_ENABLE_BOOL(pie,
 [  --enable-pie           Enable Position Independent Executables],
     MOZ_PIE=1,
     MOZ_PIE= )
 
 if test "$GNU_CC$CLANG_CC" -a -n "$MOZ_PIE"; then
     AC_MSG_CHECKING([for PIE support])
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -274,19 +274,17 @@ def mozconfig_options(mozconfig, automat
 
         for key, value in mozconfig['env']['added'].iteritems():
             add(key, value)
             os.environ[key] = value
         for key, (_, value) in mozconfig['env']['modified'].iteritems():
             add(key, value)
             os.environ[key] = value
         for key, value in mozconfig['vars']['added'].iteritems():
-            # mozconfig_loader adds _IS_SET variables that are irrelevant
-            if not key.endswith('_IS_SET'):
-                add(key, value)
+            add(key, value)
         for key, (_, value) in mozconfig['vars']['modified'].iteritems():
             add(key, value)
 
 
 # Mozilla-Build
 # ==============================================================
 option(env='MOZILLABUILD', nargs=1,
        help='Path to Mozilla Build (Windows-only)')
@@ -904,18 +902,8 @@ def js_option(*args, **kwargs):
     opt = option(*args, **kwargs)
 
     @depends(opt.option, build_project)
     def js_option(value, build_project):
         if build_project != 'js':
             return value.format(opt.option)
 
     add_old_configure_arg(js_option)
-
-
-# Bug 1278542: This function is a workaround to resolve
-# |android_ndk_include|'s dependency on 'gonkdir.' The
-# actual implementation is located in b2g/moz.configure.
-# Remove this function as soon as 'android_ndk_include'
-# depends on 'target.'
-@depends('--help')
-def gonkdir(_):
-    return None
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -60,19 +60,19 @@ def have_yasm(value):
 
 set_config('HAVE_YASM', have_yasm)
 # Until the YASM variable is not necessary in old-configure.
 add_old_configure_assignment('YASM', have_yasm)
 
 # Android NDK
 # ==============================================================
 
-@depends('--disable-compile-environment', build_project, gonkdir, '--help')
-def compiling_android(compile_env, build_project, gonkdir, _):
-    return compile_env and (gonkdir or build_project in ('mobile/android', 'js'))
+@depends('--disable-compile-environment', build_project, '--help')
+def compiling_android(compile_env, build_project, _):
+    return compile_env and build_project in ('mobile/android', 'js')
 
 include('android-ndk.configure', when=compiling_android)
 
 # MacOS deployment target version
 # ==============================================================
 # This needs to happen before any compilation test is done.
 
 option('--enable-macos-target', env='MACOSX_DEPLOYMENT_TARGET', nargs=1,
--- a/build/mozconfig.cache
+++ b/build/mozconfig.cache
@@ -9,17 +9,17 @@ if test -z "$bucket" -a -z "$NO_CACHE"; 
 
 # buildbot (or builders that use buildprops.json):
 if [ -f $topsrcdir/../buildprops.json ]; then
 read branch platform master <<EOF
 $(python2.7 -c 'import json; p = json.loads(open("'"$topsrcdir"'/../buildprops.json").read())["properties"]; print p["branch"], p["platform"], p["master"]' 2> /dev/null)
 EOF
 
 bucket=
-if test -z "$SCCACHE_DISABLE" -a -z "$no_sccache" -a -z "$MOZ_PGO_IS_SET" -a -z "$MOZ_PGO"; then
+if test -z "$SCCACHE_DISABLE"; then
     case "${branch}" in
     try)
         case "${master}" in
         *scl1.mozilla.com*|*.scl3.mozilla.com*)
             bucket=mozilla-releng-s3-cache-us-west-1-try
             ;;
         *use1.mozilla.com*)
             bucket=mozilla-releng-s3-cache-us-east-1-try
@@ -39,17 +39,17 @@ if test -z "$SCCACHE_DISABLE" -a -z "$no
             ;;
         esac
         ;;
     esac
 fi
 fi
 
 # builds where buildprops didn't have the data (eg: taskcluster or non-buildbot) and without sccache disabled:
-if test -z "$bucket" -a -z "$SCCACHE_DISABLE" -a -z "$no_sccache" -a -z "$MOZ_PGO_IS_SET" -a -z "$MOZ_PGO"; then
+if test -z "$bucket" -a -z "$SCCACHE_DISABLE"; then
 
     # prevent rerun if az is set, or wget is not available
     if test -z "$availability_zone" -a -x "$(command -v wget)"; then
         if test -n "${TASKCLUSTER_WORKER_GROUP}"; then
             # TASKCLUSTER_WORKER_GROUP is just the region now, so
             # stick an extra character on to make the already-convoluted logic
             # here simpler.
             availability_zone="${TASKCLUSTER_WORKER_GROUP}x"
@@ -103,26 +103,26 @@ if test -z "$platform"; then
         ;;
     esac
 fi
 
 if test -z "$bucket"; then
     case "$platform" in
     win*) : ;;
     *)
-        ac_add_options --with-ccache
+        export CCACHE=ccache
     esac
 else
     mk_add_options "export SCCACHE_BUCKET=$bucket"
     case "$master" in
     *us[ew][12].mozilla.com*|*euc1.mozilla.com*)
         mk_add_options "export SCCACHE_NAMESERVER=169.254.169.253"
         ;;
     esac
-    ac_add_options "--with-ccache=$topsrcdir/sccache2/sccache${suffix}"
+    export CCACHE="$topsrcdir/sccache2/sccache${suffix}"
     export SCCACHE_VERBOSE_STATS=1
     mk_add_options MOZ_PREFLIGHT_ALL+=build/sccache.mk
     mk_add_options MOZ_POSTFLIGHT_ALL+=build/sccache.mk
     mk_add_options "UPLOAD_EXTRA_FILES+=sccache.log.gz"
     case "$platform" in
     win*)
         # sccache supports a special flag to create depfiles.
         #TODO: bug 1318370 - move this all into toolchain.configure
--- a/build/mozconfig.common
+++ b/build/mozconfig.common
@@ -18,8 +18,9 @@ ac_add_options --enable-crashreporter
 MOZ_ADDON_SIGNING=${MOZ_ADDON_SIGNING-1}
 # Disable enforcing that add-ons are signed by the trusted root
 MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0}
 
 ac_add_options --enable-js-shell
 
 . "$topsrcdir/build/mozconfig.automation"
 . "$topsrcdir/build/mozconfig.rust"
+. "$topsrcdir/build/mozconfig.cache"
--- a/build/mozconfig.no-compile
+++ b/build/mozconfig.no-compile
@@ -1,10 +1,15 @@
 ac_add_options --disable-compile-environment
 
+# In case mozconfig.cache was already included
+unset CCACHE
+# In case it wasn't
+NO_CACHE=1
+
 # Override any toolchain defines we've inherited from other mozconfigs.
 unset CC
 unset CXX
 unset HOST_CC
 unset HOST_CXX
 unset RUSTC
 unset CARGO
 unset MAKECAB
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -501,16 +501,20 @@ int do_relocation_section(Elf *elf, unsi
     if (dyn == nullptr) {
         fprintf(stderr, "Couldn't find SHT_DYNAMIC section\n");
         return -1;
     }
 
     ElfSegment *relro = elf->getSegmentByType(PT_GNU_RELRO);
 
     ElfRel_Section<Rel_Type> *section = (ElfRel_Section<Rel_Type> *)dyn->getSectionForType(Rel_Type::d_tag);
+    if (section == nullptr) {
+        fprintf(stderr, "No relocations\n");
+        return -1;
+    }
     assert(section->getType() == Rel_Type::sh_type);
 
     Elf32_Shdr relhack32_section =
         { 0, SHT_PROGBITS, SHF_ALLOC, 0, (Elf32_Off)-1, 0, SHN_UNDEF, 0,
           Elf_RelHack::size(elf->getClass()), Elf_RelHack::size(elf->getClass()) }; // TODO: sh_addralign should be an alignment, not size
     Elf32_Shdr relhackcode32_section =
         { 0, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0, (Elf32_Off)-1, 0,
           SHN_UNDEF, 0, 1, 0 };
--- a/devtools/client/netmonitor/index.js
+++ b/devtools/client/netmonitor/index.js
@@ -10,22 +10,19 @@
  * See README.md for more information.
  */
 const React = require("react");
 const ReactDOM = require("react-dom");
 const { bindActionCreators } = require("redux");
 const { bootstrap, renderRoot } = require("devtools-launchpad");
 const EventEmitter = require("devtools-modules/src/utils/event-emitter");
 const { Services: { appinfo, pref }} = require("devtools-modules");
-const { configureStore } = require("./src/utils/create-store");
 
-require("./src/assets/styles/netmonitor.css");
-
-EventEmitter.decorate(window);
-
+// Initialize preferences as early as possible
+pref("devtools.cache.disabled", false);
 pref("devtools.netmonitor.enabled", true);
 pref("devtools.netmonitor.filters", "[\"all\"]");
 pref("devtools.netmonitor.visibleColumns",
      "[\"status\",\"method\",\"file\",\"domain\",\"cause\"," +
      "\"type\",\"transferred\",\"contentSize\",\"waterfall\"]"
 );
 pref("devtools.netmonitor.panes-network-details-width", 550);
 pref("devtools.netmonitor.panes-network-details-height", 450);
@@ -36,16 +33,21 @@ pref("devtools.netmonitor.har.jsonpCallb
 pref("devtools.netmonitor.har.includeResponseBodies", true);
 pref("devtools.netmonitor.har.compress", false);
 pref("devtools.netmonitor.har.forceExport", false);
 pref("devtools.netmonitor.har.pageLoadedTimeout", 1500);
 pref("devtools.netmonitor.har.enableAutoExportToFile", false);
 pref("devtools.webconsole.persistlog", false);
 pref("devtools.styleeditor.enabled", true);
 
+const { configureStore } = require("./src/utils/create-store");
+
+require("./src/assets/styles/netmonitor.css");
+
+EventEmitter.decorate(window);
 const App = require("./src/components/app");
 const store = configureStore();
 const actions = bindActionCreators(require("./src/actions"), store.dispatch);
 const { onConnect } = require("./src/connector");
 
 // Inject to global window for testing
 window.store = store;
 
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -583,17 +583,19 @@ skip-if = toolkit == 'android' #bug 6870
 [test_bug922681.html]
 [test_bug927196.html]
 [test_bug962251.html]
 [test_bug976673.html]
 [test_bug982153.html]
 [test_bug999456.html]
 [test_bug1022229.html]
 [test_bug1025933.html]
+skip-if = stylo # bug 1293844
 [test_bug1037687.html]
+skip-if = stylo # bug 1293844
 [test_bug1043106.html]
 [test_bug1057176.html]
 [test_bug1060938.html]
 [test_bug1064481.html]
 [test_bug1070015.html]
 [test_bug1075702.html]
 [test_bug1081686.html]
 skip-if = toolkit == 'android'
--- a/dom/base/test/test_mutationobservers.html
+++ b/dom/base/test/test_mutationobservers.html
@@ -601,16 +601,22 @@ function testExpandos() {
     SpecialPowers.gc();
     SpecialPowers.gc();
     SpecialPowers.gc();
   }
   div.setAttribute("foo", "bar2");
 }
 
 function testOutsideShadowDOM() {
+  if (!div.createShadowRoot) {
+    todo(false, "Skipping testOutsideShadowDOM and testInsideShadowDOM " +
+         "because createShadowRoot is not supported");
+    then(testMarquee);
+    return;
+  }
   var m = new M(function(records, observer) {
     is(records.length, 1);
     is(records[0].type, "attributes", "Should have got attributes");
     observer.disconnect();
     then(testInsideShadowDOM);
   });
   m.observe(div, {
       attributes: true,
--- a/dom/credentialmanagement/Credential.cpp
+++ b/dom/credentialmanagement/Credential.cpp
@@ -41,10 +41,22 @@ Credential::GetId(nsAString& aId) const
 }
 
 void
 Credential::GetType(nsAString& aType) const
 {
   aType.Assign(mType);
 }
 
+void
+Credential::SetId(const nsAString& aId)
+{
+  mId.Assign(aId);
+}
+
+void
+Credential::SetType(const nsAString& aType)
+{
+  mType.Assign(aType);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/credentialmanagement/Credential.h
+++ b/dom/credentialmanagement/Credential.h
@@ -39,16 +39,22 @@ public:
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void
   GetId(nsAString& aId) const;
 
   void
   GetType(nsAString& aType) const;
 
+  void
+  SetId(const nsAString& aId);
+
+  void
+  SetType(const nsAString& aType);
+
 private:
   nsCOMPtr<nsPIDOMWindowInner> mParent;
   nsAutoString mId;
   nsAutoString mType;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/ContentEventHandler.h
+++ b/dom/events/ContentEventHandler.h
@@ -161,28 +161,40 @@ public:
       return IsValid() && mNode->IsElement() && !mOffset && !mAfterOpenTag;
     }
     bool IsImmediatelyAfterOpenTag() const
     {
       return IsValid() && mNode->IsElement() && !mOffset && mAfterOpenTag;
     }
     nsresult SetToRangeStart(nsRange* aRange) const
     {
-      nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mNode));
-      return aRange->SetStart(domNode, mOffset);
+      if (!IsValid()) {
+        return NS_ERROR_FAILURE;
+      }
+      ErrorResult errorResult;
+      aRange->SetStart(*mNode, mOffset, errorResult);
+      return errorResult.StealNSResult();
     }
     nsresult SetToRangeEnd(nsRange* aRange) const
     {
-      nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mNode));
-      return aRange->SetEnd(domNode, mOffset);
+      if (!IsValid()) {
+        return NS_ERROR_FAILURE;
+      }
+      ErrorResult errorResult;
+      aRange->SetEnd(*mNode, mOffset, errorResult);
+      return errorResult.StealNSResult();
     }
     nsresult SetToRangeEndAfter(nsRange* aRange) const
     {
-      nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mNode));
-      return aRange->SetEndAfter(domNode);
+      if (!IsValid()) {
+        return NS_ERROR_FAILURE;
+      }
+      ErrorResult errorResult;
+      aRange->SetEndAfter(*mNode, errorResult);
+      return errorResult.StealNSResult();
     }
   };
 
   // NodePositionBefore isn't good name if mNode isn't an element node nor
   // mOffset is not 0, though, when mNode is an element node and mOffset is 0,
   // this is treated as before the open tag of mNode.
   struct NodePositionBefore final : public NodePosition
   {
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -529,16 +529,17 @@ IMEStateManager::OnChangeFocusInternal(n
   // process actually gets focus because if user types keys before that they
   // are handled by IME.
   IMEState newState =
     newTabParent ? IMEState(IMEState::DISABLED) :
                    GetNewIMEState(aPresContext, aContent);
   bool setIMEState = true;
 
   if (newTabParent) {
+    MOZ_ASSERT(XRE_IsParentProcess());
     if (aAction.mFocusChange == InputContextAction::MENU_GOT_PSEUDO_FOCUS ||
         aAction.mFocusChange == InputContextAction::MENU_LOST_PSEUDO_FOCUS) {
       // XXX When menu keyboard listener is being uninstalled, IME state needs
       //     to be restored by the child process asynchronously.  Therefore,
       //     some key events which are fired immediately after closing menu
       //     may not be handled by IME.
       Unused << newTabParent->
         SendMenuKeyboardListenerInstalled(sInstalledMenuKeyboardListener);
@@ -554,17 +555,17 @@ IMEStateManager::OnChangeFocusInternal(n
            "and the IME state is already disabled by a remote process"));
       } else {
         MOZ_LOG(sISMLog, LogLevel::Debug,
           ("  OnChangeFocusInternal(), will disable IME "
            "until new focused element (or document) in the child process "
            "will get focus actually"));
       }
     } else if (newWidget->GetInputContext().mOrigin !=
-                 InputContext::ORIGIN_CONTENT) {
+                 InputContext::ORIGIN_MAIN) {
       // When focus is NOT changed actually, we shouldn't set IME state if
       // current input context was set by a remote process since that means
       // that the window is being activated and the child process may have
       // composition.  Then, we shouldn't commit the composition with making
       // IME state disabled.
       setIMEState = false;
       MOZ_LOG(sISMLog, LogLevel::Debug,
         ("  OnChangeFocusInternal(), doesn't set IME "
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -131,21 +131,24 @@ skip-if = (e10s && os == "mac") # bug 12
 [test_bug1003432.html]
 support-files = test_bug1003432.js
 [test_bug1013412.html]
 [test_bug1017086_disable.html]
 support-files = bug1017086_inner.html
 [test_bug1017086_enable.html]
 support-files = bug1017086_inner.html
 [test_bug1079236.html]
+skip-if = stylo # bug 1293844
 [test_bug1145910.html]
+skip-if = stylo # bug 1293844
 [test_bug1150308.html]
+skip-if = stylo # bug 1293844
 [test_bug1248459.html]
 [test_bug1264380.html]
-run-if = (e10s && os != "win") # Bug 1270043, crash at windows platforms; Bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode.
+run-if = (e10s && os != "win" && !stylo) # Bug 1270043, crash at windows platforms; Bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode. bug 1293844 for stylo.
 [test_bug1327798.html]
 subsuite = clipboard
 [test_clickevent_on_input.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_continuous_wheel_events.html]
 [test_dblclick_explicit_original_target.html]
 [test_dom_activate_event.html]
 [test_dom_keyboard_event.html]
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1129,41 +1129,16 @@ ContentParent::RecvConnectPluginBridge(c
   // pointer and just throw it away.
   uint32_t dummy = 0;
   if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) {
     return IPC_FAIL(this, "SetupBridge failed");
   }
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-ContentParent::RecvGetBlocklistState(const uint32_t& aPluginId,
-                                     uint32_t* aState)
-{
-  *aState = nsIBlocklistService::STATE_BLOCKED;
-
-  RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
-  if (!pluginHost) {
-    NS_WARNING("Plugin host not found");
-    return IPC_FAIL_NO_REASON(this);
-  }
-  nsPluginTag* tag =  pluginHost->PluginWithId(aPluginId);
-
-  if (!tag) {
-    // Default state is blocked anyway
-    NS_WARNING("Plugin tag not found. This should never happen, but to avoid a crash we're forcibly blocking it");
-    return IPC_OK();
-  }
-
-  if (NS_FAILED(tag->GetBlocklistState(aState))) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-  return IPC_OK();
-}
-
 /*static*/ TabParent*
 ContentParent::CreateBrowser(const TabContext& aContext,
                              Element* aFrameElement,
                              ContentParent* aOpenerContentParent,
                              TabParent* aSameTabGroupAs,
                              uint64_t aNextTabParentId)
 {
   AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -299,19 +299,16 @@ public:
                                                  Endpoint<PPluginModuleParent>* aEndpoint) override;
 
   virtual mozilla::ipc::IPCResult RecvMaybeReloadPlugins() override;
 
   virtual mozilla::ipc::IPCResult RecvConnectPluginBridge(const uint32_t& aPluginId,
                                                           nsresult* aRv,
                                                           Endpoint<PPluginModuleParent>* aEndpoint) override;
 
-  virtual mozilla::ipc::IPCResult RecvGetBlocklistState(const uint32_t& aPluginId,
-                                                        uint32_t* aIsBlocklisted) override;
-
   virtual mozilla::ipc::IPCResult RecvUngrabPointer(const uint32_t& aTime) override;
 
   virtual mozilla::ipc::IPCResult RecvRemovePermission(const IPC::Principal& aPrincipal,
                                                        const nsCString& aPermissionType,
                                                        nsresult* aRv) override;
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -636,21 +636,16 @@ parent:
      * This call is used by asynchronous plugin instantiation to notify the
      * content parent that it is now safe to initiate the plugin bridge for
      * the specified plugin id. The endpoint for the content process part of the
      * bridge is returned.
      */
     sync ConnectPluginBridge(uint32_t aPluginId)
         returns (nsresult rv, Endpoint<PPluginModuleParent> aEndpoint);
 
-    /**
-     * Return the current blocklist state for a particular plugin.
-     */
-    sync GetBlocklistState(uint32_t aPluginId) returns (uint32_t aState);
-
     async PJavaScript();
 
     async PRemoteSpellcheckEngine();
 
     async InitCrashReporter(Shmem shmem, NativeThreadId tid);
 
     /**
      * Is this token compatible with the provided version?
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -154,54 +154,50 @@ CanCreateWMFDecoder()
   static Maybe<bool> result;
   if (result.isNothing()) {
     result.emplace(CanCreateMFTDecoder(aGuid));
   }
   return result.value();
 }
 
 static bool
-IsH264DecoderBlacklisted()
+IsWin7H264Decoder4KCapable()
 {
-#ifdef BLACKLIST_CRASHY_H264_DECODERS
   WCHAR systemPath[MAX_PATH + 1];
   if (!ConstructSystem32Path(L"msmpeg2vdec.dll", systemPath, MAX_PATH + 1)) {
-    // Cannot build path -> Assume it's not the blacklisted DLL.
+    // Cannot build path -> Assume it's the old DLL or it's missing.
     return false;
   }
 
   DWORD zero;
   DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
   if (infoSize == 0) {
-    // Can't get file info -> Assume we don't have the blacklisted DLL.
+    // Can't get file info -> Assume it's the old DLL or it's missing.
     return false;
   }
   auto infoData = MakeUnique<unsigned char[]>(infoSize);
   VS_FIXEDFILEINFO *vInfo;
   UINT vInfoLen;
   if (GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) &&
     VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen))
   {
-    if ((vInfo->dwFileVersionMS == ((12u << 16) | 0u))
-        && ((vInfo->dwFileVersionLS == ((9200u << 16) | 16426u))
-            || (vInfo->dwFileVersionLS == ((9200u << 16) | 17037u)))) {
-      // 12.0.9200.16426 & .17037 are blacklisted on Win64, see bug 1242343.
-      return true;
-    }
+    uint64_t version =
+      uint64_t(vInfo->dwFileVersionMS) << 32 | uint64_t(vInfo->dwFileVersionLS);
+    // 12.0.9200.16426 & later allow for >1920x1088 resolutions.
+    const uint64_t minimum =
+      (uint64_t(12) << 48) | (uint64_t(9200) << 16) | uint64_t(16426);
+    return version >= minimum;
   }
-#endif // BLACKLIST_CRASHY_H264_DECODERS
+  // Can't get file version -> Assume it's the old DLL.
   return false;
 }
 
 /* static */ bool
 WMFDecoderModule::HasH264()
 {
-  if (IsH264DecoderBlacklisted()) {
-    return false;
-  }
   return CanCreateWMFDecoder<CLSID_CMSH264DecoderMFT>();
 }
 
 /* static */ bool
 WMFDecoderModule::HasAAC()
 {
   return CanCreateWMFDecoder<CLSID_CMSAACDecMFT>();
 }
@@ -229,24 +225,25 @@ WMFDecoderModule::Supports(const TrackIn
   }
   if (MP4Decoder::IsH264(aTrackInfo.mMimeType)
       && WMFDecoderModule::HasH264()) {
     if (!MediaPrefs::PDMWMFAllowUnsupportedResolutions()) {
       const VideoInfo* videoInfo = aTrackInfo.GetAsVideoInfo();
       MOZ_ASSERT(videoInfo);
       // Check Windows format constraints, based on:
       // https://msdn.microsoft.com/en-us/library/windows/desktop/dd797815(v=vs.85).aspx
-      if (IsWin8OrLater()) {
-        // Windows >7 supports at most 4096x2304.
+      if (IsWin8OrLater() || IsWin7H264Decoder4KCapable()) {
+        // Windows >7, and Win7 with recent-enough decoder, support at most
+        // 4096x2304.
         if (videoInfo->mImage.width > 4096
             || videoInfo->mImage.height > 2304) {
           return false;
         }
       } else {
-        // Windows <=7 supports at most 1920x1088.
+        // Windows <=7 (with original decoder) supports at most 1920x1088.
         if (videoInfo->mImage.width > 1920
             || videoInfo->mImage.height > 1088) {
           return false;
         }
       }
     }
     return true;
   }
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -407,17 +407,17 @@ var interfaceNamesInGlobalScope =
     "HTMLBRElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLButtonElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLCanvasElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLCollection",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "HTMLContentElement",
+    {name: "HTMLContentElement", stylo: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLDataElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLDataListElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLDetailsElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "HTMLDialogElement", disabled: true},
@@ -505,17 +505,17 @@ var interfaceNamesInGlobalScope =
     "HTMLProgressElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLQuoteElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLScriptElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLSelectElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "HTMLShadowElement",
+    {name: "HTMLShadowElement", stylo: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLSourceElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLSpanElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLStyleElement",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "HTMLTableCaptionElement",
@@ -835,17 +835,17 @@ var interfaceNamesInGlobalScope =
     "ServiceWorkerContainer",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ServiceWorkerRegistration",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ScopedCredential", disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "ScopedCredentialInfo", disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "ShadowRoot", // Bogus, but the test harness forces it on.  See bug 1159768.
+    {name: "ShadowRoot", stylo: false}, // Bogus, but the test harness forces it on.  See bug 1159768.
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "SharedWorker",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SimpleGestureEvent", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SimpleTest", xbl: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "SourceBuffer",
@@ -1291,16 +1291,17 @@ function createInterfaceMap(isXBLScope) 
   var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
   var isNightly = version.endsWith("a1");
   var isRelease = !version.includes("a");
   var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
   var isMac = /Mac OS/.test(navigator.oscpu);
   var isWindows = /Windows/.test(navigator.oscpu);
   var isAndroid = navigator.userAgent.includes("Android");
   var isLinux = /Linux/.test(navigator.oscpu) && !isAndroid;
+  var isStylo = SpecialPowers.DOMWindowUtils.isStyledByServo;
   var isSecureContext = window.isSecureContext;
 
   var interfaceMap = {};
 
   function addInterfaces(interfaces)
   {
     for (var entry of interfaces) {
       if (typeof(entry) === "string") {
@@ -1311,16 +1312,17 @@ function createInterfaceMap(isXBLScope) 
             (entry.nightlyAndroid === !(isAndroid && isNightly) && isAndroid) ||
             (entry.xbl === !isXBLScope) ||
             (entry.desktop === !isDesktop) ||
             (entry.windows === !isWindows) ||
             (entry.releaseNonWindows === !isRelease && !isWindows) ||
             (entry.mac === !isMac) ||
             (entry.linux === !isLinux) ||
             (entry.android === !isAndroid && !entry.nightlyAndroid) ||
+            (entry.stylo === !isStylo) ||
             (entry.release === !isRelease) ||
             (entry.isSecureContext === !isSecureContext) ||
             entry.disabled) {
           interfaceMap[entry.name] = false;
         } else {
           interfaceMap[entry.name] = true;
         }
       }
--- a/dom/tests/mochitest/webcomponents/mochitest.ini
+++ b/dom/tests/mochitest/webcomponents/mochitest.ini
@@ -1,55 +1,78 @@
 [DEFAULT]
 support-files =
   inert_style.css
   dummy_page.html
 
 [test_bug900724.html]
 [test_bug1017896.html]
 [test_bug1176757.html]
+skip-if = stylo # bug 1293844
 [test_bug1276240.html]
 [test_content_element.html]
+skip-if = stylo # bug 1293844
 [test_custom_element_adopt_callbacks.html]
 [test_custom_element_callback_innerhtml.html]
 [test_custom_element_clone_callbacks.html]
 [test_custom_element_clone_callbacks_extended.html]
 [test_custom_element_htmlconstructor.html]
 skip-if = os == 'android' # bug 1323645
 support-files =
   htmlconstructor_autonomous_tests.js
   htmlconstructor_builtin_tests.js
 [test_custom_element_import_node_created_callback.html]
 [test_custom_element_in_shadow.html]
+skip-if = stylo # bug 1293844
 [test_custom_element_register_invalid_callbacks.html]
 [test_custom_element_get.html]
 [test_custom_element_when_defined.html]
 [test_nested_content_element.html]
+skip-if = stylo # bug 1293844
 [test_dest_insertion_points.html]
+skip-if = stylo # bug 1293844
 [test_dest_insertion_points_shadow.html]
+skip-if = stylo # bug 1293844
 [test_fallback_dest_insertion_points.html]
+skip-if = stylo # bug 1293844
 [test_detached_style.html]
+skip-if = stylo # bug 1293844
 [test_dynamic_content_element_matching.html]
+skip-if = stylo # bug 1293844
 [test_document_adoptnode.html]
+skip-if = stylo # bug 1293844
 [test_document_importnode.html]
+skip-if = stylo # bug 1293844
 [test_document_register.html]
 [test_document_register_base_queue.html]
 [test_document_register_lifecycle.html]
 [test_document_register_parser.html]
 [test_document_register_stack.html]
 [test_document_shared_registry.html]
 [test_event_dispatch.html]
+skip-if = stylo # bug 1293844
 [test_event_retarget.html]
+skip-if = stylo # bug 1293844
 [test_event_stopping.html]
+skip-if = stylo # bug 1293844
 [test_template.html]
 [test_template_xhtml.html]
 [test_template_custom_elements.html]
 [test_shadowroot.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_inert_element.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_host.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_style.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_style_multiple_shadow.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_style_order.html]
+skip-if = stylo # bug 1293844
 [test_shadowroot_youngershadowroot.html]
+skip-if = stylo # bug 1293844
 [test_style_fallback_content.html]
+skip-if = stylo # bug 1293844
 [test_unresolved_pseudo_class.html]
 [test_link_prefetch.html]
-[test_bug1269155.html]
\ No newline at end of file
+[test_bug1269155.html]
+skip-if = stylo # bug 1293844
--- a/dom/webauthn/WebAuthnManager.cpp
+++ b/dom/webauthn/WebAuthnManager.cpp
@@ -690,16 +690,23 @@ WebAuthnManager::FinishMakeCredential(ns
   nsresult rv = U2FDecomposeRegistrationResponse(regData, pubKeyBuf, keyHandleBuf,
                                                  attestationCertBuf, signatureBuf);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     Cancel(rv);
     return;
   }
   MOZ_ASSERT(keyHandleBuf.Length() <= 0xFFFF);
 
+  nsAutoString keyHandleBase64Url;
+  rv = keyHandleBuf.ToJwkBase64(keyHandleBase64Url);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    Cancel(rv);
+    return;
+  }
+
   CryptoBuffer clientDataBuf;
   if (!clientDataBuf.Assign(mClientData.ref())) {
     Cancel(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   CryptoBuffer rpIdHashBuf;
   if (!rpIdHashBuf.Assign(mInfo.ref().RpIdHash())) {
@@ -770,16 +777,18 @@ WebAuthnManager::FinishMakeCredential(ns
   // values returned from the authenticator as well as the clientDataJSON
   // computed earlier.
   RefPtr<AuthenticatorAttestationResponse> attestation =
       new AuthenticatorAttestationResponse(mCurrentParent);
   attestation->SetClientDataJSON(clientDataBuf);
   attestation->SetAttestationObject(attObj);
 
   RefPtr<PublicKeyCredential> credential = new PublicKeyCredential(mCurrentParent);
+  credential->SetId(keyHandleBase64Url);
+  credential->SetType(NS_LITERAL_STRING("public-key"));
   credential->SetRawId(keyHandleBuf);
   credential->SetResponse(attestation);
 
   mTransactionPromise->MaybeResolve(credential);
   MaybeClearTransaction();
 }
 
 void
@@ -812,16 +821,23 @@ WebAuthnManager::FinishGetAssertion(nsTA
                                              signatureData);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     Cancel(rv);
     return;
   }
 
   CryptoBuffer credentialBuf;
   if (!credentialBuf.Assign(aCredentialId)) {
+    Cancel(NS_ERROR_OUT_OF_MEMORY);
+    return;
+  }
+
+  nsAutoString credentialBase64Url;
+  rv = credentialBuf.ToJwkBase64(credentialBase64Url);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
     Cancel(rv);
     return;
   }
 
   // If any authenticator returns success:
 
   // Create a new PublicKeyCredential object named value and populate its fields
   // with the values returned from the authenticator as well as the
@@ -829,16 +845,18 @@ WebAuthnManager::FinishGetAssertion(nsTA
   RefPtr<AuthenticatorAssertionResponse> assertion =
     new AuthenticatorAssertionResponse(mCurrentParent);
   assertion->SetClientDataJSON(clientDataBuf);
   assertion->SetAuthenticatorData(authenticatorDataBuf);
   assertion->SetSignature(signatureData);
 
   RefPtr<PublicKeyCredential> credential =
     new PublicKeyCredential(mCurrentParent);
+  credential->SetId(credentialBase64Url);
+  credential->SetType(NS_LITERAL_STRING("public-key"));
   credential->SetRawId(credentialBuf);
   credential->SetResponse(assertion);
 
   mTransactionPromise->MaybeResolve(credential);
   MaybeClearTransaction();
 }
 
 void
--- a/dom/webauthn/tests/test_webauthn_loopback.html
+++ b/dom/webauthn/tests/test_webauthn_loopback.html
@@ -38,23 +38,28 @@ function() {
   let gAssertionChallenge = new Uint8Array(16);
   window.crypto.getRandomValues(gAssertionChallenge);
 
   testMakeCredential();
 
   function decodeCreatedCredential(aCredInfo) {
     /* PublicKeyCredential : Credential
        - rawId: Key Handle buffer pulled from U2F Register() Response
+       - id: Key Handle buffer in base64url form, should == rawId
+       - type: Literal 'public-key'
        - response : AuthenticatorAttestationResponse : AuthenticatorResponse
          - attestationObject: CBOR object
          - clientDataJSON: serialized JSON
        - clientExtensionResults: (not yet supported)
     */
 
+    is(aCredInfo.type, "public-key", "Credential type must be public-key")
+
     ok(aCredInfo.rawId.length > 0, "Key ID exists");
+    is(aCredInfo.id, bytesToBase64UrlSafe(aCredInfo.rawId), "Encoded Key ID and Raw Key ID match");
 
     let clientData = JSON.parse(buffer2string(aCredInfo.response.clientDataJSON));
     is(clientData.challenge, bytesToBase64UrlSafe(gCredentialChallenge), "Challenge is correct");
     is(clientData.origin, window.location.origin, "Origin is correct");
     is(clientData.hashAlg, "S256", "Hash algorithm is correct");
 
     return webAuthnDecodeAttestation(aCredInfo.response.attestationObject.buffer)
     .then(function(decodedResult) {
@@ -63,23 +68,28 @@ function() {
       aCredInfo.attestationObject = decodedResult.attestationObject;
       return aCredInfo;
     });
   }
 
   function checkAssertionAndSigValid(aPublicKey, aAssertion) {
     /* PublicKeyCredential : Credential
        - rawId: ID of Credential from AllowList that succeeded
+       - id: Key Handle buffer in base64url form, should == rawId
+       - type: Literal 'public-key'
        - response : AuthenticatorAssertionResponse : AuthenticatorResponse
          - clientDataJSON: serialized JSON
          - authenticatorData: RP ID Hash || U2F Sign() Response
          - signature: U2F Sign() Response
     */
 
+    is(aAssertion.type, "public-key", "Credential type must be public-key")
+
     ok(aAssertion.rawId.length > 0, "Key ID exists");
+    is(aAssertion.id, bytesToBase64UrlSafe(aAssertion.rawId), "Encoded Key ID and Raw Key ID match");
 
     ok(aAssertion.response.authenticatorData.length > 0, "Authenticator data exists");
     let clientData = JSON.parse(buffer2string(aAssertion.response.clientDataJSON));
     is(clientData.challenge, bytesToBase64UrlSafe(gAssertionChallenge), "Challenge is correct");
     is(clientData.origin, window.location.origin, "Origin is correct");
     is(clientData.hashAlg, "S256", "Hash algorithm is correct");
 
     // Parse the signature data
--- a/dom/webidl/WebAuthentication.webidl
+++ b/dom/webidl/WebAuthentication.webidl
@@ -6,30 +6,30 @@
  * The origin of this IDL file is
  * https://www.w3.org/TR/webauthn/
  */
 
 /***** Interfaces to Data *****/
 
 [SecureContext, Pref="security.webauth.webauthn"]
 interface PublicKeyCredential : Credential {
-    readonly attribute ArrayBuffer           rawId;
-    readonly attribute AuthenticatorResponse response;
+    [SameObject] readonly attribute ArrayBuffer           rawId;
+    [SameObject] readonly attribute AuthenticatorResponse response;
     // Extensions are not supported yet.
-    // readonly attribute AuthenticationExtensions clientExtensionResults;
+    // [SameObject] readonly attribute AuthenticationExtensions clientExtensionResults;
 };
 
 [SecureContext, Pref="security.webauth.webauthn"]
 interface AuthenticatorResponse {
-    readonly attribute ArrayBuffer clientDataJSON;
+    [SameObject] readonly attribute ArrayBuffer clientDataJSON;
 };
 
 [SecureContext, Pref="security.webauth.webauthn"]
 interface AuthenticatorAttestationResponse : AuthenticatorResponse {
-    readonly attribute ArrayBuffer attestationObject;
+    [SameObject] readonly attribute ArrayBuffer attestationObject;
 };
 
 dictionary PublicKeyCredentialParameters {
     required PublicKeyCredentialType  type;
     required WebAuthnAlgorithmID algorithm; // NOTE: changed from AllgorithmIdentifier because typedef (object or DOMString) not serializable
 };
 
 dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
@@ -94,18 +94,18 @@ dictionary PublicKeyCredentialDescriptor
     required BufferSource id;
     sequence<WebAuthnTransport>   transports;
 };
 
 typedef (boolean or DOMString) WebAuthnAlgorithmID; // Fix when upstream there's a definition of how to serialize AlgorithmIdentifier
 
 [SecureContext, Pref="security.webauth.webauthn"]
 interface AuthenticatorAssertionResponse : AuthenticatorResponse {
-    readonly attribute ArrayBuffer      authenticatorData;
-    readonly attribute ArrayBuffer      signature;
+    [SameObject] readonly attribute ArrayBuffer      authenticatorData;
+    [SameObject] readonly attribute ArrayBuffer      signature;
 };
 
 // Renamed from "Transport" to avoid a collision with U2F
 enum WebAuthnTransport {
     "usb",
     "nfc",
     "ble"
 };
--- a/gfx/config/gfxVars.h
+++ b/gfx/config/gfxVars.h
@@ -34,16 +34,17 @@ class gfxVarReceiver;
   _(PDMWMFDisableD3D11Dlls,     nsCString,        nsCString())          \
   _(PDMWMFDisableD3D9Dlls,      nsCString,        nsCString())          \
   _(DXInterop2Blocked,          bool,             false)                \
   _(UseWebRender,               bool,             false)                \
   _(UseWebRenderANGLE,          bool,             false)                \
   _(ScreenDepth,                int32_t,          0)                    \
   _(GREDirectory,               nsCString,        nsCString())          \
   _(UseOMTP,                    bool,             false)                \
+  _(AllowD3D11KeyedMutex,       bool,             false)                \
 
   /* Add new entries above this line. */
 
 // Some graphics settings are computed on the UI process and must be
 // communicated to content and GPU processes. gfxVars helps facilitate
 // this. Its function is similar to gfxPrefs, except rather than hold
 // user preferences, it holds dynamically computed values.
 //
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -10,16 +10,17 @@
 #include "gfxPrefs.h"
 #include "gfxWindowsPlatform.h"
 #include "mozilla/D3DMessageUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/gfx/GraphicsMessages.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/DeviceAttachmentsD3D11.h"
 #include "mozilla/layers/MLGDeviceD3D11.h"
 #include "mozilla/layers/PaintThread.h"
 #include "nsIGfxInfo.h"
 #include "nsString.h"
 #include <d3d11.h>
@@ -950,22 +951,18 @@ DeviceManagerDx::TextureSharingWorks()
   }
   return mDeviceStatus->textureSharingWorks();
 }
 
 bool
 DeviceManagerDx::CanInitializeKeyedMutexTextures()
 {
   MutexAutoLock lock(mDeviceLock);
-  if (!mDeviceStatus) {
-    return false;
-  }
-  // Disable this on all Intel devices because of crashes.
-  // See bug 1292923.
-  return (mDeviceStatus->adapter().VendorId != 0x8086 || gfxPrefs::Direct3D11AllowIntelMutex());
+  return mDeviceStatus && gfxPrefs::Direct3D11AllowKeyedMutex() &&
+         gfxVars::AllowD3D11KeyedMutex();
 }
 
 bool
 DeviceManagerDx::HasCrashyInitData()
 {
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2280,27 +2280,38 @@ gfxPlatform::InitAcceleration()
   // If this is called for the first time on a non-main thread, we're screwed.
   // At the moment there's no explicit guarantee that the main thread calls
   // this before the compositor thread, but let's at least make the assumption
   // explicit.
   MOZ_ASSERT(NS_IsMainThread(), "can only initialize prefs on the main thread");
 
   gfxPrefs::GetSingleton();
 
+  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+  nsCString discardFailureId;
+  int32_t status;
+
   if (XRE_IsParentProcess()) {
     gfxVars::SetBrowserTabsRemoteAutostart(BrowserTabsRemoteAutostart());
     gfxVars::SetOffscreenFormat(GetOffscreenFormat());
     gfxVars::SetRequiresAcceleratedGLContextForCompositorOGL(
               RequiresAcceleratedGLContextForCompositorOGL());
+#ifdef XP_WIN
+    if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX,
+                                               discardFailureId, &status))) {
+      gfxVars::SetAllowD3D11KeyedMutex(status == nsIGfxInfo::FEATURE_STATUS_OK);
+    } else {
+      // If we couldn't properly evaluate the status, err on the side
+      // of caution and give this functionality to the user.
+      gfxCriticalNote << "Cannot evaluate keyed mutex feature status";
+      gfxVars::SetAllowD3D11KeyedMutex(true);
+    }
+#endif
   }
 
-  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-  nsCString discardFailureId;
-  int32_t status;
-
   if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
 #ifdef XP_WIN
     Preferences::GetBool("media.windows-media-foundation.use-dxva", true) &&
 #endif
       NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING,
                                                discardFailureId, &status))) {
       if (status == nsIGfxInfo::FEATURE_STATUS_OK || gfxPrefs::HardwareVideoDecodingForceEnabled()) {
         sLayersSupportsHardwareVideoDecoding = true;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -432,17 +432,17 @@ private:
   DECL_GFX_PREF(Once, "gfx.content.skia-font-cache-size",      SkiaContentFontCacheSize, int32_t, 10);
 
   DECL_GFX_PREF(Once, "gfx.device-reset.limit",                DeviceResetLimitCount, int32_t, 10);
   DECL_GFX_PREF(Once, "gfx.device-reset.threshold-ms",         DeviceResetThresholdMilliseconds, int32_t, -1);
 
   DECL_GFX_PREF(Once, "gfx.direct2d.disabled",                 Direct2DDisabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled",            Direct2DForceEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.direct3d11.reuse-decoder-device",   Direct3D11ReuseDecoderDevice, int32_t, -1);
-  DECL_GFX_PREF(Live, "gfx.direct3d11.allow-intel-mutex",      Direct3D11AllowIntelMutex, bool, true);
+  DECL_GFX_PREF(Live, "gfx.direct3d11.allow-keyed-mutex",      Direct3D11AllowKeyedMutex, bool, true);
   DECL_GFX_PREF(Live, "gfx.direct3d11.use-double-buffering",   Direct3D11UseDoubleBuffering, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct3d11.enable-debug-layer",     Direct3D11EnableDebugLayer, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct3d11.break-on-error",         Direct3D11BreakOnError, bool, false);
   DECL_GFX_PREF(Live, "gfx.downloadable_fonts.keep_variation_tables", KeepVariationTables, bool, false);
   DECL_GFX_PREF(Live, "gfx.downloadable_fonts.otl_validation", ValidateOTLTables, bool, true);
   DECL_GFX_PREF(Live, "gfx.draw-color-bars",                   CompositorDrawColorBars, bool, false);
   DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll",      HidePluginsForScroll, bool, true);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -384,17 +384,17 @@ void MessageLoop::PostTask_Helper(alread
   }
 
   // Tasks should only be queued before or during the Run loop, not after.
   MOZ_ASSERT(!shutting_down_);
 
 #ifdef MOZ_TASK_TRACER
   nsCOMPtr<nsIRunnable> tracedTask = task;
   if (mozilla::tasktracer::IsStartLogging()) {
-    tracedTask = mozilla::tasktracer::CreateTracedRunnable(Move(task));
+    tracedTask = mozilla::tasktracer::CreateTracedRunnable(tracedTask.forget());
     (static_cast<mozilla::tasktracer::TracedRunnable*>(tracedTask.get()))->DispatchTask();
   }
   PendingTask pending_task(tracedTask.forget(), true);
 #else
   PendingTask pending_task(Move(task), true);
 #endif
 
   if (delay_ms > 0) {
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -530,16 +530,18 @@ GeckoChildProcessHost::SetChildLogName(c
   // for the time we launch the sub-process.  It's copied to the new
   // environment.
   PR_SetEnv(buffer.BeginReading());
 }
 
 bool
 GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
 {
+  AutoSetProfilerEnvVarsForChildProcess profilerEnvironment;
+
   // If NSPR log files are not requested, we're done.
   const char* origNSPRLogName = PR_GetEnv("NSPR_LOG_FILE");
   const char* origMozLogName = PR_GetEnv("MOZ_LOG_FILE");
   if (!origNSPRLogName && !origMozLogName) {
     return PerformAsyncLaunchInternal(aExtraOpts, arch);
   }
 
   // - Note: this code is not called re-entrantly, nor are restoreOrig*LogName
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -132,17 +132,19 @@ description =
 [PTestLatency::Rpc]
 description =
 [PTestLatency::Synchro]
 description =
 [PTestLatency::Synchro2]
 description =
 [PTestNestedLoops::R]
 description =
-[PTestPriority::Msg2]
+[PTestPriority::PMsg2]
+description =
+[PTestPriority::PMsg4]
 description =
 [PTestRPC::Test1_Start]
 description =
 [PTestRPC::Test1_InnerEvent]
 description =
 [PTestRPC::Test2_OutOfOrder]
 description =
 [PTestRPC::Test1_InnerQuery]
@@ -851,18 +853,16 @@ description =
 [PContent::CreateChildProcess]
 description =
 [PContent::BridgeToChildProcess]
 description =
 [PContent::LoadPlugin]
 description =
 [PContent::ConnectPluginBridge]
 description =
-[PContent::GetBlocklistState]
-description =
 [PContent::NSSU2FTokenIsCompatibleVersion]
 description =
 [PContent::NSSU2FTokenIsRegistered]
 description =
 [PContent::NSSU2FTokenRegister]
 description =
 [PContent::NSSU2FTokenSign]
 description =
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1540,17 +1540,17 @@ BaselineCompiler::emit_JSOP_FUNCTIONTHIS
     if (!callVM(GetFunctionThisInfo))
         return false;
 
     masm.bind(&skipCall);
     frame.push(R0);
     return true;
 }
 
-typedef bool (*GetNonSyntacticGlobalThisFn)(JSContext*, HandleObject, MutableHandleValue);
+typedef void (*GetNonSyntacticGlobalThisFn)(JSContext*, HandleObject, MutableHandleValue);
 static const VMFunction GetNonSyntacticGlobalThisInfo =
     FunctionInfo<GetNonSyntacticGlobalThisFn>(js::GetNonSyntacticGlobalThis,
                                               "GetNonSyntacticGlobalThis");
 
 bool
 BaselineCompiler::emit_JSOP_GLOBALTHIS()
 {
     frame.syncStack(0);
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -67,20 +67,16 @@ MOZ_DEFAULT_COMPILER
 
 if test -z "$JS_STANDALONE"; then
   autoconfmk=autoconf-js.mk
 fi
 AC_SUBST(autoconfmk)
 
 MOZ_ANDROID_NDK
 
-if test -n "$gonkdir" ; then
-    LDFLAGS="-L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib --sysroot=$gonkdir/out/target/product/$GONK_PRODUCT/obj/ -llog $LDFLAGS"
-fi
-
 case "$target" in
 *-apple-darwin*)
     MOZ_IOS_SDK
     ;;
 esac
 
 dnl ========================================================
 dnl Checks for compilers.
@@ -465,26 +461,24 @@ if test "$GNU_CC"; then
     LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for -z text option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,-z,text"
-    AC_TRY_LINK(,,AC_MSG_RESULT([yes])
-                  [NSPR_LDFLAGS="$NSPR_LDFLAGS -Wl,-z,text"],
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for --build-id option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,--build-id"
-    AC_TRY_LINK(,,AC_MSG_RESULT([yes])
-                  [NSPR_LDFLAGS="$NSPR_LDFLAGS -Wl,--build-id"],
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     _DEFINES_CFLAGS='-include $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
 fi
 
 if test "$GNU_CXX"; then
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -3242,17 +3242,18 @@ js::GetThisValueForDebuggerMaybeOptimize
                 res.setMagic(JS_OPTIMIZED_OUT);
 
             return true;
         }
 
         MOZ_CRASH("'this' binding must be found");
     }
 
-    return GetNonSyntacticGlobalThis(cx, scopeChain, res);
+    GetNonSyntacticGlobalThis(cx, scopeChain, res);
+    return true;
 }
 
 bool
 js::CheckLexicalNameConflict(JSContext* cx, Handle<LexicalEnvironmentObject*> lexicalEnv,
                              HandleObject varObj, HandlePropertyName name)
 {
     const char* redeclKind = nullptr;
     RootedId id(cx, NameToId(name));
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -125,36 +125,34 @@ js::GetFunctionThis(JSContext* cx, Abstr
         res.set(frame.thisArgument());
         return true;
     }
 
     RootedValue thisv(cx, frame.thisArgument());
     return BoxNonStrictThis(cx, thisv, res);
 }
 
-bool
+void
 js::GetNonSyntacticGlobalThis(JSContext* cx, HandleObject envChain, MutableHandleValue res)
 {
     RootedObject env(cx, envChain);
     while (true) {
         if (IsExtensibleLexicalEnvironment(env)) {
             res.set(env->as<LexicalEnvironmentObject>().thisValue());
-            return true;
+            return;
         }
         if (!env->enclosingEnvironment()) {
             // This can only happen in Debugger eval frames: in that case we
             // don't always have a global lexical env, see EvaluateInEnv.
             MOZ_ASSERT(env->is<GlobalObject>());
             res.set(GetThisValue(env));
-            return true;
+            return;
         }
         env = env->enclosingEnvironment();
     }
-
-    return true;
 }
 
 bool
 js::Debug_CheckSelfHosted(JSContext* cx, HandleValue fun)
 {
 #ifndef DEBUG
     MOZ_CRASH("self-hosted checks should only be done in Debug builds");
 #endif
@@ -2721,18 +2719,17 @@ CASE(JSOP_FUNCTIONTHIS)
     if (!GetFunctionThis(cx, REGS.fp(), REGS.stackHandleAt(-1)))
         goto error;
 END_CASE(JSOP_FUNCTIONTHIS)
 
 CASE(JSOP_GLOBALTHIS)
 {
     if (script->hasNonSyntacticScope()) {
         PUSH_NULL();
-        if (!GetNonSyntacticGlobalThis(cx, REGS.fp()->environmentChain(), REGS.stackHandleAt(-1)))
-            goto error;
+        GetNonSyntacticGlobalThis(cx, REGS.fp()->environmentChain(), REGS.stackHandleAt(-1));
     } else {
         PUSH_COPY(cx->global()->lexicalEnvironment().thisValue());
     }
 }
 END_CASE(JSOP_GLOBALTHIS)
 
 CASE(JSOP_CHECKISOBJ)
 {
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -25,17 +25,17 @@ class EnvironmentIter;
  * compartment, and replace other primitives with boxed versions.
  */
 extern bool
 BoxNonStrictThis(JSContext* cx, HandleValue thisv, MutableHandleValue vp);
 
 extern bool
 GetFunctionThis(JSContext* cx, AbstractFramePtr frame, MutableHandleValue res);
 
-extern bool
+extern void
 GetNonSyntacticGlobalThis(JSContext* cx, HandleObject envChain, MutableHandleValue res);
 
 /*
  * numToSkip is the number of stack values the expression decompiler should skip
  * before it reaches |v|. If it's -1, the decompiler will search the stack.
  */
 extern bool
 ReportIsNotFunction(JSContext* cx, HandleValue v, int numToSkip,
--- a/layout/inspector/tests/test_bug522601.xhtml
+++ b/layout/inspector/tests/test_bug522601.xhtml
@@ -232,42 +232,44 @@ addLoadEvent(function() {
   testFunc(walkerAnon, "previousNode", $("s").nextSibling, "step back to more text (anon)");
   testFunc(walkerAnon, "previousNode", $("s").previousSibling,
            "step back to some text (anon)");
   testFunc(walkerAnon, "previousNode", anonDiv,
            "step back to anonymous div");
   testFunc(walkerAnon, "previousNode", $("display"), "step back to root (anon)");
   testFunc(walkerAnon, "previousNode", null, "step back past root (anon)");
 
-  var shadowdiv = document.querySelector('#test-shadow');
-  var shadowRoot = shadowdiv.createShadowRoot();
-  var h = document.createElement("header");
-  var c = document.createElement("content");
-  c.setAttribute("select", "h2");
-  h.appendChild(c);
-  shadowRoot.appendChild(h);
+  if (Element.prototype.createShadowRoot) {
+    var shadowdiv = document.querySelector('#test-shadow');
+    var shadowRoot = shadowdiv.createShadowRoot();
+    var h = document.createElement("header");
+    var c = document.createElement("content");
+    c.setAttribute("select", "h2");
+    h.appendChild(c);
+    shadowRoot.appendChild(h);
 
-  var walkerShadow =
-    SpecialPowers.Cc["@mozilla.org/inspector/deep-tree-walker;1"]
-                 .createInstance(SpecialPowers.Ci.inIDeepTreeWalker);
-  walkerShadow.showAnonymousContent = true;
-  walkerShadow.init($("test-shadow"), NodeFilter.SHOW_ALL);
-  var c1 = walkerShadow.nextNode();
-  var c2 = walkerShadow.nextNode();
-  var c3 = walkerShadow.nextNode();
+    var walkerShadow =
+        SpecialPowers.Cc["@mozilla.org/inspector/deep-tree-walker;1"]
+                     .createInstance(SpecialPowers.Ci.inIDeepTreeWalker);
+    walkerShadow.showAnonymousContent = true;
+    walkerShadow.init($("test-shadow"), NodeFilter.SHOW_ALL);
+    var c1 = walkerShadow.nextNode();
+    var c2 = walkerShadow.nextNode();
+    var c3 = walkerShadow.nextNode();
 
-  walkerShadow.currentNode = c1;
-  is(SpecialPowers.unwrap(walkerShadow.currentNode), h,
-     "Unexpected shadow element 1");
-  walkerShadow.currentNode = c2;
-  is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2"),
-     "Unexpected shadow element 2");
-  walkerShadow.currentNode = c3;
-  is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2").firstChild,
-     "Unexpected shadow element 3");
+    walkerShadow.currentNode = c1;
+    is(SpecialPowers.unwrap(walkerShadow.currentNode), h,
+       "Unexpected shadow element 1");
+    walkerShadow.currentNode = c2;
+    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2"),
+       "Unexpected shadow element 2");
+    walkerShadow.currentNode = c3;
+    is(SpecialPowers.unwrap(walkerShadow.currentNode), $("h2").firstChild,
+       "Unexpected shadow element 3");
+  }
 
   SimpleTest.finish();
 });
 
 ]]>
 </script>
 </pre>
 </body>
--- a/layout/reftests/border-image/reftest.list
+++ b/layout/reftests/border-image/reftest.list
@@ -25,17 +25,17 @@ fails-if(Android) fails-if(usesRepeatRes
 == center-scaling-4l.html center-scaling-4l-ref.html
 == center-scaling-4tb.html center-scaling-4tb-ref.html
 == center-scaling-4lr.html center-scaling-4lr-ref.html
 == side-scaling-1h.html side-scaling-1h-ref.html
 == side-scaling-1v.html side-scaling-1v-ref.html
 == border-image-width-1a.html border-image-width-1-ref.html
 == border-image-width-1b.html border-image-width-1-ref.html
 == border-image-width-1c.html border-image-width-1-ref.html
-skip-if(styloVsGecko) == border-image-width-large.html border-image-width-large-ref.html
+== border-image-width-large.html border-image-width-large-ref.html
 == border-image-outset-1a.html border-image-outset-1-ref.html
 == border-image-outset-1b.html border-image-outset-1-ref.html
 == border-image-outset-1c.html border-image-outset-1-ref.html
 == border-image-nofill-1.html border-image-nofill-1-ref.html
 == border-image-outset-resize-1.html border-image-outset-resize-1-ref.html
 fuzzy-if(asyncPan&&!layersGPUAccelerated,140,514) == border-image-outset-move-1.html border-image-outset-move-1-ref.html
 == border-image-style-none.html border-image-style-none-ref.html
 == border-image-style-none-length.html border-image-style-none-length-ref.html
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1812,18 +1812,18 @@ fuzzy-if(skiaContent,1,5) == 956513-1.sv
 fuzzy-if(skiaContent,1,80) == 961887-1.html 961887-1-ref.html
 == 961887-2.html 961887-2-ref.html
 == 961887-3.html 961887-3-ref.html
 pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,3712) == 966992-1.html 966992-1-ref.html
 skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
 skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
 fuzzy-if(skiaContent,1,123) == 978911-1.svg 978911-1-ref.svg
 == 983084-1.html 983084-1-ref.html
-skip-if(styloVsGecko) == 983084-2.html 983084-2-ref.html
-skip-if(styloVsGecko) == 983084-3.html 983084-1-ref.html
+== 983084-2.html 983084-2-ref.html
+== 983084-3.html 983084-1-ref.html
 == 983691-1.html 983691-ref.html
 HTTP(..) == 983985-1.html 983985-1-ref.html
 HTTP(..) == 983985-2.html 983985-2-ref.html
 == 985303-1a.html 985303-1-ref.html
 == 985303-1b.html 985303-1-ref.html
 == 987680-1.html 987680-1-ref.html
 # Fuzzy on WR due to alpha blending
 fuzzy-if(d2d,1,601) fuzzy-if(webrender,1,1473) == 991046-1.html 991046-1-ref.html
@@ -1861,17 +1861,17 @@ test-pref(dom.webcomponents.enabled,true
 == 1069716-1.html 1069716-1-ref.html
 fails-if(webrender) == 1078262-1.html about:blank
 test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html
 == 1081185-1.html 1081185-1-ref.html
 == 1097437-1.html 1097437-1-ref.html
 == 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test
 == 1105137-1.html 1105137-1-ref.html
 fuzzy-if(d2d,36,304) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&d2d,127,701) HTTP(..) == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow-ref.html
-skip-if(styloVsGecko) == 1111753-1.html about:blank
+== 1111753-1.html about:blank
 == 1114526-1.html 1114526-1-ref.html
 fuzzy-if(skiaContent,1,800000) == 1119117-1a.html 1119117-1-ref.html
 fuzzy-if(skiaContent,1,800000) == 1119117-1b.html 1119117-1-ref.html
 == 1120431-1.html 1120431-1-ref.html
 == 1120431-2.html 1120431-2-ref.html
 == 1121748-1.html 1121748-1-ref.html
 == 1121748-2.html 1121748-2-ref.html
 == 1127107-1a-nowrap.html 1127107-1-ref.html
--- a/layout/reftests/css-valuesandunits/reftest.list
+++ b/layout/reftests/css-valuesandunits/reftest.list
@@ -1,12 +1,12 @@
 == unit-rem-div-fontsize.html unit-rem-ref.html
 == unit-rem-div-width-inner.html unit-rem-ref.html
 == unit-rem-div-width-outer.html unit-rem-ref.html
-skip-if(styloVsGecko||stylo) == unit-rem-iframe.html unit-rem-ref-iframe.html
+== unit-rem-iframe.html unit-rem-ref-iframe.html
 == unit-rem-root-fontsize.html unit-rem-ref-root-fontsize.html
 == unit-rem-root-fontsize.html unit-rem-ref2-root-fontsize.html
 == unit-rem-root-width.html unit-rem-ref-root-width.html
 == unit-rem.svg unit-rem-ref.svg
 == unit-vh-vw.html unit-vh-vw-ref.html
 == unit-vh-vw-zoom.html unit-vh-vw-zoom-ref.html
 == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto-ref.html
 fails-if(styloVsGecko||stylo) == unit-vh-vw-overflow-scroll.html unit-vh-vw-overflow-scroll-ref.html
--- a/layout/reftests/font-face/reftest.list
+++ b/layout/reftests/font-face/reftest.list
@@ -63,50 +63,50 @@ HTTP(..) == cross-iframe-1.html cross-if
 # unicode-range
 HTTP(..) == unicoderange-1.html unicoderange-1-ref.html
 HTTP(..) == unicoderange-2.html unicoderange-2-ref.html
 HTTP(..) == unicoderange-3.html unicoderange-3-ref.html
 HTTP(..) == unicoderange-4.html unicoderange-4-ref.html
 
 # Dynamic changes
 # we need to skip these because of the bug that's causing order-2.html to fail
-skip-if(styloVsGecko) HTTP(..) == enable-sheet-1.html enable-sheet-1-ref.html
-skip skip-if(styloVsGecko) HTTP(..) == enable-sheet-2.html multiple-in-family-1-ref.html
+HTTP(..) == enable-sheet-1.html enable-sheet-1-ref.html
+skip HTTP(..) == enable-sheet-2.html multiple-in-family-1-ref.html
 skip HTTP(..) == enable-sheet-3.html multiple-in-family-1-ref.html
 HTTP(..) == enable-sheet-4.html enable-sheet-4-ref.html
-skip-if(styloVsGecko) HTTP(..) == enable-sheet-5.html enable-sheet-4-ref.html
+HTTP(..) == enable-sheet-5.html enable-sheet-4-ref.html
 skip HTTP(..) == enable-sheet-6.html multiple-in-family-1-ref.html
 skip HTTP(..) == enable-sheet-7.html multiple-in-family-1-ref.html
 HTTP(..) == disable-sheet-1.html disable-sheet-1-ref.html
 # We're missing disable-sheet-{2,3,6,7} (analogs to
 # enable-sheet{2,3,6,7}) because I don't know how to detect test
 # completion for those cases.
 HTTP(..) == disable-sheet-4.html disable-sheet-4-ref.html
-skip-if(styloVsGecko) HTTP(..) == disable-sheet-5.html disable-sheet-4-ref.html
+HTTP(..) == disable-sheet-5.html disable-sheet-4-ref.html
 HTTP(..) == sheet-set-base-1.html sheet-set-base-1-ref.html
 random-if(cocoaWidget) HTTP(..) == sheet-set-switch-1.html sheet-set-switch-1-ref.html # bug 468217
-skip-if(styloVsGecko) HTTP(..) == insert-rule-1a.html insert-rule-1-ref.html
-skip-if(styloVsGecko) HTTP(..) == insert-rule-1b.html insert-rule-1-ref.html
-skip-if(styloVsGecko) HTTP(..) == delete-rule-1.html delete-rule-1-ref.html
+HTTP(..) == insert-rule-1a.html insert-rule-1-ref.html
+HTTP(..) == insert-rule-1b.html insert-rule-1-ref.html
+HTTP(..) == delete-rule-1.html delete-rule-1-ref.html
 random-if(styloVsGecko) HTTP(..) == media-query-add-1.html media-query-add-1-ref.html
 random-if(styloVsGecko) HTTP(..) == media-query-remove-1.html media-query-remove-1-ref.html
 HTTP(..) != media-query-add-1-ref.html media-query-remove-1-ref.html
 
 HTTP(..) == ahem-metrics-1.html ahem-metrics-1-ref.html
-skip-if(styloVsGecko) HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
-skip-if(styloVsGecko||stylo) HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
+HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
+HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
 
 == local-1.html local-1-ref.html
 == local-styled-1.html local-styled-1-ref.html
 
 HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
 HTTP(..) == synthetic-variations.html synthetic-variations-ref.html
 
 # Leak test
-skip-if(styloVsGecko) HTTP(..) load 486974-1.html
+HTTP(..) load 486974-1.html
 
 # compare fonts with and without bad head checksum
 HTTP(..) == load-badchecksum.html load-badchecksum-ref.html
 
 # @font-face names take precedence over names of platform fonts (bug 494360)
 HTTP(..) == name-collision.html name-collision-ref.html
 HTTP(..) == name-collision-bad-url.html name-collision-bad-url-ref.html
 
@@ -127,17 +127,17 @@ HTTP(..) == 507960-1-bad-checksums-woff.
 HTTP(..) != 507960-1-bad-sfnt-version-ttf.html 507960-1-ref.html
 HTTP(..) != 507960-1-bad-sfnt-version-woff.html 507960-1-ref.html
 HTTP(..) != 507960-1-bad-woff-sig.html 507960-1-ref.html
 HTTP(..) != 507960-1-bad-offset-woff.html 507960-1-ref.html
 HTTP(..) != 507960-1-woff-bad-hint.html 507960-1-ref.html
 
 # Tests for bug 523717
 HTTP(..) == underline-offset-change-1.html underline-offset-change-1-ref.html
-skip-if(styloVsGecko) HTTP(..) == underline-offset-change-2.html underline-offset-change-2-ref.html
+HTTP(..) == underline-offset-change-2.html underline-offset-change-2-ref.html
 fails-if(cocoaWidget) fails-if(winWidget) HTTP(..) != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132
 
 HTTP(..) != 534352-1-extra-cmap-sentinel.html 534352-1-extra-cmap-sentinel-ref.html
 HTTP(..) == bug533251.html bug533251-ref.html
 
 # Bug 875287
 HTTP(..) == font-familiy-whitespace-1.html font-familiy-whitespace-1-ref.html
 HTTP(..) != font-familiy-whitespace-1.html font-familiy-whitespace-1-notref.html
--- a/layout/reftests/forms/input/number/reftest.list
+++ b/layout/reftests/forms/input/number/reftest.list
@@ -34,17 +34,17 @@ skip-if(Android) == number-max-height-2.
 
 # number of significant fractional digits:
 == number-significant-fractional-digits.html number-significant-fractional-digits-ref.html
 
 # focus
 fuzzy-if(skiaContent,2,5) needs-focus skip-if(styloVsGecko||stylo) == focus-handling.html focus-handling-ref.html
 
 # select
-fuzzy-if(skiaContent,1,1) skip-if(styloVsGecko) == number-selected.html number-selected-ref.html
+fuzzy-if(skiaContent,1,1) == number-selected.html number-selected-ref.html
 
 # pseudo-elements not usable from content:
 == number-pseudo-elements.html number-pseudo-elements-ref.html
 
 == number-placeholder.html number-placeholder-ref.html
 
 # check that if the anonymous text control is reframed, we reframe the whole
 # number control (the fuzzy is for the top-right and bottom-left of the border
--- a/layout/reftests/svg/smil/style/reftest.list
+++ b/layout/reftests/svg/smil/style/reftest.list
@@ -62,17 +62,17 @@ fuzzy-if(skiaContent,1,885) == anim-css-
 fuzzy-if(skiaContent,1,210) == anim-css-fillopacity-1-from-by.svg       anim-css-fillopacity-1-ref.svg
 == anim-css-fillopacity-1-from-to.svg       anim-css-fillopacity-1-ref.svg
 fuzzy-if(skiaContent,1,550) == anim-css-fillopacity-1-to.svg            anim-css-fillopacity-1-ref.svg
 == anim-css-fillopacity-2-paced.svg         anim-css-fillopacity-2-ref.svg
 fails == anim-css-fillopacity-3-clamp-big.svg     anim-css-fillopacity-3-ref.svg # bug 501188
 fuzzy-if(skiaContent,1,365) == anim-css-fillopacity-3-clamp-small.svg   anim-css-fillopacity-3-ref.svg
 
 # 'font' shorthand property
-fails-if(styloVsGecko||stylo) == anim-css-font-1.svg  anim-css-font-1-ref.svg
+== anim-css-font-1.svg  anim-css-font-1-ref.svg
 
 # 'font-size' property, from/by/to with pixel values only
 == anim-css-fontsize-1-from-by-px-px.svg    anim-css-fontsize-1-ref.svg
 == anim-css-fontsize-1-from-to-px-px.svg    anim-css-fontsize-1-ref.svg
 
 # 'font-size' property (accepts unitless values)
 == anim-css-fontsize-1-from-to-no-no.svg    anim-css-fontsize-1-ref.svg
 == anim-css-fontsize-1-from-to-no-px.svg    anim-css-fontsize-1-ref.svg
--- a/layout/reftests/text-overflow/reftest.list
+++ b/layout/reftests/text-overflow/reftest.list
@@ -3,17 +3,17 @@
 fuzzy-if(Android,16,244) HTTP(..) == marker-basic.html marker-basic-ref.html  # Bug 1128229
 HTTP(..) == marker-string.html marker-string-ref.html
 skip-if(Android) HTTP(..) == bidi-simple.html bidi-simple-ref.html # Fails on Android due to anti-aliasing
 skip-if(!gtkWidget) fuzzy-if(gtkWidget,2,289) HTTP(..) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing
 fuzzy-if(Android,24,4000) fuzzy-if(cocoaWidget,1,40) fuzzy-if(asyncPan&&!layersGPUAccelerated,140,1836) HTTP(..) == scroll-rounding.html scroll-rounding-ref.html # bug 760264
 fuzzy(2,453) fuzzy-if(skiaContent,9,2100) fails-if(gtkWidget) HTTP(..) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103
 HTTP(..) == false-marker-overlap.html false-marker-overlap-ref.html
 HTTP(..) == visibility-hidden.html visibility-hidden-ref.html
-fuzzy-if(asyncPan&&!layersGPUAccelerated,102,1724) fuzzy-if(gtkWidget,10,8) skip-if(stylo) HTTP(..) == block-padding.html block-padding-ref.html
+fuzzy-if(asyncPan&&!layersGPUAccelerated,102,1724) fuzzy-if(gtkWidget,10,8) HTTP(..) == block-padding.html block-padding-ref.html
 HTTP(..) == quirks-decorations.html quirks-decorations-ref.html
 HTTP(..) == quirks-line-height.html quirks-line-height-ref.html
 HTTP(..) == standards-decorations.html standards-decorations-ref.html
 HTTP(..) == standards-line-height.html standards-line-height-ref.html
 fuzzy-if(skiaContent,1,4200) HTTP(..) == selection.html selection-ref.html
 HTTP(..) == marker-shadow.html marker-shadow-ref.html
 == aligned-baseline.html aligned-baseline-ref.html
 skip-if(Android) fuzzy-if(skiaContent,1,5) == clipped-elements.html clipped-elements-ref.html
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -13,17 +13,17 @@ random-if(!cocoaWidget) == font-size-adj
 # == font-size-adjust-03.html font-size-adjust-03-ref.html
 == justification-1.html justification-1-ref.html
 == justification-2a.html justification-2-ref.html
 == justification-2b.html justification-2-ref.html
 == justification-2c.html justification-2-ref.html
 != justification-2d.html justification-2-ref.html
 == justification-cjk-extension.html justification-cjk-extension-ref.html
 == justification-space-diacritic.html justification-space-diacritic-ref.html
-skip-if(styloVsGecko) HTTP(..) load ligature-with-space-1.html
+HTTP(..) load ligature-with-space-1.html
 == line-editing-1a.html line-editing-1-ref.html
 == line-editing-1b.html line-editing-1-ref.html
 == line-editing-1c.html line-editing-1-ref.html
 == line-editing-1d.html line-editing-1-ref.html
 == line-editing-1e.html line-editing-1-ref.html
 fails-if(cocoaWidget||(winWidget&&dwrite)) HTTP(..) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864
 HTTP(..) == lineheight-metrics-2a.html lineheight-metrics-2-ref.html
 HTTP(..) == lineheight-metrics-2b.html lineheight-metrics-2-ref.html
--- a/layout/reftests/w3c-css/received/reftest.list
+++ b/layout/reftests/w3c-css/received/reftest.list
@@ -1070,17 +1070,17 @@ fuzzy-if(OSX||winWidget,75,404) == css-w
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-slr-009.xht css-writing-modes-3/text-baseline-slr-009-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-srl-008.xht css-writing-modes-3/text-baseline-vrl-006-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vlr-003.xht css-writing-modes-3/text-baseline-vrl-002-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vlr-005.xht css-writing-modes-3/text-baseline-vrl-002-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vlr-007.xht css-writing-modes-3/text-baseline-vrl-006-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-002.xht css-writing-modes-3/text-baseline-vrl-002-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-004.xht css-writing-modes-3/text-baseline-vrl-002-ref.xht
 fuzzy-if(OSX||winWidget,215,780) == css-writing-modes-3/text-baseline-vrl-006.xht css-writing-modes-3/text-baseline-vrl-006-ref.xht
-skip-if(stylo) fuzzy-if(OSX,15,16) == css-writing-modes-3/text-combine-upright-decorations-001.html css-writing-modes-3/reference/text-combine-upright-decorations-001.html
+fuzzy-if(OSX,15,16) == css-writing-modes-3/text-combine-upright-decorations-001.html css-writing-modes-3/reference/text-combine-upright-decorations-001.html
 == css-writing-modes-3/text-combine-upright-inherit-all-001.html css-writing-modes-3/reference/text-combine-upright-inherit-all-001.html
 == css-writing-modes-3/text-combine-upright-inherit-all-002.html css-writing-modes-3/reference/text-combine-upright-inherit-all-002.html
 == css-writing-modes-3/text-combine-upright-layout-rules-001.html css-writing-modes-3/reference/text-combine-upright-layout-rules-001-ref.html
 == css-writing-modes-3/text-combine-upright-line-breaking-rules-001.html css-writing-modes-3/text-combine-upright-line-breaking-rules-001-ref.html
 fuzzy(255,960) fails-if(stylo) == css-writing-modes-3/text-combine-upright-value-all-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html
 fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
 fuzzy(255,960) != css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html
 fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -33,16 +33,17 @@ GeckoStyleContext::Initialize()
 
 GeckoStyleContext::GeckoStyleContext(GeckoStyleContext* aParent,
                                      nsIAtom* aPseudoTag,
                                      CSSPseudoElementType aPseudoType,
                                      already_AddRefed<nsRuleNode> aRuleNode,
                                      bool aSkipParentDisplayBasedStyleFixup)
   : nsStyleContext(aParent, aPseudoTag, aPseudoType)
   , mCachedResetData(nullptr)
+  , mRefCnt(0)
   , mChild(nullptr)
   , mEmptyChild(nullptr)
   , mRuleNode(Move(aRuleNode))
 #ifdef DEBUG
   , mComputingStruct(nsStyleStructID_None)
 #endif
 {
   mBits |= NS_STYLE_CONTEXT_IS_GECKO;
@@ -76,16 +77,31 @@ void*
 GeckoStyleContext::operator new(size_t sz, nsPresContext* aPresContext)
 {
   MOZ_ASSERT(sz == sizeof(GeckoStyleContext));
   // Check the recycle list first.
   return aPresContext->PresShell()->
     AllocateByObjectID(eArenaObjectID_GeckoStyleContext, sz);
 }
 
+// Overridden to prevent the global delete from being called, since the memory
+// came out of an nsIArena instead of the global delete operator's heap.
+void
+GeckoStyleContext::Destroy()
+{
+  // Get the pres context.
+  RefPtr<nsPresContext> presContext = PresContext();
+  // Call our destructor.
+  this->~GeckoStyleContext();
+  // Don't let the memory be freed, since it will be recycled
+  // instead. Don't call the global operator delete.
+  presContext->PresShell()->
+    FreeByObjectID(eArenaObjectID_GeckoStyleContext, this);
+}
+
 GeckoStyleContext::~GeckoStyleContext()
 {
   nsPresContext *presContext = PresContext();
 #ifdef DEBUG
   NS_ASSERTION(HasNoChildren(), "destructing context with children");
   if (sExpensiveStyleStructAssertionsEnabled) {
     // Assert that the style structs we are about to destroy are not referenced
     // anywhere else in the style context tree.  These checks are expensive,
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -133,16 +133,23 @@ public:
 
   bool HasNoChildren() const;
 
   nsRuleNode* RuleNode() const {
     MOZ_ASSERT(mRuleNode);
     return mRuleNode;
   }
 
+  bool HasSingleReference() const {
+    NS_ASSERTION(mRefCnt != 0,
+                 "do not call HasSingleReference on a newly created "
+                 "nsStyleContext with no references yet");
+    return mRefCnt == 1;
+  }
+
   void AddRef() {
     if (mRefCnt == UINT32_MAX) {
       NS_WARNING("refcount overflow, leaking object");
       return;
     }
     ++mRefCnt;
     NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
     return;
@@ -215,24 +222,27 @@ public:
   // is set for a struct, that means that the pointer for that struct is
   // owned by an ancestor or by the rule node rather than by this style context.
   // Since style contexts typically have some inherited data but only sometimes
   // have reset data, we always allocate the mCachedInheritedData, but only
   // sometimes allocate the mCachedResetData.
   nsResetStyleData*       mCachedResetData; // Cached reset style data.
   nsInheritedStyleData    mCachedInheritedData; // Cached inherited style data
 
+  uint32_t mRefCnt;
+
 #ifdef DEBUG
   void AssertStructsNotUsedElsewhere(GeckoStyleContext* aDestroyingContext,
                                      int32_t aLevels) const;
 #endif
 
 private:
   // Helper for ClearCachedInheritedStyleDataOnDescendants.
   void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
+  void Destroy();
 
   // Children are kept in two circularly-linked lists.  The list anchor
   // is not part of the list (null for empty), and we point to the first
   // child.
   // mEmptyChild for children whose rule node is the root rule node, and
   // mChild for other children.  The order of children is not
   // meaningful.
   GeckoStyleContext* mChild;
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1381420-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title></title>
+<style>
+@keyframes anim {
+  from { transform: scale(1); }
+  to { transform: rotate(0deg); }
+}
+#target {
+  animation: anim 3s infinite;
+  background-color: blue;
+  width: 100px;
+  height: 100px;
+}
+</style>
+<div>
+<div id="target"></div>
+<details id="details" open>
+  <summary>Summary</summary>
+  <p>detail description</p>
+</details>
+</div>
+<script>
+window.addEventListener('load', () => {
+  requestAnimationFrame(() => {
+    details.open = false;
+    SpecialPowers.getDOMWindowUtils(window)
+                 .sendMouseEvent("mousemove", 100, 100, 1,
+                                 0, 1, 0);
+    requestAnimationFrame(() => {
+      document.documentElement.classList.remove("reftest-wait");
+    });
+  });
+});
+</script>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -170,16 +170,18 @@ load 1370793-1.xhtml
 load 1371450-1.html
 load 1374175-1.html
 load 1375812-1.html
 load 1377053-1.html
 load 1377256-1.html
 load 1378064-1.html
 load 1378814.html
 load 1380800.html
+load link-transition-before.html
+load 1381420-1.html
 load 1381682.html
 load 1382672.html
 load 1382710.html
 load 1383001.html
 load 1383001-2.html
 load 1383319.html
 pref(dom.animations-api.core.enabled,true) load 1383589-1.html
 load 1383975.html
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3689,23 +3689,26 @@ nsRuleNode::SetFont(nsPresContext* aPres
     NS_STYLE_FONT_DIALOG         == LookAndFeel::eFont_Dialog &&
     NS_STYLE_FONT_BUTTON         == LookAndFeel::eFont_Button &&
     NS_STYLE_FONT_PULL_DOWN_MENU == LookAndFeel::eFont_PullDownMenu &&
     NS_STYLE_FONT_LIST           == LookAndFeel::eFont_List &&
     NS_STYLE_FONT_FIELD          == LookAndFeel::eFont_Field,
     "LookAndFeel.h system-font constants out of sync with nsStyleConsts.h");
 
   // Fall back to defaultVariableFont.
-  nsFont systemFont = *defaultVariableFont;
+  Maybe<nsFont> lazySystemFont;
   const nsCSSValue* systemFontValue = aRuleData->ValueForSystemFont();
   if (eCSSUnit_Enumerated == systemFontValue->GetUnit()) {
+    lazySystemFont.emplace(*defaultVariableFont);
     LookAndFeel::FontID fontID =
       (LookAndFeel::FontID)systemFontValue->GetIntValue();
-    ComputeSystemFont(&systemFont, fontID, aPresContext, defaultVariableFont);
-  }
+    ComputeSystemFont(lazySystemFont.ptr(), fontID, aPresContext,
+                      defaultVariableFont);
+  }
+  const nsFont& systemFont = lazySystemFont.refOr(*defaultVariableFont);
 
   // font-family: font family list, enum, inherit
   const nsCSSValue* familyValue = aRuleData->ValueForFontFamily();
   NS_ASSERTION(eCSSUnit_Enumerated != familyValue->GetUnit(),
                "system fonts should not be in mFamily anymore");
   if (eCSSUnit_FontFamilyList == familyValue->GetUnit()) {
     // set the correct font if we are using DocumentFonts OR we are overriding for XUL
     // MJA: bug 31816
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -79,17 +79,16 @@ const uint32_t nsStyleContext::sDependen
 #endif
 
 nsStyleContext::nsStyleContext(nsStyleContext* aParent,
                                nsIAtom* aPseudoTag,
                                CSSPseudoElementType aPseudoType)
   : mParent(aParent)
   , mPseudoTag(aPseudoTag)
   , mBits(((uint64_t)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT)
-  , mRefCnt(0)
 #ifdef DEBUG
   , mFrameRefCnt(0)
 #endif
 {}
 
 void
 nsStyleContext::AddChild(nsStyleContext* aChild)
 {
@@ -430,17 +429,18 @@ void nsStyleContext::List(FILE* out, int
 {
   nsAutoCString str;
   // Indent
   int32_t ix;
   for (ix = aIndent; --ix >= 0; ) {
     str.AppendLiteral("  ");
   }
   str.Append(nsPrintfCString("%p(%d) parent=%p ",
-                             (void*)this, mRefCnt, (void *)mParent));
+                             (void*)this, IsGecko() ? AsGecko()->mRefCnt : 0,
+                             (void *)mParent));
   if (mPseudoTag) {
     nsAutoString  buffer;
     mPseudoTag->ToString(buffer);
     AppendUTF16toUTF8(buffer, str);
     str.Append(' ');
   }
 
   if (IsServo()) {
@@ -467,35 +467,16 @@ void nsStyleContext::List(FILE* out, int
   if (aListDescendants) {
     if (GeckoStyleContext* gecko = GetAsGecko()) {
       gecko->ListDescendants(out, aIndent);
     }
   }
 }
 #endif
 
-// Overridden to prevent the global delete from being called, since the memory
-// came out of an nsIArena instead of the global delete operator's heap.
-void
-nsStyleContext::Destroy()
-{
-  if (IsGecko()) {
-    // Get the pres context.
-    RefPtr<nsPresContext> presContext = PresContext();
-    // Call our destructor.
-    this->AsGecko()->~GeckoStyleContext();
-    // Don't let the memory be freed, since it will be recycled
-    // instead. Don't call the global operator delete.
-    presContext->PresShell()->
-      FreeByObjectID(eArenaObjectID_GeckoStyleContext, this);
-  } else {
-    delete static_cast<ServoStyleContext*>(this);
-  }
-}
-
 already_AddRefed<GeckoStyleContext>
 NS_NewStyleContext(GeckoStyleContext* aParentContext,
                    nsIAtom* aPseudoTag,
                    CSSPseudoElementType aPseudoType,
                    nsRuleNode* aRuleNode,
                    bool aSkipParentDisplayBasedStyleFixup)
 {
   RefPtr<nsRuleNode> node = aRuleNode;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -57,18 +57,16 @@ public:
   bool IsGecko() const { return !IsServo(); }
   bool IsServo() const { return (mBits & NS_STYLE_CONTEXT_IS_GECKO) == 0; }
 #else
   bool IsGecko() const { return true; }
   bool IsServo() const { return false; }
 #endif
   MOZ_DECL_STYLO_CONVERT_METHODS(mozilla::GeckoStyleContext, mozilla::ServoStyleContext);
 
-  void Destroy();
-
   // These two methods are for use by ArenaRefPtr.
   static mozilla::ArenaObjectID ArenaObjectID()
   {
     return mozilla::eArenaObjectID_GeckoStyleContext;
   }
   nsIPresShell* Arena();
 
   void AddChild(nsStyleContext* aChild);
@@ -86,23 +84,16 @@ public:
     --mFrameRefCnt;
   }
 
   uint32_t FrameRefCnt() const {
     return mFrameRefCnt;
   }
 #endif
 
-  bool HasSingleReference() const {
-    NS_ASSERTION(mRefCnt != 0,
-                 "do not call HasSingleReference on a newly created "
-                 "nsStyleContext with no references yet");
-    return mRefCnt == 1;
-  }
-
   inline nsPresContext* PresContext() const;
 
   inline mozilla::GeckoStyleContext* GetParent() const;
 
   nsStyleContext* GetParentAllowServo() const {
     return mParent;
   }
 
@@ -355,18 +346,16 @@ protected:
   // mBits stores a number of things:
   //  - It records (using the style struct bits) which structs are
   //    inherited from the parent context or owned by the rule node (i.e.,
   //    not owned by the style context).
   //  - It also stores the additional bits listed at the top of
   //    nsStyleStruct.h.
   uint64_t                mBits;
 
-  uint32_t                mRefCnt;
-
 #ifdef DEBUG
   uint32_t                mFrameRefCnt; // number of frames that use this
                                         // as their style context
 
   static bool DependencyAllowed(nsStyleStructID aOuterSID,
                                 nsStyleStructID aInnerSID)
   {
     return !!(sDependencyTable[aOuterSID] &
--- a/layout/style/test/test_hover_quirk.html
+++ b/layout/style/test/test_hover_quirk.html
@@ -12,20 +12,29 @@ https://bugzilla.mozilla.org/show_bug.cg
       color: rgb(255, 0, 0);
     }
     #content :-moz-any(:hover) {
       text-transform: lowercase;
     }
     #content :hover::after {
       content: "any element";
     }
+
     #content :hover:first-of-type .child::after {
       content: "any child";
     }
 
+    #content .parent .child::after {
+      content: "wrong" !important;
+    }
+
+    #content .parent:hover .child::after {
+      content: "any child" !important;
+    }
+
     /* Should apply only to links: */
     #content :hover {
       color: rgb(0, 255, 0) !important;
       text-transform: uppercase !important;
     }
     #content :hover .child::after {
       content: "link child" !important;
     }
@@ -60,23 +69,25 @@ https://bugzilla.mozilla.org/show_bug.cg
          "Unexpected pseudo-element content for child");
     }
 
     SimpleTest.waitForExplicitFinish();
     SimpleTest.waitForFocus(function() {
       test(document.getElementById("span"), false);
       test(document.getElementById("label"), false);
       test(document.getElementById("link"), true);
+      test(document.getElementById("div"), false);
       SimpleTest.finish();
     });
   </script>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783213">Mozilla Bug 783213</a>
   <p id="display"></p>
   <div id="content">
     <span id="span">Span<span class="child"></span></span><br>
     <label id="label">Label<span class="child"></span></label><br>
-    <a id="link" href="#">Link<span class="child"></span></a>
+    <a id="link" href="#">Link<span class="child"></span></a><br>
+    <div id="div" class="parent">Div <span><span class="child"></span></span></div><br>
   </div>
   <pre id="test"></pre>
 </body>
 </html>
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -176,17 +176,16 @@ import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.regex.Pattern;
 
-import static org.mozilla.gecko.mma.MmaDelegate.NEW_TAB;
 public class BrowserApp extends GeckoApp
                         implements ActionModePresenter,
                                    AnchoredPopup.OnVisibilityChangeListener,
                                    BookmarkEditFragment.Callbacks,
                                    BrowserSearch.OnEditSuggestionListener,
                                    BrowserSearch.OnSearchListener,
                                    DynamicToolbarAnimator.MetricsListener,
                                    DynamicToolbarAnimator.ToolbarChromeProxy,
@@ -3722,20 +3721,18 @@ public class BrowserApp extends GeckoApp
         final int itemId = item.getItemId();
 
         // Track the menu action. We don't know much about the context, but we can use this to determine
         // the frequency of use for various actions.
         String extras = getResources().getResourceEntryName(itemId);
         if (TextUtils.equals(extras, "new_private_tab")) {
             // Mask private browsing
             extras = "new_tab";
-        } else {
-            // We only track opening normal tab
-            MmaDelegate.track(NEW_TAB);
         }
+
         Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.MENU, extras);
 
         mBrowserToolbar.cancelEdit();
 
         if (itemId == R.id.bookmark) {
             tab = Tabs.getInstance().getSelectedTab();
             if (tab != null) {
                 final String extra;
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -46,16 +46,18 @@ import android.net.Uri;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.provider.Browser;
 import android.support.annotation.UiThread;
 import android.support.v4.content.ContextCompat;
 import android.text.TextUtils;
 import android.util.Log;
 
+import static org.mozilla.gecko.mma.MmaDelegate.NEW_TAB;
+
 
 public class Tabs implements BundleEventListener {
     private static final String LOGTAG = "GeckoTabs";
 
     public static final String INTENT_EXTRA_TAB_ID = "TabId";
     public static final String INTENT_EXTRA_SESSION_UUID = "SessionUUID";
     private static final String PRIVATE_TAB_INTENT_EXTRA = "private_tab";
 
@@ -1045,16 +1047,17 @@ public class Tabs implements BundleEvent
         return tabToSelect;
     }
 
     /**
      * Opens a new tab and loads either about:home or, if PREFS_HOMEPAGE_FOR_EVERY_NEW_TAB is set,
      * the user's homepage.
      */
     public Tab addTab() {
+        MmaDelegate.track(NEW_TAB);
         return loadUrl(getHomepageForNewTab(mAppContext), Tabs.LOADURL_NEW_TAB);
     }
 
     public Tab addPrivateTab() {
         if (SkinConfig.isPhoton()) {
             return loadUrl(getHomepageForNewTab(mAppContext), Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE);
         } else {
             return loadUrl(AboutPages.PRIVATEBROWSING, Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE);
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStrip.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStrip.java
@@ -16,21 +16,19 @@ import android.view.LayoutInflater;
 import android.view.TouchDelegate;
 import android.view.View;
 import android.view.ViewTreeObserver;
 
 import org.mozilla.gecko.BrowserApp.TabStripInterface;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.mma.MmaDelegate;
 import org.mozilla.gecko.widget.themed.ThemedImageButton;
 import org.mozilla.gecko.widget.themed.ThemedLinearLayout;
 
-import static org.mozilla.gecko.mma.MmaDelegate.NEW_TAB;
 
 public class TabStrip extends ThemedLinearLayout
                       implements TabStripInterface {
     private static final String LOGTAG = "GeckoTabStrip";
 
     private final TabStripView tabStripView;
     private final ThemedImageButton addTabButton;
 
@@ -56,17 +54,16 @@ public class TabStrip extends ThemedLine
         addTabButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 final Tabs tabs = Tabs.getInstance();
                 if (isPrivateMode()) {
                     tabs.addPrivateTab();
                 } else {
                     tabs.addTab();
-                    MmaDelegate.track(NEW_TAB);
                 }
             }
         });
 
         getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                 @Override
                 public boolean onPreDraw() {
                     getViewTreeObserver().removeOnPreDrawListener(this);
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
@@ -44,18 +44,16 @@ import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 
 import org.mozilla.gecko.switchboard.SwitchBoard;
 
 import org.mozilla.gecko.widget.themed.ThemedImageButton;
 
-import static org.mozilla.gecko.mma.MmaDelegate.NEW_TAB;
-
 public class TabsPanel extends LinearLayout
                        implements GeckoPopupMenu.OnMenuItemClickListener,
                                   LightweightTheme.OnChangeListener,
                                   IconTabWidget.OnTabChangedListener,
                                   SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String LOGTAG = "Gecko" + TabsPanel.class.getSimpleName();
 
     public enum Panel {
@@ -209,18 +207,16 @@ public class TabsPanel extends LinearLay
         mPopupMenu.show();
     }
 
     private void addTab() {
         Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.ACTIONBAR, "new_tab");
 
         if (mCurrentPanel == Panel.NORMAL_TABS) {
             mActivity.addTab();
-            // We only track opening normal tab
-            MmaDelegate.track(NEW_TAB);
         } else {
             mActivity.addPrivateTab();
         }
 
         mActivity.autoHideTabs();
     }
 
     @Override
--- a/mobile/android/components/extensions/schemas/tabs.json
+++ b/mobile/android/components/extensions/schemas/tabs.json
@@ -53,34 +53,34 @@
         }
       },
       {
         "id": "Tab",
         "type": "object",
         "properties": {
           "id": {"type": "integer", "minimum": -1, "optional": true, "description": "The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a Tab may not be assigned an ID, for example when querying foreign tabs using the $(ref:sessions) API, in which case a session ID may be present. Tab ID can also be set to $(ref:tabs.TAB_ID_NONE) for apps and devtools windows."},
           "index": {"type": "integer", "minimum": -1, "description": "The zero-based index of the tab within its window."},
-          "windowId": {"type": "integer", "minimum": 0, "description": "The ID of the window the tab is contained within."},
+          "windowId": {"type": "integer", "optional": true, "minimum": 0, "description": "The ID of the window the tab is contained within."},
           "openerTabId": {"unsupported": true, "type": "integer", "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists."},
           "selected": {"type": "boolean", "description": "Whether the tab is selected.", "deprecated": "Please use $(ref:tabs.Tab.highlighted).", "unsupported": true},
           "highlighted": {"type": "boolean", "description": "Whether the tab is highlighted. Works as an alias of active."},
           "active": {"type": "boolean", "description": "Whether the tab is active in its window. (Does not necessarily mean the window is focused.)"},
           "pinned": {"type": "boolean", "description": "Whether the tab is pinned."},
           "lastAccessed": {"type": "integer", "optional": true, "description": "The last time the tab was accessed as the number of milliseconds since epoch."},
           "audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the speaker audio indicator is showing."},
           "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."},
           "url": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "title": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
           "favIconUrl": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."},
           "status": {"type": "string", "optional": true, "description": "Either <em>loading</em> or <em>complete</em>."},
           "incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."},
           "width": {"type": "integer", "optional": true, "description": "The width of the tab in pixels."},
           "height": {"type": "integer", "optional": true, "description": "The height of the tab in pixels."},
-          "sessionId": {"unsupported": true, "type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."},
-          "cookieStoreId": {"type": "string", "description": "The CookieStoreId used for the tab."}
+          "sessionId": {"type": "string", "optional": true, "description": "The session ID used to uniquely identify a Tab obtained from the $(ref:sessions) API."},
+          "cookieStoreId": {"type": "string", "optional": true, "description": "The CookieStoreId used for the tab."}
         }
       },
       {
         "id": "ZoomSettingsMode",
         "type": "string",
         "description": "Defines how zoom changes are handled, i.e. which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.",
         "enum": [
           {
@@ -404,16 +404,17 @@
           {
             "type": "function",
             "name": "callback",
             "optional": true,
             "parameters": [
               {
                 "name": "tab",
                 "$ref": "Tab",
+                "optional": true,
                 "description": "Details about the created tab. Will contain the ID of the new tab."
               }
             ]
           }
         ]
       },
       {
         "name": "duplicate",
--- a/mobile/android/config/mozconfigs/common
+++ b/mobile/android/config/mozconfigs/common
@@ -78,17 +78,16 @@ else
 fi
 
 export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Use ccache
-. "$topsrcdir/build/mozconfig.cache"
 
 HOST_CC="$topsrcdir/gcc/bin/gcc"
 HOST_CXX="$topsrcdir/gcc/bin/g++"
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
 # Use libc++ as our C++ standard library
 ac_add_options --with-android-cxx-stl=libc++
--- a/mobile/android/config/mozconfigs/common.override
+++ b/mobile/android/config/mozconfigs/common.override
@@ -3,9 +3,8 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # This file is included at the bottom of all native android mozconfigs
 #
 # Disable enforcing that add-ons are signed by the trusted root
 MOZ_REQUIRE_SIGNING=0
 
 . "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
--- a/mobile/android/config/tooltool-manifests/android-gradle-dependencies/releng.manifest
+++ b/mobile/android/config/tooltool-manifests/android-gradle-dependencies/releng.manifest
@@ -10,19 +10,19 @@
     "size": 573952124,
     "visibility": "internal",
     "digest": "1d495d7a7386af3f27b14982e0ff7b0963fd1a63a08040b9b1db0e94c9681fa3704c195ba8be23b5f73e15101b2b767293bc8f96e0584e17867ef13b074e5038",
     "algorithm": "sha512",
     "filename": "android-sdk-linux.tar.xz",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 139759616,
-    "digest": "56f632c063744fa6d57a13a2647916e22e5bb89f4e02d7e94df1d45b5532c1db12a6e97d9c3951963f4e89b68467cca6818f7fe86d26b7e28577d04e196e873b",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 151322128,
+    "digest": "1d6d6e8bbf7535a4f1c8f1292562e30c868bfd3ac323992fc287be09f7fa3167c2f9e01dc98143967983e30488fe3ecaebff530ba4ec9113033d60af936c4f4d",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
     "algorithm": "sha512",
     "visibility": "public",
--- a/mobile/android/config/tooltool-manifests/android-x86/releng.manifest
+++ b/mobile/android/config/tooltool-manifests/android-x86/releng.manifest
@@ -43,19 +43,19 @@
     "version": "gcc 4.9.4 + PR64905",
     "size": 101297752,
     "digest": "42aa2e3fdd232b5e390472a788e7f7db71a1fee4221e260b6cb58c9a1d73e6cdd10afcbac137f7844290169cd6b561b424ecc92b159e9726b0ad5de3f478a8be",
     "algorithm": "sha512",
     "filename": "gcc.tar.xz",
     "unpack": true
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 139759616,
-    "digest": "56f632c063744fa6d57a13a2647916e22e5bb89f4e02d7e94df1d45b5532c1db12a6e97d9c3951963f4e89b68467cca6818f7fe86d26b7e28577d04e196e873b",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 151322128,
+    "digest": "1d6d6e8bbf7535a4f1c8f1292562e30c868bfd3ac323992fc287be09f7fa3167c2f9e01dc98143967983e30488fe3ecaebff530ba4ec9113033d60af936c4f4d",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "jcentral.tar.xz",
--- a/mobile/android/config/tooltool-manifests/android/releng.manifest
+++ b/mobile/android/config/tooltool-manifests/android/releng.manifest
@@ -68,19 +68,19 @@
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "gradle-dist.tar.xz",
     "unpack": true,
     "digest": "e3cfe7f8259ad97722243d4e873d5a05c014bfc24d637427f89d804bf5073290229c778ea303142cf06c2dc79e0492f23521f57d3a73825f55b8db587317646f",
     "size": 51753660
   },
   {
-    "version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
-    "size": 139759616,
-    "digest": "56f632c063744fa6d57a13a2647916e22e5bb89f4e02d7e94df1d45b5532c1db12a6e97d9c3951963f4e89b68467cca6818f7fe86d26b7e28577d04e196e873b",
+    "version": "rustc 1.19.0 (0ade33941 2017-07-17) repack",
+    "size": 151322128,
+    "digest": "1d6d6e8bbf7535a4f1c8f1292562e30c868bfd3ac323992fc287be09f7fa3167c2f9e01dc98143967983e30488fe3ecaebff530ba4ec9113033d60af936c4f4d",
     "algorithm": "sha512",
     "filename": "rustc.tar.xz",
     "unpack": true
   },
   {
     "algorithm": "sha512",
     "visibility": "public",
     "filename": "dotgradle.tar.xz",
--- a/mobile/android/themes/core/aboutReaderControls.css
+++ b/mobile/android/themes/core/aboutReaderControls.css
@@ -58,16 +58,17 @@
   position: fixed;
   width: 100%;
   left: 0;
   margin: 0;
   padding: 0;
   bottom: 0;
   list-style: none;
   pointer-events: none;
+  transition: opacity 420ms linear;
 }
 
 .toolbar > * {
   float: right;
 }
 
 .button {
   width: 56px;
@@ -88,17 +89,18 @@
 }
 
 /* Remove dotted border when button is focused */
 .button::-moz-focus-inner,
 .dropdown-popup > div > button::-moz-focus-inner {
   border: 0;
 }
 
-.button[hidden] {
+.button[hidden],
+.toolbar[hidden] {
   display: none;
 }
 
 .dropdown-toggle,
 #reader-popup {
   pointer-events: auto;
 }
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1026,30 +1026,30 @@ pref("toolkit.asyncshutdown.crash_timeou
 // Extra logging for AsyncShutdown barriers and phases
 pref("toolkit.asyncshutdown.log", false);
 
 // Enable deprecation warnings.
 pref("devtools.errorconsole.deprecation_warnings", true);
 
 #ifdef NIGHTLY_BUILD
 // Don't show the Browser Toolbox prompt on local builds / nightly
-pref("devtools.debugger.prompt-connection", false);
+sticky_pref("devtools.debugger.prompt-connection", false);
 #else
-pref("devtools.debugger.prompt-connection", true);
+sticky_pref("devtools.debugger.prompt-connection", true);
 #endif
 
 #ifdef MOZILLA_OFFICIAL
 // Disable debugging chrome
-pref("devtools.chrome.enabled", false);
+sticky_pref("devtools.chrome.enabled", false);
 // Disable remote debugging connections
-pref("devtools.debugger.remote-enabled", false);
+sticky_pref("devtools.debugger.remote-enabled", false);
 #else
 // In local builds, enable the browser toolbox by default
-pref("devtools.chrome.enabled", true);
-pref("devtools.debugger.remote-enabled", true);
+sticky_pref("devtools.chrome.enabled", true);
+sticky_pref("devtools.debugger.remote-enabled", true);
 #endif
 
 
 // Disable remote debugging protocol logging
 pref("devtools.debugger.log", false);
 pref("devtools.debugger.log.verbose", false);
 
 pref("devtools.debugger.remote-port", 6000);
--- a/old-configure.in
+++ b/old-configure.in
@@ -79,75 +79,24 @@ MOZ_USE_PTHREADS=
 _PTHREAD_LDFLAGS=""
 
 MOZ_DEFAULT_COMPILER
 
 if test "$COMPILE_ENVIRONMENT"; then
     MOZ_ANDROID_NDK
 fi # COMPILE_ENVIRONMENT
 
-if test -n "$gonkdir"; then
-    dnl export for js/src/configure. We can't pass the option down normally,
-    dnl because it's a `--enable-project=b2g`-only option.
-    export gonkdir
-    kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
-    android_source="$gonkdir"
-    ANDROID_SOURCE="$android_source"
-
-    case "$android_version" in
-    15)
-        CPPFLAGS="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/ -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/dalvik/libnativehelper/include/nativehelper $CPPFLAGS"
-        MOZ_SECUREELEMENT=1
-        ;;
-    17|18)
-        CPPFLAGS="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include $CPPFLAGS"
-        MOZ_SECUREELEMENT=1
-        ;;
-    19)
-        CPPFLAGS="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include $CPPFLAGS"
-        MOZ_AUDIO_OFFLOAD=1
-        MOZ_SECUREELEMENT=1
-        AC_SUBST(MOZ_AUDIO_OFFLOAD)
-        AC_DEFINE(MOZ_AUDIO_OFFLOAD)
-        ;;
-    21|22)
-        CPPFLAGS="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include $CPPFLAGS"
-        MOZ_AUDIO_OFFLOAD=1
-        AC_SUBST(MOZ_AUDIO_OFFLOAD)
-        AC_DEFINE(MOZ_AUDIO_OFFLOAD)
-        ;;
-    *)
-        AC_MSG_ERROR([Unsupported platform version: $android_version])
-        ;;
-    esac
-
-    CPPFLAGS="-I$gonkdir/system -I$gonkdir/system/core/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/external/valgrind/fxos-include $CPPFLAGS"
-    LDFLAGS="-L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib $LDFLAGS"
-
+case "$target" in
+*-android*|*-linuxandroid*)
     AC_DEFINE(ANDROID)
-    AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
-    AC_DEFINE(HAVE_SYS_UIO_H)
-    AC_DEFINE(HAVE_PTHREADS)
-
-    dnl ANDROID_VERSION is only required for the AC_SUBST below
-    ANDROID_VERSION=$android_version
-    AC_SUBST(ANDROID_VERSION)
-
-    direct_nspr_config=1
-
-else
-    case "$target" in
-    *-android*|*-linuxandroid*)
-        AC_DEFINE(ANDROID)
-        ;;
-    *-linux*)
-        AC_PATH_PROG(OBJCOPY,objcopy)
-        ;;
-    esac
-fi
+    ;;
+*-linux*)
+    AC_PATH_PROG(OBJCOPY,objcopy)
+    ;;
+esac
 
 case "$target" in
 *-apple-darwin*)
     MOZ_IOS_SDK
     ;;
 esac
 
 AC_SUBST(ANDROID_SOURCE)
@@ -508,17 +457,17 @@ MOZ_FIX_LINK_PATHS="-Wl,-rpath-link,${DI
 
 MOZ_FS_LAYOUT=unix
 
 dnl Configure platform-specific CPU architecture compiler options.
 dnl ==============================================================
 if test "$COMPILE_ENVIRONMENT"; then
     MOZ_ARCH_OPTS
 else
-    if test "$OS_TARGET" = Android -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
+    if test "$OS_TARGET" = Android; then
         dnl Default Android builds to ARMv7.
         MOZ_ARCH=armv7-a
     fi
 fi # COMPILE_ENVIRONMENT
 
 dnl ========================================================
 dnl Android libstdc++, placed here so it can use MOZ_ARCH
 dnl computed above.
@@ -577,26 +526,24 @@ if test "$GNU_CC"; then
     LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for -z text option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,-z,text"
-    AC_TRY_LINK(,,AC_MSG_RESULT([yes])
-                  [NSPR_LDFLAGS="$NSPR_LDFLAGS -Wl,-z,text"],
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for --build-id option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,--build-id"
-    AC_TRY_LINK(,,AC_MSG_RESULT([yes])
-                  [NSPR_LDFLAGS="$NSPR_LDFLAGS -Wl,--build-id"],
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for --ignore-unresolved-symbol option to ld])
     HAVE_LINKER_SUPPORT_IGNORE_UNRESOLVED=
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,--ignore-unresolved-symbol,environ"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes])
@@ -852,23 +799,19 @@ case "$target" in
         LDFLAGS=$_SAVE_LDFLAGS
     fi
 
     MOZ_FIX_LINK_PATHS="-Wl,-executable_path,${DIST}/bin"
     ;;
 
 *-android*|*-linuxandroid*)
     AC_DEFINE(NO_PW_GECOS)
-    if test -n "$gonkdir"; then
-        _PLATFORM_HAVE_RIL=1
-        MOZ_SYNTH_PICO=1
-    else
-        if test "$COMPILE_ENVIRONMENT"; then
-            MOZ_LINKER=1
-        fi
+
+    if test "$COMPILE_ENVIRONMENT"; then
+        MOZ_LINKER=1
     fi
 
     MOZ_GFX_OPTIMIZE_MOBILE=1
     if test -z "$CLANG_CC"; then
         MOZ_OPTIMIZE_FLAGS="-freorder-blocks -fno-reorder-functions -Os"
     else
         # From https://github.com/android-ndk/ndk/issues/133#issuecomment-308549264
         # -Oz is smaller than -Os on clang.
@@ -909,17 +852,16 @@ case "$target" in
         CFLAGS="$CFLAGS -mms-bitfields"
         CXXFLAGS="$CXXFLAGS -mms-bitfields"
         DSO_LDOPTS='-shared'
         MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
         MKCSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
         RC='$(WINDRES)'
         # Use static libgcc and libstdc++
         LDFLAGS="$LDFLAGS -static"
-        NSPR_LDFLAGS="$NSPR_LDFLAGS -static-libgcc"
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32"
         MOZ_FIX_LINK_PATHS=
 
         WIN32_CONSOLE_EXE_LDFLAGS=-mconsole
         WIN32_GUI_EXE_LDFLAGS=-mwindows
@@ -1845,17 +1787,16 @@ if test -n "$MOZ_LINKER" -a "$OS_TARGET"
   if test "$ac_cv_crt_has_text_relocations" = yes; then
     dnl While we want libraries to skip the CRT files, we don't want
     dnl executables to be treated the same way. We thus set the flag
     dnl in DSO_LDOPTS and not LDFLAGS. However, to pass it to nspr,
     dnl we need to use LDFLAGS because nspr doesn't inherit DSO_LDOPTS.
     dnl Using LDFLAGS in nspr is safe, since we only really build
     dnl libraries there.
     DSO_LDOPTS="$DSO_LDOPTS -nostartfiles"
-    NSPR_LDFLAGS="$NSPR_LDFLAGS -nostartfiles"
   fi
 fi
 
 dnl End of C++ language/feature checks
 AC_LANG_C
 
 dnl ========================================================
 dnl =  Internationalization checks
@@ -2292,23 +2233,21 @@ AC_SUBST(MOZ_B2G)
 AC_SUBST(MOZ_MULET)
 AC_SUBST(MOZ_B2G_VERSION)
 
 dnl ========================================================
 dnl Ensure Android SDK and build-tools versions depending on
 dnl mobile target.
 dnl ========================================================
 
-if test -z "$gonkdir" ; then
-    case "$MOZ_BUILD_APP" in
-    mobile/android)
-        MOZ_ANDROID_SDK(23, 23, 23.0.3 23.0.1, 25.3.2 25.3.1)
-        ;;
-    esac
-fi
+case "$MOZ_BUILD_APP" in
+mobile/android)
+    MOZ_ANDROID_SDK(23, 23, 23.0.3 23.0.1, 25.3.2 25.3.1)
+    ;;
+esac
 
 dnl ========================================================
 dnl =
 dnl = Toolkit Options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Toolkit Options)
 
@@ -2735,29 +2674,16 @@ if test -n "$MOZ_APPLEMEDIA"; then
   # We load VideoToolbox and CoreMedia dynamically, so they don't appear here.
   LDFLAGS="$LDFLAGS -framework AudioToolbox"
   dnl Verify CoreMedia is available.
   AC_CHECK_HEADER([CoreMedia/CoreMedia.h], [],
     [AC_MSG_ERROR([MacOS X 10.7 SDK or later is required])])
 fi
 fi # COMPILE_ENVIRONMENT
 
-dnl ========================================================
-dnl = Built-in fragmented MP4 support.
-dnl ========================================================
-
-if test x"$MOZ_WIDGET_TOOLKIT" = x"gonk" -a -n "$MOZ_FMP4" -a -n "$android_version"; then
-    # we now know for sure that $android_version is not an empty string!
-    if test "$android_version" -ge "18"; then
-        MOZ_GONK_MEDIACODEC=1
-        AC_SUBST(MOZ_GONK_MEDIACODEC)
-    fi
-fi
-
-
 dnl system libvpx Support
 dnl ========================================================
 MOZ_ARG_WITH_BOOL(system-libvpx,
 [  --with-system-libvpx    Use system libvpx (located with pkgconfig)],
     MOZ_SYSTEM_LIBVPX=1)
 
 MOZ_LIBVPX_CFLAGS=
 MOZ_LIBVPX_LIBS=
@@ -2944,23 +2870,19 @@ esac
 
 MOZ_ARG_DISABLE_BOOL(pulseaudio,
 [  --disable-pulseaudio          Disable PulseAudio support],
    MOZ_PULSEAUDIO=,
    MOZ_PULSEAUDIO=1)
 
 if test -n "$MOZ_PULSEAUDIO"; then
     AC_DEFINE(MOZ_PULSEAUDIO)
-    if test -z "$gonkdir"; then
-        PKG_CHECK_MODULES(MOZ_PULSEAUDIO, libpulse, ,
-             [echo "$MOZ_PULSEAUDIO_PKG_ERRORS"
-              AC_MSG_ERROR([pulseaudio audio backend requires libpulse development package])])
-    else
-        MOZ_PULSEAUDIO_CFLAGS="-I$gonkdir/external/pulseaudio/pulseaudio/src"
-    fi
+    PKG_CHECK_MODULES(MOZ_PULSEAUDIO, libpulse, ,
+         [echo "$MOZ_PULSEAUDIO_PKG_ERRORS"
+          AC_MSG_ERROR([pulseaudio audio backend requires libpulse development package])])
 fi
 
 AC_SUBST(MOZ_PULSEAUDIO)
 
 dnl ========================================================
 dnl NegotiateAuth
 dnl ========================================================
 
@@ -3544,19 +3466,16 @@ fi
 MOZ_ARG_DISABLE_BOOL(sandbox,
 [  --disable-sandbox        Disable sandboxing support],
     MOZ_SANDBOX=,
     MOZ_SANDBOX=1)
 
 dnl ========================================================
 dnl = Content process sandboxing
 dnl ========================================================
-if test -n "$gonkdir"; then
-    MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
-fi
 
 case "$OS_TARGET" in
 WINNT)
     MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
     ;;
 Darwin)
     MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
     ;;
@@ -4184,39 +4103,16 @@ dnl bug 988880: disable startup cache on
 if test -n "$MOZ_B2G"; then
   MOZ_DISABLE_STARTUPCACHE=1
 fi
 if test -n "$MOZ_DISABLE_STARTUPCACHE"; then
   AC_DEFINE(MOZ_DISABLE_STARTUPCACHE)
 fi
 AC_SUBST(MOZ_DISABLE_STARTUPCACHE)
 
-dnl =========================================
-dnl = Enable packaging Gaia with B2G desktop
-dnl =========================================
-if test x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
-    if test -n "$GAIADIR" -a ! -d "$GAIADIR" ; then
-        AC_MSG_ERROR([GAIADIR '$GAIADIR' isn't a valid directory])
-    fi
-
-    AC_SUBST(GAIADIR)
-    if test -n "$GAIADIR" ; then
-        AC_DEFINE(PACKAGE_GAIA)
-    fi
-
-    if test -n "$FXOS_SIMULATOR" -a -z "$GAIADIR" ; then
-        AC_MSG_ERROR([FXOS_SIMULATOR=1 requires GAIADIR to be defined])
-    fi
-
-    if test -n "$FXOS_SIMULATOR" ; then
-        AC_DEFINE(FXOS_SIMULATOR)
-        AC_SUBST(FXOS_SIMULATOR)
-    fi
-fi
-
 dnl ========================================================
 dnl = Enable Pico Speech Synthesis (Gonk usually)
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(synth-pico,
 [  --enable-synth-pico  Set compile flags necessary for compiling Pico Web Speech API ],
     MOZ_SYNTH_PICO=1,
     MOZ_SYNTH_PICO= )
 if test -n "$MOZ_SYNTH_PICO"; then
@@ -4663,17 +4559,17 @@ else
         PKG_CHECK_MODULES(CAIRO_XRENDER, cairo-xlib-xrender >= $CAIRO_VERSION)
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS $CAIRO_XRENDER_LIBS"
         MOZ_CAIRO_OSLIBS="$MOZ_CAIRO_LIBS"
         MOZ_CAIRO_CFLAGS="$MOZ_CAIRO_CFLAGS $CAIRO_XRENDER_CFLAGS"
     fi
 fi
 
 case "$MOZ_WIDGET_TOOLKIT" in
-android|gonk)
+android)
     TK_CFLAGS="$MOZ_CAIRO_CFLAGS $MOZ_PIXMAN_CFLAGS"
     TK_LIBS="$MOZ_CAIRO_LIBS $MOZ_PIXMAN_LIBS"
     ;;
 esac
 
 AC_SUBST(MOZ_TREE_CAIRO)
 AC_SUBST_LIST(MOZ_CAIRO_CFLAGS)
 AC_SUBST_LIST(MOZ_CAIRO_LIBS)
@@ -4699,21 +4595,16 @@ dnl ====================================
 dnl necko configuration options
 dnl ========================================================
 
 dnl
 dnl option to disable necko's wifi scanner
 dnl
 
 case "$OS_TARGET" in
-  Android)
-    if test -n "$gonkdir"; then
-      NECKO_WIFI=1
-    fi
-    ;;
   Darwin)
     if test -z "$MOZ_IOS"; then
       NECKO_WIFI=1
     fi
     ;;
   DragonFly|FreeBSD|WINNT)
     NECKO_WIFI=1
     ;;
--- a/python/mozboot/mozboot/android.py
+++ b/python/mozboot/mozboot/android.py
@@ -6,33 +6,16 @@
 from __future__ import print_function
 
 import errno
 import os
 import stat
 import subprocess
 import sys
 
-# These are the platform and build-tools versions for building
-# mobile/android, respectively. Try to keep these in synch with the
-# build system and Mozilla's automation.
-ANDROID_TARGET_SDK = '23'
-ANDROID_BUILD_TOOLS_VERSION = '23.0.3'
-
-# These are the "Android packages" needed for building Firefox for Android.
-# Use |android list sdk --extended| to see these identifiers.
-ANDROID_PACKAGES = [
-    'tools',
-    'platform-tools',
-    'build-tools-%s' % ANDROID_BUILD_TOOLS_VERSION,
-    'android-%s' % ANDROID_TARGET_SDK,
-    'extra-google-m2repository',
-    'extra-android-m2repository',
-]
-
 ANDROID_NDK_EXISTS = '''
 Looks like you have the Android NDK installed at:
 %s
 '''
 
 ANDROID_SDK_EXISTS = '''
 Looks like you have the Android SDK installed at:
 %s
@@ -153,103 +136,165 @@ def get_paths(os_name):
                                    os.path.expanduser(os.path.join('~', '.mozbuild')))
     sdk_path = os.environ.get('ANDROID_SDK_HOME',
                               os.path.join(mozbuild_path, 'android-sdk-{}'.format(os_name)))
     ndk_path = os.environ.get('ANDROID_NDK_HOME',
                               os.path.join(mozbuild_path, 'android-ndk-r11c'))
     return (mozbuild_path, sdk_path, ndk_path)
 
 
-def ensure_android(os_name, artifact_mode):
+def ensure_dir(dir):
+    '''Ensures the given directory exists'''
+    if dir and not os.path.exists(dir):
+        try:
+            os.makedirs(dir)
+        except OSError as error:
+            if error.errno != errno.EEXIST:
+                raise
+
+
+def ensure_android(os_name, artifact_mode=False, no_interactive=False):
     '''
     Ensure the Android SDK (and NDK, if `artifact_mode` is falsy) are
     installed.  If not, fetch and unpack the SDK and/or NDK from the
     given URLs.  Ensure the required Android SDK packages are
     installed.
 
     `os_name` can be 'linux' or 'macosx'.
     '''
     # The user may have an external Android SDK (in which case we
     # save them a lengthy download), or they may have already
     # completed the download. We unpack to
-    # ~/.mozbuild/{android-sdk-$OS_NAME, android-ndk-r11c}.
+    # ~/.mozbuild/{android-sdk-$OS_NAME, android-ndk-$VER}.
     mozbuild_path, sdk_path, ndk_path = get_paths(os_name)
     os_tag = 'darwin' if os_name == 'macosx' else os_name
     sdk_url = 'https://dl.google.com/android/repository/sdk-tools-{}-3859397.zip'.format(os_tag)
     ndk_url = android_ndk_url(os_name)
 
-    ensure_android_sdk_and_ndk(path=os.path.join(mozbuild_path, 'android-sdk-{}'.format(os_name)),
+    ensure_android_sdk_and_ndk(mozbuild_path, os_name,
                                sdk_path=sdk_path, sdk_url=sdk_url,
                                ndk_path=ndk_path, ndk_url=ndk_url,
                                artifact_mode=artifact_mode)
 
+    if no_interactive:
+        # Cribbed from observation and https://stackoverflow.com/a/38381577.
+        path = os.path.join(mozbuild_path, 'android-sdk-{}'.format(os_name), 'licenses')
+        ensure_dir(path)
+
+        licenses = {
+            'android-sdk-license': '8933bad161af4178b1185d1a37fbf41ea5269c55',
+            'android-sdk-preview-license': '84831b9409646a918e30573bab4c9c91346d8abd',
+        }
+        for license, tag in licenses.items():
+            lname = os.path.join(path, license)
+            if not os.path.isfile(lname):
+                open(lname, 'w').write('\n{}\n'.format(tag))
+
+
     # We expect the |sdkmanager| tool to be at
     # ~/.mozbuild/android-sdk-$OS_NAME/tools/bin/sdkmanager.
     sdkmanager_tool = os.path.join(sdk_path, 'tools', 'bin', 'sdkmanager')
     ensure_android_packages(sdkmanager_tool=sdkmanager_tool)
 
 
-def ensure_android_sdk_and_ndk(path, sdk_path, sdk_url, ndk_path, ndk_url, artifact_mode):
+def ensure_android_sdk_and_ndk(mozbuild_path, os_name, sdk_path, sdk_url, ndk_path, ndk_url, artifact_mode):
     '''
     Ensure the Android SDK and NDK are found at the given paths.  If not, fetch
-    and unpack the SDK and/or NDK from the given URLs into |path|.
+    and unpack the SDK and/or NDK from the given URLs into |mozbuild_path/{android-sdk-$OS_NAME,android-ndk-$VER}|.
     '''
 
     # It's not particularly bad to overwrite the NDK toolchain, but it does take
     # a while to unpack, so let's avoid the disk activity if possible.  The SDK
     # may prompt about licensing, so we do this first.
     # Check for Android NDK only if we are not in artifact mode.
     if not artifact_mode:
         if os.path.isdir(ndk_path):
             print(ANDROID_NDK_EXISTS % ndk_path)
         else:
-            install_mobile_android_sdk_or_ndk(ndk_url, path)
+            # The NDK archive unpacks into a top-level android-ndk-$VER directory.
+            install_mobile_android_sdk_or_ndk(ndk_url, mozbuild_path)
 
     # We don't want to blindly overwrite, since we use the
     # |sdkmanager| tool to install additional parts of the Android
     # toolchain.  If we overwrite, we lose whatever Android packages
     # the user may have already installed.
     if os.path.isfile(os.path.join(sdk_path, 'tools', 'bin', 'sdkmanager')):
         print(ANDROID_SDK_EXISTS % sdk_path)
     elif os.path.isdir(sdk_path):
         raise NotImplementedError(ANDROID_SDK_TOO_OLD % sdk_path)
     else:
-        install_mobile_android_sdk_or_ndk(sdk_url, path)
+        # The SDK archive used to include a top-level
+        # android-sdk-$OS_NAME directory; it no longer does so.  We
+        # preserve the old convention to smooth detecting existing SDK
+        # installations.
+        install_mobile_android_sdk_or_ndk(sdk_url, os.path.join(mozbuild_path, 'android-sdk-{}'.format(os_name)))
 
 
 def ensure_android_packages(sdkmanager_tool, packages=None):
     '''
     Use the given sdkmanager tool (like 'sdkmanager') to install required
     Android packages.
     '''
 
     # This tries to install all the required Android packages.  The user
     # may be prompted to agree to the Android license.
     package_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), 'android-packages.txt'))
-    print(package_file_name)
     print(INSTALLING_ANDROID_PACKAGES % open(package_file_name, 'rt').read())
     subprocess.check_call([sdkmanager_tool,
                            '--package_file={}'.format(package_file_name)])
 
 
 def suggest_mozconfig(os_name, artifact_mode=False):
     _mozbuild_path, sdk_path, ndk_path = get_paths(os_name)
     if artifact_mode:
         print(MOBILE_ANDROID_ARTIFACT_MODE_MOZCONFIG_TEMPLATE % (sdk_path))
     else:
         print(MOBILE_ANDROID_MOZCONFIG_TEMPLATE % (sdk_path, ndk_path))
 
 
 def android_ndk_url(os_name, ver='r11c'):
     # Produce a URL like
-    # 'https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip
+    # 'https://dl.google.com/android/repository/android-ndk-$VER-linux-x86_64.zip
     base_url = 'https://dl.google.com/android/repository/android-ndk'
 
     if os_name == 'macosx':
         # |mach bootstrap| uses 'macosx', but Google uses 'darwin'.
         os_name = 'darwin'
 
     if sys.maxsize > 2**32:
         arch = 'x86_64'
     else:
         arch = 'x86'
 
     return '%s-%s-%s-%s.zip' % (base_url, ver, os_name, arch)
+
+
+def main(argv):
+    import optparse # No argparse, which is new in Python 2.7.
+    import platform
+
+    parser = optparse.OptionParser()
+    parser.add_option('-a', '--artifact-mode', dest='artifact_mode', action='store_true',
+                      help='If true, install only the Android SDK (and not the Android NDK).')
+    parser.add_option('--no-interactive', dest='no_interactive', action='store_true',
+                      help='Accept the Android SDK licenses without user interaction.')
+
+    options, _ = parser.parse_args(argv)
+
+    os_name = None
+    if platform.system() == 'Darwin':
+        os_name = 'macosx'
+    elif platform.system() == 'Linux':
+        os_name = 'linux'
+    elif platform.system() == 'Windows':
+        os_name = 'windows'
+    else:
+        raise NotImplementedError("We don't support bootstrapping the Android SDK (or Android NDK) "
+                                  "on {} yet!".format(platform.system()))
+
+    ensure_android(os_name, artifact_mode=options.artifact_mode, no_interactive=options.no_interactive)
+    suggest_mozconfig(os_name, options.artifact_mode)
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
--- a/python/mozboot/mozboot/archlinux.py
+++ b/python/mozboot/mozboot/archlinux.py
@@ -118,17 +118,18 @@ class ArchlinuxBootstrapper(StyloInstall
                   'toolchain requires 32 bit binaries be enabled (see '
                   'https://wiki.archlinux.org/index.php/Android).  You may need to '
                   'manually enable the multilib repository following the instructions '
                   'at https://wiki.archlinux.org/index.php/Multilib.')
             raise e
 
         # 2. Android pieces.
         import android
-        android.ensure_android('linux', artifact_mode=artifact_mode)
+        android.ensure_android('linux', artifact_mode=artifact_mode,
+                               no_interactive=self.no_interactive)
 
     def suggest_mobile_android_mozconfig(self, artifact_mode=False):
         import android
         android.suggest_mozconfig('linux', artifact_mode=artifact_mode)
 
     def suggest_mobile_android_artifact_mode_mozconfig(self):
         self.suggest_mobile_android_mozconfig(artifact_mode=True)
 
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -146,17 +146,17 @@ ac_add_options --enable-artifact-builds
 # This should match OLDEST_NON_LEGACY_VERSION from
 # the hg setup wizard in version-control-tools.
 MODERN_MERCURIAL_VERSION = LooseVersion('3.7.3')
 
 # Upgrade Python older than this.
 MODERN_PYTHON_VERSION = LooseVersion('2.7.3')
 
 # Upgrade rust older than this.
-MODERN_RUST_VERSION = LooseVersion('1.18.0')
+MODERN_RUST_VERSION = LooseVersion('1.19.0')
 
 class BaseBootstrapper(object):
     """Base class for system bootstrappers."""
 
     def __init__(self, no_interactive=False):
         self.package_manager_updated = False
         self.no_interactive = no_interactive
         self.state_dir = None
--- a/python/mozboot/mozboot/centosfedora.py
+++ b/python/mozboot/mozboot/centosfedora.py
@@ -107,17 +107,18 @@ class CentOSFedoraBootstrapper(StyloInst
 
             self.run_as_root(['rpm', '-ivh', yasm])
 
     def ensure_mobile_android_packages(self, artifact_mode=False):
         # Install Android specific packages.
         self.dnf_install(*self.mobile_android_packages)
 
         import android
-        android.ensure_android('linux', artifact_mode=artifact_mode)
+        android.ensure_android('linux', artifact_mode=artifact_mode,
+                               no_interactive=self.no_interactive)
 
     def suggest_mobile_android_mozconfig(self, artifact_mode=False):
         import android
         android.suggest_mozconfig('linux', artifact_mode=artifact_mode)
 
     def suggest_mobile_android_artifact_mode_mozconfig(self):
         self.suggest_mobile_android_mozconfig(artifact_mode=True)
 
--- a/python/mozboot/mozboot/debian.py
+++ b/python/mozboot/mozboot/debian.py
@@ -122,17 +122,18 @@ class DebianBootstrapper(StyloInstall, B
         # http://developer.android.com/sdk/installing/index.html?pkg=tools.
         self.run_as_root(['dpkg', '--add-architecture', 'i386'])
         # After adding a new arch, the list of packages has to be updated
         self.apt_update()
         self.apt_install(*self.mobile_android_packages)
 
         # 2. Android pieces.
         import android
-        android.ensure_android('linux', artifact_mode=artifact_mode)
+        android.ensure_android('linux', artifact_mode=artifact_mode,
+                               no_interactive=self.no_interactive)
 
     def suggest_mobile_android_mozconfig(self, artifact_mode=False):
         import android
         android.suggest_mozconfig('linux', artifact_mode=artifact_mode)
 
     def suggest_mobile_android_artifact_mode_mozconfig(self):
         self.suggest_mobile_android_mozconfig(artifact_mode=True)
 
--- a/python/mozboot/mozboot/mach_commands.py
+++ b/python/mozboot/mozboot/mach_commands.py
@@ -18,20 +18,22 @@ class Bootstrap(object):
     """Bootstrap system and mach for optimal development experience."""
 
     @Command('bootstrap', category='devenv',
              description='Install required system packages for building.')
     @CommandArgument('--application-choice',
                      default=None,
                      help='Pass in an application choice (see mozboot.bootstrap.APPLICATIONS) '
                      'instead of using the default interactive prompt.')
-    def bootstrap(self, application_choice=None):
+    @CommandArgument('--no-interactive', dest='no_interactive', action='store_true',
+                     help='Answer yes to any (Y/n) interactive prompts.')
+    def bootstrap(self, application_choice=None, no_interactive=False):
         from mozboot.bootstrap import Bootstrapper
 
-        bootstrapper = Bootstrapper(choice=application_choice)
+        bootstrapper = Bootstrapper(choice=application_choice, no_interactive=no_interactive)
         bootstrapper.bootstrap()
 
 
 @CommandProvider
 class VersionControlCommands(object):
     def __init__(self, context):
         self._context = context
 
--- a/python/mozboot/mozboot/osx.py
+++ b/python/mozboot/mozboot/osx.py
@@ -349,17 +349,18 @@ class OSXBootstrapper(BaseBootstrapper):
             print(JAVA_LICENSE_NOTICE)  # We accepted a license agreement for the user.
 
         is_64bits = sys.maxsize > 2**32
         if not is_64bits:
             raise Exception('You need a 64-bit version of Mac OS X to build Firefox for Android.')
 
         # 2. Android pieces.
         import android
-        android.ensure_android('macosx', artifact_mode=artifact_mode)
+        android.ensure_android('macosx', artifact_mode=artifact_mode,
+                               no_interactive=self.no_interactive)
 
     def suggest_homebrew_mobile_android_mozconfig(self, artifact_mode=False):
         import android
         android.suggest_mozconfig('macosx', artifact_mode=artifact_mode)
 
     def _ensure_macports_packages(self, packages):
         self.port = self.which('port')
         assert self.port is not None
@@ -412,17 +413,18 @@ class OSXBootstrapper(BaseBootstrapper):
                             'to get the latest version.')
 
         is_64bits = sys.maxsize > 2**32
         if not is_64bits:
             raise Exception('You need a 64-bit version of Mac OS X to build Firefox for Android.')
 
         # 2. Android pieces.
         import android
-        android.ensure_android('macosx', artifact_mode=artifact_mode)
+        android.ensure_android('macosx', artifact_mode=artifact_mode,
+                               no_interactive=self.no_interactive)
 
     def suggest_macports_mobile_android_mozconfig(self, artifact_mode=False):
         import android
         android.suggest_mozconfig('macosx', artifact_mode=artifact_mode)
 
     def ensure_package_manager(self):
         '''
         Search package mgr in sys.path, if none is found, prompt the user to install one.
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -2,16 +2,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import argparse
 import collections
 import errno
+import hashlib
 import itertools
 import json
 import logging
 import operator
 import os
 import subprocess
 import sys
 
@@ -33,16 +34,17 @@ from mozbuild.base import (
     BuildEnvironmentNotFoundException,
     MachCommandBase,
     MachCommandConditions as conditions,
     MozbuildObject,
     MozconfigFindException,
     MozconfigLoadException,
     ObjdirMismatchException,
 )
+from mozbuild.util import ensureParentDir
 
 from mozbuild.backend import (
     backends,
     get_backend_class,
 )
 from mozbuild.shellutil import quote as shell_quote
 
 
@@ -1686,24 +1688,26 @@ class PackageFrontend(MachCommandBase):
     @CommandArgument('--authentication-file', metavar='FILE',
         help='Use the RelengAPI token found in the given file to authenticate')
     @CommandArgument('--tooltool-url', metavar='URL',
         help='Use the given url as tooltool server')
     @CommandArgument('--no-unpack', action='store_true',
         help='Do not unpack any downloaded file')
     @CommandArgument('--retry', type=int, default=0,
         help='Number of times to retry failed downloads')
+    @CommandArgument('--artifact-manifest', metavar='FILE',
+        help='Store a manifest about the downloaded taskcluster artifacts')
     @CommandArgument('files', nargs='*',
         help='A list of files to download, in the form path@task-id, in '
              'addition to the files listed in the tooltool manifest.')
     def artifact_toolchain(self, verbose=False, cache_dir=None,
                           skip_cache=False, from_build=(),
                           tooltool_manifest=None, authentication_file=None,
                           tooltool_url=None, no_unpack=False, retry=None,
-                          files=()):
+                          artifact_manifest=None, files=()):
         '''Download, cache and install pre-built toolchains.
         '''
         from mozbuild.artifacts import ArtifactCache
         from mozbuild.action.tooltool import (
             FileRecord,
             open_manifest,
             unpack_file,
         )
@@ -1911,37 +1915,57 @@ class PackageFrontend(MachCommandBase):
                 downloaded.append(record)
                 break
 
             if not valid:
                 self.log(logging.ERROR, 'artifact', {'name': record.basename},
                          'Failed to download {name}')
                 return 1
 
+        artifacts = {} if artifact_manifest else None
+
         for record in downloaded:
             local = os.path.join(os.getcwd(), record.basename)
             if os.path.exists(local):
                 os.unlink(local)
             # unpack_file needs the file with its final name to work
             # (https://github.com/mozilla/build-tooltool/issues/38), so we
             # need to copy it, even though we remove it later. Use hard links
             # when possible.
             try:
                 os.link(record.filename, local)
             except Exception:
                 shutil.copy(record.filename, local)
+            # Keep a sha256 of each downloaded file, for the chain-of-trust
+            # validation.
+            if artifact_manifest is not None:
+                with open(local) as fh:
+                    h = hashlib.sha256()
+                    while True:
+                        data = fh.read(1024 * 1024)
+                        if not data:
+                            break
+                        h.update(data)
+                artifacts[record.url] = {
+                    'sha256': h.hexdigest(),
+                }
             if record.unpack and not no_unpack:
                 unpack_file(local, record.setup)
                 os.unlink(local)
 
         if not downloaded:
             self.log(logging.ERROR, 'artifact', {}, 'Nothing to download')
             if files:
                 return 1
 
+        if artifacts:
+            ensureParentDir(artifact_manifest)
+            with open(artifact_manifest, 'w') as fh:
+                json.dump(artifacts, fh, indent=4, sort_keys=True)
+
         return 0
 
 
 @CommandProvider
 class Vendor(MachCommandBase):
     """Vendor third-party dependencies into the source repository."""
 
     @Command('vendor', category='misc',
--- a/python/mozbuild/mozbuild/mozconfig_loader
+++ b/python/mozbuild/mozbuild/mozconfig_loader
@@ -32,29 +32,16 @@ ac_add_app_options() {
   echo "$*"
   echo "------END_AC_APP_OPTION"
 }
 
 mk_add_options() {
   for _mozconfig_opt; do
     echo "------BEGIN_MK_OPTION"
     echo $_mozconfig_opt
-    # Remove any leading "export"
-    opt=${_mozconfig_opt#export}
-    case "$_mozconfig_opt" in
-    *\?=*) _mozconfig_op="?=" ;;
-    *:=*) _mozconfig_op=":=" ;;
-    *+=*) _mozconfig_op="+=" ;;
-    *=*) _mozconfig_op="=" ;;
-    esac
-    # Remove the operator and the value that follows
-    _mozconfig_name=${_mozconfig_opt%%${_mozconfig_op}*}
-    # Note: $(echo ${_mozconfig_name}) strips the variable from any leading and trailing
-    # whitespaces.
-    eval "$(echo ${_mozconfig_name})_IS_SET=1"
     echo "------END_MK_OPTION"
   done
 }
 
 echo "------BEGIN_ENV_BEFORE_SOURCE"
 $3 $4
 echo "------END_ENV_BEFORE_SOURCE"
 
--- a/python/mozbuild/mozbuild/test/test_mozconfig.py
+++ b/python/mozbuild/mozbuild/test/test_mozconfig.py
@@ -314,20 +314,16 @@ class TestMozconfigLoader(unittest.TestC
             mozconfig.write('mk_add_options BIZ=1\n')
             mozconfig.flush()
 
             result = self.get_loader().read_mozconfig(mozconfig.name)
             self.assertEqual(result['topobjdir'], '/foo/bar')
             self.assertEqual(result['make_flags'], ['-j8', '-s'])
             self.assertEqual(result['make_extra'], ['FOO=BAR BAZ', 'BIZ=1'])
 
-            vars = result['vars']['added']
-            for var in ('MOZ_OBJDIR', 'MOZ_MAKE_FLAGS', 'FOO', 'BIZ'):
-                self.assertEqual(vars.get('%s_IS_SET' % var), '1')
-
     def test_read_empty_mozconfig_objdir_environ(self):
         os.environ[b'MOZ_OBJDIR'] = b'obj-firefox'
         with NamedTemporaryFile(mode='w') as mozconfig:
             result = self.get_loader().read_mozconfig(mozconfig.name)
             self.assertEqual(result['topobjdir'], 'obj-firefox')
 
     def test_read_capture_mk_options_objdir_environ(self):
         """Ensures mk_add_options calls are captured and override the environ."""
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -3460,17 +3460,17 @@ dependencies = [
  "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
 version = "0.48.0"
-source = "git+https://github.com/servo/webrender#8fd634882111415a65da67e947f26eb170234f2f"
+source = "git+https://github.com/servo/webrender#283192c41743a59da87b065cbc14c659d94c90b5"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3489,17 +3489,17 @@ dependencies = [
  "thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "webrender_api"
 version = "0.48.0"
-source = "git+https://github.com/servo/webrender#8fd634882111415a65da67e947f26eb170234f2f"
+source = "git+https://github.com/servo/webrender#283192c41743a59da87b065cbc14c659d94c90b5"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -29,17 +29,17 @@ use std::collections::HashMap;
 use std::fmt;
 use std::sync::Arc;
 use style::computed_values::{border_style, image_rendering};
 use style::values::computed::Filter;
 use style_traits::cursor::Cursor;
 use text::TextRun;
 use text::glyph::ByteIndex;
 use webrender_api::{self, ClipId, ColorF, GradientStop, LocalClip, MixBlendMode, ScrollPolicy};
-use webrender_api::{TransformStyle, WebGLContextId};
+use webrender_api::{ScrollSensitivity, TransformStyle, WebGLContextId};
 
 pub use style::dom::OpaqueNode;
 
 /// The factor that we multiply the blur radius by in order to inflate the boundaries of display
 /// items that involve a blur. This ensures that the display item boundaries include all the ink.
 pub static BLUR_INFLATION_FACTOR: i32 = 3;
 
 #[derive(HeapSizeOf, Deserialize, Serialize)]
@@ -554,17 +554,17 @@ impl fmt::Debug for StackingContext {
                self.bounds,
                self.overflow,
                self.id)
     }
 }
 
 #[derive(Clone, Debug, HeapSizeOf, Deserialize, Serialize)]
 pub enum ScrollRootType {
-    ScrollFrame,
+    ScrollFrame(ScrollSensitivity),
     Clip,
 }
 
 /// Defines a stacking context.
 #[derive(Clone, Debug, HeapSizeOf, Deserialize, Serialize)]
 pub struct ScrollRoot {
     /// The WebRender clip id of this scroll root based on the source of this clip
     /// and information about the fragment.
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -66,17 +66,17 @@ use style::values::generics::image::{Cir
 use style::values::generics::image::{GradientItem as GenericGradientItem, GradientKind};
 use style::values::generics::image::{Image, ShapeExtent};
 use style::values::generics::image::PaintWorklet;
 use style::values::specified::position::{X, Y};
 use style_traits::CSSPixel;
 use style_traits::cursor::Cursor;
 use table_cell::CollapsedBordersForCell;
 use webrender_api::{ClipId, ColorF, ComplexClipRegion, GradientStop, LocalClip, RepeatMode};
-use webrender_api::{LineStyle, ScrollPolicy, TransformStyle};
+use webrender_api::{LineStyle, ScrollPolicy, ScrollSensitivity, TransformStyle};
 use webrender_helpers::{ToBorderRadius, ToMixBlendMode, ToRectF, ToTransformStyle};
 
 trait ResolvePercentage {
     fn resolve(&self, length: u32) -> u32;
 }
 
 impl ResolvePercentage for NumberOrPercentage {
     fn resolve(&self, length: u32) -> u32 {
@@ -2252,17 +2252,16 @@ pub trait BlockFlowDisplayListBuilding {
                                           preserved_state: &mut PreservedDisplayListState);
     fn setup_clipping_for_block(&mut self,
                                 state: &mut DisplayListBuildState,
                                 preserved_state: &mut PreservedDisplayListState,
                                 stacking_context_type: BlockStackingContextType)
                                 -> ClipId;
     fn setup_scroll_root_for_overflow(&mut self,
                                       state: &mut DisplayListBuildState,
-                                      preserved_state: &mut PreservedDisplayListState,
                                       border_box: &Rect<Au>);
     fn setup_scroll_root_for_css_clip(&mut self,
                                       state: &mut DisplayListBuildState,
                                       preserved_state: &mut PreservedDisplayListState,
                                       stacking_relative_border_box: &Rect<Au>);
     fn create_pseudo_stacking_context_for_block(&mut self,
                                                 parent_stacking_context_id: StackingContextId,
                                                 parent_scroll_root_id: ClipId,
@@ -2478,32 +2477,31 @@ impl BlockFlowDisplayListBuilding for Bl
             &self.base.early_absolute_position_info.relative_containing_block_size,
             self.base.early_absolute_position_info.relative_containing_block_mode,
             coordinate_system);
 
         if stacking_context_type == BlockStackingContextType::StackingContext {
             self.transform_clip_to_coordinate_space(state, preserved_state);
         }
 
-        self.setup_scroll_root_for_overflow(state, preserved_state, &stacking_relative_border_box);
+        self.setup_scroll_root_for_overflow(state, &stacking_relative_border_box);
         self.setup_scroll_root_for_css_clip(state, preserved_state, &stacking_relative_border_box);
         self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
 
         match self.positioning() {
             position::T::absolute | position::T::relative | position::T::fixed =>
                 state.containing_block_scroll_root_id = state.current_scroll_root_id,
             _ => {}
         }
 
         containing_scroll_root_id
     }
 
     fn setup_scroll_root_for_overflow(&mut self,
                                       state: &mut DisplayListBuildState,
-                                      preserved_state: &mut PreservedDisplayListState,
                                       border_box: &Rect<Au>) {
         if !self.overflow_style_may_require_scroll_root() {
             return;
         }
 
         let content_box = self.fragment.stacking_relative_content_box(&border_box);
         let has_scrolling_overflow =
             self.base.overflow.scroll.origin != Point2D::zero() ||
@@ -2521,53 +2519,41 @@ impl BlockFlowDisplayListBuilding for Bl
         // when fragments map to more than one flow, such as in the case of table
         // wrappers. We just accept the first scroll root in that case.
         let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip),
                                              state.layout_context.id.to_webrender());
         if state.has_scroll_root(new_scroll_root_id) {
             return;
         }
 
-        let overflow_x = self.fragment.style.get_box().overflow_x;
-        let overflow_y = self.fragment.style.get_box().overflow_y;
-
-        let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size;
-        let mut content_size = Size2D::new(content_size.x, content_size.y);
-        if overflow_x::T::hidden == overflow_x {
-            content_size.width = content_box.size.width;
-        }
-
-        if overflow_x::T::hidden == overflow_y {
-            content_size.height = content_box.size.height;
-        }
-
-        if overflow_x::T::hidden == overflow_y || overflow_x::T::hidden == overflow_x {
-            preserved_state.push_clip(state, &border_box, self.positioning());
-        }
-
-        let mut root_type = ScrollRootType::ScrollFrame;
-        if overflow_x::T::hidden == overflow_y && overflow_x::T::hidden == overflow_x {
-            root_type = ScrollRootType::Clip;
-        }
+        let sensitivity = if overflow_x::T::hidden == self.fragment.style.get_box().overflow_x &&
+                             overflow_x::T::hidden == self.fragment.style.get_box().overflow_y {
+            ScrollSensitivity::Script
+        } else {
+            ScrollSensitivity::ScriptAndInputEvents
+        };
 
         let clip_rect = build_inner_border_box_for_border_rect(&border_box, &self.fragment.style);
         let mut clip = ClippingRegion::from_rect(&clip_rect);
         let radii = build_border_radius_for_inner_rect(&border_box, &self.fragment.style);
         if !radii.is_square() {
             clip.intersect_with_rounded_rect(&clip_rect, &radii)
         }
 
+        let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size;
+        let content_size = Size2D::new(content_size.x, content_size.y);
+
         let parent_id = self.scroll_root_id(state.layout_context.id);
         state.add_scroll_root(
             ScrollRoot {
                 id: new_scroll_root_id,
                 parent_id: parent_id,
                 clip: clip,
                 content_rect: Rect::new(content_box.origin, content_size),
-                root_type,
+                root_type: ScrollRootType::ScrollFrame(sensitivity),
             },
             self.base.stacking_context_id
         );
 
         self.base.scroll_root_id = Some(new_scroll_root_id);
         state.current_scroll_root_id = new_scroll_root_id;
     }
 
--- a/servo/components/layout/webrender_helpers.rs
+++ b/servo/components/layout/webrender_helpers.rs
@@ -11,18 +11,18 @@ use app_units::Au;
 use euclid::{Point2D, Vector2D, Rect, SideOffsets2D, Size2D};
 use gfx::display_list::{BorderDetails, BorderRadii, BoxShadowClipMode, ClippingRegion};
 use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal, ScrollRootType};
 use gfx::display_list::StackingContextType;
 use msg::constellation_msg::PipelineId;
 use style::computed_values::{image_rendering, mix_blend_mode, transform_style};
 use style::values::computed::{BorderStyle, Filter};
 use style::values::generics::effects::Filter as GenericFilter;
-use webrender_api::{self, ComplexClipRegion, DisplayListBuilder, ExtendMode};
-use webrender_api::{LayoutTransform, ClipId};
+use webrender_api::{self, ClipId, ComplexClipRegion, DisplayListBuilder, ExtendMode};
+use webrender_api::LayoutTransform;
 
 pub trait WebRenderDisplayListConverter {
     fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
 }
 
 trait WebRenderDisplayItemConverter {
     fn convert_to_webrender(&self,
                             builder: &mut DisplayListBuilder,
@@ -185,17 +185,17 @@ trait ToFilterOps {
     fn to_filter_ops(&self) -> Vec<webrender_api::FilterOp>;
 }
 
 impl ToFilterOps for Vec<Filter> {
     fn to_filter_ops(&self) -> Vec<webrender_api::FilterOp> {
         let mut result = Vec::with_capacity(self.len());
         for filter in self.iter() {
             match *filter {
-                GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius)),
+                GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.to_f32_px())),
                 GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount)),
                 GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount)),
                 GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount)),
                 GenericFilter::HueRotate(angle) => result.push(webrender_api::FilterOp::HueRotate(angle.radians())),
                 GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount)),
                 GenericFilter::Opacity(amount) => result.push(webrender_api::FilterOp::Opacity(amount.into())),
                 GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount)),
                 GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount)),
@@ -501,22 +501,23 @@ impl WebRenderDisplayItemConverter for D
                 let our_id = item.scroll_root.id;
                 let webrender_id = match item.scroll_root.root_type {
                    ScrollRootType::Clip => {
                         builder.define_clip(Some(our_id),
                                             item.scroll_root.clip.main.to_rectf(),
                                             item.scroll_root.clip.get_complex_clips(),
                                             None)
                     }
-                    ScrollRootType::ScrollFrame => {
+                    ScrollRootType::ScrollFrame(scroll_sensitivity) => {
                         builder.define_scroll_frame(Some(our_id),
                                                     item.scroll_root.content_rect.to_rectf(),
                                                     item.scroll_root.clip.main.to_rectf(),
                                                     item.scroll_root.clip.get_complex_clips(),
-                                                    None)
+                                                    None,
+                                                    scroll_sensitivity)
                     }
                 };
                 debug_assert!(our_id == webrender_id);
 
                 builder.pop_clip_id();
             }
         }
     }
--- a/servo/components/selectors/matching.rs
+++ b/servo/components/selectors/matching.rs
@@ -88,32 +88,32 @@ impl<'a, 'b, Impl> LocalMatchingContext<
             nesting_level: 0,
             // We flip this off once third sequence is reached.
             hover_active_quirk_disabled: selector.has_pseudo_element(),
         }
     }
 
     /// Updates offset of Selector to show new compound selector.
     /// To be able to correctly re-synthesize main SelectorIter.
-    pub fn note_next_sequence(&mut self, selector_iter: &SelectorIter<Impl>) {
+    fn note_position(&mut self, selector_iter: &SelectorIter<Impl>) {
         if let QuirksMode::Quirks = self.shared.quirks_mode() {
             if self.selector.has_pseudo_element() && self.offset != 0 {
-                // This is the _second_ call to note_next_sequence,
+                // This is the _second_ call to note_position,
                 // which means we've moved past the compound
                 // selector adjacent to the pseudo-element.
                 self.hover_active_quirk_disabled = false;
             }
 
             self.offset = self.selector.len() - selector_iter.selector_length();
         }
     }
 
     /// Returns true if current compound selector matches :active and :hover quirk.
     /// https://quirks.spec.whatwg.org/#the-active-and-hover-quirk
-    pub fn active_hover_quirk_matches(&mut self) -> bool {
+    pub fn active_hover_quirk_matches(&self) -> bool {
         if self.shared.quirks_mode() != QuirksMode::Quirks {
             return false;
         }
 
         // Don't allow it in recursive selectors such as :not and :-moz-any.
         if self.nesting_level != 0 {
             return false;
         }
@@ -485,21 +485,22 @@ pub fn matches_complex_selector<E, F>(mu
         // The only other parser-allowed Component in this sequence is a state
         // class. We just don't match in that case.
         if let Some(s) = iter.next() {
             debug_assert!(matches!(*s, Component::NonTSPseudoClass(..)),
                           "Someone messed up pseudo-element parsing");
             return false;
         }
 
-        // Advance to the non-pseudo-element part of the selector, and inform the context.
+        // Advance to the non-pseudo-element part of the selector, and inform
+        // the context.
         if iter.next_sequence().is_none() {
             return true;
         }
-        context.note_next_sequence(&mut iter);
+        context.note_position(&iter);
     }
 
     match matches_complex_selector_internal(iter,
                                             element,
                                             context,
                                             &mut RelevantLinkStatus::Looking,
                                             flags_setter) {
         SelectorMatchingResult::Matched => true,
@@ -521,18 +522,16 @@ fn matches_complex_selector_internal<E, 
     let matches_all_simple_selectors = selector_iter.all(|simple| {
         matches_simple_selector(simple, element, context, &relevant_link, flags_setter)
     });
 
     debug!("Matching for {:?}, simple selector {:?}, relevant link {:?}",
            element, selector_iter, relevant_link);
 
     let combinator = selector_iter.next_sequence();
-    // Inform the context that the we've advanced to the next compound selector.
-    context.note_next_sequence(&mut selector_iter);
     let siblings = combinator.map_or(false, |c| c.is_sibling());
     if siblings {
         flags_setter(element, HAS_SLOW_SELECTOR_LATER_SIBLINGS);
     }
 
     if !matches_all_simple_selectors {
         return SelectorMatchingResult::NotMatchedAndRestartFromClosestLaterSibling;
     }
@@ -562,16 +561,18 @@ fn matches_complex_selector_internal<E, 
                 }
             };
 
             loop {
                 let element = match next_element {
                     None => return candidate_not_found,
                     Some(next_element) => next_element,
                 };
+                // Note in which compound selector are we currently.
+                context.note_position(&selector_iter);
                 let result = matches_complex_selector_internal(selector_iter.clone(),
                                                                &element,
                                                                context,
                                                                relevant_link,
                                                                flags_setter);
                 match (result, c) {
                     // Return the status immediately.
                     (SelectorMatchingResult::Matched, _) => return result,
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -2114,16 +2114,69 @@ fn static_assert() {
         use gecko_bindings::bindings::Gecko_CopyAlternateValuesFrom;
 
         self.gecko.mFont.variantAlternates = other.gecko.mFont.variantAlternates;
         unsafe {
             Gecko_CopyAlternateValuesFrom(&mut self.gecko.mFont, &other.gecko.mFont);
         }
     }
 
+    pub fn clone_font_variant_alternates(&self) -> longhands::font_variant_alternates::computed_value::T {
+        use Atom;
+        % for value in "normal swash stylistic ornaments annotation styleset character_variant historical".split():
+            use gecko_bindings::structs::NS_FONT_VARIANT_ALTERNATES_${value.upper()};
+        % endfor
+        use properties::longhands::font_variant_alternates::VariantAlternates;
+        use properties::longhands::font_variant_alternates::VariantAlternatesList;
+        use values::CustomIdent;
+
+        if self.gecko.mFont.variantAlternates == NS_FONT_VARIANT_ALTERNATES_NORMAL as u16 {
+            return VariantAlternatesList(vec![].into_boxed_slice());
+        }
+
+        let mut alternates = Vec::with_capacity(self.gecko.mFont.alternateValues.len());
+        if self.gecko.mFont.variantAlternates & (NS_FONT_VARIANT_ALTERNATES_HISTORICAL as u16) != 0 {
+            alternates.push(VariantAlternates::HistoricalForms);
+        }
+
+        <%
+            property_need_ident_list = "styleset character_variant".split()
+        %>
+        % for value in property_need_ident_list:
+            let mut ${value}_list = Vec::new();
+        % endfor
+
+        for gecko_alternate_value in self.gecko.mFont.alternateValues.iter() {
+            let ident = Atom::from(gecko_alternate_value.value.to_string());
+            match gecko_alternate_value.alternate {
+                % for value in "Swash Stylistic Ornaments Annotation".split():
+                    NS_FONT_VARIANT_ALTERNATES_${value.upper()} => {
+                        alternates.push(VariantAlternates::${value}(CustomIdent(ident)));
+                    },
+                % endfor
+                % for value in property_need_ident_list:
+                    NS_FONT_VARIANT_ALTERNATES_${value.upper()} => {
+                        ${value}_list.push(CustomIdent(ident));
+                    },
+                % endfor
+                x => {
+                    panic!("Found unexpected value for font-variant-alternates: {:?}", x);
+                }
+            }
+        }
+
+        % for value in property_need_ident_list:
+            if !${value}_list.is_empty() {
+                alternates.push(VariantAlternates::${to_camel_case(value)}(${value}_list.into_boxed_slice()));
+            }
+        % endfor
+
+        VariantAlternatesList(alternates.into_boxed_slice())
+    }
+
     ${impl_simple_type_with_conversion("font_variant_ligatures", "mFont.variantLigatures")}
     ${impl_simple_type_with_conversion("font_variant_east_asian", "mFont.variantEastAsian")}
     ${impl_simple_type_with_conversion("font_variant_numeric", "mFont.variantNumeric")}
 
     #[allow(non_snake_case)]
     pub fn set__moz_min_font_size_ratio(&mut self, v: longhands::_moz_min_font_size_ratio::computed_value::T) {
         let percentage = if v.0 > 255. {
             255.
@@ -3718,24 +3771,24 @@ fn static_assert() {
                 if let Some(top) = rect.top {
                     self.gecko.mClip.y = top.0;
                 } else {
                     self.gecko.mClip.y = 0;
                     self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
                 }
 
                 if let Some(bottom) = rect.bottom {
-                    self.gecko.mClip.height = bottom.0 - self.gecko.mClip.y;
+                    self.gecko.mClip.height = (bottom - Au(self.gecko.mClip.y)).0;
                 } else {
                     self.gecko.mClip.height = 1 << 30; // NS_MAXSIZE
                     self.gecko.mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO as u8;
                 }
 
                 if let Some(right) = rect.right {
-                    self.gecko.mClip.width = right.0 - self.gecko.mClip.x;
+                    self.gecko.mClip.width = (right - Au(self.gecko.mClip.x)).0;
                 } else {
                     self.gecko.mClip.width = 1 << 30; // NS_MAXSIZE
                     self.gecko.mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO as u8;
                 }
             },
             Either::Second(_auto) => {
                 self.gecko.mClipFlags = NS_STYLE_CLIP_AUTO as u8;
                 self.gecko.mClip.x = 0;
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -1257,17 +1257,17 @@ macro_rules! impl_gecko_keyword_conversi
                                 "auto none normal",
                                 products="gecko",
                                 gecko_ffi_name="mFont.kerning",
                                 gecko_constant_prefix="NS_FONT_KERNING",
                                 spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning",
                                 flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
                                 animation_value_type="discrete")}
 
-<%helpers:longhand name="font-variant-alternates" products="gecko" animation_value_type="none"
+<%helpers:longhand name="font-variant-alternates" products="gecko" animation_value_type="discrete"
                    flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
                    spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates">
     use properties::longhands::system_font::SystemFont;
     use std::fmt;
     use style_traits::ToCss;
     use values::CustomIdent;
 
     no_viewport_percentage!(SpecifiedValue);
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2774,18 +2774,23 @@ pub extern "C" fn Servo_TakeChangeHint(e
     let element = GeckoElement(element);
 
     let damage = match element.mutate_data() {
         Some(mut data) => {
             *was_restyled = data.restyle.is_restyle();
 
             let damage = data.restyle.damage;
             if restyle_behavior == structs::TraversalRestyleBehavior::ForThrottledAnimationFlush {
-                debug_assert!(data.restyle.is_restyle() || damage.is_empty(),
-                              "Restyle damage should be empty if the element was not restyled");
+                if !*was_restyled {
+                    // Don't touch elements if the element was not restyled
+                    // in throttled animation flush.
+                    debug!("Skip post traversal for throttled animation flush {:?} restyle={:?}",
+                           element, data.restyle);
+                    return nsChangeHint(0);
+                }
                 // In the case where we call this function for post traversal for
                 // flusing throttled animations (i.e. without normal restyle
                 // traversal), we need to preserve restyle hints for normal restyle
                 // traversal. Restyle hints for animations have been already
                 // removed during animation-only traversal.
                 debug_assert!(!data.restyle.hint.has_animation_hint(),
                               "Animation restyle hints should have been already removed");
                 data.clear_restyle_flags_and_damage();
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -135,8 +135,28 @@ linux64-libdmg:
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-libdmg-hfsplus.sh
         toolchain-artifact: public/build/dmg.tar.xz
+
+linux64-sccache:
+    description: "sccache toolchain build"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TL(sccache)
+        tier: 2
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: desktop-build}
+        max-run-time: 36000
+        env:
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/linux64/clang.manifest"
+    run:
+        using: toolchain-script
+        script: build-sccache.sh
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+        toolchain-artifact: public/build/sccache2.tar.xz
--- a/taskcluster/ci/toolchain/windows.yml
+++ b/taskcluster/ci/toolchain/windows.yml
@@ -82,8 +82,27 @@ win64-clang-tidy:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/build-clang-cl.manifest"
     run:
         using: toolchain-script
         script: build-clang-tidy64-windows.sh
         resources:
             - 'build/build-clang/**'
             - 'taskcluster/scripts/misc/build-clang-windows-helper64.sh'
         toolchain-artifact: public/build/clang-tidy.tar.bz2
+
+win64-sccache:
+    description: "sccache toolchain build"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TW64(sccache)
+        tier: 2
+    worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
+    worker:
+        max-run-time: 36000
+        env:
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
+    run:
+        using: toolchain-script
+        script: build-sccache.sh
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+        toolchain-artifact: public/build/sccache2.tar.bz2
new file mode 100755
--- /dev/null
+++ b/taskcluster/scripts/misc/build-sccache.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+set -x -e -v
+
+SCCACHE_REVISION=69334a26ba65fc88e3934271a2ce6781c51b445e
+
+# This script is for building sccache
+
+case "$(uname -s)" in
+Linux)
+    WORKSPACE=$HOME/workspace
+    UPLOAD_DIR=$HOME/artifacts
+    export CC=clang
+    PATH="$WORKSPACE/build/src/clang/bin:$PATH"
+    COMPRESS_EXT=xz
+    ;;
+MINGW*)
+    WORKSPACE=$PWD
+    UPLOAD_DIR=$WORKSPACE/public/build
+    WIN_WORKSPACE="$(pwd -W)"
+    COMPRESS_EXT=bz2
+
+    export INCLUDE="$WIN_WORKSPACE/build/src/vs2015u3/VC/include;$WIN_WORKSPACE/build/src/vs2015u3/VC/atlmfc/include;$WIN_WORKSPACE/build/src/vs2015u3/SDK/Include/10.0.14393.0/ucrt;$WIN_WORKSPACE/build/src/vs2015u3/SDK/Include/10.0.14393.0/shared;$WIN_WORKSPACE/build/src/vs2015u3/SDK/Include/10.0.14393.0/um;$WIN_WORKSPACE/build/src/vs2015u3/SDK/Include/10.0.14393.0/winrt;$WIN_WORKSPACE/build/src/vs2015u3/DIA SDK/include"
+
+    export LIB="$WIN_WORKSPACE/build/src/vs2015u3/VC/lib/amd64;$WIN_WORKSPACE/build/src/vs2015u3/VC/atlmfc/lib/amd64;$WIN_WORKSPACE/build/src/vs2015u3/SDK/lib/10.0.14393.0/um/x64;$WIN_WORKSPACE/build/src/vs2015u3/SDK/lib/10.0.14393.0/ucrt/x64;$WIN_WORKSPACE/build/src/vs2015u3/DIA SDK/lib/amd64"
+
+    PATH="$WORKSPACE/build/src/vs2015u3/VC/bin/amd64:$WORKSPACE/build/src/vs2015u3/VC/bin:$WORKSPACE/build/src/vs2015u3/SDK/bin/x64:$WORKSPACE/build/src/vs2015u3/redist/x64/Microsoft.VC140.CRT:$WORKSPACE/build/src/vs2015u3/SDK/Redist/ucrt/DLLs/x64:$WORKSPACE/build/src/vs2015u3/DIA SDK/bin/amd64:$WORKSPACE/build/src/mingw64/bin:$PATH"
+    ;;
+esac
+
+cd $WORKSPACE/build/src
+
+. taskcluster/scripts/misc/tooltool-download.sh
+
+PATH="$PWD/rustc/bin:$PATH"
+
+git clone https://github.com/mozilla/sccache sccache
+
+cd sccache
+
+git checkout $SCCACHE_REVISION
+
+cargo build --verbose --release
+
+mkdir sccache2
+cp target/release/sccache* sccache2/
+tar -acf sccache2.tar.$COMPRESS_EXT sccache2
+mkdir -p $UPLOAD_DIR
+cp sccache2.tar.$COMPRESS_EXT $UPLOAD_DIR
--- a/taskcluster/scripts/misc/tooltool-download.sh
+++ b/taskcluster/scripts/misc/tooltool-download.sh
@@ -18,14 +18,18 @@ if [ -e "$TOOLTOOL_AUTH_FILE" ]; then
     TOOLTOOL_DL_FLAGS="${TOOLTOOL_DL_FLAGS=} --authentication-file=$TOOLTOOL_AUTH_FILE"
 fi
 
 if [ -n "$RELENGAPI_PORT" ]; then
     # When the worker has the relengapi proxy setup, use it.
     TOOLTOOL_DL_FLAGS="${TOOLTOOL_DL_FLAGS=} --tooltool-url=http://relengapi/tooltool/"
 fi
 
+if [ -n "$UPLOAD_DIR" ]; then
+    TOOLTOOL_DL_FLAGS="${TOOLTOOL_DL_FLAGS=} --artifact-manifest $UPLOAD_DIR/toolchains.json"
+fi
+
 : TOOLTOOL_CACHE                ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache}
 export TOOLTOOL_CACHE
 
 ./mach artifact toolchain -v${TOOLTOOL_DL_FLAGS} --tooltool-manifest "${TOOLTOOL_MANIFEST}"${TOOLTOOL_CACHE:+ --cache-dir ${TOOLTOOL_CACHE}} --retry 5${MOZ_TOOLCHAINS:+ ${MOZ_TOOLCHAINS}}
 
 cd $OLDPWD
--- a/taskcluster/taskgraph/transforms/job/toolchain.py
+++ b/taskcluster/taskgraph/transforms/job/toolchain.py
@@ -75,16 +75,17 @@ def add_optimizations(config, run, taskd
 @run_job_using("docker-worker", "toolchain-script", schema=toolchain_run_schema)
 def docker_worker_toolchain(config, job, taskdesc):
     run = job['run']
     taskdesc['run-on-projects'] = ['trunk', 'try']
 
     worker = taskdesc['worker']
     worker['artifacts'] = []
     worker['caches'] = []
+    worker['chain-of-trust'] = True
 
     docker_worker_add_public_artifacts(config, job, taskdesc)
     docker_worker_add_tc_vcs_cache(config, job, taskdesc)
     docker_worker_add_gecko_vcs_env_vars(config, job, taskdesc)
     support_vcs_checkout(config, job, taskdesc)
 
     env = worker['env']
     env.update({
@@ -141,16 +142,17 @@ def windows_toolchain(config, job, taskd
     taskdesc['run-on-projects'] = ['trunk', 'try']
 
     worker = taskdesc['worker']
 
     worker['artifacts'] = [{
         'path': r'public\build',
         'type': 'directory',
     }]
+    worker['chain-of-trust'] = True
 
     docker_worker_add_gecko_vcs_env_vars(config, job, taskdesc)
 
     # We fetch LLVM SVN into this.
     svn_cache = 'level-{}-toolchain-clang-cl-build-svn'.format(config.params['level'])
     worker['mounts'] = [{
         'cache-name': svn_cache,
         'directory': r'llvm-sources',
--- a/testing/mozharness/configs/developer_config.py
+++ b/testing/mozharness/configs/developer_config.py
@@ -35,15 +35,16 @@ config = {
     "virtualenv_path": '%s/build/venv' % os.getcwd(),
     "preflight_run_cmd_suites": [],
     "postflight_run_cmd_suites": [],
 
     # Tooltool related
     "download_tooltool": True,
     "tooltool_cache": os.path.join(LOCAL_WORKDIR, "builds/tooltool_cache"),
     "tooltool_cache_path": os.path.join(LOCAL_WORKDIR, "builds/tooltool_cache"),
+    "tooltool_authentication_file": os.path.join(LOCAL_WORKDIR, "relengapi.tok"),
 
     # VCS tools
     "gittool.py": 'http://hg.mozilla.org/build/puppet/raw-file/faaf5abd792e/modules/packages/files/gittool.py',
 
     # Android related
     "host_utils_url": "https://api.pub.build.mozilla.org/tooltool/sha512/372c89f9dccaf5ee3b9d35fd1cfeb089e1e5db3ff1c04e35aa3adc8800bc61a2ae10e321f37ae7bab20b56e60941f91bb003bcb22035902a73d70872e7bd3282",
 }
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1126,16 +1126,18 @@ or run without that action (ie: --no-{ac
             sys.executable, '-u',
             os.path.join(dirs['abs_src_dir'], 'mach'),
             'artifact',
             'toolchain',
             '-v',
             '--retry', '4',
             '--tooltool-manifest',
             tooltool_manifest_path,
+            '--artifact-manifest',
+            os.path.join(dirs['abs_src_dir'], 'toolchains.json'),
             '--tooltool-url',
             c['tooltool_url'],
         ]
         auth_file = self._get_tooltool_auth_file()
         if auth_file:
             cmd.extend(['--authentication-file', auth_file])
         cache = c['env'].get('TOOLTOOL_CACHE')
         if cache:
--- a/testing/mozharness/mozharness/mozilla/tooltool.py
+++ b/testing/mozharness/mozharness/mozilla/tooltool.py
@@ -81,16 +81,18 @@ class TooltoolMixin(object):
 
         # handle authentication file, if given
         auth_file = self._get_auth_file()
         if auth_file and os.path.exists(auth_file):
             cmd.extend(['--authentication-file', auth_file])
 
         if self.topsrcdir:
             cmd.extend(['--tooltool-manifest', manifest])
+            cmd.extend(['--artifact-manifest',
+                        os.path.join(self.topsrcdir, 'toolchains.json')])
         else:
             cmd.extend(['fetch', '-m', manifest, '-o'])
 
         if cache:
             cmd.extend(['--cache-dir' if self.topsrcdir else '-c', cache])
 
         toolchains = os.environ.get('MOZ_TOOLCHAINS')
         if toolchains:
--- a/testing/mozharness/scripts/desktop_l10n.py
+++ b/testing/mozharness/scripts/desktop_l10n.py
@@ -1072,16 +1072,18 @@ class DesktopSingleLocale(LocalesMixin, 
             python, '-u',
             os.path.join(dirs['abs_mozilla_dir'], 'mach'),
             'artifact',
             'toolchain',
             '-v',
             '--retry', '4',
             '--tooltool-manifest',
             tooltool_manifest_path,
+            '--artifact-manifest',
+            os.path.join(dirs['abs_mozilla_dir'], 'toolchains.json'),
             '--tooltool-url',
             config['tooltool_url'],
         ]
         auth_file = self._get_tooltool_auth_file()
         if auth_file and os.path.exists(auth_file):
             cmd.extend(['--authentication-file', auth_file])
         cache = config['bootstrap_env'].get('TOOLTOOL_CACHE')
         if cache:
--- a/testing/mozharness/scripts/repackage.py
+++ b/testing/mozharness/scripts/repackage.py
@@ -101,16 +101,18 @@ class Repackage(BaseScript):
             sys.executable, '-u',
             os.path.join(dirs['abs_mozilla_dir'], 'mach'),
             'artifact',
             'toolchain',
             '-v',
             '--retry', '4',
             '--tooltool-manifest',
             tooltool_manifest_path,
+            '--artifact-manifest',
+            os.path.join(dirs['abs_mozilla_dir'], 'toolchains.json'),
             '--tooltool-url',
             config['tooltool_url'],
         ]
         auth_file = self._get_tooltool_auth_file()
         if auth_file:
             cmd.extend(['--authentication-file', auth_file])
         cache = config.get('tooltool_cache')
         if cache:
--- a/testing/talos/talos/cmdline.py
+++ b/testing/talos/talos/cmdline.py
@@ -120,17 +120,17 @@ def create_parser(mach_interface=False):
     add_arg('--setpref', action='append', default=[], dest="extraPrefs",
             metavar="PREF=VALUE",
             help="defines an extra user preference")
     add_arg('--mitmproxy',
             help='Test uses mitmproxy to serve the pages, specify the '
                  'path and name of the mitmdump file to playback')
     add_arg('--mitmdumpPath',
             help="Path to mitmproxy's mitmdump playback tool")
-    add_arg("--firstNonBlankPaint", action='store_true', dest="first_non_blank_paint",
+    add_arg("--firstNonBlankPaint", action='store_true', dest="fnbpaint",
             help="Wait for firstNonBlankPaint event before recording the time")
     add_arg('--webServer', dest='webserver',
             help="DEPRECATED")
     if not mach_interface:
         add_arg('--develop', action='store_true', default=False,
                 help="useful for running tests on a developer machine."
                      " Doesn't upload to the graph servers.")
     add_arg("--cycles", type=int,
--- a/testing/talos/talos/config.py
+++ b/testing/talos/talos/config.py
@@ -34,16 +34,17 @@ DEFAULTS = dict(
         resolution=1,
         rss=False,
         mainthread=False,
         shutdown=False,
         timeout=3600,
         tpchrome=True,
         tpcycles=10,
         tpmozafterpaint=False,
+        fnbpaint=False,
         firstpaint=False,
         userready=False,
         testeventmap=[],
         base_vs_ref=False,
         tpdisable_e10s=False,
         tpnoisy=True,
         tppagecycles=1,
         tploadnocache=False,
@@ -202,16 +203,17 @@ GLOBAL_OVERRIDES = (
     'mainthread',
     'shutdown',
     'tpcycles',
     'tpdelay',
     'tppagecycles',
     'tpmanifest',
     'tptimeout',
     'tpmozafterpaint',
+    'fnbpaint',
     'firstpaint',
     'userready',
 )
 
 
 CONF_VALIDATORS = []
 
 
@@ -356,23 +358,26 @@ def build_manifest(config, manifestName)
     # return new manifest
     return newManifestName
 
 
 def get_test(config, global_overrides, counters, test_instance):
     mozAfterPaint = getattr(test_instance, 'tpmozafterpaint', None)
     firstPaint = getattr(test_instance, 'firstpaint', None)
     userReady = getattr(test_instance, 'userready', None)
+    firstNonBlankPaint = getattr(test_instance, 'fnbpaint', None)
 
     test_instance.update(**global_overrides)
 
     # update original value of mozAfterPaint, this could be 'false',
     # so check for None
     if mozAfterPaint is not None:
         test_instance.tpmozafterpaint = mozAfterPaint
+    if firstNonBlankPaint is not None:
+        test_instance.fnbpaint = firstNonBlankPaint
     if firstPaint is not None:
         test_instance.firstpaint = firstPaint
     if userReady is not None:
         test_instance.userready = userReady
 
     # fix up url
     url = getattr(test_instance, 'url', None)
     if url:
--- a/testing/talos/talos/pageloader/chrome/pageloader.js
+++ b/testing/talos/talos/pageloader/chrome/pageloader.js
@@ -38,16 +38,17 @@ var report;
 var noisy = false;
 var timeout = -1;
 var delay = 250;
 var running = false;
 var forceCC = true;
 var reportRSS = true;
 
 var useMozAfterPaint = false;
+var useFNBPaint = false;
 var gPaintWindow = window;
 var gPaintListener = false;
 var loadNoCache = false;
 var scrollTest = false;
 var gDisableE10S = false;
 var gUseE10S = false;
 var profilingInfo = false;
 
@@ -144,16 +145,17 @@ function plInit() {
     if (args.numPageCycles) numPageCycles = parseInt(args.numPageCycles);
     if (args.width) winWidth = parseInt(args.width);
     if (args.height) winHeight = parseInt(args.height);
     if (args.filter) pageFilterRegexp = new RegExp(args.filter);
     if (args.noisy) noisy = true;
     if (args.timeout) timeout = parseInt(args.timeout);
     if (args.delay) delay = parseInt(args.delay);
     if (args.mozafterpaint) useMozAfterPaint = true;
+    if (args.fnbpaint) useFNBPaint = true;
     if (args.rss) reportRSS = true;
     if (args.loadnocache) loadNoCache = true;
     if (args.scrolltest) scrollTest = true;
     if (args.disableE10S) gDisableE10S = true;
     if (args.profilinginfo) profilingInfo = JSON.parse(args.profilinginfo)
 
     if (profilingInfo) {
       TalosParentProfiler.initFromObject(profilingInfo);
@@ -257,46 +259,66 @@ function plInit() {
         browserWindow.focus();
 
         content = browserWindow.getBrowser();
         gUseE10S = !gDisableE10S || (plPageFlags() & EXECUTE_SCROLL_TEST) ||
                     (content.selectedBrowser &&
                     content.selectedBrowser.getAttribute("remote") == "true")
 
         // Load the frame script for e10s / IPC message support
-        if (gUseE10S) {
-          let contentScript = "data:,function _contentLoadHandler(e) { " +
-            "  if (e.originalTarget.defaultView == content) { " +
-            "    content.wrappedJSObject.tpRecordTime = function(t, s, n) { sendAsyncMessage('PageLoader:RecordTime', { time: t, startTime: s, testName: n }); }; ";
-          if (useMozAfterPaint) {
-            contentScript += "" +
-            "function _contentPaintHandler() { " +
-            "  var utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils); " +
-            "  if (utils.isMozAfterPaintPending) { " +
-            "    addEventListener('MozAfterPaint', function(e) { " +
-            "      removeEventListener('MozAfterPaint', arguments.callee, true); " +
-            "      sendAsyncMessage('PageLoader:LoadEvent', {}); " +
-            "    }, true); " +
-            "  } else { " +
-            "    sendAsyncMessage('PageLoader:LoadEvent', {}); " +
-            "  } " +
-            "}; " +
-            "content.setTimeout(_contentPaintHandler, 0); ";
-          } else {
-            contentScript += "    sendAsyncMessage('PageLoader:LoadEvent', {}); ";
-          }
+        let contentScript = "data:,function _contentLoadHandler(e) { " +
+          "  if (e.originalTarget.defaultView == content) { " +
+          "    content.wrappedJSObject.tpRecordTime = function(t, s, n) { sendAsyncMessage('PageLoader:RecordTime', { time: t, startTime: s, testName: n }); }; ";
+        if (useFNBPaint) {
           contentScript += "" +
-            "  }" +
-            "} " +
-            "addEventListener('load', _contentLoadHandler, true); ";
-          content.selectedBrowser.messageManager.loadFrameScript(contentScript, false, true);
-          content.selectedBrowser.messageManager.loadFrameScript("chrome://pageloader/content/talos-content.js", false);
-          content.selectedBrowser.messageManager.loadFrameScript("chrome://pageloader/content/tscroll.js", false, true);
-          content.selectedBrowser.messageManager.loadFrameScript("chrome://talos-powers-content/content/TalosContentProfiler.js", false, true);
+          "var gRetryCounter = 0; " +
+          "function _contentFNBPaintHandler() { " +
+          "  x = content.window.performance.timing.timeToNonBlankPaint; " +
+          "  if (typeof x == 'undefined') { " +
+          "    sendAsyncMessage('PageLoader:FNBPaintError', {}); " +
+          "  } " +
+          "  if (x > 0) { " +
+          "    sendAsyncMessage('PageLoader:LoadEvent', { 'fnbpaint': x }); " +
+          "  } else { " +
+          "    gRetryCounter += 1; " +
+          "    if (gRetryCounter <= 10) { " +
+          "      dump('fnbpaint is not yet available (0), retry number ' + gRetryCounter + '...\\n'); " +
+          "      content.setTimeout(_contentFNBPaintHandler, 100); " +
+          "    } else { " +
+          "      dump('unable to get a value for fnbpaint after ' + gRetryCounter + ' retries\\n'); " +
+          "      sendAsyncMessage('PageLoader:FNBPaintError', {}); " +
+          "    } " +
+          "  } " +
+          "}; " +
+          "content.setTimeout(_contentFNBPaintHandler, 0); ";
+        } else if (useMozAfterPaint) {
+          contentScript += "" +
+          "function _contentPaintHandler() { " +
+          "  var utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils); " +
+          "  if (utils.isMozAfterPaintPending) { " +
+          "    addEventListener('MozAfterPaint', function(e) { " +
+          "      removeEventListener('MozAfterPaint', arguments.callee, true); " +
+          "      sendAsyncMessage('PageLoader:LoadEvent', {}); " +
+          "    }, true); " +
+          "  } else { " +
+          "    sendAsyncMessage('PageLoader:LoadEvent', {}); " +
+          "  } " +
+          "}; " +
+          "content.setTimeout(_contentPaintHandler, 0); ";
+        } else {
+          contentScript += "    sendAsyncMessage('PageLoader:LoadEvent', {}); ";
         }
+        contentScript += "" +
+          "  }" +
+          "} " +
+          "addEventListener('load', _contentLoadHandler, true); ";
+        content.selectedBrowser.messageManager.loadFrameScript(contentScript, false, true);
+        content.selectedBrowser.messageManager.loadFrameScript("chrome://pageloader/content/talos-content.js", false);
+        content.selectedBrowser.messageManager.loadFrameScript("chrome://pageloader/content/tscroll.js", false, true);
+        content.selectedBrowser.messageManager.loadFrameScript("chrome://pageloader/content/Profiler.js", false, true);
 
         if (reportRSS) {
           initializeMemoryCollector(plLoadPage, 100);
         } else {
           setTimeout(plLoadPage, 100);
         }
       }, 500);
     };
@@ -311,16 +333,17 @@ function plInit() {
 function plPageFlags() {
   return pages[pageIndex].flags;
 }
 
 var ContentListener = {
   receiveMessage(message) {
     switch (message.name) {
       case "PageLoader:LoadEvent": return plLoadHandlerMessage(message);
+      case "PageLoader:FNBPaintError": return plFNBPaintErrorMessage(message);
       case "PageLoader:RecordTime": return plRecordTimeMessage(message);
     }
     return undefined;
   },
 };
 
 // load the current page, start timing
 var removeLastAddedListener = null;
@@ -337,54 +360,31 @@ function plLoadPage() {
     removeLastAddedListener = null;
   }
 
   if (removeLastAddedMsgListener) {
     removeLastAddedMsgListener();
     removeLastAddedMsgListener = null;
   }
 
-  if ((plPageFlags() & TEST_DOES_OWN_TIMING) && !gUseE10S) {
-    // if the page does its own timing, use a capturing handler
-    // to make sure that we can set up the function for content to call
-
-    content.addEventListener("load", plLoadHandlerCapturing, true);
-    removeLastAddedListener = function() {
-      content.removeEventListener("load", plLoadHandlerCapturing, true);
-      if (useMozAfterPaint) {
-        content.removeEventListener("MozAfterPaint", plPaintedCapturing, true);
-        gPaintListener = false;
-      }
-    };
-  } else if (!gUseE10S) {
-    // if the page doesn't do its own timing, use a bubbling handler
-    // to make sure that we're called after the page's own onload() handling
-
-    // XXX we use a capturing event here too -- load events don't bubble up
-    // to the <browser> element.  See bug 390263.
-    content.addEventListener("load", plLoadHandler, true);
-    removeLastAddedListener = function() {
-      content.removeEventListener("load", plLoadHandler, true);
-      if (useMozAfterPaint) {
-        gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true);
-        gPaintListener = false;
-      }
-    };
+  // messages to watch for page load
+  let mm = content.selectedBrowser.messageManager;
+  mm.addMessageListener("PageLoader:LoadEvent", ContentListener);
+  mm.addMessageListener("PageLoader:RecordTime", ContentListener);
+  if (useFNBPaint) {
+    mm.addMessageListener("PageLoader:FNBPaintError", ContentListener);
   }
 
-  // If the test browser is remote (e10s / IPC) we need to use messages to watch for page load
-  if (gUseE10S) {
-    let mm = content.selectedBrowser.messageManager;
-    mm.addMessageListener("PageLoader:LoadEvent", ContentListener);
-    mm.addMessageListener("PageLoader:RecordTime", ContentListener);
-    removeLastAddedMsgListener = function() {
-      mm.removeMessageListener("PageLoader:LoadEvent", ContentListener);
-      mm.removeMessageListener("PageLoader:RecordTime", ContentListener);
-    };
-  }
+  removeLastAddedMsgListener = function() {
+    mm.removeMessageListener("PageLoader:LoadEvent", ContentListener);
+    mm.removeMessageListener("PageLoader:RecordTime", ContentListener);
+    if (useFNBPaint) {
+      mm.removeMessageListener("PageLoader:FNBPaintError", ContentListener);
+    }
+  };
 
   failTimeout.register(loadFail, timeout);
 
   // record which page we are about to open
   TalosParentProfiler.mark("Opening " + pages[pageIndex].url.path);
 
   if (reportRSS) {
     collectMemory(startAndLoadURI, pageName);
@@ -648,41 +648,52 @@ function waitForPainted() {
 }
 
 function plPainted() {
   gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true);
   gPaintListener = false;
   _loadHandler();
 }
 
-function _loadHandler() {
+function _loadHandler(fnbpaint = 0) {
   failTimeout.clear();
+  var end_time = 0;
 
-  var end_time = Date.now();
-  var time = (end_time - start_time);
+  if (fnbpaint !== 0) {
+    // window.performance.timing.timeToNonBlankPaint is a timestamp
+    end_time = fnbpaint;
+  } else {
+    end_time = Date.now();
+  }
+
+  var duration = (end_time - start_time);
 
   TalosParentProfiler.pause("Bubbling load handler fired.");
 
   // does this page want to do its own timing?
   // if so, we shouldn't be here
   if (plPageFlags() & TEST_DOES_OWN_TIMING) {
     dumpLine("tp: Bubbling onload handler used with page that does its own timing?");
     plStop(true);
   }
 
-  plRecordTime(time);
+  plRecordTime(duration);
 
   if (doRenderTest)
     runRenderTest();
 
   plNextPage();
 }
 
 // the core handler for remote (e10s) browser
-function plLoadHandlerMessage() {
+function plLoadHandlerMessage(message) {
+  let fnbpaint = 0;
+  if (message.json.fnbpaint !== undefined) {
+    fnbpaint = message.json.fnbpaint;
+  }
   failTimeout.clear();
 
   if ((plPageFlags() & EXECUTE_SCROLL_TEST)) {
     // Let the page settle down after its load event, then execute the scroll test.
     setTimeout(sendScroll, 500);
   } else if ((plPageFlags() & TEST_DOES_OWN_TIMING)) {
     var time;
 
@@ -700,32 +711,38 @@ function plLoadHandlerMessage() {
 
     if (time !== undefined) {
       plRecordTime(time);
       if (doRenderTest)
         runRenderTest();
       plNextPage();
     }
   } else {
-    _loadHandler();
+    _loadHandler(fnbpaint);
   }
 }
 
 // the record time handler used for remote (e10s) browser
 function plRecordTimeMessage(message) {
   gTime = message.json.time;
   gStartTime = message.json.startTime;
   recordedName = message.json.testName;
 
   if (useMozAfterPaint) {
     gStartTime = message.json.startTime;
   }
   _loadHandlerCapturing();
 }
 
+// error retrieving fnbpaint
+function plFNBPaintErrorMessage(message) {
+  dumpLine("Abort: firstNonBlankPaint value is not available after loading the page");
+  plStop(true);
+}
+
 function runRenderTest() {
   const redrawsPerSample = 500;
 
   if (!Ci.nsIDOMWindowUtils)
     return;
 
   var win;
 
@@ -773,27 +790,31 @@ function plStopAll(force) {
 
   if (reportRSS) {
     stopMemCollector();
   }
 
   if (content) {
     content.removeEventListener("load", plLoadHandlerCapturing, true);
     content.removeEventListener("load", plLoadHandler, true);
-    if (useMozAfterPaint)
+
+    if (useMozAfterPaint) {
       content.removeEventListener("MozAfterPaint", plPaintedCapturing, true);
       content.removeEventListener("MozAfterPaint", plPainted, true);
+    }
 
-    if (gUseE10S) {
-      let mm = content.selectedBrowser.messageManager;
-      mm.removeMessageListener("PageLoader:LoadEvent", ContentListener);
-      mm.removeMessageListener("PageLoader:RecordTime", ContentListener);
+    let mm = content.selectedBrowser.messageManager;
+    mm.removeMessageListener("PageLoader:LoadEvent", ContentListener);
+    mm.removeMessageListener("PageLoader:RecordTime", ContentListener);
 
-      mm.loadFrameScript("data:,removeEventListener('load', _contentLoadHandler, true);", false, true);
+    if (useFNBPaint) {
+      mm.removeMessageListener("PageLoader:FNBPaintError", ContentListener);
     }
+
+    mm.loadFrameScript("data:,removeEventListener('load', _contentLoadHandler, true);", false, true);
   }
 
   if (MozillaFileLogger && MozillaFileLogger._foStream)
     MozillaFileLogger.close();
 
   goQuitApplication();
 }
 
--- a/testing/talos/talos/pageloader/components/tp-cmdline.js
+++ b/testing/talos/talos/pageloader/components/tp-cmdline.js
@@ -92,16 +92,17 @@ PageLoaderCmdLineHandler.prototype =
       args.height = cmdLine.handleFlagWithParam("tpheight", false);
       args.profilinginfo = cmdLine.handleFlagWithParam("tpprofilinginfo", false);
       args.offline = cmdLine.handleFlag("tpoffline", false);
       args.noisy = cmdLine.handleFlag("tpnoisy", false);
       args.timeout = cmdLine.handleFlagWithParam("tptimeout", false);
       args.delay = cmdLine.handleFlagWithParam("tpdelay", false);
       args.noForceCC = cmdLine.handleFlag("tpnoforcecc", false);
       args.mozafterpaint = cmdLine.handleFlag("tpmozafterpaint", false);
+      args.fnbpaint = cmdLine.handleFlag("fnbpaint", false);
       args.loadnocache = cmdLine.handleFlag("tploadnocache", false);
       args.scrolltest = cmdLine.handleFlag("tpscrolltest", false);
       args.disableE10s = cmdLine.handleFlag("tpdisable_e10s", false);
       args.rss = cmdLine.handleFlag("rss", false);
     } catch (e) {
       return;
     }
 
@@ -111,36 +112,37 @@ PageLoaderCmdLineHandler.prototype =
     Services.ww.openWindow(null, chromeURL, "_blank",
                             "chrome,dialog=no,all", args);
 
     // Don't pass command line to the default app processor
     cmdLine.preventDefault = true;
   },
 
   helpInfo:
-  "  -tp <file>         Run pageload perf tests on given manifest\n" +
-  "  -tpfilter str      Only include pages from manifest that contain str (regexp)\n" +
-  "  -tpcycles n        Loop through pages n times\n" +
-  "  -tppagecycles n    Loop through each page n times before going onto the next page\n" +
-  "  -tpstart n         Start at index n in the manifest\n" +
-  "  -tpend n           End with index n in the manifest\n" +
-  "  -tpchrome          Test with normal browser chrome\n" +
-  "  -tprender          Run render-only benchmark for each page\n" +
-  "  -tpwidth width     Width of window\n" +
-  "  -tpheight height   Height of window\n" +
-  "  -tbprofilinginfo   A JSON object describing profiler settings\n" +
-  "  -tpoffline         Force offline mode\n" +
-  "  -tpnoisy           Dump the name of the last loaded page to console\n" +
-  "  -tptimeout         Max amount of time given for a page to load, quit if exceeded\n" +
-  "  -tpdelay           Amount of time to wait between each pageload\n" +
-  "  -tpnoforcecc       Don't force cycle collection between each pageload\n" +
-  "  -tpmozafterpaint   Measure Time after recieving MozAfterPaint event instead of load event\n" +
-  "  -tpscrolltest      Unknown\n" +
-  "  -tpdisable_e10s    disable pageloader e10s code path\n" +
-  "  -rss               Dump RSS after each page is loaded\n"
+  "  -tp <file>             Run pageload perf tests on given manifest\n" +
+  "  -tpfilter str          Only include pages from manifest that contain str (regexp)\n" +
+  "  -tpcycles n            Loop through pages n times\n" +
+  "  -tppagecycles n        Loop through each page n times before going onto the next page\n" +
+  "  -tpstart n             Start at index n in the manifest\n" +
+  "  -tpend n               End with index n in the manifest\n" +
+  "  -tpchrome              Test with normal browser chrome\n" +
+  "  -tprender              Run render-only benchmark for each page\n" +
+  "  -tpwidth width         Width of window\n" +
+  "  -tpheight height       Height of window\n" +
+  "  -tbprofilinginfo       A JSON object describing profiler settings\n" +
+  "  -tpoffline             Force offline mode\n" +
+  "  -tpnoisy               Dump the name of the last loaded page to console\n" +
+  "  -tptimeout             Max amount of time given for a page to load, quit if exceeded\n" +
+  "  -tpdelay               Amount of time to wait between each pageload\n" +
+  "  -tpnoforcecc           Don't force cycle collection between each pageload\n" +
+  "  -tpmozafterpaint       Measure Time after recieving MozAfterPaint event instead of load event\n" +
+  "  -fnbpaint  Measure time after a first non-blank paint has occurred\n" +
+  "  -tpscrolltest          Unknown\n" +
+  "  -tpdisable_e10s        disable pageloader e10s code path\n" +
+  "  -rss                   Dump RSS after each page is loaded\n"
 
 };
 
 
 var PageLoaderCmdLineFactory =
 {
   createInstance(outer, iid) {
     if (outer != null) {
--- a/testing/talos/talos/pageloader/install.rdf
+++ b/testing/talos/talos/pageloader/install.rdf
@@ -1,15 +1,15 @@
 <?xml version="1.0"?>
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>pageloader@mozilla.org</em:id>
-    <em:version>1.0.19</em:version>
+    <em:version>1.0.22</em:version>
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>44.0</em:minVersion>
         <em:maxVersion>*</em:maxVersion>
       </Description>
     </em:targetApplication>
     <!-- Front End MetaData -->
index a763e390731f5379ddf5fa77090550009a002d13..798826525491b3d762503a422b1481f140238d19
GIT binary patch
literal 30804
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
T#9tpk{`Fe^HS?^T|GN5Lrf&Lt
--- a/testing/talos/talos/run_tests.py
+++ b/testing/talos/talos/run_tests.py
@@ -56,21 +56,22 @@ def buildCommandLine(test):
         for cycle_var in ['tppagecycles', 'tpcycles', 'cycles']:
             if test[cycle_var] > 2:
                 test[cycle_var] = 2
 
     # build pageloader command from options
     url = ['-tp', test['tpmanifest']]
     CLI_bool_options = ['tpchrome', 'tpmozafterpaint', 'tpdisable_e10s',
                         'tpnoisy', 'rss', 'tprender', 'tploadnocache',
-                        'tpscrolltest']
+                        'tpscrolltest', 'fnbpaint']
     CLI_options = ['tpcycles', 'tppagecycles', 'tpdelay', 'tptimeout']
     for key in CLI_bool_options:
         if test.get(key):
             url.append('-%s' % key)
+
     for key in CLI_options:
         value = test.get(key)
         if value:
             url.extend(['-%s' % key, str(value)])
 
     # XXX we should actually return the list but since we abuse
     # the url as a command line flag to pass to firefox all over the place
     # will just make a string for now
@@ -117,16 +118,21 @@ def run_tests(config, browser_config):
         browser_config['extra_args'] = '--no-remote'
 
     # with addon signing for production talos, we want to develop without it
     if browser_config['develop'] or browser_config['branch_name'] == 'Try':
         browser_config['preferences']['xpinstall.signatures.required'] = False
 
     browser_config['preferences']['extensions.allow-non-mpc-extensions'] = True
 
+    # if using firstNonBlankPaint, must turn on pref for it
+    if test.get('fnbpaint', False):
+        LOG.info("Using firstNonBlankPaint, so turning on pref for it")
+        browser_config['preferences']['dom.performance.time_to_non_blank_paint.enabled'] = True
+
     # set defaults
     testdate = config.get('testdate', '')
 
     # get the process name from the path to the browser
     if not browser_config['process']:
         browser_config['process'] = \
             os.path.basename(browser_config['browser_path'])
 
@@ -217,19 +223,16 @@ def run_tests(config, browser_config):
         # mitmproxy cert setup needs path to mozharness install; mozharness has set this
         # value in the SCRIPTSPATH env var for us in mozharness/mozilla/testing/talos.py
         scripts_path = os.environ.get('SCRIPTSPATH')
         LOG.info('scripts_path: %s' % str(scripts_path))
         mitmproxy.install_mitmproxy_cert(mitmproxy_proc,
                                          browser_config['browser_path'],
                                          str(scripts_path))
 
-    if config.get('first_non_blank_paint', False):
-        browser_config['firstNonBlankPaint'] = True
-
     testname = None
     # run the tests
     timer = utils.Timer()
     LOG.suite_start(tests=[test['name'] for test in tests])
     try:
         for test in tests:
             testname = test['name']
             LOG.test_start(testname)
--- a/testing/talos/talos/test.py
+++ b/testing/talos/talos/test.py
@@ -99,16 +99,17 @@ class TsBase(Test):
         'gecko_profile_entries',
         'gecko_profile_startup',
         'preferences',
         'xperf_counters',
         'xperf_providers',
         'xperf_user_providers',
         'xperf_stackwalk',
         'tpmozafterpaint',
+        'fnbpaint',
         'firstpaint',
         'userready',
         'testeventmap',
         'base_vs_ref',
         'extensions',
         'filters',
         'setup',
         'cleanup',
@@ -228,17 +229,17 @@ class tresize(TsBase):
 
 class PageloaderTest(Test):
     """abstract base class for a Talos Pageloader test"""
     tpmanifest = None  # test manifest
     tpcycles = 1  # number of time to run each page
     cycles = None
     timeout = None
     keys = ['tpmanifest', 'tpcycles', 'tppagecycles', 'tprender', 'tpchrome',
-            'tpmozafterpaint', 'tploadnocache', 'firstpaint', 'userready',
+            'tpmozafterpaint', 'fnbpaint', 'tploadnocache', 'firstpaint', 'userready',
             'testeventmap', 'base_vs_ref', 'rss', 'mainthread', 'resolution', 'cycles',
             'gecko_profile', 'gecko_profile_interval', 'gecko_profile_entries',
             'tptimeout', 'win_counters', 'w7_counters', 'linux_counters', 'mac_counters',
             'tpscrolltest', 'xperf_counters', 'timeout', 'shutdown', 'responsiveness',
             'profile_path', 'xperf_providers', 'xperf_user_providers', 'xperf_stackwalk',
             'filters', 'preferences', 'extensions', 'setup', 'cleanup',
             'lower_is_better', 'alert_threshold', 'unit', 'webextensions']
 
@@ -249,16 +250,17 @@ class QuantumPageloadTest(PageloaderTest
     """
     tpcycles = 1
     tppagecycles = 25
     gecko_profile_interval = 1
     gecko_profile_entries = 2000000
     filters = filter.ignore_first.prepare(5) + filter.median.prepare()
     unit = 'ms'
     lower_is_better = True
+    fnbpaint = True
 
 
 @register_test()
 class tpaint(PageloaderTest):
     """
     Tests the amount of time it takes the open a new window. This test does
     not include startup time. Multiple test windows are opened in succession,
     results reported are the average amount of time required to create and
@@ -548,17 +550,16 @@ class tp5o_scroll(PageloaderTest):
     """
     Tests scroll (like tscrollx does, including ASAP) but on the tp5o pageset.
     """
     tpmanifest = '${talos}/tests/tp5n/tp5o.manifest'
     tpcycles = 1
     tppagecycles = 12
     gecko_profile_interval = 2
     gecko_profile_entries = 2000000
-
     tpscrolltest = True
     """ASAP mode"""
     tpmozafterpaint = False
     preferences = {'layout.frame_rate': 0,
                    'docshell.event_starvation_delay_hint': 1,
                    'dom.send_after_paint_to_content': False,
                    'layout.css.scroll-behavior.spring-constant': "'10'",
                    'toolkit.framesRecording.bufferSize': 10000}
--- a/testing/web-platform/meta/web-animations/animation-model/animation-types/accumulation-per-property.html.ini
+++ b/testing/web-platform/meta/web-animations/animation-model/animation-types/accumulation-per-property.html.ini
@@ -10,24 +10,16 @@
   [content: ""a"" onto ""b""]
     expected:
       if stylo: FAIL
 
   [filter: same ordered filter functions]
     expected:
       if stylo: FAIL
 
-  [font-variant-alternates: "stylistic(unknown)" onto "swash(unknown)"]
-    expected:
-      if stylo: FAIL
-
-  [font-variant-alternates: "swash(unknown)" onto "stylistic(unknown)"]
-    expected:
-      if stylo: FAIL
-
   [grid-template-areas: "". . a b" ". .a b"" onto "none"]
     expected:
       if stylo: FAIL
 
   [grid-template-columns: "5px" onto "1px"]
     expected:
       if stylo: FAIL
 
--- a/testing/web-platform/meta/web-animations/animation-model/animation-types/addition-per-property.html.ini
+++ b/testing/web-platform/meta/web-animations/animation-model/animation-types/addition-per-property.html.ini
@@ -8,24 +8,16 @@ prefs: [layout.css.contain.enabled:true,
   [content: ""b"" onto ""a""]
     expected:
       if stylo: FAIL
 
   [content: ""a"" onto ""b""]
     expected:
       if stylo: FAIL
 
-  [font-variant-alternates: "stylistic(unknown)" onto "swash(unknown)"]
-    expected:
-      if stylo: FAIL
-
-  [font-variant-alternates: "swash(unknown)" onto "stylistic(unknown)"]
-    expected:
-      if stylo: FAIL
-
   [grid-template-areas: "". . a b" ". .a b"" onto "none"]
     expected:
       if stylo: FAIL
 
   [grid-template-columns: "5px" onto "1px"]
     expected:
       if stylo: FAIL
 
--- a/testing/web-platform/meta/web-animations/animation-model/animation-types/interpolation-per-property.html.ini
+++ b/testing/web-platform/meta/web-animations/animation-model/animation-types/interpolation-per-property.html.ini
@@ -24,28 +24,16 @@ prefs: [layout.css.contain.enabled:true,
   [content uses discrete animation when animating between ""a"" and ""b"" with effect easing]
     expected:
       if stylo: FAIL
 
   [content uses discrete animation when animating between ""a"" and ""b"" with keyframe easing]
     expected:
       if stylo: FAIL
 
-  [font-variant-alternates uses discrete animation when animating between "swash(unknown)" and "stylistic(unknown)" with linear easing]
-    expected:
-      if stylo: FAIL
-
-  [font-variant-alternates uses discrete animation when animating between "swash(unknown)" and "stylistic(unknown)" with effect easing]
-    expected:
-      if stylo: FAIL
-
-  [font-variant-alternates uses discrete animation when animating between "swash(unknown)" and "stylistic(unknown)" with keyframe easing]
-    expected:
-      if stylo: FAIL
-
   [grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with linear easing]
     expected:
       if stylo: FAIL
 
   [grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with effect easing]
     expected:
       if stylo: FAIL
 
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -2133,37 +2133,69 @@ class CallEntry extends Entry {
 
     return fixedArgs;
   }
 }
 
 // Represents a "function" defined in a schema namespace.
 FunctionEntry = class FunctionEntry extends CallEntry {
   static parseSchema(schema, path) {
+    // When not in DEBUG mode, we just need to know *if* this returns.
+    let returns = !!schema.returns;
+    if (DEBUG && "returns" in schema) {
+      returns = {
+        type: Schemas.parseSchema(schema.returns, path, ["optional", "name"]),
+        optional: schema.returns.optional || false,
+        name: "result",
+      };
+    }
+
     return new this(schema, path, schema.name,
                     Schemas.parseSchema(schema, path,
                       ["name", "unsupported", "returns",
                        "permissions",
                        "allowAmbiguousOptionalArguments"]),
                     schema.unsupported || false,
                     schema.allowAmbiguousOptionalArguments || false,
-                    schema.returns || null,
+                    returns,
                     schema.permissions || null);
   }
 
   constructor(schema, path, name, type, unsupported, allowAmbiguousOptionalArguments, returns, permissions) {
     super(schema, path, name, type.parameters, allowAmbiguousOptionalArguments);
     this.unsupported = unsupported;
     this.returns = returns;
     this.permissions = permissions;
 
     this.isAsync = type.isAsync;
     this.hasAsyncCallback = type.hasAsyncCallback;
   }
 
+  checkValue({type, optional, name}, value, context) {
+    if (optional && value == null) {
+      return;
+    }
+    if (type.reference === "ExtensionPanel" || type.reference === "Port") {
+      // TODO: We currently treat objects with functions as SubModuleType,
+      // which is just wrong, and a bigger yak.  Skipping for now.
+      return;
+    }
+    const {error} = type.normalize(value, context);
+    if (error) {
+      this.throwError(context, `Type error for ${name} value (${error})`);
+    }
+  }
+
+  checkCallback(args, context) {
+    const callback = this.parameters[this.parameters.length - 1];
+    for (const [i, param] of callback.type.parameters.entries()) {
+      this.checkValue(param, args[i], context);
+    }
+  }
+
   getDescriptor(path, context) {
     let apiImpl = context.getImplementation(path.join("."), this.name);
 
     let stub;
     if (this.isAsync) {
       stub = (...args) => {
         this.checkDeprecated(context);
         let actuals = this.checkParameters(args, context);
@@ -2172,29 +2204,47 @@ FunctionEntry = class FunctionEntry exte
           callback = actuals.pop();
         }
         if (callback === null && context.isChromeCompat) {
           // We pass an empty stub function as a default callback for
           // the `chrome` API, so promise objects are not returned,
           // and lastError values are reported immediately.
           callback = () => {};
         }
-        return apiImpl.callAsyncFunction(actuals, callback);
+        if (DEBUG && this.hasAsyncCallback && callback) {
+          let original = callback;
+          callback = (...args) => {
+            this.checkCallback(args, context);
+            original(...args);
+          };
+        }
+        let result = apiImpl.callAsyncFunction(actuals, callback);
+        if (DEBUG && this.hasAsyncCallback && !callback) {
+          return result.then(result => {
+            this.checkCallback([result], context);
+            return result;
+          });
+        }
+        return result;
       };
     } else if (!this.returns) {
       stub = (...args) => {
         this.checkDeprecated(context);
         let actuals = this.checkParameters(args, context);
         return apiImpl.callFunctionNoReturn(actuals);
       };
     } else {
       stub = (...args) => {
         this.checkDeprecated(context);
         let actuals = this.checkParameters(args, context);
-        return apiImpl.callFunction(actuals);
+        let result = apiImpl.callFunction(actuals);
+        if (DEBUG && this.returns) {
+          this.checkValue(this.returns, result, context);
+        }
+        return result;
       };
     }
 
     return {
       descriptor: {value: Cu.exportFunction(stub, context.cloneScope)},
       revoke() {
         apiImpl.revoke();
         apiImpl = null;
--- a/toolkit/components/extensions/schemas/alarms.json
+++ b/toolkit/components/extensions/schemas/alarms.json
@@ -65,17 +65,21 @@
             "name": "name",
             "optional": true,
             "description": "The name of the alarm to get. Defaults to the empty string."
           },
           {
             "type": "function",
             "name": "callback",
             "parameters": [
-              { "name": "alarm", "$ref": "Alarm" }
+              {
+                "name": "alarm",
+                "$ref": "Alarm",
+                "optional": true
+               }
             ]
           }
         ]
       },
       {
         "name": "getAll",
         "type": "function",
         "description": "Gets an array of all the alarms.",
--- a/toolkit/components/extensions/schemas/cookies.json
+++ b/toolkit/components/extensions/schemas/cookies.json
@@ -40,17 +40,18 @@
         }
       },
       {
         "id": "CookieStore",
         "type": "object",
         "description": "Represents a cookie store in the browser. An incognito mode window, for instance, uses a separate cookie store from a non-incognito window.",
         "properties": {
           "id": {"type": "string", "description": "The unique identifier for the cookie store."},
-          "tabIds": {"type": "array", "items": {"type": "integer"}, "description": "Identifiers of all the browser tabs that share this cookie store."}
+          "tabIds": {"type": "array", "items": {"type": "integer"}, "description": "Identifiers of all the browser tabs that share this cookie store."},
+          "incognito": {"type": "boolean", "description": "Indicates if this is an incognito cookie store"}
         }
       },
       {
         "id": "OnChangedCause",
         "type": "string",
         "enum": ["evicted", "expired", "explicit", "expired_overwrite", "overwrite"],
         "description": "The underlying reason behind the cookie's change. If a cookie was inserted, or removed via an explicit call to $(ref:cookies.remove), \"cause\" will be \"explicit\". If a cookie was automatically removed due to expiry, \"cause\" will be \"expired\". If a cookie was removed due to being overwritten with an already-expired expiration date, \"cause\" will be set to \"expired_overwrite\".  If a cookie was automatically removed due to garbage collection, \"cause\" will be \"evicted\".  If a cookie was automatically removed due to a \"set\" call that overwrote it, \"cause\" will be \"overwrite\". Plan your response accordingly."
       }
--- a/toolkit/components/extensions/schemas/downloads.json
+++ b/toolkit/components/extensions/schemas/downloads.json
@@ -91,17 +91,18 @@
             "description": "An identifier that is persistent across browser sessions.",
             "type": "integer"
           },
           "url": {
             "description": "Absolute URL.",
             "type": "string"
           },
           "referrer": {
-            "type": "string"
+            "type": "string",
+            "optional": true
           },
           "filename": {
             "description": "Absolute local path.",
             "type": "string"
           },
           "incognito": {
             "description": "False if this download is recorded in the history, true if it is not recorded.",
             "type": "boolean"
--- a/toolkit/components/extensions/schemas/extension.json
+++ b/toolkit/components/extensions/schemas/extension.json
@@ -80,32 +80,30 @@
               }
             }
           }
         ],
         "returns": {
           "type": "array",
           "description": "Array of global objects",
           "items": {
-            "name": "viewGlobals",
             "type": "object",
             "isInstanceOf": "Window",
             "additionalProperties": { "type": "any" }
           }
         }
       },
       {
         "name": "getBackgroundPage",
         "type": "function",
         "description": "Returns the JavaScript 'window' object for the background page running inside the current extension. Returns null if the extension has no background page.",
         "parameters": [],
         "returns": {
             "type": "object",
             "optional": true,
-            "name": "backgroundPageGlobal",
             "isInstanceOf": "Window",
             "additionalProperties": { "type": "any" }
          }
       },
       {
         "name": "isAllowedIncognitoAccess",
         "type": "function",
         "description": "Retrieves the state of the extension's access to Incognito-mode (as determined by the user-controlled 'Allowed in Incognito' checkbox.",
--- a/toolkit/components/extensions/schemas/identity.json
+++ b/toolkit/components/extensions/schemas/identity.json
@@ -188,17 +188,17 @@
             "name": " path",
             "type": "string",
             "default": "",
             "optional": true,
             "description": "The path appended to the end of the generated URL. "
           }
         ],
         "returns": {
-          "string": "path"
+          "type": "string"
         }
       }
     ],
     "events": [
       {
         "name": "onSignInChanged",
         "unsupported": true,
         "type": "function",
--- a/toolkit/components/extensions/schemas/management.json
+++ b/toolkit/components/extensions/schemas/management.json
@@ -41,17 +41,17 @@
         "description": "A reason the item is disabled.",
         "type": "string",
         "enum": ["unknown", "permissions_increase"]
       },
       {
         "id": "ExtensionType",
         "description": "The type of this extension. Will always be 'extension'.",
         "type": "string",
-        "enum": ["extension"]
+        "enum": ["extension", "theme"]
       },
       {
         "id": "ExtensionInstallType",
         "description": "How the extension was installed. One of<br><var>development</var>: The extension was loaded unpacked in developer mode,<br><var>normal</var>: The extension was installed normally via an .xpi file,<br><var>sideload</var>: The extension was installed by other software on the machine,<br><var>other</var>: The extension was installed by other means.",
         "type": "string",
         "enum": ["development", "normal", "sideload", "other"]
       },
       {
--- a/toolkit/components/extensions/schemas/manifest.json
+++ b/toolkit/components/extensions/schemas/manifest.json
@@ -328,16 +328,34 @@
           },
           {
             "type": "string",
             "pattern": "^file:///.*$"
           }
         ]
       },
       {
+        "id": "MatchPatternInternal",
+        "description": "Same as MatchPattern above, but includes moz-extension protocol",
+        "choices": [
+          {
+            "type": "string",
+            "enum": ["<all_urls>"]
+          },
+          {
+            "type": "string",
+            "pattern": "^(https?|wss?|file|ftp|moz-extension|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+)/.*$"
+          },
+          {
+            "type": "string",
+            "pattern": "^file:///.*$"
+          }
+        ]
+      },
+      {
         "id": "ContentScript",
         "type": "object",
         "description": "Details of the script or CSS to inject. Either the code or the file property must be set, but both may not be set at the same time. Based on InjectDetails, but using underscore rather than camel case naming conventions.",
         "additionalProperties": { "$ref": "UnrecognizedProperty" },
         "properties": {
           "matches": {
             "type": "array",
             "optional": false,
--- a/toolkit/components/extensions/schemas/notifications.json
+++ b/toolkit/components/extensions/schemas/notifications.json
@@ -311,16 +311,17 @@
         "parameters": [
           {
             "type": "function",
             "name": "callback",
             "parameters": [
               {
                 "name": "notifications",
                 "type": "object",
+                "additionalProperties": {"$ref": "CreateNotificationOptions"},
                 "description": "The set of notifications currently in the system."
               }
             ]
           }
         ]
       },
       {
         "name": "getPermissionLevel",
--- a/toolkit/components/extensions/schemas/permissions.json
+++ b/toolkit/components/extensions/schemas/permissions.json
@@ -28,17 +28,17 @@
           "permissions": {
             "type": "array",
             "items": { "$ref": "manifest.Permission" },
             "optional": true,
             "default": []
           },
           "origins": {
             "type": "array",
-            "items": { "$ref": "manifest.MatchPattern" },
+            "items": { "$ref": "manifest.MatchPatternInternal" },
             "optional": true,
             "default": []
           }
         }
       }
     ],
     "functions": [
       {
--- a/toolkit/components/extensions/schemas/web_navigation.json
+++ b/toolkit/components/extensions/schemas/web_navigation.json
@@ -68,24 +68,32 @@
             "parameters": [
               {
                 "type": "object",
                 "name": "details",
                 "optional": true,
                 "description": "Information about the requested frame, null if the specified frame ID and/or tab ID are invalid.",
                 "properties": {
                   "errorOccurred": {
-                    "unsupported": true,
+                    "optional": true,
                     "type": "boolean",
                     "description": "True if the last navigation in this frame was interrupted by an error, i.e. the onErrorOccurred event fired."
                   },
                   "url": {
                     "type": "string",
                     "description": "The URL currently associated with this frame, if the frame identified by the frameId existed at one point in the given tab. The fact that an URL is associated with a given frameId does not imply that the corresponding frame still exists."
                   },
+                  "tabId": {
+                    "type": "integer",
+                    "description": "The ID of the tab in which the frame is."
+                  },
+                  "frameId": {
+                    "type": "integer",
+                    "description": "The ID of the frame. 0 indicates that this is the main frame; a positive value indicates the ID of a subframe."
+                  },
                   "parentFrameId": {
                     "type": "integer",
                     "description": "ID of frame that wraps the frame. Set to -1 of no parent frame exists."
                   }
                 }
               }
             ]
           }
@@ -113,25 +121,29 @@
                 "name": "details",
                 "type": "array",
                 "description": "A list of frames in the given tab, null if the specified tab ID is invalid.",
                 "optional": true,
                 "items": {
                   "type": "object",
                   "properties": {
                     "errorOccurred": {
-                      "unsupported": true,
+                      "optional": true,
                       "type": "boolean",
                       "description": "True if the last navigation in this frame was interrupted by an error, i.e. the onErrorOccurred event fired."
                     },
                     "processId": {
                       "unsupported": true,
                       "type": "integer",
                       "description": "The ID of the process runs the renderer for this tab."
                     },
+                    "tabId": {
+                      "type": "integer",
+                      "description": "The ID of the tab in which the frame is."
+                    },
                     "frameId": {
                       "type": "integer",
                       "description": "The ID of the frame. 0 indicates that this is the main frame; a positive value indicates the ID of a subframe."
                     },
                     "parentFrameId": {
                       "type": "integer",
                       "description": "ID of frame that wraps the frame. Set to -1 of no parent frame exists."
                     },
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
@@ -71,17 +71,17 @@ let json = [
      {
        id: "submodule",
        type: "object",
        functions: [
          {
            name: "sub_foo",
            type: "function",
            parameters: [],
-           returns: "integer",
+           returns: {type: "integer"},
          },
        ],
      },
    ],
 
    functions: [
      {
        name: "foo",
@@ -399,16 +399,19 @@ class TallyingAPIImplementation extends 
   constructor(namespace, name) {
     super();
     this.namespace = namespace;
     this.name = name;
   }
 
   callFunction(args) {
     tally("call", this.namespace, this.name, args);
+    if (this.name === "sub_foo") {
+      return 13;
+    }
   }
 
   callFunctionNoReturn(args) {
     tally("call", this.namespace, this.name, args);
   }
 
   getProperty() {
     tally("get", this.namespace, this.name);
@@ -1495,16 +1498,17 @@ let defaultsJson = [
        type: "function",
        parameters: [
          {name: "arg", type: "object", optional: true, properties: {
            prop1: {type: "integer", optional: true},
          }, default: {prop1: 1}},
        ],
        returns: {
          type: "object",
+         additionalProperties: true,
        },
      },
    ]},
 ];
 
 add_task(async function testDefaults() {
   let url = "data:," + JSON.stringify(defaultsJson);
   await Schemas.load(url);
@@ -1531,8 +1535,85 @@ add_task(async function testDefaults() {
 
   let root = {};
   Schemas.inject(root, localWrapper);
 
   deepEqual(root.defaultsJson.defaultFoo(), {prop1: 1, newProp: 1});
   deepEqual(root.defaultsJson.defaultFoo({prop1: 2}), {prop1: 2, newProp: 1});
   deepEqual(root.defaultsJson.defaultFoo(), {prop1: 1, newProp: 1});
 });
+
+let returnsJson = [{
+  namespace: "returns",
+  types: [
+    {
+      id: "Widget",
+      type: "object",
+      properties: {
+        size: {type: "integer"},
+        colour: {type: "string", optional: true},
+      },
+    },
+  ],
+  functions: [
+    {
+      name: "complete",
+      type: "function",
+      returns: {$ref: "Widget"},
+      parameters: [],
+    },
+    {
+      name: "optional",
+      type: "function",
+      returns: {$ref: "Widget"},
+      parameters: [],
+    },
+    {
+      name: "invalid",
+      type: "function",
+      returns: {$ref: "Widget"},
+      parameters: [],
+    },
+  ],
+}];
+
+add_task(async function testReturns() {
+  const url = "data:," + JSON.stringify(returnsJson);
+  await Schemas.load(url);
+
+  const apiObject = {
+    complete() {
+      return {size: 3, colour: "orange"};
+    },
+    optional() {
+      return {size: 4};
+    },
+    invalid() {
+      return {};
+    },
+  };
+
+  const localWrapper = {
+    cloneScope: global,
+    shouldInject(ns) {
+      return true;
+    },
+    getImplementation(ns, name) {
+      return new LocalAPIImplementation(apiObject, name, null);
+    },
+  };
+
+  const root = {};
+  Schemas.inject(root, localWrapper);
+
+  deepEqual(root.returns.complete(), {size: 3, colour: "orange"});
+  deepEqual(root.returns.optional(), {size: 4},
+            "Missing optional properties is allowed");
+
+  if (AppConstants.DEBUG) {
+    Assert.throws(() => root.returns.invalid(),
+                  `Type error for result value (Property "size" is required)`,
+                  "Should throw for invalid result in DEBUG builds");
+  } else {
+    deepEqual(root.returns.invalid(), {},
+              "Doesn't throw for invalid result value in release builds");
+  }
+});
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_async.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_async.js
@@ -3,16 +3,24 @@
 Components.utils.import("resource://gre/modules/ExtensionCommon.jsm");
 Components.utils.import("resource://gre/modules/Schemas.jsm");
 
 let {BaseContext, LocalAPIImplementation} = ExtensionCommon;
 
 let schemaJson = [
   {
     namespace: "testnamespace",
+    types: [{
+      id: "Widget",
+      type: "object",
+      properties: {
+        size: {type: "integer"},
+        colour: {type: "string", optional: true},
+      },
+    }],
     functions: [{
       name: "one_required",
       type: "function",
       parameters: [{
         name: "first",
         type: "function",
         parameters: [],
       }],
@@ -39,16 +47,28 @@ let schemaJson = [
       type: "function",
       async: "first",
       parameters: [{
         name: "first",
         type: "function",
         parameters: [],
         optional: true,
       }],
+    }, {
+      name: "async_result",
+      type: "function",
+      async: "callback",
+      parameters: [{
+        name: "callback",
+        type: "function",
+        parameters: [{
+          name: "widget",
+          $ref: "Widget",
+        }],
+      }],
     }],
   },
 ];
 
 const global = this;
 class StubContext extends BaseContext {
   constructor() {
     let fakeExtension = {id: "test@web.extension"};
@@ -142,16 +162,46 @@ add_task(async function testParameterVal
     assertNoThrows("async_optional");
     assertNoThrows("async_optional", null);
     assertNoThrows("async_optional", cb);
     assertThrows("async_optional", cb, null);
     assertThrows("async_optional", cb, cb);
   }
 });
 
+add_task(async function testCheckAsyncResults() {
+  await Schemas.load("data:," + JSON.stringify(schemaJson));
+
+  const complete = generateAPIs({}, {
+    async_result: async () => ({size: 5, colour: "green"}),
+  });
+
+  const optional = generateAPIs({}, {
+    async_result: async () => ({size: 6}),
+  });
+
+  const invalid = generateAPIs({}, {
+    async_result: async () => ({}),
+  });
+
+  deepEqual(await complete.async_result(), {size: 5, colour: "green"});
+
+  deepEqual(await optional.async_result(), {size: 6},
+            "Missing optional properties is allowed");
+
+  if (AppConstants.DEBUG) {
+    await Assert.rejects(invalid.async_result(),
+          `Type error for widget value (Property "size" is required)`,
+          "Should throw for invalid callback argument in DEBUG builds");
+  } else {
+    deepEqual(await invalid.async_result(), {},
+              "Invalid callback argument doesn't throw in release builds");
+  }
+});
+
 add_task(async function testAsyncResults() {
   await Schemas.load("data:," + JSON.stringify(schemaJson));
   function runWithCallback(func) {
     do_print(`Calling testnamespace.${func.name}, expecting callback with result`);
     return new Promise(resolve => {
       let result = "uninitialized value";
       let returnValue = func(reply => {
         result = reply;
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_revoke.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_revoke.js
@@ -41,17 +41,17 @@ let json = [
       {
         id: "submodule",
         type: "object",
         functions: [
           {
             name: "sub_foo",
             type: "function",
             parameters: [],
-            returns: "integer",
+            returns: {type: "integer"},
           },
         ],
       },
     ],
 
     functions: [
       {
         name: "func",
@@ -116,16 +116,19 @@ class APIImplementation extends SchemaAP
   }
 
   revoke(...args) {
     this.record("revoke", args);
   }
 
   callFunction(...args) {
     this.record("callFunction", args);
+    if (this.name === "sub_foo") {
+      return 13;
+    }
   }
 
   callFunctionNoReturn(...args) {
     this.record("callFunctionNoReturn", args);
   }
 
   getProperty(...args) {
     this.record("getProperty", args);
--- a/toolkit/components/reader/AboutReader.jsm
+++ b/toolkit/components/reader/AboutReader.jsm
@@ -241,18 +241,21 @@ AboutReader.prototype = {
         if (target.classList.contains("dropdown-toggle")) {
           this._toggleDropdownClicked(aEvent);
         } else if (!target.closest(".dropdown-popup")) {
           this._closeDropdowns();
         }
         break;
       case "scroll":
         this._closeDropdowns(true);
-        let isScrollingUp = this._scrollOffset > aEvent.pageY;
-        this._setSystemUIVisibility(isScrollingUp);
+        if (!gIsFirefoxDesktop && this._scrollOffset != aEvent.pageY) {
+          let isScrollingUp = this._scrollOffset > aEvent.pageY;
+          this._setSystemUIVisibility(isScrollingUp);
+          this._setToolbarVisibility(isScrollingUp);
+        }
         this._scrollOffset = aEvent.pageY;
         break;
       case "resize":
         this._updateImageMargins();
         if (this._isToolbarVertical) {
           this._win.setTimeout(() => {
             for (let dropdown of this._doc.querySelectorAll(".dropdown.open")) {
               this._updatePopupPosition(dropdown);
@@ -612,16 +615,34 @@ AboutReader.prototype = {
 
     AsyncPrefs.set("reader.font_type", this._fontType);
   },
 
   _setSystemUIVisibility(visible) {
     this._mm.sendAsyncMessage("Reader:SystemUIVisibility", { visible });
   },
 
+  _setToolbarVisibility(visible) {
+    let tb = this._toolbarElement;
+
+    if (visible) {
+      if (tb.style.opacity != "1") {
+        tb.removeAttribute("hidden");
+        tb.style.opacity = "1";
+      }
+    } else if (tb.style.opacity != "0") {
+      tb.addEventListener("transitionend", evt => {
+        if (tb.style.opacity == "0") {
+          tb.setAttribute("hidden", "");
+        }
+      }, { once: true });
+      tb.style.opacity = "0";
+    }
+  },
+
   async _loadArticle() {
     let url = this._getOriginalUrl();
     this._showProgressDelayed();
 
     let article;
     if (this._articlePromise) {
       article = await this._articlePromise;
     } else {
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -6,16 +6,18 @@
 
 #include "nsFormFillController.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
 #include "mozilla/dom/HTMLInputElement.h"
+#include "mozilla/dom/PageTransitionEvent.h"
+#include "mozilla/Logging.h"
 #include "nsIFormAutoComplete.h"
 #include "nsIInputListAutoComplete.h"
 #include "nsIAutoCompleteSimpleResult.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsIServiceManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -41,16 +43,19 @@
 #include "nsILoadContext.h"
 #include "nsIFrame.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsFocusManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using mozilla::ErrorResult;
+using mozilla::LogLevel;
+
+static mozilla::LazyLogModule sLogger("satchel");
 
 static nsIFormAutoComplete*
 GetFormAutoComplete()
 {
   static nsCOMPtr<nsIFormAutoComplete> sInstance;
   static bool sInitialized = false;
   if (!sInitialized) {
     nsresult rv;
@@ -229,16 +234,17 @@ nsFormFillController::NativeAnonymousChi
 void
 nsFormFillController::ParentChainChanged(nsIContent* aContent)
 {
 }
 
 void
 nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode)
 {
+  MOZ_LOG(sLogger, LogLevel::Verbose, ("NodeWillBeDestroyed: %p", aNode));
   mPwmgrInputs.Remove(aNode);
   mAutofillInputs.Remove(aNode);
   if (aNode == mListNode) {
     mListNode = nullptr;
     RevalidateDataList();
   } else if (aNode == mFocusedInputNode) {
     mFocusedInputNode = nullptr;
     mFocusedInput = nullptr;
@@ -256,16 +262,18 @@ nsFormFillController::MaybeRemoveMutatio
 }
 
 ////////////////////////////////////////////////////////////////////////
 //// nsIFormFillController
 
 NS_IMETHODIMP
 nsFormFillController::AttachToBrowser(nsIDocShell *aDocShell, nsIAutoCompletePopup *aPopup)
 {
+  MOZ_LOG(sLogger, LogLevel::Debug,
+          ("AttachToBrowser for docShell %p with popup %p", aDocShell, aPopup));
   NS_ENSURE_TRUE(aDocShell && aPopup, NS_ERROR_ILLEGAL_VALUE);
 
   mDocShells.AppendElement(aDocShell);
   mPopups.AppendElement(aPopup);
 
   // Listen for focus events on the domWindow of the docShell
   nsCOMPtr<nsPIDOMWindowOuter> window = GetWindowForDocShell(aDocShell);
   AddWindowListeners(window);
@@ -335,16 +343,19 @@ nsFormFillController::MarkAsAutofillFiel
 {
   /*
    * Support other components implementing form autofill and handle autocomplete
    * for the field.
    */
   nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
   NS_ENSURE_STATE(node);
 
+  MOZ_LOG(sLogger, LogLevel::Verbose,
+          ("MarkAsAutofillField: aInput = %p, node = %p", aInput, node.get()));
+
   if (mAutofillInputs.Get(node)) {
     return NS_OK;
   }
 
   mAutofillInputs.Put(node, true);
   node->AddMutationObserverUnlessExists(this);
 
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(aInput);
@@ -581,23 +592,25 @@ nsFormFillController::GetSearchCount(uin
   *aSearchCount = 1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFormFillController::GetSearchAt(uint32_t index, nsACString & _retval)
 {
   if (mAutofillInputs.Get(mFocusedInputNode)) {
+    MOZ_LOG(sLogger, LogLevel::Debug, ("GetSearchAt: autofill-profiles field"));
     nsCOMPtr<nsIAutoCompleteSearch> profileSearch = do_GetService("@mozilla.org/autocomplete/search;1?name=autofill-profiles");
     if (profileSearch) {
       _retval.AssignLiteral("autofill-profiles");
       return NS_OK;
     }
   }
 
+  MOZ_LOG(sLogger, LogLevel::Debug, ("GetSearchAt: form-history field"));
   _retval.AssignLiteral("form-history");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFormFillController::GetTextValue(nsAString & aTextValue)
 {
   if (mFocusedInput) {
@@ -757,25 +770,28 @@ nsFormFillController::GetUserContextId(u
 
 ////////////////////////////////////////////////////////////////////////
 //// nsIAutoCompleteSearch
 
 NS_IMETHODIMP
 nsFormFillController::StartSearch(const nsAString &aSearchString, const nsAString &aSearchParam,
                                   nsIAutoCompleteResult *aPreviousResult, nsIAutoCompleteObserver *aListener)
 {
+  MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch for %p", mFocusedInput));
+
   nsresult rv;
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(mFocusedInputNode);
 
   // If the login manager has indicated it's responsible for this field, let it
   // handle the autocomplete. Otherwise, handle with form history.
   // This method is sometimes called in unit tests and from XUL without a focused node.
   if (mFocusedInputNode &&
       (mPwmgrInputs.Get(mFocusedInputNode) ||
        formControl->ControlType() == NS_FORM_INPUT_PASSWORD)) {
+    MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch: login field"));
 
     // Handle the case where a password field is focused but
     // MarkAsLoginManagerField wasn't called because password manager is disabled.
     if (!mLoginManager) {
       mLoginManager = do_GetService("@mozilla.org/login-manager;1");
     }
 
     if (NS_WARN_IF(!mLoginManager)) {
@@ -786,16 +802,17 @@ nsFormFillController::StartSearch(const 
     // satchel manage the field?
     mLastListener = aListener;
     rv = mLoginManager->AutoCompleteSearchAsync(aSearchString,
                                                 aPreviousResult,
                                                 mFocusedInput,
                                                 this);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
+    MOZ_LOG(sLogger, LogLevel::Debug, ("StartSearch: non-login field"));
     mLastListener = aListener;
 
     nsCOMPtr<nsIAutoCompleteResult> datalistResult;
     if (mFocusedInput) {
       rv = PerformInputListAutoComplete(aSearchString,
                                         getter_AddRefs(datalistResult));
       NS_ENSURE_SUCCESS(rv, rv);
     }
@@ -960,31 +977,38 @@ nsFormFillController::HandleEvent(nsIDOM
       }
 
       if (mFocusedInput) {
         if (doc == mFocusedInputNode->OwnerDoc()) {
           StopControllingInput();
         }
       }
 
-      RemoveForDocument(doc);
+      // Only remove the observer notifications and marked autofill and password
+      // manager fields if the page isn't going to be persisted (i.e. it's being
+      // unloaded) so that appropriate autocomplete handling works with bfcache.
+      bool persisted = aEvent->InternalDOMEvent()->AsPageTransitionEvent()->Persisted();
+      if (!persisted) {
+        RemoveForDocument(doc);
+      }
     }
     break;
   default:
     // Handling the default case to shut up stupid -Wswitch warnings.
     // One day compilers will be smarter...
     break;
   }
 
   return NS_OK;
 }
 
 void
 nsFormFillController::RemoveForDocument(nsIDocument* aDoc)
 {
+  MOZ_LOG(sLogger, LogLevel::Verbose, ("RemoveForDocument: %p", aDoc));
   for (auto iter = mPwmgrInputs.Iter(); !iter.Done(); iter.Next()) {
     const nsINode* key = iter.Key();
     if (key && (!aDoc || key->OwnerDoc() == aDoc)) {
       // mFocusedInputNode's observer is tracked separately, so don't remove it
       // here.
       if (key != mFocusedInputNode) {
         const_cast<nsINode*>(key)->RemoveMutationObserver(this);
       }
@@ -1011,16 +1035,17 @@ nsFormFillController::IsTextControl(nsIN
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aNode);
   return formControl &&
          formControl->IsSingleLineTextControl(false);
 }
 
 void
 nsFormFillController::MaybeStartControllingInput(nsIDOMHTMLInputElement* aInput)
 {
+  MOZ_LOG(sLogger, LogLevel::Verbose, ("MaybeStartControllingInput for %p", aInput));
   nsCOMPtr<nsINode> inputNode = do_QueryInterface(aInput);
   if (!inputNode) {
     return;
   }
 
   if (!IsTextControl(inputNode)) {
     return;
   }
@@ -1273,16 +1298,17 @@ nsFormFillController::ShowPopup()
 }
 
 ////////////////////////////////////////////////////////////////////////
 //// nsFormFillController
 
 void
 nsFormFillController::AddWindowListeners(nsPIDOMWindowOuter* aWindow)
 {
+  MOZ_LOG(sLogger, LogLevel::Debug, ("AddWindowListeners for window %p", aWindow));
   if (!aWindow) {
     return;
   }
 
   EventTarget* target = aWindow->GetChromeEventHandler();
 
   if (!target) {
     return;
@@ -1308,16 +1334,17 @@ nsFormFillController::AddWindowListeners
 
   // Note that any additional listeners added should ensure that they ignore
   // untrusted events, which might be sent by content that's up to no good.
 }
 
 void
 nsFormFillController::RemoveWindowListeners(nsPIDOMWindowOuter* aWindow)
 {
+  MOZ_LOG(sLogger, LogLevel::Debug, ("RemoveWindowListeners for window %p", aWindow));
   if (!aWindow) {
     return;
   }
 
   StopControllingInput();
 
   nsCOMPtr<nsIDocument> doc = aWindow->GetDoc();
   RemoveForDocument(doc);
@@ -1339,16 +1366,17 @@ nsFormFillController::RemoveWindowListen
   target->RemoveEventListener(NS_LITERAL_STRING("compositionend"), this,
                               true);
   target->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
 }
 
 void
 nsFormFillController::StartControllingInput(nsIDOMHTMLInputElement *aInput)
 {
+  MOZ_LOG(sLogger, LogLevel::Verbose, ("StartControllingInput for %p", aInput));
   // Make sure we're not still attached to an input
   StopControllingInput();
 
   if (!mController) {
     return;
   }
 
   // Find the currently focused docShell
@@ -1391,20 +1419,24 @@ nsFormFillController::StopControllingInp
 
   if (mController) {
     // Reset the controller's input, but not if it has been switched
     // to another input already, which might happen if the user switches
     // focus by clicking another autocomplete textbox
     nsCOMPtr<nsIAutoCompleteInput> input;
     mController->GetInput(getter_AddRefs(input));
     if (input == this) {
+      MOZ_LOG(sLogger, LogLevel::Verbose,
+              ("StopControllingInput: Nulled controller input for %p", this));
       mController->SetInput(nullptr);
     }
   }
 
+  MOZ_LOG(sLogger, LogLevel::Verbose,
+          ("StopControllingInput: Stopped controlling %p", mFocusedInput));
   if (mFocusedInputNode) {
     MaybeRemoveMutationObserver(mFocusedInputNode);
 
     mFocusedInputNode = nullptr;
     mFocusedInput = nullptr;
   }
 
   if (mFocusedPopup) {
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -403,16 +403,17 @@ UPLOAD_FILES= \
   $(call QUOTED_WILDCARD,$(MOZ_BUILDINFO_FILE)) \
   $(call QUOTED_WILDCARD,$(MOZ_BUILDID_INFO_TXT_FILE)) \
   $(call QUOTED_WILDCARD,$(MOZ_MOZINFO_FILE)) \
   $(call QUOTED_WILDCARD,$(MOZ_TEST_PACKAGES_FILE)) \
   $(call QUOTED_WILDCARD,$(PKG_JSSHELL)) \
   $(call QUOTED_WILDCARD,$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip) \
   $(call QUOTED_WILDCARD,$(topobjdir)/browser/installer/windows/instgen/setup.exe) \
   $(call QUOTED_WILDCARD,$(topobjdir)/browser/installer/windows/instgen/setup-stub.exe) \
+  $(call QUOTED_WILDCARD,$(topsrcdir)/toolchains.json) \
   $(if $(UPLOAD_EXTRA_FILES), $(foreach f, $(UPLOAD_EXTRA_FILES), $(wildcard $(DIST)/$(f))))
 
 ifneq ($(filter-out en-US x-test,$(AB_CD)),)
   UPLOAD_FILES += \
     $(call QUOTED_WILDCARD,$(topobjdir)/browser/installer/windows/l10ngen/setup.exe) \
     $(call QUOTED_WILDCARD,$(topobjdir)/browser/installer/windows/l10ngen/setup-stub.exe)
 endif
 
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -420,16 +420,35 @@ public:
     delete sInstance;
     sInstance = nullptr;
 
     return samplerThread;
   }
 
   static bool Exists(PSLockRef) { return !!sInstance; }
 
+  static bool Equals(PSLockRef,
+                     int aEntries, double aInterval, uint32_t aFeatures,
+                     const char** aFilters, uint32_t aFilterCount)
+  {
+    if (sInstance->mEntries != aEntries ||
+        sInstance->mInterval != aInterval ||
+        sInstance->mFeatures != aFeatures ||
+        sInstance->mFilters.length() != aFilterCount) {
+      return false;
+    }
+
+    for (uint32_t i = 0; i < sInstance->mFilters.length(); ++i) {
+      if (strcmp(sInstance->mFilters[i].c_str(), aFilters[i]) != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   static size_t SizeOf(PSLockRef, MallocSizeOf aMallocSizeOf)
   {
     size_t n = aMallocSizeOf(sInstance);
 
     n += sInstance->mBuffer->SizeOfIncludingThis(aMallocSizeOf);
 
     return n;
   }
@@ -1675,16 +1694,33 @@ PrintUsageThenExit(int aExitCode)
     "  the profiler's circular buffer when the profiler is first started.\n"
     "  If unset, the platform default is used.\n"
     "\n"
     "  MOZ_PROFILER_STARTUP_INTERVAL=<1..1000>\n"
     "  If MOZ_PROFILER_STARTUP is set, specifies the sample interval,\n"
     "  measured in milliseconds, when the profiler is first started.\n"
     "  If unset, the platform default is used.\n"
     "\n"
+    "  MOZ_PROFILER_STARTUP_FEATURES_BITFIELD=<Number>\n"
+    "  If MOZ_PROFILER_STARTUP is set, specifies the profiling features, as\n"
+    "  the integer value of the features bitfield.\n"
+    "  If unset, the value from MOZ_PROFILER_STARTUP_FEATURES is used.\n"
+    "\n"
+    "  MOZ_PROFILER_STARTUP_FEATURES=<Features>\n"
+    "  If MOZ_PROFILER_STARTUP is set, specifies the profiling features, as\n"
+    "  a comma-separated list of strings.\n"
+    "  Ignored if  MOZ_PROFILER_STARTUP_FEATURES_BITFIELD is set.\n"
+    "  If unset, the platform default is used.\n"
+    "\n"
+    "  MOZ_PROFILER_STARTUP_FILTERS=<Filters>\n"
+    "  If MOZ_PROFILER_STARTUP is set, specifies the thread filters, as a\n"
+    "  comma-separated list of strings. A given thread will be sampled if any\n"
+    "  of the filters is a case-insensitive substring of the thread name.\n"
+    "  If unset, a default is used.\n"
+    "\n"
     "  MOZ_PROFILER_SHUTDOWN\n"
     "  If set, the profiler saves a profile to the named file on shutdown.\n"
     "\n"
     "  MOZ_PROFILER_LUL_TEST\n"
     "  If set to any value, runs LUL unit tests at startup.\n"
     "\n"
     "  This platform %s native unwinding.\n"
     "\n",
@@ -1984,16 +2020,43 @@ GeckoProfilerReporter::CollectReports(ns
     "Memory used by LUL, a stack unwinder used by the Gecko Profiler.");
 #endif
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(GeckoProfilerReporter, nsIMemoryReporter)
 
+static bool
+HasFeature(const char** aFeatures, uint32_t aFeatureCount, const char* aFeature)
+{
+  for (size_t i = 0; i < aFeatureCount; i++) {
+    if (strcmp(aFeatures[i], aFeature) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+uint32_t
+ParseFeaturesFromStringArray(const char** aFeatures, uint32_t aFeatureCount)
+{
+  #define ADD_FEATURE_BIT(n_, str_, Name_) \
+    if (HasFeature(aFeatures, aFeatureCount, str_)) { \
+      features |= ProfilerFeature::Name_; \
+    }
+
+  uint32_t features = 0;
+  PROFILER_FOR_EACH_FEATURE(ADD_FEATURE_BIT)
+
+  #undef ADD_FEATURE_BIT
+
+  return features;
+}
+
 // Find the ThreadInfo for the current thread. This should only be called in
 // places where TLSInfo can't be used. On success, *aIndexOut is set to the
 // index if it is non-null.
 static ThreadInfo*
 FindLiveThreadInfo(PSLockRef aLock, int* aIndexOut = nullptr)
 {
   ThreadInfo* ret = nullptr;
   Thread::tid_t id = Thread::GetCurrentId();
@@ -2101,42 +2164,70 @@ MozGlueLabelEnter(const char* aLabel, co
 void
 MozGlueLabelExit(PseudoStack* aPseudoStack)
 {
   if (aPseudoStack) {
     aPseudoStack->pop();
   }
 }
 
+static nsTArray<const char*>
+SplitAtCommas(const char* aString, UniquePtr<char[]>& aStorage)
+{
+  size_t len = strlen(aString);
+  aStorage = MakeUnique<char[]>(len + 1);
+  PodCopy(aStorage.get(), aString, len + 1);
+
+  // Iterate over all characters in aStorage and split at commas, by
+  // overwriting commas with the null char.
+  nsTArray<const char*> array;
+  size_t currentElementStart = 0;
+  for (size_t i = 0; i <= len; i++) {
+    if (aStorage[i] == ',') {
+      aStorage[i] = '\0';
+    }
+    if (aStorage[i] == '\0') {
+      array.AppendElement(&aStorage[currentElementStart]);
+      currentElementStart = i + 1;
+    }
+  }
+  return array;
+}
+
 void
 profiler_init(void* aStackTop)
 {
   LOG("profiler_init");
 
   MOZ_RELEASE_ASSERT(!CorePS::Exists());
 
+  if (getenv("MOZ_PROFILER_HELP")) {
+    PrintUsageThenExit(0); // terminates execution
+  }
+
   SharedLibraryInfo::Initialize();
 
   uint32_t features =
 #if defined(GP_OS_android)
                       ProfilerFeature::Java |
 #endif
                       ProfilerFeature::JS |
                       ProfilerFeature::Leaf |
 #if defined(HAVE_NATIVE_UNWIND)
                       ProfilerFeature::StackWalk |
 #endif
                       ProfilerFeature::Threads |
                       0;
 
-  const char* filters[] = { "GeckoMain", "Compositor", "DOM Worker" };
-
-  if (getenv("MOZ_PROFILER_HELP")) {
-    PrintUsageThenExit(0); // terminates execution
-  }
+  UniquePtr<char[]> filterStorage;
+
+  nsTArray<const char*> filters;
+  filters.AppendElement("GeckoMain");
+  filters.AppendElement("Compositor");
+  filters.AppendElement("DOM Worker");
 
   int entries = PROFILER_DEFAULT_ENTRIES;
   double interval = PROFILER_DEFAULT_INTERVAL;
 
   {
     PSAutoLock lock(gPSMutex);
 
     // We've passed the possible failure point. Instantiate CorePS, which
@@ -2162,52 +2253,83 @@ profiler_init(void* aStackTop)
     RegisterProfilerLabelEnterExit(MozGlueLabelEnter, MozGlueLabelExit);
 
     // (Linux-only) We could create CorePS::mLul and read unwind info into it
     // at this point. That would match the lifetime implied by destruction of
     // it in profiler_shutdown() just below. However, that gives a big delay on
     // startup, even if no profiling is actually to be done. So, instead, it is
     // created on demand at the first call to PlatformStart().
 
-    if (!getenv("MOZ_PROFILER_STARTUP")) {
+    const char* startupEnv = getenv("MOZ_PROFILER_STARTUP");
+    if (!startupEnv || startupEnv[0] == '\0') {
       return;
     }
 
     LOG("- MOZ_PROFILER_STARTUP is set");
 
     const char* startupEntries = getenv("MOZ_PROFILER_STARTUP_ENTRIES");
-    if (startupEntries) {
+    if (startupEntries && startupEntries[0] != '\0') {
       errno = 0;
       entries = strtol(startupEntries, nullptr, 10);
       if (errno == 0 && entries > 0) {
         LOG("- MOZ_PROFILER_STARTUP_ENTRIES = %d", entries);
       } else {
         PrintUsageThenExit(1);
       }
     }
 
     const char* startupInterval = getenv("MOZ_PROFILER_STARTUP_INTERVAL");
-    if (startupInterval) {
+    if (startupInterval && startupInterval[0] != '\0') {
       errno = 0;
       interval = PR_strtod(startupInterval, nullptr);
       if (errno == 0 && interval > 0.0 && interval <= 1000.0) {
         LOG("- MOZ_PROFILER_STARTUP_INTERVAL = %f", interval);
       } else {
         PrintUsageThenExit(1);
       }
     }
 
+    const char* startupFeaturesBitfield =
+      getenv("MOZ_PROFILER_STARTUP_FEATURES_BITFIELD");
+    if (startupFeaturesBitfield && startupFeaturesBitfield[0] != '\0') {
+      errno = 0;
+      features = strtol(startupFeaturesBitfield, nullptr, 10);
+      if (errno == 0 && features != 0) {
+        LOG("- MOZ_PROFILER_STARTUP_FEATURES_BITFIELD = %d", features);
+      } else {
+        PrintUsageThenExit(1);
+      }
+    } else {
+      const char* startupFeatures = getenv("MOZ_PROFILER_STARTUP_FEATURES");
+      if (startupFeatures && startupFeatures[0] != '\0') {
+        // Interpret startupFeatures as a list of feature strings, separated by
+        // commas.
+        UniquePtr<char[]> featureStringStorage;
+        nsTArray<const char*> featureStringArray =
+          SplitAtCommas(startupFeatures, featureStringStorage);
+        features = ParseFeaturesFromStringArray(featureStringArray.Elements(),
+                                                featureStringArray.Length());
+        LOG("- MOZ_PROFILER_STARTUP_FEATURES = %d", features);
+      }
+    }
+
+    const char* startupFilters = getenv("MOZ_PROFILER_STARTUP_FILTERS");
+    if (startupFilters && startupFilters[0] != '\0') {
+      filters = SplitAtCommas(startupFilters, filterStorage);
+      LOG("- MOZ_PROFILER_STARTUP_FILTERS = %s", startupFilters);
+    }
+
     locked_profiler_start(lock, entries, interval, features,
-                          filters, MOZ_ARRAY_LENGTH(filters));
+                          filters.Elements(), filters.Length());
   }
 
   // We do this with gPSMutex unlocked. The comment in profiler_stop() explains
   // why.
-  NotifyProfilerStarted(entries, interval, features, filters,
-                        MOZ_ARRAY_LENGTH(filters));
+  NotifyProfilerStarted(entries, interval, features,
+                        filters.Elements(), filters.Length());
 }
 
 static void
 locked_profiler_save_profile_to_file(PSLockRef aLock, const char* aFilename);
 
 static SamplerThread*
 locked_profiler_stop(PSLockRef aLock);
 
@@ -2306,16 +2428,70 @@ profiler_get_start_params(int* aEntries,
 
   const Vector<std::string>& filters = ActivePS::Filters(lock);
   MOZ_ALWAYS_TRUE(aFilters->resize(filters.length()));
   for (uint32_t i = 0; i < filters.length(); ++i) {
     (*aFilters)[i] = filters[i].c_str();
   }
 }
 
+AutoSetProfilerEnvVarsForChildProcess::AutoSetProfilerEnvVarsForChildProcess(
+  MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
+{
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+
+  MOZ_RELEASE_ASSERT(CorePS::Exists());
+
+  PSAutoLock lock(gPSMutex);
+
+  if (!ActivePS::Exists(lock)) {
+    PR_SetEnv("MOZ_PROFILER_STARTUP=");
+    return;
+  }
+
+  PR_SetEnv("MOZ_PROFILER_STARTUP=1");
+  SprintfLiteral(mSetEntries, "MOZ_PROFILER_STARTUP_ENTRIES=%d",
+                 ActivePS::Entries(lock));
+  PR_SetEnv(mSetEntries);
+
+  SprintfLiteral(mSetInterval, "MOZ_PROFILER_STARTUP_INTERVAL=%f",
+                 ActivePS::Interval(lock));
+  PR_SetEnv(mSetInterval);
+
+  SprintfLiteral(mSetFeaturesBitfield,
+                 "MOZ_PROFILER_STARTUP_FEATURES_BITFIELD=%d",
+                 ActivePS::Features(lock));
+  PR_SetEnv(mSetFeaturesBitfield);
+
+  std::string filtersString;
+  const Vector<std::string>& filters = ActivePS::Filters(lock);
+  for (uint32_t i = 0; i < filters.length(); ++i) {
+    filtersString += filters[i];
+    if (i != filters.length() - 1) {
+      filtersString += ",";
+    }
+  }
+  SprintfLiteral(mSetFilters, "MOZ_PROFILER_STARTUP_FILTERS=%s",
+                 filtersString.c_str());
+  PR_SetEnv(mSetFilters);
+}
+
+AutoSetProfilerEnvVarsForChildProcess::~AutoSetProfilerEnvVarsForChildProcess()
+{
+  // Our current process doesn't look at these variables after startup, so we
+  // can just unset all the variables. This allows us to use literal strings,
+  // which will be valid for the whole life time of the program and can be
+  // passed to PR_SetEnv without problems.
+  PR_SetEnv("MOZ_PROFILER_STARTUP=");
+  PR_SetEnv("MOZ_PROFILER_STARTUP_ENTRIES=");
+  PR_SetEnv("MOZ_PROFILER_STARTUP_INTERVAL=");
+  PR_SetEnv("MOZ_PROFILER_STARTUP_FEATURES_BITFIELD=");
+  PR_SetEnv("MOZ_PROFILER_STARTUP_FILTERS=");
+}
+
 static void
 locked_profiler_save_profile_to_file(PSLockRef aLock, const char* aFilename)
 {
   LOG("locked_profiler_save_profile_to_file(%s)", aFilename);
 
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
   std::ofstream stream;
@@ -2514,16 +2690,63 @@ profiler_start(int aEntries, double aInt
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
   }
   NotifyProfilerStarted(aEntries, aInterval, aFeatures,
                         aFilters, aFilterCount);
 }
 
+void
+profiler_ensure_started(int aEntries, double aInterval, uint32_t aFeatures,
+                        const char** aFilters, uint32_t aFilterCount)
+{
+  LOG("profiler_ensure_started");
+
+  bool startedProfiler = false;
+  SamplerThread* samplerThread = nullptr;
+  {
+    PSAutoLock lock(gPSMutex);
+
+    // Initialize if necessary.
+    if (!CorePS::Exists()) {
+      profiler_init(nullptr);
+    }
+
+    if (ActivePS::Exists(lock)) {
+      // The profiler is active.
+      if (!ActivePS::Equals(lock, aEntries, aInterval, aFeatures,
+                            aFilters, aFilterCount)) {
+        // Stop and restart with different settings.
+        samplerThread = locked_profiler_stop(lock);
+        locked_profiler_start(lock, aEntries, aInterval, aFeatures,
+                              aFilters, aFilterCount);
+        startedProfiler = true;
+      }
+    } else {
+      // The profiler is stopped.
+      locked_profiler_start(lock, aEntries, aInterval, aFeatures,
+                            aFilters, aFilterCount);
+      startedProfiler = true;
+    }
+  }
+
+  // We do these operations with gPSMutex unlocked. The comments in
+  // profiler_stop() explain why.
+  if (samplerThread) {
+    ProfilerParent::ProfilerStopped();
+    NotifyObservers("profiler-stopped");
+    delete samplerThread;
+  }
+  if (startedProfiler) {
+    NotifyProfilerStarted(aEntries, aInterval, aFeatures,
+                          aFilters, aFilterCount);
+  }
+}
+
 static MOZ_MUST_USE SamplerThread*
 locked_profiler_stop(PSLockRef aLock)
 {
   LOG("locked_profiler_stop");
 
   MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock));
 
   // At the very start, clear RacyFeatures.
--- a/tools/profiler/core/platform.h
+++ b/tools/profiler/core/platform.h
@@ -122,9 +122,13 @@ typedef mozilla::UniquePtr<PlatformData,
   UniquePlatformData;
 UniquePlatformData AllocPlatformData(int aThreadId);
 
 namespace mozilla {
 class JSONWriter;
 }
 void AppendSharedLibraries(mozilla::JSONWriter& aWriter);
 
+// Convert the array of strings to a bitfield.
+uint32_t ParseFeaturesFromStringArray(const char** aFeatures,
+                                      uint32_t aFeatureCount);
+
 #endif /* ndef TOOLS_PLATFORM_H_ */
--- a/tools/profiler/gecko/PProfiler.ipdl
+++ b/tools/profiler/gecko/PProfiler.ipdl
@@ -13,16 +13,17 @@ namespace mozilla {
 // those processes.
 // It is a top-level protocol so that its child endpoint can be on a
 // background thread, so that profiles can be gathered even if the main thread
 // is unresponsive.
 async protocol PProfiler
 {
 child:
   async Start(ProfilerInitParams params);
+  async EnsureStarted(ProfilerInitParams params);
   async Stop();
   async Pause();
   async Resume();
 
   async GatherProfile() returns (nsCString profile);
 };
 
 } // namespace mozilla
--- a/tools/profiler/gecko/ProfilerChild.cpp
+++ b/tools/profiler/gecko/ProfilerChild.cpp
@@ -34,16 +34,31 @@ ProfilerChild::RecvStart(const ProfilerI
                  params.features(),
                  filterArray.Elements(),
                  filterArray.Length());
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+ProfilerChild::RecvEnsureStarted(const ProfilerInitParams& params)
+{
+  nsTArray<const char*> filterArray;
+  for (size_t i = 0; i < params.filters().Length(); ++i) {
+    filterArray.AppendElement(params.filters()[i].get());
+  }
+
+  profiler_ensure_started(params.entries(), params.interval(),
+                          params.features(),
+                          filterArray.Elements(), filterArray.Length());
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 ProfilerChild::RecvStop()
 {
   profiler_stop();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ProfilerChild::RecvPause()
--- a/tools/profiler/gecko/ProfilerParent.cpp
+++ b/tools/profiler/gecko/ProfilerParent.cpp
@@ -125,36 +125,42 @@ ProfilerParent::ProfilerParent()
 
 void
 ProfilerParent::Init()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   ProfilerParentTracker::StartTracking(this);
 
-  if (profiler_is_active()) {
-    // If the profiler is already running in this process, start it in the
-    // child process immediately.
-    int entries = 0;
-    double interval = 0;
-    mozilla::Vector<const char*> filters;
-    uint32_t features;
-    profiler_get_start_params(&entries, &interval, &features, &filters);
+  // We propagated the profiler state from the parent process to the child
+  // process through MOZ_PROFILER_STARTUP* environment variables.
+  // However, the profiler state might have changed in this process since then,
+  // and now that an active communication channel has been established with the
+  // child process, it's a good time to sync up the two profilers again.
 
+  int entries = 0;
+  double interval = 0;
+  mozilla::Vector<const char*> filters;
+  uint32_t features;
+  profiler_get_start_params(&entries, &interval, &features, &filters);
+
+  if (entries != 0) {
     ProfilerInitParams ipcParams;
     ipcParams.enabled() = true;
     ipcParams.entries() = entries;
     ipcParams.interval() = interval;
     ipcParams.features() = features;
 
     for (uint32_t i = 0; i < filters.length(); ++i) {
       ipcParams.filters().AppendElement(filters[i]);
     }
 
-    Unused << SendStart(ipcParams);
+    Unused << SendEnsureStarted(ipcParams);
+  } else {
+    Unused << SendStop();
   }
 }
 
 ProfilerParent::~ProfilerParent()
 {
   MOZ_COUNT_DTOR(ProfilerParent);
 
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
--- a/tools/profiler/gecko/nsProfiler.cpp
+++ b/tools/profiler/gecko/nsProfiler.cpp
@@ -86,49 +86,28 @@ nsProfiler::Observe(nsISupports *aSubjec
 
 NS_IMETHODIMP
 nsProfiler::CanProfile(bool *aCanProfile)
 {
   *aCanProfile = !mLockedForPrivateBrowsing;
   return NS_OK;
 }
 
-static bool
-HasFeature(const char** aFeatures, uint32_t aFeatureCount, const char* aFeature)
-{
-  for (size_t i = 0; i < aFeatureCount; i++) {
-    if (strcmp(aFeatures[i], aFeature) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
 NS_IMETHODIMP
 nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
                           const char** aFeatures, uint32_t aFeatureCount,
                           const char** aFilters, uint32_t aFilterCount)
 {
   if (mLockedForPrivateBrowsing) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  #define ADD_FEATURE_BIT(n_, str_, Name_) \
-    if (HasFeature(aFeatures, aFeatureCount, str_)) { \
-      features |= ProfilerFeature::Name_; \
-    }
-
-  // Convert the array of strings to a bitfield.
-  uint32_t features = 0;
-  PROFILER_FOR_EACH_FEATURE(ADD_FEATURE_BIT)
-
-  #undef ADD_FEATURE_BIT
-
   ResetGathering();
 
+  uint32_t features = ParseFeaturesFromStringArray(aFeatures, aFeatureCount);
   profiler_start(aEntries, aInterval, features, aFilters, aFilterCount);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsProfiler::StopProfiler()
 {
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -157,16 +157,26 @@ PROFILER_FUNC_VOID(profiler_shutdown())
 PROFILER_FUNC_VOID(profiler_start(int aEntries, double aInterval,
                                   uint32_t aFeatures,
                                   const char** aFilters, uint32_t aFilterCount))
 
 // Stop the profiler and discard the profile without saving it. A no-op if the
 // profiler is inactive. After stopping the profiler is "inactive".
 PROFILER_FUNC_VOID(profiler_stop())
 
+// If the profiler is inactive, start it. If it's already active, restart it if
+// the requested settings differ from the current settings. Both the check and
+// the state change are performed while the profiler state is locked.
+// The only difference to profiler_start is that the current buffer contents are
+// not discarded if the profiler is already running with the requested settings.
+PROFILER_FUNC_VOID(profiler_ensure_started(int aEntries, double aInterval,
+                                           uint32_t aFeatures,
+                                           const char** aFilters,
+                                           uint32_t aFilterCount))
+
 //---------------------------------------------------------------------------
 // Control the profiler
 //---------------------------------------------------------------------------
 
 // Register/unregister threads with the profiler. Both functions operate the
 // same whether the profiler is active or inactive.
 PROFILER_FUNC_VOID(profiler_register_thread(const char* name,
                                             void* guessStackTop))
@@ -626,11 +636,34 @@ public:
   }
 
 protected:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   const char* mCategory;
   const char* mMarkerName;
 };
 
+// Set MOZ_PROFILER_STARTUP* environment variables that will be inherited into
+// a child process that is about to be launched, in order to make that child
+// process start with the same profiler settings as in the current process.
+#ifdef MOZ_GECKO_PROFILER
+class MOZ_RAII AutoSetProfilerEnvVarsForChildProcess
+{
+public:
+  explicit AutoSetProfilerEnvVarsForChildProcess(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
+  ~AutoSetProfilerEnvVarsForChildProcess();
+
+private:
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+  char mSetEntries[64];
+  char mSetInterval[64];
+  char mSetFeaturesBitfield[64];
+  char mSetFilters[1024];
+};
+#else
+class AutoSetProfilerEnvVarsForChildProcess
+{
+};
+#endif
+
 } // namespace mozilla
 
 #endif  // GeckoProfiler_h
--- a/tools/profiler/public/ProfilerChild.h
+++ b/tools/profiler/public/ProfilerChild.h
@@ -31,16 +31,17 @@ class ProfilerChild final : public PProf
   nsCString GrabShutdownProfile();
 
   void Destroy();
 
 private:
   virtual ~ProfilerChild();
 
   mozilla::ipc::IPCResult RecvStart(const ProfilerInitParams& params) override;
+  mozilla::ipc::IPCResult RecvEnsureStarted(const ProfilerInitParams& params) override;
   mozilla::ipc::IPCResult RecvStop() override;
   mozilla::ipc::IPCResult RecvPause() override;
   mozilla::ipc::IPCResult RecvResume() override;
   mozilla::ipc::IPCResult RecvGatherProfile(GatherProfileResolver&& aResolve) override;
 
   void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
 
   nsCOMPtr<nsIThread> mThread;
--- a/tools/profiler/tasktracer/GeckoTaskTracer.h
+++ b/tools/profiler/tasktracer/GeckoTaskTracer.h
@@ -141,17 +141,17 @@ UniquePtr<nsTArray<nsCString>> GetLogged
 
 // Returns the timestamp when Task Tracer is enabled in this process.
 PRTime GetStartTime();
 
 /**
  * Internal functions.
  */
 
-already_AddRefed<Runnable>
+already_AddRefed<nsIRunnable>
 CreateTracedRunnable(already_AddRefed<nsIRunnable>&& aRunnable);
 
 // Free the TraceInfo allocated on a thread's TLS. Currently we are wrapping
 // tasks running on nsThreads and base::thread, so FreeTraceInfo is called at
 // where nsThread and base::thread release themselves.
 void FreeTraceInfo();
 
 const char* GetJSLabelPrefix();
--- a/tools/profiler/tasktracer/TracedTaskCommon.cpp
+++ b/tools/profiler/tasktracer/TracedTaskCommon.cpp
@@ -90,16 +90,19 @@ TracedTaskCommon::ClearTLSTraceInfo()
   info->mCurTraceSourceId = 0;
   info->mCurTraceSourceType = SourceEventType::Unknown;
   info->mCurTaskId = 0;
 }
 
 /**
  * Implementation of class TracedRunnable.
  */
+
+NS_IMPL_ISUPPORTS(TracedRunnable, nsIRunnable);
+
 TracedRunnable::TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj)
   : TracedTaskCommon()
   , mOriginalObj(Move(aOriginalObj))
 {
   Init();
   LogVirtualTablePtr(mTaskId, mSourceEventId, *reinterpret_cast<uintptr_t**>(mOriginalObj.get()));
 }
 
@@ -118,20 +121,20 @@ TracedRunnable::Run()
 
   return rv;
 }
 
 /**
  * CreateTracedRunnable() returns a TracedRunnable wrapping the original
  * nsIRunnable object, aRunnable.
  */
-already_AddRefed<Runnable>
+already_AddRefed<nsIRunnable>
 CreateTracedRunnable(already_AddRefed<nsIRunnable>&& aRunnable)
 {
-  RefPtr<Runnable> runnable = new TracedRunnable(Move(aRunnable));
+  RefPtr<nsIRunnable> runnable = new TracedRunnable(Move(aRunnable));
   return runnable.forget();
 }
 
 void
 VirtualTask::AutoRunTask::StartScope(VirtualTask* aTask)
 {
   mTask->SetTLSTraceInfo();
   LogBegin(mTask->mTaskId, mTask->mSourceEventId);
--- a/tools/profiler/tasktracer/TracedTaskCommon.h
+++ b/tools/profiler/tasktracer/TracedTaskCommon.h
@@ -53,19 +53,20 @@ protected:
   SourceEventType mSourceEventType;
   uint64_t mSourceEventId;
   uint64_t mParentTaskId;
   uint64_t mTaskId;
   bool mIsTraceInfoInit;
 };
 
 class TracedRunnable : public TracedTaskCommon
-                     , public Runnable
+                     , public nsIRunnable
 {
 public:
+  NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIRUNNABLE
 
   explicit TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj);
 
 private:
   virtual ~TracedRunnable();
 
   nsCOMPtr<nsIRunnable> mOriginalObj;
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -166,16 +166,89 @@ TEST(GeckoProfiler, FeaturesAndParams)
     // These calls are no-ops.
     profiler_stop();
     profiler_stop();
 
     InactiveFeaturesAndParamsCheck();
   }
 }
 
+TEST(GeckoProfiler, EnsureStarted)
+{
+  InactiveFeaturesAndParamsCheck();
+
+  uint32_t features = ProfilerFeature::JS | ProfilerFeature::Threads;
+  const char* filters[] = { "GeckoMain", "Compositor" };
+  {
+    // Inactive -> Active
+    profiler_ensure_started(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                            features, filters, MOZ_ARRAY_LENGTH(filters));
+
+    ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                      features, filters, MOZ_ARRAY_LENGTH(filters));
+  }
+
+  {
+    // Active -> Active with same settings
+
+    // First, write some samples into the buffer.
+    PR_Sleep(PR_MillisecondsToInterval(500));
+
+    uint32_t currPos1, entries1, generation1;
+    profiler_get_buffer_info(&currPos1, &entries1, &generation1);
+    ASSERT_TRUE(generation1 > 0 || currPos1 > 0);
+
+    // Call profiler_ensure_started with the same settings as before.
+    // This operation must not clear our buffer!
+    profiler_ensure_started(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                            features, filters, MOZ_ARRAY_LENGTH(filters));
+
+    ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                      features, filters, MOZ_ARRAY_LENGTH(filters));
+
+    // Check that our position in the buffer stayed the same or advanced.
+    // In particular, it shouldn't have reverted to the start.
+    uint32_t currPos2, entries2, generation2;
+    profiler_get_buffer_info(&currPos2, &entries2, &generation2);
+    ASSERT_TRUE(generation2 >= generation1);
+    ASSERT_TRUE(generation2 > generation1 || currPos2 >= currPos1);
+  }
+
+  {
+    // Active -> Active with *different* settings
+
+    uint32_t currPos1, entries1, generation1;
+    profiler_get_buffer_info(&currPos1, &entries1, &generation1);
+
+    // Call profiler_ensure_started with a different feature set than the one it's
+    // currently running with. This is supposed to stop and restart the
+    // profiler, thereby discarding the buffer contents.
+    uint32_t differentFeatures = features | ProfilerFeature::Leaf;
+    profiler_ensure_started(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                            differentFeatures,
+                            filters, MOZ_ARRAY_LENGTH(filters));
+
+    ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
+                      differentFeatures, filters, MOZ_ARRAY_LENGTH(filters));
+
+    uint32_t currPos2, entries2, generation2;
+    profiler_get_buffer_info(&currPos2, &entries2, &generation2);
+    ASSERT_TRUE(generation2 <= generation1);
+    ASSERT_TRUE(generation2 < generation1 || currPos2 < currPos1);
+  }
+
+  {
+    // Active -> Inactive
+
+    profiler_stop();
+
+    InactiveFeaturesAndParamsCheck();
+  }
+}
+
 TEST(GeckoProfiler, DifferentThreads)
 {
   InactiveFeaturesAndParamsCheck();
 
   nsCOMPtr<nsIThread> thread;
   nsresult rv = NS_NewNamedThread("GeckoProfGTest", getter_AddRefs(thread));
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
--- a/tools/tryselect/mach_commands.py
+++ b/tools/tryselect/mach_commands.py
@@ -1,25 +1,36 @@
 # 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/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import argparse
+import os
+import sys
 
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
     Command,
     SubCommand,
 )
 
 from mozbuild.base import BuildEnvironmentNotFoundException, MachCommandBase
 
+CONFIG_ENVIRONMENT_NOT_FOUND = '''
+No config environment detected. This means we are unable to properly
+detect test files in the specified paths or tags. Please run:
+
+    $ mach configure
+
+and try again.
+'''.lstrip()
+
 
 def syntax_parser():
     from tryselect.selectors.syntax import arg_parser
     parser = arg_parser()
     # The --no-artifact flag is only interpreted locally by |mach try|; it's not
     # like the --artifact flag, which is interpreted remotely by the try server.
     #
     # We need a tri-state where set is different than the default value, so we
@@ -106,13 +117,18 @@ class TrySelect(MachCommandBase):
             if self.substs.get("MOZ_ARTIFACT_BUILDS"):
                 kwargs['local_artifact_build'] = True
         except BuildEnvironmentNotFoundException:
             # If we don't have a build locally, we can't tell whether
             # an artifact build is desired, but we still want the
             # command to succeed, if possible.
             pass
 
+        config_status = os.path.join(self.topobjdir, 'config.status')
+        if (kwargs['paths'] or kwargs['tags']) and not config_status:
+            print(CONFIG_ENVIRONMENT_NOT_FOUND)
+            sys.exit(1)
+
         def resolver_func():
             return self._spawn(TestResolver)
 
         at = AutoTry(self.topsrcdir, resolver_func, self._mach_context)
         return at.run(**kwargs)
--- a/tools/tryselect/selectors/syntax.py
+++ b/tools/tryselect/selectors/syntax.py
@@ -10,25 +10,16 @@ import os
 import re
 import subprocess
 import sys
 import which
 from collections import defaultdict
 
 import mozpack.path as mozpath
 
-CONFIG_ENVIRONMENT_NOT_FOUND = '''
-No config environment detected. This means we are unable to properly
-detect test files in the specified paths or tags. Please run:
-
-    $ mach configure
-
-and try again.
-'''.lstrip()
-
 
 def arg_parser():
     parser = argparse.ArgumentParser()
     parser.add_argument('paths', nargs='*', help='Paths to search for tests to run on try.')
     parser.add_argument('-b', '--build', dest='builds', default='do',
                         help='Build types to run (d for debug, o for optimized).')
     parser.add_argument('-p', '--platform', dest='platforms', action='append',
                         help='Platforms to run (required if not found in the environment as '
@@ -724,20 +715,16 @@ class AutoTry(object):
             sys.exit(1)
 
         if not any(kwargs[item] for item in ("paths", "tests", "tags")):
             kwargs["paths"], kwargs["tags"] = self.find_paths_and_tags(kwargs["verbose"])
 
         builds, platforms, tests, talos, jobs, paths, tags, extra = self.validate_args(**kwargs)
 
         if paths or tags:
-            if not os.path.exists(os.path.join(self.topobjdir, 'config.status')):
-                print(CONFIG_ENVIRONMENT_NOT_FOUND)
-                sys.exit(1)
-
             paths = [os.path.relpath(os.path.normpath(os.path.abspath(item)), self.topsrcdir)
                      for item in paths]
             paths_by_flavor = self.paths_by_flavor(paths=paths, tags=tags)
 
             if not paths_by_flavor and not tests:
                 print("No tests were found when attempting to resolve paths:\n\n\t%s" %
                       paths)
                 sys.exit(1)
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -168,16 +168,19 @@ GetPrefNameForFeature(int32_t aFeature)
       name = BLACKLIST_PREF_BRANCH "canvas2d.acceleration";
       break;
     case nsIGfxInfo::FEATURE_WEBGL2:
       name = BLACKLIST_PREF_BRANCH "webgl2";
       break;
     case nsIGfxInfo::FEATURE_ADVANCED_LAYERS:
       name = BLACKLIST_PREF_BRANCH "layers.advanced";
       break;
+    case nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX:
+      name = BLACKLIST_PREF_BRANCH "d3d11.keyed.mutex";
+      break;
     case nsIGfxInfo::FEATURE_VP8_HW_DECODE:
     case nsIGfxInfo::FEATURE_VP9_HW_DECODE:
     case nsIGfxInfo::FEATURE_DX_INTEROP2:
     case nsIGfxInfo::FEATURE_GPU_PROCESS:
       // We don't provide prefs for these features.
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
@@ -350,16 +353,18 @@ BlacklistFeatureToGfxFeature(const nsASt
   else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION"))
     return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION;
   else if (aFeature.EqualsLiteral("CANVAS2D_ACCELERATION"))
       return nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION;
   else if (aFeature.EqualsLiteral("WEBGL2"))
     return nsIGfxInfo::FEATURE_WEBGL2;
   else if (aFeature.EqualsLiteral("ADVANCED_LAYERS"))
     return nsIGfxInfo::FEATURE_ADVANCED_LAYERS;
+  else if (aFeature.EqualsLiteral("D3D11_KEYED_MUTEX"))
+    return nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX;
 
   // If we don't recognize the feature, it may be new, and something
   // this version doesn't understand.  So, nothing to do.  This is
   // different from feature not being specified at all, in which case
   // this method should not get called and we should continue with the
   // "all features" blocklisting.
   return -1;
 }
@@ -981,16 +986,17 @@ GfxInfoBase::EvaluateDownloadedBlacklist
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_ENCODE,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_DECODE,
     nsIGfxInfo::FEATURE_WEBGL_MSAA,
     nsIGfxInfo::FEATURE_STAGEFRIGHT,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION,
     nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION,
     nsIGfxInfo::FEATURE_WEBGL2,
     nsIGfxInfo::FEATURE_ADVANCED_LAYERS,
+    nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX,
     0
   };
 
   // For every feature we know about, we evaluate whether this blacklist has a
   // non-STATUS_OK status. If it does, we set the pref we evaluate in
   // GetFeatureStatus above, so we don't need to hold on to this blacklist
   // anywhere permanent.
   int i = 0;
--- a/widget/nsIGfxInfo.idl
+++ b/widget/nsIGfxInfo.idl
@@ -121,18 +121,20 @@ interface nsIGfxInfo : nsISupports
   /* Whether NV_dx_interop2 is supported, starting in 50. */
   const long FEATURE_DX_INTEROP2 = 19;
   /* Whether the GPU process is supported, starting in 52. */
   const long FEATURE_GPU_PROCESS = 20;
   /* Whether the WebGL2 is supported, starting in 54 */
   const long FEATURE_WEBGL2 = 21;
   /* Whether Advanced Layers is supported, starting in 56 */
   const long FEATURE_ADVANCED_LAYERS = 22;
+  /* Whether D3D11 keyed mutex is supported, starting in 56 */
+  const long FEATURE_D3D11_KEYED_MUTEX = 23;
   /* the maximum feature value. */
-  const long FEATURE_MAX_VALUE = FEATURE_ADVANCED_LAYERS;
+  const long FEATURE_MAX_VALUE = FEATURE_D3D11_KEYED_MUTEX;
 
   /*
    * A set of return values from GetFeatureStatus
    */
 
   /* The driver is safe to the best of our knowledge */
   const long FEATURE_STATUS_OK = 1;
   /* We don't know the status of the feature yet. The analysis probably hasn't finished yet. */
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1313,16 +1313,27 @@ GfxInfo::GetGfxDriverInfo()
     ////////////////////////////////////
     // FEATURE_DX_INTEROP2
 
     // All AMD.
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_DX_INTEROP2, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "DX_INTEROP2_AMD_CRASH");
+
+    ////////////////////////////////////
+    // FEATURE_D3D11_KEYED_MUTEX
+
+    // bug 1359416
+    APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel),
+      (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelHDGraphicsToSandyBridge),
+      nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
+      DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_BUG_1359416");
+
   }
   return *mDriverInfo;
 }
 
 nsresult
 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
                               int32_t *aStatus,
                               nsAString & aSuggestedDriverVersion,