Merge inbound to mozilla-central. a=merge
authorBogdan Tara <btara@mozilla.com>
Mon, 11 Feb 2019 23:55:15 +0200
changeset 516429 b9187fa10f13
parent 516408 6d8e6f960446 (current diff)
parent 516428 26c4e662c4fa (diff)
child 516465 21620d9c3bb4
child 516498 42a097167d36
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone67.0a1
first release with
nightly linux32
b9187fa10f13 / 67.0a1 / 20190211215545 / files
nightly linux64
b9187fa10f13 / 67.0a1 / 20190211215545 / files
nightly mac
b9187fa10f13 / 67.0a1 / 20190211215545 / files
nightly win32
b9187fa10f13 / 67.0a1 / 20190211215545 / files
nightly win64
b9187fa10f13 / 67.0a1 / 20190211215545 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
js/src/wasm/WasmStubs.cpp
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1520,17 +1520,21 @@ pref("toolkit.telemetry.hybridContent.en
 pref("browser.ping-centre.telemetry", true);
 pref("browser.ping-centre.log", false);
 pref("browser.ping-centre.staging.endpoint", "https://onyx_tiles.stage.mozaws.net/v3/links/ping-centre");
 pref("browser.ping-centre.production.endpoint", "https://tiles.services.mozilla.com/v3/links/ping-centre");
 
 // Enable GMP support in the addon manager.
 pref("media.gmp-provider.enabled", true);
 
+// Enable blocking access to storage from tracking resources only in nightly
+// and early beta. By default the value is 0: BEHAVIOR_ACCEPT
+#ifdef EARLY_BETA_OR_EARLIER
 pref("network.cookie.cookieBehavior", 4 /* BEHAVIOR_REJECT_TRACKER */);
+#endif
 
 pref("browser.contentblocking.allowlist.storage.enabled", true);
 
 pref("dom.storage_access.enabled", true);
 
 pref("dom.storage_access.auto_grants", true);
 pref("dom.storage_access.max_concurrent_auto_grants", 5);
 
--- a/browser/components/aboutconfig/content/aboutconfig.css
+++ b/browser/components/aboutconfig/content/aboutconfig.css
@@ -74,31 +74,36 @@ body.config-warning {
   background-image: url("chrome://browser/skin/preferences/in-content/privacy-security.svg");
   background-repeat: no-repeat;
   background-position: 9px center;
   background-size: 16px 16px;
 }
 
 #prefs > tr > td,
 #prefs > tr > th {
-  padding: 0;
+  padding: 4px;
   width: 50%;
   font-weight: inherit;
 }
 
 #prefs > tr > th {
   text-align: unset;
   padding-inline-start: 30px;
 }
 
 #prefs > tr.deleted > th {
   font-weight: bold;
   opacity: 0.4;
 }
 
+#prefs > tr > td.cell-edit,
+#prefs > tr > td.cell-reset {
+  padding: 0;
+}
+
 .cell-value {
   white-space: pre-wrap;
   word-break: break-all;
 }
 
 td.cell-value > form > input[type="text"],
 td.cell-value > form > input[type="number"] {
   -moz-appearance: textfield;
--- a/browser/components/aboutconfig/content/aboutconfig.js
+++ b/browser/components/aboutconfig/content/aboutconfig.js
@@ -129,16 +129,17 @@ class PrefRow {
     this.editCell.appendChild(
       this.editButton = document.createElement("button")
     );
     delete this.resetButton;
 
     nameCell.setAttribute("scope", "row");
     this.valueCell.className = "cell-value";
     this.editCell.className = "cell-edit";
+    this.resetCell.className = "cell-reset";
 
     // Add <wbr> behind dots to prevent line breaking in random mid-word places.
     let parts = this.name.split(".");
     for (let i = 0; i < parts.length - 1; i++) {
       nameCell.append(parts[i] + ".", document.createElement("wbr"));
     }
     nameCell.append(parts[parts.length - 1]);
 
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.1.243
+Current extension version is: 2.2.8
 
-Taken from upstream commit: c0d6e46e
+Taken from upstream commit: dfe7d9bc
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.1.243';
-var pdfjsBuild = 'c0d6e46e';
+var pdfjsVersion = '2.2.8';
+var pdfjsBuild = 'dfe7d9bc';
 
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 
 var pdfjsDisplayAPI = __w_pdfjs_require__(6);
 
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(18);
 
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(19);
@@ -1406,17 +1406,17 @@ function _fetchDocument(worker, source, 
 
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
 
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.1.243',
+    apiVersion: '2.2.8',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -3137,19 +3137,19 @@ const InternalRenderTask = function Inte
       }
     }
 
   }
 
   return InternalRenderTask;
 }();
 
-const version = '2.1.243';
+const version = '2.2.8';
 exports.version = version;
-const build = 'c0d6e46e';
+const build = 'dfe7d9bc';
 exports.build = build;
 
 /***/ }),
 /* 7 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-const pdfjsVersion = '2.1.243';
-const pdfjsBuild = 'c0d6e46e';
+const pdfjsVersion = '2.2.8';
+const pdfjsBuild = 'dfe7d9bc';
 
 const pdfjsCoreWorker = __w_pdfjs_require__(1);
 
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
@@ -370,17 +370,17 @@ var WorkerMessageHandler = {
   },
 
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.1.243';
+    let workerVersion = '2.2.8';
 
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
 
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
@@ -21478,17 +21478,17 @@ var PartialEvaluator = function PartialE
               let baseEncoding = (0, _encodings.getEncoding)(baseEncodingName);
 
               if (baseEncoding && (glyphName = baseEncoding[charcode])) {
                 toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);
                 continue;
               }
             }
 
-            toUnicode[charcode] = String.fromCharCode(code);
+            toUnicode[charcode] = String.fromCodePoint(code);
           }
 
           continue;
         }
 
         toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);
       }
 
@@ -21578,17 +21578,17 @@ var PartialEvaluator = function PartialE
                 continue;
               }
 
               k += 2;
               var w2 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1);
               str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
             }
 
-            map[charCode] = String.fromCharCode.apply(String, str);
+            map[charCode] = String.fromCodePoint.apply(String, str);
           });
           return new _fonts.ToUnicodeMap(map);
         });
       }
 
       return Promise.resolve(null);
     },
     readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) {
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -3644,70 +3644,57 @@ class PDFSidebar {
         if (this.isOpen) {
           this.close();
           return true;
         }
 
         return false;
 
       case SidebarView.THUMBS:
-        this.thumbnailButton.classList.add('toggled');
-        this.outlineButton.classList.remove('toggled');
-        this.attachmentsButton.classList.remove('toggled');
-        this.thumbnailView.classList.remove('hidden');
-        this.outlineView.classList.add('hidden');
-        this.attachmentsView.classList.add('hidden');
-
         if (this.isOpen && isViewChanged) {
-          this._updateThumbnailViewer();
-
           shouldForceRendering = true;
         }
 
         break;
 
       case SidebarView.OUTLINE:
         if (this.outlineButton.disabled) {
           return false;
         }
 
-        this.thumbnailButton.classList.remove('toggled');
-        this.outlineButton.classList.add('toggled');
-        this.attachmentsButton.classList.remove('toggled');
-        this.thumbnailView.classList.add('hidden');
-        this.outlineView.classList.remove('hidden');
-        this.attachmentsView.classList.add('hidden');
         break;
 
       case SidebarView.ATTACHMENTS:
         if (this.attachmentsButton.disabled) {
           return false;
         }
 
-        this.thumbnailButton.classList.remove('toggled');
-        this.outlineButton.classList.remove('toggled');
-        this.attachmentsButton.classList.add('toggled');
-        this.thumbnailView.classList.add('hidden');
-        this.outlineView.classList.add('hidden');
-        this.attachmentsView.classList.remove('hidden');
         break;
 
       default:
         console.error(`PDFSidebar._switchView: "${view}" is not a valid view.`);
         return false;
     }
 
-    this.active = view | 0;
+    this.active = view;
+    this.thumbnailButton.classList.toggle('toggled', view === SidebarView.THUMBS);
+    this.outlineButton.classList.toggle('toggled', view === SidebarView.OUTLINE);
+    this.attachmentsButton.classList.toggle('toggled', view === SidebarView.ATTACHMENTS);
+    this.thumbnailView.classList.toggle('hidden', view !== SidebarView.THUMBS);
+    this.outlineView.classList.toggle('hidden', view !== SidebarView.OUTLINE);
+    this.attachmentsView.classList.toggle('hidden', view !== SidebarView.ATTACHMENTS);
 
     if (forceOpen && !this.isOpen) {
       this.open();
       return true;
     }
 
     if (shouldForceRendering) {
+      this._updateThumbnailViewer();
+
       this._forceRendering();
     }
 
     if (isViewChanged) {
       this._dispatchEvent();
     }
 
     this._hideUINotification(this.active);
@@ -3717,18 +3704,17 @@ class PDFSidebar {
 
   open() {
     if (this.isOpen) {
       return;
     }
 
     this.isOpen = true;
     this.toggleButton.classList.add('toggled');
-    this.outerContainer.classList.add('sidebarMoving');
-    this.outerContainer.classList.add('sidebarOpen');
+    this.outerContainer.classList.add('sidebarMoving', 'sidebarOpen');
 
     if (this.active === SidebarView.THUMBS) {
       this._updateThumbnailViewer();
     }
 
     this._forceRendering();
 
     this._dispatchEvent();
@@ -6882,22 +6868,21 @@ class PDFOutlineViewer {
 
         this._toggleOutlineItem(div, shouldShowAll);
       }
     };
 
     div.insertBefore(toggler, div.firstChild);
   }
 
-  _toggleOutlineItem(root, show) {
+  _toggleOutlineItem(root, show = false) {
     this.lastToggleIsShow = show;
-    let togglers = root.querySelectorAll('.outlineItemToggler');
-
-    for (let i = 0, ii = togglers.length; i < ii; ++i) {
-      togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden');
+
+    for (const toggler of root.querySelectorAll('.outlineItemToggler')) {
+      toggler.classList.toggle('outlineItemsHidden', !show);
     }
   }
 
   toggleOutlineTree() {
     if (!this.outline) {
       return;
     }
 
@@ -10590,87 +10575,54 @@ class SecondaryToolbar {
         if (close) {
           this.close();
         }
       });
     }
   }
 
   _bindCursorToolsListener(buttons) {
-    this.eventBus.on('cursortoolchanged', function (evt) {
-      buttons.cursorSelectToolButton.classList.remove('toggled');
-      buttons.cursorHandToolButton.classList.remove('toggled');
-
-      switch (evt.tool) {
-        case _pdf_cursor_tools.CursorTool.SELECT:
-          buttons.cursorSelectToolButton.classList.add('toggled');
-          break;
-
-        case _pdf_cursor_tools.CursorTool.HAND:
-          buttons.cursorHandToolButton.classList.add('toggled');
-          break;
-      }
+    this.eventBus.on('cursortoolchanged', function ({
+      tool
+    }) {
+      buttons.cursorSelectToolButton.classList.toggle('toggled', tool === _pdf_cursor_tools.CursorTool.SELECT);
+      buttons.cursorHandToolButton.classList.toggle('toggled', tool === _pdf_cursor_tools.CursorTool.HAND);
     });
   }
 
   _bindScrollModeListener(buttons) {
-    function scrollModeChanged(evt) {
-      buttons.scrollVerticalButton.classList.remove('toggled');
-      buttons.scrollHorizontalButton.classList.remove('toggled');
-      buttons.scrollWrappedButton.classList.remove('toggled');
-
-      switch (evt.mode) {
-        case _ui_utils.ScrollMode.VERTICAL:
-          buttons.scrollVerticalButton.classList.add('toggled');
-          break;
-
-        case _ui_utils.ScrollMode.HORIZONTAL:
-          buttons.scrollHorizontalButton.classList.add('toggled');
-          break;
-
-        case _ui_utils.ScrollMode.WRAPPED:
-          buttons.scrollWrappedButton.classList.add('toggled');
-          break;
-      }
-
-      const isScrollModeHorizontal = evt.mode === _ui_utils.ScrollMode.HORIZONTAL;
+    function scrollModeChanged({
+      mode
+    }) {
+      buttons.scrollVerticalButton.classList.toggle('toggled', mode === _ui_utils.ScrollMode.VERTICAL);
+      buttons.scrollHorizontalButton.classList.toggle('toggled', mode === _ui_utils.ScrollMode.HORIZONTAL);
+      buttons.scrollWrappedButton.classList.toggle('toggled', mode === _ui_utils.ScrollMode.WRAPPED);
+      const isScrollModeHorizontal = mode === _ui_utils.ScrollMode.HORIZONTAL;
       buttons.spreadNoneButton.disabled = isScrollModeHorizontal;
       buttons.spreadOddButton.disabled = isScrollModeHorizontal;
       buttons.spreadEvenButton.disabled = isScrollModeHorizontal;
     }
 
     this.eventBus.on('scrollmodechanged', scrollModeChanged);
     this.eventBus.on('secondarytoolbarreset', evt => {
       if (evt.source === this) {
         scrollModeChanged({
           mode: _ui_utils.ScrollMode.VERTICAL
         });
       }
     });
   }
 
   _bindSpreadModeListener(buttons) {
-    function spreadModeChanged(evt) {
-      buttons.spreadNoneButton.classList.remove('toggled');
-      buttons.spreadOddButton.classList.remove('toggled');
-      buttons.spreadEvenButton.classList.remove('toggled');
-
-      switch (evt.mode) {
-        case _ui_utils.SpreadMode.NONE:
-          buttons.spreadNoneButton.classList.add('toggled');
-          break;
-
-        case _ui_utils.SpreadMode.ODD:
-          buttons.spreadOddButton.classList.add('toggled');
-          break;
-
-        case _ui_utils.SpreadMode.EVEN:
-          buttons.spreadEvenButton.classList.add('toggled');
-          break;
-      }
+    function spreadModeChanged({
+      mode
+    }) {
+      buttons.spreadNoneButton.classList.toggle('toggled', mode === _ui_utils.SpreadMode.NONE);
+      buttons.spreadOddButton.classList.toggle('toggled', mode === _ui_utils.SpreadMode.ODD);
+      buttons.spreadEvenButton.classList.toggle('toggled', mode === _ui_utils.SpreadMode.EVEN);
     }
 
     this.eventBus.on('spreadmodechanged', spreadModeChanged);
     this.eventBus.on('secondarytoolbarreset', evt => {
       if (evt.source === this) {
         spreadModeChanged({
           mode: _ui_utils.SpreadMode.NONE
         });
--- a/browser/extensions/pdfjs/moz.yaml
+++ b/browser/extensions/pdfjs/moz.yaml
@@ -15,15 +15,15 @@ origin:
   description: Portable Document Format (PDF) viewer that is built with HTML5
 
   # Full URL for the package's homepage/etc
   # Usually different from repository url
   url: https://github.com/mozilla/pdf.js
 
   # Human-readable identifier for this version/release
   # Generally "version NNN", "tag SSS", "bookmark SSS"
-  release: version 2.1.243
+  release: version 2.2.8
 
   # The package's license, where possible using the mnemonic from
   # https://spdx.org/licenses/
   # Multiple licenses can be specified (as a YAML list)
   # A "LICENSE" file must exist containing the full license text
   license: Apache-2.0
--- a/devtools/client/inspector/rules/test/head.js
+++ b/devtools/client/inspector/rules/test/head.js
@@ -16,24 +16,21 @@ registerCleanupFunction(() => {
 });
 
 var {getInplaceEditorForSpan: inplaceEditor} =
   require("devtools/client/shared/inplace-editor");
 
 const ROOT_TEST_DIR = getRootDirectory(gTestPath);
 const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
 
-const STYLE_INSPECTOR_L10N
-      = new LocalizationHelper("devtools/shared/locales/styleinspector.properties");
-
-Services.prefs.setBoolPref("devtools.inspector.shapesHighlighter.enabled", true);
+const STYLE_INSPECTOR_L10N =
+  new LocalizationHelper("devtools/shared/locales/styleinspector.properties");
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("devtools.defaultColorUnit");
-  Services.prefs.clearUserPref("devtools.inspector.shapesHighlighter.enabled");
 });
 
 /**
  * The rule-view tests rely on a frame-script to be injected in the content test
  * page. So override the shared-head's addTab to load the frame script after the
  * tab was added.
  * FIXME: Refactor the rule-view tests to use the testActor instead of a frame
  * script, so they can run on remote targets too.
--- a/devtools/client/preferences/devtools-client.js
+++ b/devtools/client/preferences/devtools-client.js
@@ -45,18 +45,16 @@ pref("devtools.inspector.show_pseudo_ele
 // The default size for image preview tooltips in the rule-view/computed-view/markup-view
 pref("devtools.inspector.imagePreviewTooltipSize", 300);
 // Enable user agent style inspection in rule-view
 pref("devtools.inspector.showUserAgentStyles", false);
 // Show all native anonymous content
 pref("devtools.inspector.showAllAnonymousContent", false);
 // Show user agent shadow roots
 pref("devtools.inspector.showUserAgentShadowRoots", false);
-// Enable the CSS shapes highlighter
-pref("devtools.inspector.shapesHighlighter.enabled", true);
 // Enable the font highlight-on-hover feature
 pref("devtools.inspector.fonthighlighter.enabled", true);
 // Enable tracking of style changes and the Changes panel in the Inspector
 pref("devtools.inspector.changes.enabled", true);
 // Enable the new Rules View
 pref("devtools.inspector.new-rulesview.enabled", false);
 // Enable the 'scrollable' markup-badges in nightly only for now
 #if defined(NIGHTLY_BUILD)
--- a/devtools/client/shared/output-parser.js
+++ b/devtools/client/shared/output-parser.js
@@ -1,15 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const Services = require("Services");
 const {angleUtils} = require("devtools/client/shared/css-angle");
 const {colorUtils} = require("devtools/shared/css/color");
 const {getCSSLexer} = require("devtools/shared/css/lexer");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {appendText} = require("devtools/client/inspector/shared/utils");
 
 loader.lazyRequireGetter(this, "CSS_TYPES", "devtools/shared/css/constants", true);
 
@@ -31,18 +30,16 @@ const COLOR_TAKING_FUNCTIONS = ["linear-
                                 "-moz-repeating-linear-gradient", "radial-gradient",
                                 "-moz-radial-gradient", "repeating-radial-gradient",
                                 "-moz-repeating-radial-gradient", "drop-shadow"];
 // Functions that accept a shape argument.
 const BASIC_SHAPE_FUNCTIONS = ["polygon", "circle", "ellipse", "inset"];
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
-const CSS_SHAPES_ENABLED_PREF = "devtools.inspector.shapesHighlighter.enabled";
-
 /**
  * This module is used to process text for output by developer tools. This means
  * linking JS files with the debugger, CSS files with the style editor, JS
  * functions with the debugger, placing color swatches next to colors and
  * adding doorhanger previews where possible (images, angles, lengths,
  * border radius, cubic-bezier etc.).
  *
  * Usage:
@@ -363,17 +360,16 @@ OutputParser.prototype = {
               const functionText = functionName + functionData.join("") + ")";
 
               if (options.expectCubicBezier && token.text === "cubic-bezier") {
                 this._appendCubicBezier(functionText, options);
               } else if (colorOK() &&
                          colorUtils.isValidCSSColor(functionText, this.cssColor4)) {
                 this._appendColor(functionText, options);
               } else if (options.expectShape &&
-                         Services.prefs.getBoolPref(CSS_SHAPES_ENABLED_PREF) &&
                          BASIC_SHAPE_FUNCTIONS.includes(token.text)) {
                 this._appendShape(functionText, options);
               } else {
                 this._appendTextNode(functionText);
               }
             }
           }
           break;
--- a/devtools/client/shared/test/browser_outputparser.js
+++ b/devtools/client/shared/test/browser_outputparser.js
@@ -1,17 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const OutputParser = require("devtools/client/shared/output-parser");
 const {initCssProperties, getCssProperties} = require("devtools/shared/fronts/css-properties");
 const { CSS_PROPERTIES_DB} = require("devtools/shared/css/properties-db");
-const CSS_SHAPES_ENABLED_PREF = "devtools.inspector.shapesHighlighter.enabled";
 
 add_task(async function() {
   await addTab("about:blank");
   await performTest();
   gBrowser.removeCurrentTab();
 });
 
 async function performTest() {
@@ -303,17 +302,17 @@ function testParseAngle(doc, parser) {
     });
 
   swatchCount = frag.querySelectorAll(".test-angleswatch").length;
   is(swatchCount, 1, "angle swatch was created");
 }
 
 function testParseShape(doc, parser) {
   info("Test shape parsing");
-  pushPref(CSS_SHAPES_ENABLED_PREF, true);
+
   const tests = [
     {
       desc: "Polygon shape",
       definition: "polygon(evenodd, 0px 0px, 10%200px,30%30% , calc(250px - 10px) 0 ,\n "
                   + "12em var(--variable), 100% 100%) margin-box",
       spanCount: 18,
     },
     {
--- a/dom/asmjscache/AsmJSCache.h
+++ b/dom/asmjscache/AsmJSCache.h
@@ -9,16 +9,35 @@
 
 #include "ipc/IPCMessageUtils.h"
 #include "js/TypeDecls.h"
 #include "js/Vector.h"
 #include "jsapi.h"
 
 class nsIPrincipal;
 
+namespace JS {
+
+enum AsmJSCacheResult {
+  AsmJSCache_Success,
+  AsmJSCache_MIN = AsmJSCache_Success,
+  AsmJSCache_ModuleTooSmall,
+  AsmJSCache_SynchronousScript,
+  AsmJSCache_QuotaExceeded,
+  AsmJSCache_StorageInitFailure,
+  AsmJSCache_Disabled_Internal,
+  AsmJSCache_Disabled_ShellFlags,
+  AsmJSCache_Disabled_JitInspector,
+  AsmJSCache_InternalError,
+  AsmJSCache_Disabled_PrivateBrowsing,
+  AsmJSCache_LIMIT
+};
+
+}  // namespace JS
+
 namespace mozilla {
 
 namespace ipc {
 
 class PrincipalInfo;
 
 }  // namespace ipc
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -77,17 +77,16 @@
 
 #include "mozilla/Logging.h"
 #include "prthread.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "GeckoProfiler.h"
 #include "mozilla/IdleTaskRunner.h"
 #include "nsIDocShell.h"
 #include "nsIPresShell.h"
@@ -2380,36 +2379,16 @@ static void SetMemoryGCSliceTimePrefChan
 }
 
 static void SetIncrementalCCPrefChangedCallback(const char* aPrefName,
                                                 void* aClosure) {
   bool pref = Preferences::GetBool(aPrefName);
   sIncrementalCC = pref;
 }
 
-static bool AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
-                                       const char16_t* aBegin,
-                                       const char16_t* aLimit, size_t* aSize,
-                                       const uint8_t** aMemory,
-                                       intptr_t* aHandle) {
-  nsIPrincipal* principal = nsJSPrincipals::get(
-      JS::GetRealmPrincipals(js::GetNonCCWObjectRealm(aGlobal)));
-  return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
-                                      aHandle);
-}
-
-static JS::AsmJSCacheResult AsmJSCacheOpenEntryForWrite(
-    JS::Handle<JSObject*> aGlobal, const char16_t* aBegin, const char16_t* aEnd,
-    size_t aSize, uint8_t** aMemory, intptr_t* aHandle) {
-  nsIPrincipal* principal = nsJSPrincipals::get(
-      JS::GetRealmPrincipals(js::GetNonCCWObjectRealm(aGlobal)));
-  return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
-                                       aHandle);
-}
-
 class JSDispatchableRunnable final : public Runnable {
   ~JSDispatchableRunnable() { MOZ_ASSERT(!mDispatchable); }
 
  public:
   explicit JSDispatchableRunnable(JS::Dispatchable* aDispatchable)
       : mozilla::Runnable("JSDispatchableRunnable"),
         mDispatchable(aDispatchable) {
     MOZ_ASSERT(mDispatchable);
@@ -2473,22 +2452,16 @@ void nsJSContext::EnsureStatics() {
   // Let's make sure that our main thread is the same as the xpcom main thread.
   MOZ_ASSERT(NS_IsMainThread());
 
   AutoJSAPI jsapi;
   jsapi.Init();
 
   sPrevGCSliceCallback = JS::SetGCSliceCallback(jsapi.cx(), DOMGCSliceCallback);
 
-  // Set up the asm.js cache callbacks
-  static const JS::AsmJSCacheOps asmJSCacheOps = {
-      AsmJSCacheOpenEntryForRead, asmjscache::CloseEntryForRead,
-      AsmJSCacheOpenEntryForWrite, asmjscache::CloseEntryForWrite};
-  JS::SetAsmJSCacheOps(jsapi.cx(), &asmJSCacheOps);
-
   JS::InitDispatchToEventLoop(jsapi.cx(), DispatchToEventLoop, nullptr);
   JS::InitConsumeStreamCallback(jsapi.cx(), ConsumeStream,
                                 FetchUtil::ReportJSStreamError);
 
   // Set these global xpconnect options...
   Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackMB,
                                        "javascript.options.mem.high_water_mark",
                                        (void*)JSGC_MAX_MALLOC_BYTES);
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -34,17 +34,16 @@
 #include "mozilla/AbstractThread.h"
 #include "mozilla/AntiTrackingCommon.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
-#include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/AtomList.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/MessageChannel.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/PerformanceService.h"
@@ -658,53 +657,16 @@ void CTypesActivityCallback(JSContext* a
       worker->EndCTypesCallback();
       break;
 
     default:
       MOZ_CRASH("Unknown type flag!");
   }
 }
 
-static nsIPrincipal* GetPrincipalForAsmJSCacheOp() {
-  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-  if (!workerPrivate) {
-    return nullptr;
-  }
-
-  // asmjscache::OpenEntryForX guarnatee to only access the given nsIPrincipal
-  // from the main thread.
-  return workerPrivate->GetPrincipalDontAssertMainThread();
-}
-
-static bool AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
-                                       const char16_t* aBegin,
-                                       const char16_t* aLimit, size_t* aSize,
-                                       const uint8_t** aMemory,
-                                       intptr_t* aHandle) {
-  nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
-  if (!principal) {
-    return false;
-  }
-
-  return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
-                                      aHandle);
-}
-
-static JS::AsmJSCacheResult AsmJSCacheOpenEntryForWrite(
-    JS::Handle<JSObject*> aGlobal, const char16_t* aBegin, const char16_t* aEnd,
-    size_t aSize, uint8_t** aMemory, intptr_t* aHandle) {
-  nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
-  if (!principal) {
-    return JS::AsmJSCache_InternalError;
-  }
-
-  return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
-                                       aHandle);
-}
-
 // JSDispatchableRunnables are WorkerRunnables used to dispatch JS::Dispatchable
 // back to their worker thread. A WorkerRunnable is used for two reasons:
 //
 // 1. The JS::Dispatchable::run() callback may run JS so we cannot use a control
 // runnable since they use async interrupts and break JS run-to-completion.
 //
 // 2. The DispatchToEventLoopCallback interface is *required* to fail during
 // shutdown (see jsapi.h) which is exactly what WorkerRunnable::Dispatch() will
@@ -819,22 +781,16 @@ bool InitJSContextForWorker(WorkerPrivat
 
   JS_SetNativeStackQuota(aWorkerCx, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
 
   // Security policy:
   static const JSSecurityCallbacks securityCallbacks = {
       ContentSecurityPolicyAllows};
   JS_SetSecurityCallbacks(aWorkerCx, &securityCallbacks);
 
-  // Set up the asm.js cache callbacks
-  static const JS::AsmJSCacheOps asmJSCacheOps = {
-      AsmJSCacheOpenEntryForRead, asmjscache::CloseEntryForRead,
-      AsmJSCacheOpenEntryForWrite, asmjscache::CloseEntryForWrite};
-  JS::SetAsmJSCacheOps(aWorkerCx, &asmJSCacheOps);
-
   // A WorkerPrivate lives strictly longer than its JSRuntime so we can safely
   // store a raw pointer as the callback's closure argument on the JSRuntime.
   JS::InitDispatchToEventLoop(aWorkerCx, DispatchToEventLoop,
                               (void*)aWorkerPrivate);
 
   JS::InitConsumeStreamCallback(aWorkerCx, ConsumeStream,
                                 FetchUtil::ReportJSStreamError);
 
--- a/dom/worklet/WorkletThread.cpp
+++ b/dom/worklet/WorkletThread.cpp
@@ -280,17 +280,16 @@ WorkletThread::DelayedDispatch(already_A
     // TODO: error propagation
     return;
   }
 
   // FIXME: JS_SetDefaultLocale
   // FIXME: JSSettings
   // FIXME: JS_SetNativeStackQuota
   // FIXME: JS_SetSecurityCallbacks
-  // FIXME: JS::SetAsmJSCacheOps
   // FIXME: JS::SetAsyncTaskCallbacks
   // FIXME: JS_AddInterruptCallback
   // FIXME: JS::SetCTypesActivityCallback
   // FIXME: JS_SetGCZeal
 
   if (!JS::InitSelfHostedCode(context->Context())) {
     // TODO: error propagation
     return;
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -52,16 +52,17 @@
 #include "js/StableStringChars.h"
 #include "js/StructuredClone.h"
 #include "js/UbiNode.h"
 #include "js/UbiNodeBreadthFirst.h"
 #include "js/UbiNodeShortestPaths.h"
 #include "js/UniquePtr.h"
 #include "js/Vector.h"
 #include "js/Wrapper.h"
+#include "threading/CpuCount.h"
 #include "util/StringBuffer.h"
 #include "util/Text.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
 #include "vm/Debugger.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/Iteration.h"
@@ -5066,16 +5067,29 @@ static bool SetTimeZone(JSContext* cx, u
 #endif /* _WIN32 */
 
   JS::ResetTimeZone();
 
   args.rval().setUndefined();
   return true;
 }
 
+static bool GetCoreCount(JSContext* cx, unsigned argc, Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+  RootedObject callee(cx, &args.callee());
+
+  if (args.length() != 0) {
+    ReportUsageErrorASCII(cx, callee, "Wrong number of arguments");
+    return false;
+  }
+
+  args.rval().setInt32(GetCPUCount());
+  return true;
+}
+
 static bool GetDefaultLocale(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   RootedObject callee(cx, &args.callee());
 
   if (args.length() != 0) {
     ReportUsageErrorASCII(cx, callee, "Wrong number of arguments");
     return false;
   }
@@ -6286,16 +6300,21 @@ gc::ZealModeHelpText),
     JS_FN_HELP("getTimeZone", GetTimeZone, 0, 0,
 "getTimeZone()",
 "  Get the current time zone.\n"),
 
     JS_FN_HELP("getDefaultLocale", GetDefaultLocale, 0, 0,
 "getDefaultLocale()",
 "  Get the current default locale.\n"),
 
+    JS_FN_HELP("getCoreCount", GetCoreCount, 0, 0,
+"getCoreCount()",
+"  Get the number of CPU cores from the platform layer.  Typically this\n"
+"  means the number of hyperthreads on systems where that makes sense.\n"),
+
     JS_FN_HELP("setTimeResolution", SetTimeResolution, 2, 0,
 "setTimeResolution(resolution, jitter)",
 "  Enables time clamping and jittering. Specify a time resolution in\n"
 "  microseconds and whether or not to jitter\n"),
 
     JS_FN_HELP("scriptedCallerGlobal", ScriptedCallerGlobal, 0, 0,
 "scriptedCallerGlobal()",
 "  Get the caller's global (or null). See JS::GetScriptedCallerGlobal.\n"),
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -5,17 +5,16 @@
 
 from __future__ import print_function, unicode_literals
 
 import math
 import os
 import platform
 import posixpath
 import shlex
-import shutil
 import subprocess
 import sys
 import traceback
 
 
 def add_libdir_to_path():
     from os.path import dirname, exists, join, realpath
     js_src_dir = dirname(dirname(realpath(sys.argv[0])))
@@ -25,18 +24,16 @@ def add_libdir_to_path():
 
 
 add_libdir_to_path()
 
 import jittests
 from tests import get_jitflags, valid_jitflags, get_cpu_count, get_environment_overlay, \
     change_env
 
-# Python 3.3 added shutil.which, but we can't use that yet.
-
 
 def which(name):
     if name.find(os.path.sep) != -1:
         return os.path.abspath(name)
 
     for path in os.environ["PATH"].split(os.pathsep):
         full = os.path.join(path, name)
         if os.path.exists(full):
@@ -348,20 +345,16 @@ def main(argv):
     prefix = [js_shell] + shlex.split(options.shell_args)
     prologue = os.path.join(jittests.LIB_DIR, 'prologue.js')
     if options.remote:
         prologue = posixpath.join(options.remote_test_root,
                                   'jit-tests', 'jit-tests', 'lib', 'prologue.js')
 
     prefix += ['-f', prologue]
 
-    # Clean up any remnants from previous crashes etc
-    shutil.rmtree(jittests.JS_CACHE_DIR, ignore_errors=True)
-    os.mkdir(jittests.JS_CACHE_DIR)
-
     if options.debugger:
         if job_count > 1:
             print('Multiple tests match command line'
                   ' arguments, debugger can only run one')
             jobs = list(job_list)
 
             def display_job(job):
                 flags = ""
--- a/js/src/jit-test/tests/asm.js/testBullet.js
+++ b/js/src/jit-test/tests/asm.js/testBullet.js
@@ -1,14 +1,6 @@
 // |jit-test| skip-if: !isAsmJSCompilationAvailable()
 
-// Test a big fat asm.js module. First load/compile/cache bullet.js in a
-// separate process and then load it again in this process.
-
-// Note: if you get some failure in this test, it probably has to do with
-// bullet.js and not the nestedShell() call, so try first commenting out
-// nestedShell() to see if the error reproduces.
-var code = "setIonCheckGraphCoherency(false); load('" + libdir + "bullet.js'); runBullet()";
-nestedShell("--js-cache", "--no-js-cache-per-process", "--execute=" + code);
 setIonCheckGraphCoherency(false);
 load(libdir + 'bullet.js');
 var results = runBullet();
 assertEq(results.asmJSValidated, true);
--- a/js/src/jit-test/tests/basic/bug908915.js
+++ b/js/src/jit-test/tests/basic/bug908915.js
@@ -5,17 +5,16 @@ load(libdir + "immutable-prototype.js");
 // dumpHeap()).
 os.file.redirect(null);
 
 var blacklist = {
     'quit': true,
     'crash': true,
     'readline': true,
     'terminate': true,
-    'nestedShell': true,
     'nukeAllCCWs': true,
 };
 
 function f(y) {}
 for (let e of Object.values(newGlobal())) {
     if (e.name in blacklist)
 	continue;
     print(e.name);
--- a/js/src/jit-test/tests/wasm/atomicity.js
+++ b/js/src/jit-test/tests/wasm/atomicity.js
@@ -1,13 +1,8 @@
-// |jit-test| slow;
-//
-// Temporarily marked as slow - they time out on the build systems even with
-// reduced iteration count.
-//
 // Test that wasm atomic operations implement correct mutual exclusion.
 //
 // We have several agents that attempt to hammer on a shared location with rmw
 // operations in such a way that failed atomicity will lead to an incorrect
 // result.  Each agent attempts to clear or set specific bits in a shared datum.
 
 // 1 for a little bit, 2 for a lot, 3 to quit before running tests
 const DEBUG = 0;
@@ -15,22 +10,35 @@ const DEBUG = 0;
 // The longer we run, the better, really, but we don't want to time out.
 const ITERATIONS = 100000;
 
 // If you change NUMWORKERS you must also change the tables for INIT, VAL, and
 // RESULT for all the operations, below, by adding or removing bits.
 const NUMWORKERS = 2;
 const NUMAGENTS = NUMWORKERS + 1;
 
+// Need at least one thread per agent.
+
 if (!wasmThreadsSupported() || helperThreadCount() < NUMWORKERS) {
     if (DEBUG > 0)
         print("Threads not supported");
     quit(0);
 }
 
+// Unless there are enough actual cores the spinning threads will not interact
+// in the desired way (we'll be waiting on preemption to advance), and this
+// makes the test pointless and also will usually make it time out.  So bail out
+// if we can't have one core per agent.
+
+if (getCoreCount() < NUMAGENTS) {
+    if (DEBUG > 0)
+        print("Fake or feeble hardware");
+    quit(0);
+}
+
 // Most of the simulators have poor support for mutual exclusion and are anyway
 // too slow; avoid intermittent failures and timeouts.
 
 let conf = getBuildConfiguration();
 if (conf["arm-simulator"] || conf["arm64-simulator"] ||
     conf["mips-simulator"] || conf["mips64-simulator"])
 {
     if (DEBUG > 0)
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3201,16 +3201,17 @@ static bool IsResumableMIRType(MIRType t
     case MIRType::Slots:
     case MIRType::Elements:
     case MIRType::Pointer:
     case MIRType::Shape:
     case MIRType::ObjectGroup:
     case MIRType::Doublex2:  // NYI, see also RSimdBox::recover
     case MIRType::SinCosDouble:
     case MIRType::Int64:
+    case MIRType::RefOrNull:
       return false;
   }
   MOZ_CRASH("Unknown MIRType.");
 }
 
 static void AssertResumableOperands(MNode* node) {
   for (size_t i = 0, e = node->numOperands(); i < e; ++i) {
     MDefinition* op = node->getOperand(i);
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -461,16 +461,17 @@ enum class MIRType : uint8_t {
   // Types above are specialized.
   Value,
   SinCosDouble,  // Optimizing a sin/cos to sincos.
   ObjectOrNull,
   None,         // Invalid, used as a placeholder.
   Slots,        // A slots vector
   Elements,     // An elements vector
   Pointer,      // An opaque pointer that receives no special treatment
+  RefOrNull,    // Wasm Ref/AnyRef/NullRef: a raw JSObject* or a raw (void*)0
   Shape,        // A Shape pointer.
   ObjectGroup,  // An ObjectGroup pointer.
   Last = ObjectGroup,
   // Representing both SIMD.IntBxN and SIMD.UintBxN.
   Int8x16 = Int32 | (4 << VECTOR_SCALE_SHIFT),
   Int16x8 = Int32 | (3 << VECTOR_SCALE_SHIFT),
   Int32x4 = Int32 | (2 << VECTOR_SCALE_SHIFT),
   Float32x4 = Float32 | (2 << VECTOR_SCALE_SHIFT),
@@ -558,16 +559,17 @@ static inline size_t MIRTypeToSize(MIRTy
       return 4;
     case MIRType::Int64:
       return 8;
     case MIRType::Float32:
       return 4;
     case MIRType::Double:
       return 8;
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       return sizeof(uintptr_t);
     default:
       MOZ_CRASH("MIRTypeToSize - unhandled case");
   }
 }
 
 static inline const char* StringFromMIRType(MIRType type) {
   switch (type) {
@@ -614,16 +616,18 @@ static inline const char* StringFromMIRT
     case MIRType::None:
       return "None";
     case MIRType::Slots:
       return "Slots";
     case MIRType::Elements:
       return "Elements";
     case MIRType::Pointer:
       return "Pointer";
+    case MIRType::RefOrNull:
+      return "RefOrNull";
     case MIRType::Shape:
       return "Shape";
     case MIRType::ObjectGroup:
       return "ObjectGroup";
     case MIRType::Int32x4:
       return "Int32x4";
     case MIRType::Int16x8:
       return "Int16x8";
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -43,16 +43,17 @@ ABIArgGenerator::ABIArgGenerator()
       useHardFp_(true) {}
 
 // See the "Parameter Passing" section of the "Procedure Call Standard for the
 // ARM Architecture" documentation.
 ABIArg ABIArgGenerator::softNext(MIRType type) {
   switch (type) {
     case MIRType::Int32:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       if (intRegIndex_ == NumIntArgRegs) {
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint32_t);
         break;
       }
       current_ = ABIArg(Register::FromCode(intRegIndex_));
       intRegIndex_++;
       break;
@@ -103,16 +104,17 @@ ABIArg ABIArgGenerator::softNext(MIRType
 
   return current_;
 }
 
 ABIArg ABIArgGenerator::hardNext(MIRType type) {
   switch (type) {
     case MIRType::Int32:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       if (intRegIndex_ == NumIntArgRegs) {
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint32_t);
         break;
       }
       current_ = ABIArg(Register::FromCode(intRegIndex_));
       intRegIndex_++;
       break;
--- a/js/src/jit/arm64/Assembler-arm64.cpp
+++ b/js/src/jit/arm64/Assembler-arm64.cpp
@@ -30,16 +30,17 @@ using mozilla::DebugOnly;
 // Note this is used for inter-wasm calls and may pass arguments and results
 // in floating point registers even if the system ABI does not.
 
 ABIArg ABIArgGenerator::next(MIRType type) {
   switch (type) {
     case MIRType::Int32:
     case MIRType::Int64:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       if (intRegIndex_ == NumIntArgRegs) {
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uintptr_t);
         break;
       }
       current_ = ABIArg(Register::FromCode(intRegIndex_));
       intRegIndex_++;
       break;
--- a/js/src/jit/mips32/Assembler-mips32.cpp
+++ b/js/src/jit/mips32/Assembler-mips32.cpp
@@ -19,16 +19,17 @@ ABIArgGenerator::ABIArgGenerator()
       useGPRForFloats_(false),
       current_() {}
 
 ABIArg ABIArgGenerator::next(MIRType type) {
   Register destReg;
   switch (type) {
     case MIRType::Int32:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       if (GetIntArgReg(usedArgSlots_, &destReg)) {
         current_ = ABIArg(destReg);
       } else {
         current_ = ABIArg(usedArgSlots_ * sizeof(intptr_t));
       }
       usedArgSlots_++;
       break;
     case MIRType::Int64:
--- a/js/src/jit/mips64/Assembler-mips64.cpp
+++ b/js/src/jit/mips64/Assembler-mips64.cpp
@@ -15,17 +15,18 @@ using namespace js::jit;
 
 ABIArgGenerator::ABIArgGenerator()
     : usedArgSlots_(0), firstArgFloat(false), current_() {}
 
 ABIArg ABIArgGenerator::next(MIRType type) {
   switch (type) {
     case MIRType::Int32:
     case MIRType::Int64:
-    case MIRType::Pointer: {
+    case MIRType::Pointer:
+    case MIRType::RefOrNull: {
       Register destReg;
       if (GetIntArgReg(usedArgSlots_, &destReg)) {
         current_ = ABIArg(destReg);
       } else {
         current_ = ABIArg(GetArgStackDisp(usedArgSlots_));
       }
       usedArgSlots_++;
       break;
--- a/js/src/jit/x64/Assembler-x64.cpp
+++ b/js/src/jit/x64/Assembler-x64.cpp
@@ -40,16 +40,17 @@ ABIArg ABIArgGenerator::next(MIRType typ
       stackOffset_ += sizeof(uint64_t);
     }
     return current_;
   }
   switch (type) {
     case MIRType::Int32:
     case MIRType::Int64:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       current_ = ABIArg(IntArgRegs[regIndex_++]);
       break;
     case MIRType::Float32:
       current_ = ABIArg(FloatArgRegs[regIndex_++].asSingle());
       break;
     case MIRType::Double:
       current_ = ABIArg(FloatArgRegs[regIndex_++]);
       break;
@@ -69,16 +70,17 @@ ABIArg ABIArgGenerator::next(MIRType typ
       MOZ_CRASH("Unexpected argument type");
   }
   return current_;
 #else
   switch (type) {
     case MIRType::Int32:
     case MIRType::Int64:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       if (intRegIndex_ == NumIntArgRegs) {
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint64_t);
         break;
       }
       current_ = ABIArg(IntArgRegs[intRegIndex_++]);
       break;
     case MIRType::Double:
--- a/js/src/jit/x86/Assembler-x86.cpp
+++ b/js/src/jit/x86/Assembler-x86.cpp
@@ -13,16 +13,17 @@ using namespace js::jit;
 
 ABIArgGenerator::ABIArgGenerator() : stackOffset_(0), current_() {}
 
 ABIArg ABIArgGenerator::next(MIRType type) {
   switch (type) {
     case MIRType::Int32:
     case MIRType::Float32:
     case MIRType::Pointer:
+    case MIRType::RefOrNull:
       current_ = ABIArg(stackOffset_);
       stackOffset_ += sizeof(uint32_t);
       break;
     case MIRType::Double:
     case MIRType::Int64:
       current_ = ABIArg(stackOffset_);
       stackOffset_ += sizeof(uint64_t);
       break;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -92,17 +92,16 @@
 #include "vm/Runtime.h"
 #include "vm/SavedStacks.h"
 #include "vm/SelfHosting.h"
 #include "vm/Shape.h"
 #include "vm/StringType.h"
 #include "vm/SymbolType.h"
 #include "vm/WrapperObject.h"
 #include "vm/Xdr.h"
-#include "wasm/AsmJS.h"
 #include "wasm/WasmModule.h"
 
 #include "vm/Compartment-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/JSAtom-inl.h"
 #include "vm/JSFunction-inl.h"
 #include "vm/JSScript-inl.h"
 #include "vm/NativeObject-inl.h"
@@ -6000,21 +5999,16 @@ JS_PUBLIC_API bool JS::FinishIncremental
     return false;
   }
   if (!script->scriptSource()->xdrFinalizeEncoder(buffer)) {
     return false;
   }
   return true;
 }
 
-JS_PUBLIC_API void JS::SetAsmJSCacheOps(JSContext* cx,
-                                        const JS::AsmJSCacheOps* ops) {
-  cx->runtime()->asmJSCacheOps = *ops;
-}
-
 bool JS::IsWasmModuleObject(HandleObject obj) {
   return obj->canUnwrapAs<WasmModuleObject>();
 }
 
 JS_PUBLIC_API RefPtr<JS::WasmModule> JS::GetWasmModule(HandleObject obj) {
   MOZ_ASSERT(JS::IsWasmModuleObject(obj));
   WasmModuleObject& mobj = obj->unwrapAs<WasmModuleObject>();
   return const_cast<wasm::Module*>(&mobj.module());
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3537,73 +3537,16 @@ enum class StackFormat { SpiderMonkey, V
 extern JS_PUBLIC_API void SetStackFormat(JSContext* cx, StackFormat format);
 
 extern JS_PUBLIC_API StackFormat GetStackFormat(JSContext* cx);
 
 }  // namespace js
 
 namespace JS {
 
-/*
- * This callback represents a request by the JS engine to open for reading the
- * existing cache entry for the given global and char range that may contain a
- * module. If a cache entry exists, the callback shall return 'true' and return
- * the size, base address and an opaque file handle as outparams. If the
- * callback returns 'true', the JS engine guarantees a call to
- * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
- * handle.
- */
-using OpenAsmJSCacheEntryForReadOp =
-    bool (*)(HandleObject global, const char16_t* begin, const char16_t* limit,
-             size_t* size, const uint8_t** memory, intptr_t* handle);
-using CloseAsmJSCacheEntryForReadOp = void (*)(size_t size,
-                                               const uint8_t* memory,
-                                               intptr_t handle);
-
-/** The list of reasons why an asm.js module may not be stored in the cache. */
-enum AsmJSCacheResult {
-  AsmJSCache_Success,
-  AsmJSCache_MIN = AsmJSCache_Success,
-  AsmJSCache_ModuleTooSmall,
-  AsmJSCache_SynchronousScript,
-  AsmJSCache_QuotaExceeded,
-  AsmJSCache_StorageInitFailure,
-  AsmJSCache_Disabled_Internal,
-  AsmJSCache_Disabled_ShellFlags,
-  AsmJSCache_Disabled_JitInspector,
-  AsmJSCache_InternalError,
-  AsmJSCache_Disabled_PrivateBrowsing,
-  AsmJSCache_LIMIT
-};
-
-/*
- * This callback represents a request by the JS engine to open for writing a
- * cache entry of the given size for the given global and char range containing
- * the just-compiled module. If cache entry space is available, the callback
- * shall return 'true' and return the base address and an opaque file handle as
- * outparams. If the callback returns 'true', the JS engine guarantees a call
- * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
- * handle.
- */
-using OpenAsmJSCacheEntryForWriteOp = AsmJSCacheResult (*)(
-    HandleObject global, const char16_t* begin, const char16_t* end,
-    size_t size, uint8_t** memory, intptr_t* handle);
-using CloseAsmJSCacheEntryForWriteOp = void (*)(size_t size, uint8_t* memory,
-                                                intptr_t handle);
-
-struct AsmJSCacheOps {
-  OpenAsmJSCacheEntryForReadOp openEntryForRead = nullptr;
-  CloseAsmJSCacheEntryForReadOp closeEntryForRead = nullptr;
-  OpenAsmJSCacheEntryForWriteOp openEntryForWrite = nullptr;
-  CloseAsmJSCacheEntryForWriteOp closeEntryForWrite = nullptr;
-};
-
-extern JS_PUBLIC_API void SetAsmJSCacheOps(JSContext* cx,
-                                           const AsmJSCacheOps* callbacks);
-
 /**
  * The WasmModule interface allows the embedding to hold a reference to the
  * underying C++ implementation of a JS WebAssembly.Module object for purposes
  * of efficient postMessage() and (de)serialization from a random thread.
  *
  * In particular, this allows postMessage() of a WebAssembly.Module:
  * GetWasmModule() is called when making a structured clone of a payload
  * containing a WebAssembly.Module object. The structured clone buffer holds a
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -503,34 +503,29 @@ static bool enableStreams = false;
 #ifdef ENABLE_BIGINT
 static bool enableBigInt = false;
 #endif
 #ifdef JS_GC_ZEAL
 static uint32_t gZealBits = 0;
 static uint32_t gZealFrequency = 0;
 #endif
 static bool printTiming = false;
-static const char* jsCacheDir = nullptr;
-static const char* jsCacheAsmJSPath = nullptr;
 static RCFile* gErrFile = nullptr;
 static RCFile* gOutFile = nullptr;
 static bool reportWarnings = true;
 static bool compileOnly = false;
 static bool fuzzingSafe = false;
 static bool disableOOMFunctions = false;
 static bool defaultToSameCompartment = true;
 
 #ifdef DEBUG
 static bool dumpEntrainedVariables = false;
 static bool OOM_printAllocationCount = false;
 #endif
 
-// Shell state this is only accessed on the main thread.
-mozilla::Atomic<bool> jsCacheOpened(false);
-
 static bool SetTimeoutValue(JSContext* cx, double t);
 
 static void KillWatchdog(JSContext* cx);
 
 static bool ScheduleWatchdog(JSContext* cx, double t);
 
 static void CancelExecution(JSContext* cx);
 
@@ -5635,19 +5630,16 @@ static bool runOffThreadDecodedScript(JS
   RootedScript script(cx, JS::FinishOffThreadScriptDecoder(cx, token));
   if (!script) {
     return false;
   }
 
   return JS_ExecuteScript(cx, script, args.rval());
 }
 
-static int sArgc;
-static char** sArgv;
-
 class AutoCStringVector {
   Vector<char*> argv_;
 
  public:
   explicit AutoCStringVector(JSContext* cx) : argv_(cx) {}
   ~AutoCStringVector() {
     for (size_t i = 0; i < argv_.length(); i++) {
       js_free(argv_[i]);
@@ -5709,122 +5701,16 @@ static bool EscapeForShell(JSContext* cx
     MOZ_ASSERT(escaped.get() + newLen == dst);
 
     argv.replace(i, std::move(escaped));
   }
   return true;
 }
 #endif
 
-static Vector<const char*, 4, js::SystemAllocPolicy> sPropagatedFlags;
-
-#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
-static bool PropagateFlagToNestedShells(const char* flag) {
-  return sPropagatedFlags.append(flag);
-}
-#endif
-
-static bool NestedShell(JSContext* cx, unsigned argc, Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-
-  AutoCStringVector argv(cx);
-
-  // The first argument to the shell is its path, which we assume is our own
-  // argv[0].
-  if (sArgc < 1) {
-    JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
-                              JSSMSG_NESTED_FAIL);
-    return false;
-  }
-  UniqueChars shellPath = DuplicateString(cx, sArgv[0]);
-  if (!shellPath || !argv.append(std::move(shellPath))) {
-    return false;
-  }
-
-  // Propagate selected flags from the current shell
-  for (unsigned i = 0; i < sPropagatedFlags.length(); i++) {
-    UniqueChars flags = DuplicateString(cx, sPropagatedFlags[i]);
-    if (!flags || !argv.append(std::move(flags))) {
-      return false;
-    }
-  }
-
-  // The arguments to nestedShell are stringified and append to argv.
-  for (unsigned i = 0; i < args.length(); i++) {
-    JSString* str = ToString(cx, args[i]);
-    if (!str) {
-      return false;
-    }
-
-    JSLinearString* linear = str->ensureLinear(cx);
-    if (!linear) {
-      return false;
-    }
-
-    UniqueChars arg;
-    if (StringEqualsAscii(linear, "--js-cache") && jsCacheDir) {
-      // As a special case, if the caller passes "--js-cache", use
-      // "--js-cache=$(jsCacheDir)" instead.
-      arg = JS_smprintf("--js-cache=%s", jsCacheDir);
-      if (!arg) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-      }
-    } else {
-      arg = JS_EncodeStringToLatin1(cx, str);
-      if (!arg) {
-        return false;
-      }
-    }
-
-    if (!argv.append(std::move(arg))) {
-      return false;
-    }
-  }
-
-  // execv assumes argv is null-terminated
-  if (!argv.append(nullptr)) {
-    return false;
-  }
-
-  int status = 0;
-#if defined(XP_WIN)
-  if (!EscapeForShell(cx, argv)) {
-    return false;
-  }
-  status = _spawnv(_P_WAIT, sArgv[0], argv.get());
-#else
-  pid_t pid = fork();
-  switch (pid) {
-    case -1:
-      JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
-                                JSSMSG_NESTED_FAIL);
-      return false;
-    case 0:
-      (void)execv(sArgv[0], argv.get());
-      exit(-1);
-    default: {
-      while (waitpid(pid, &status, 0) < 0 && errno == EINTR) {
-        continue;
-      }
-      break;
-    }
-  }
-#endif
-
-  if (status != 0) {
-    JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
-                              JSSMSG_NESTED_FAIL);
-    return false;
-  }
-
-  args.rval().setUndefined();
-  return true;
-}
-
 static bool ReadAll(int fd, wasm::Bytes* bytes) {
   size_t lastLength = bytes->length();
   while (true) {
     static const int ChunkSize = 64 * 1024;
     if (!bytes->growBy(ChunkSize)) {
       return false;
     }
 
@@ -5911,18 +5797,21 @@ class AutoPipe {
 
   void closeWriter() {
     MOZ_ASSERT(fds_[1] != -1);
     close(fds_[1]);
     fds_[1] = -1;
   }
 };
 
+static int sArgc;
+static char** sArgv;
 static const char sWasmCompileAndSerializeFlag[] =
     "--wasm-compile-and-serialize";
+static Vector<const char*, 4, js::SystemAllocPolicy> sCompilerProcessFlags;
 
 static bool CompileAndSerializeInSeparateProcess(JSContext* cx,
                                                  const uint8_t* bytecode,
                                                  size_t bytecodeLength,
                                                  wasm::Bytes* serialized) {
   AutoPipe stdIn, stdOut;
   if (!stdIn.init() || !stdOut.init()) {
     return false;
@@ -5930,20 +5819,20 @@ static bool CompileAndSerializeInSeparat
 
   AutoCStringVector argv(cx);
 
   UniqueChars argv0 = DuplicateString(cx, sArgv[0]);
   if (!argv0 || !argv.append(std::move(argv0))) {
     return false;
   }
 
-  // Propagate shell flags first, since they must precede the non-option
+  // Put compiler flags first since they must precede the non-option
   // file-descriptor args (passed on Windows, below).
-  for (unsigned i = 0; i < sPropagatedFlags.length(); i++) {
-    UniqueChars flags = DuplicateString(cx, sPropagatedFlags[i]);
+  for (unsigned i = 0; i < sCompilerProcessFlags.length(); i++) {
+    UniqueChars flags = DuplicateString(cx, sCompilerProcessFlags[i]);
     if (!flags || !argv.append(std::move(flags))) {
       return false;
     }
   }
 
   UniqueChars arg;
 
   arg = DuplicateString(sWasmCompileAndSerializeFlag);
@@ -8833,24 +8722,16 @@ static const JSFunctionSpecWithHelp fuzz
     JS_FN_HELP("line2pc", LineToPC, 0, 0,
 "line2pc([fun,] line)",
 "  Map line number to PC."),
 
     JS_FN_HELP("pc2line", PCToLine, 0, 0,
 "pc2line(fun[, pc])",
 "  Map PC to line number."),
 
-    JS_FN_HELP("nestedShell", NestedShell, 0, 0,
-"nestedShell(shellArgs...)",
-"  Execute the given code in a new JS shell process, passing this nested shell\n"
-"  the arguments passed to nestedShell. argv[0] of the nested shell will be argv[0]\n"
-"  of the current shell (which is assumed to be the actual path to the shell.\n"
-"  arguments[0] (of the call to nestedShell) will be argv[1], arguments[1] will\n"
-"  be argv[2], etc."),
-
     JS_INLINABLE_FN_HELP("assertFloat32", testingFunc_assertFloat32, 2, 0, TestAssertFloat32,
 "assertFloat32(value, isFloat32)",
 "  In IonMonkey only, asserts that value has (resp. hasn't) the MIRType::Float32 if isFloat32 is true (resp. false)."),
 
     JS_INLINABLE_FN_HELP("assertRecoveredOnBailout", testingFunc_assertRecoveredOnBailout, 2, 0,
 TestAssertRecoveredOnBailout,
 "assertRecoveredOnBailout(var)",
 "  In IonMonkey only, asserts that variable has RecoveredOnBailout flag."),
@@ -9631,131 +9512,28 @@ static bool dom_constructor(JSContext* c
 
 static bool InstanceClassHasProtoAtDepth(const Class* clasp, uint32_t protoID,
                                          uint32_t depth) {
   // There's only a single (fake) DOM object in the shell, so just return
   // true.
   return true;
 }
 
-class ScopedFileDesc {
-  intptr_t fd_;
-
- public:
-  enum LockType { READ_LOCK, WRITE_LOCK };
-  ScopedFileDesc(int fd, LockType lockType) : fd_(fd) {
-    if (fd == -1) {
-      return;
-    }
-    if (!jsCacheOpened.compareExchange(false, true)) {
-      close(fd_);
-      fd_ = -1;
-      return;
-    }
-  }
-  ~ScopedFileDesc() {
-    if (fd_ == -1) {
-      return;
-    }
-    MOZ_ASSERT(jsCacheOpened == true);
-    jsCacheOpened = false;
-    close(fd_);
-  }
-  operator intptr_t() const { return fd_; }
-  intptr_t forget() {
-    intptr_t ret = fd_;
-    fd_ = -1;
-    return ret;
-  }
-};
-
-// To guard against corrupted cache files generated by previous crashes, write
-// asmJSCacheCookie to the first uint32_t of the file only after the file is
-// fully serialized and flushed to disk.
-static const uint32_t asmJSCacheCookie = 0xabbadaba;
-
-static bool ShellOpenAsmJSCacheEntryForRead(
-    HandleObject global, const char16_t* begin, const char16_t* limit,
-    size_t* serializedSizeOut, const uint8_t** memoryOut, intptr_t* handleOut) {
-  return false;
-}
-
-static void ShellCloseAsmJSCacheEntryForRead(size_t serializedSize,
-                                             const uint8_t* memory,
-                                             intptr_t handle) {
-  // Undo the cookie adjustment done when opening the file.
-  memory -= sizeof(uint32_t);
-  serializedSize += sizeof(uint32_t);
-
-  // Release the memory mapping and file.
-#ifdef XP_WIN
-  UnmapViewOfFile(const_cast<uint8_t*>(memory));
-#else
-  munmap(const_cast<uint8_t*>(memory), serializedSize);
-#endif
-
-  MOZ_ASSERT(jsCacheOpened == true);
-  jsCacheOpened = false;
-  close(handle);
-}
-
-static JS::AsmJSCacheResult ShellOpenAsmJSCacheEntryForWrite(
-    HandleObject global, const char16_t* begin, const char16_t* end,
-    size_t serializedSize, uint8_t** memoryOut, intptr_t* handleOut) {
-  return JS::AsmJSCache_Disabled_ShellFlags;
-}
-
-static void ShellCloseAsmJSCacheEntryForWrite(size_t serializedSize,
-                                              uint8_t* memory,
-                                              intptr_t handle) {
-  // Undo the cookie adjustment done when opening the file.
-  memory -= sizeof(uint32_t);
-  serializedSize += sizeof(uint32_t);
-
-  // Write the magic cookie value after flushing the entire cache entry.
-#ifdef XP_WIN
-  FlushViewOfFile(memory, serializedSize);
-  FlushFileBuffers(HANDLE(_get_osfhandle(handle)));
-#else
-  msync(memory, serializedSize, MS_SYNC);
-#endif
-
-  MOZ_ASSERT(*(uint32_t*)memory == 0);
-  *(uint32_t*)memory = asmJSCacheCookie;
-
-  // Free the memory mapping and file.
-#ifdef XP_WIN
-  UnmapViewOfFile(const_cast<uint8_t*>(memory));
-#else
-  munmap(memory, serializedSize);
-#endif
-
-  MOZ_ASSERT(jsCacheOpened == true);
-  jsCacheOpened = false;
-  close(handle);
-}
-
 static bool ShellBuildId(JS::BuildIdCharVector* buildId) {
   // The browser embeds the date into the buildid and the buildid is embedded
   // in the binary, so every 'make' necessarily builds a new firefox binary.
   // Fortunately, the actual firefox executable is tiny -- all the code is in
   // libxul.so and other shared modules -- so this isn't a big deal. Not so
   // for the statically-linked JS shell. To avoid recompiling js.cpp and
   // re-linking 'js' on every 'make', we use a constant buildid and rely on
-  // the shell user to manually clear the cache (deleting the dir passed to
-  // --js-cache) between cache-breaking updates. Note: jit_tests.py does this
-  // on every run).
+  // the shell user to manually clear any caches between cache-breaking updates.
   const char buildid[] = "JS-shell";
   return buildId->append(buildid, sizeof(buildid));
 }
 
-static const JS::AsmJSCacheOps asmJSCacheOps = {
-    ShellOpenAsmJSCacheEntryForRead, ShellCloseAsmJSCacheEntryForRead,
-    ShellOpenAsmJSCacheEntryForWrite, ShellCloseAsmJSCacheEntryForWrite};
-
 static bool TimesAccessed(JSContext* cx, unsigned argc, Value* vp) {
   static int32_t accessed = 0;
   CallArgs args = CallArgsFromVp(argc, vp);
   args.rval().setInt32(++accessed);
   return true;
 }
 
 static const JSPropertySpec TestingProperties[] = {
@@ -10386,30 +10164,16 @@ static bool SetContextOptions(JSContext*
   reportWarnings = op.getBoolOption('w');
   compileOnly = op.getBoolOption('c');
   printTiming = op.getBoolOption('b');
   enableCodeCoverage = op.getBoolOption("code-coverage");
   enableDisassemblyDumps = op.getBoolOption('D');
   cx->runtime()->profilingScripts =
       enableCodeCoverage || enableDisassemblyDumps;
 
-  if (const char* jsCacheOpt = op.getStringOption("js-cache")) {
-    UniqueChars jsCacheChars;
-    if (!op.getBoolOption("no-js-cache-per-process")) {
-      jsCacheChars = JS_smprintf("%s/%u", jsCacheOpt, (unsigned)getpid());
-    } else {
-      jsCacheChars = DuplicateString(jsCacheOpt);
-    }
-    if (!jsCacheChars) {
-      return false;
-    }
-    jsCacheDir = jsCacheChars.release();
-    jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir).release();
-  }
-
 #ifdef DEBUG
   dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables");
 #endif
 
 #ifdef JS_GC_ZEAL
   const char* zealStr = op.getStringOption("gc-zeal");
   if (zealStr) {
     if (!cx->runtime()->gc.parseAndSetZeal(zealStr)) {
@@ -10636,27 +10400,16 @@ static int Shell(JSContext* cx, OptionPa
 
   if (enableDisassemblyDumps) {
     AutoReportException are(cx);
     if (!js::DumpRealmPCCounts(cx)) {
       result = EXITCODE_OUT_OF_MEMORY;
     }
   }
 
-  if (!op->getBoolOption("no-js-cache-per-process")) {
-    if (jsCacheAsmJSPath) {
-      unlink(jsCacheAsmJSPath);
-      JS_free(cx, const_cast<char*>(jsCacheAsmJSPath));
-    }
-    if (jsCacheDir) {
-      rmdir(jsCacheDir);
-      JS_free(cx, const_cast<char*>(jsCacheDir));
-    }
-  }
-
   /*
    * Dump remaining type inference results while we still have a context.
    * This printing depends on atoms still existing.
    */
   for (CompartmentsIter c(cx->runtime()); !c.done(); c.next()) {
     PrintTypes(cx, c, false);
   }
 
@@ -10789,27 +10542,16 @@ int main(int argc, char** argv, char** e
                         "Only compile, don't run (syntax checking mode)") ||
       !op.addBoolOption('w', "warnings", "Emit warnings") ||
       !op.addBoolOption('W', "nowarnings", "Don't emit warnings") ||
       !op.addBoolOption('s', "strict", "Check strictness") ||
       !op.addBoolOption('D', "dump-bytecode",
                         "Dump bytecode with exec count for all scripts") ||
       !op.addBoolOption('b', "print-timing",
                         "Print sub-ms runtime for each file that's run") ||
-      !op.addStringOption(
-          '\0', "js-cache", "[path]",
-          "Enable the JS cache by specifying the path of the directory to use "
-          "to hold cache files") ||
-      !op.addBoolOption(
-          '\0', "no-js-cache-per-process",
-          "Deactivates cache per process. Otherwise, generate a separate cache"
-          "sub-directory for this process inside the cache directory"
-          "specified by --js-cache. This cache directory will be removed"
-          "when the js shell exits. This is useful for running tests in"
-          "parallel.") ||
       !op.addBoolOption('\0', "code-coverage",
                         "Enable code coverage instrumentation.")
 #ifdef DEBUG
       || !op.addBoolOption('O', "print-alloc",
                            "Print the number of allocations at exit")
 #endif
       || !op.addOptionalStringArg("script",
                                   "A script to execute (after all options)") ||
@@ -11066,25 +10808,31 @@ int main(int argc, char** argv, char** e
    * allocations as possible.
    */
   OOM_printAllocationCount = op.getBoolOption('O');
 #endif
 
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
   if (op.getBoolOption("no-sse3")) {
     js::jit::CPUInfo::SetSSE3Disabled();
-    PropagateFlagToNestedShells("--no-sse3");
+    if (!sCompilerProcessFlags.append("--no-sse3")) {
+      return EXIT_SUCCESS;
+    }
   }
   if (op.getBoolOption("no-sse4")) {
     js::jit::CPUInfo::SetSSE4Disabled();
-    PropagateFlagToNestedShells("--no-sse4");
+    if (!sCompilerProcessFlags.append("--no-sse4")) {
+      return EXIT_SUCCESS;
+    }
   }
   if (op.getBoolOption("enable-avx")) {
     js::jit::CPUInfo::SetAVXEnabled();
-    PropagateFlagToNestedShells("--enable-avx");
+    if (!sCompilerProcessFlags.append("--enable-avx")) {
+      return EXIT_SUCCESS;
+    }
   }
 #endif
 
   if (op.getBoolOption("no-threads")) {
     js::DisableExtraThreads();
   }
 
   AutoLibraryLoader loader;
@@ -11146,17 +10894,16 @@ int main(int argc, char** argv, char** e
   }
 
   JS_SetTrustedPrincipals(cx, &ShellPrincipals::fullyTrusted);
   JS_SetSecurityCallbacks(cx, &ShellPrincipals::securityCallbacks);
   JS_InitDestroyPrincipalsCallback(cx, ShellPrincipals::destroy);
   JS_SetDestroyCompartmentCallback(cx, DestroyShellCompartmentPrivate);
 
   JS_AddInterruptCallback(cx, ShellInterruptCallback);
-  JS::SetAsmJSCacheOps(cx, &asmJSCacheOps);
 
   bufferStreamState = js_new<ExclusiveWaitableData<BufferStreamState>>(
       mutexid::BufferStreamState);
   if (!bufferStreamState) {
     return 1;
   }
   auto shutdownBufferStreams = MakeScopeExit([] {
     ShutdownBufferStreams();
--- a/js/src/tests/lib/jittests.py
+++ b/js/src/tests/lib/jittests.py
@@ -4,16 +4,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 # jit_test.py -- Python harness for JavaScript trace tests.
 
 from __future__ import print_function
 import os
 import posixpath
+import re
 import sys
 import traceback
 from collections import namedtuple
 from datetime import datetime
 
 if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
     from tasks_unix import run_all_tests
 else:
@@ -24,17 +25,16 @@ from results import TestOutput, escape_c
 from structuredlog import TestLogger
 
 TESTS_LIB_DIR = os.path.dirname(os.path.abspath(__file__))
 JS_DIR = os.path.dirname(os.path.dirname(TESTS_LIB_DIR))
 TOP_SRC_DIR = os.path.dirname(os.path.dirname(JS_DIR))
 TEST_DIR = os.path.join(JS_DIR, 'jit-test', 'tests')
 LIB_DIR = os.path.join(JS_DIR, 'jit-test', 'lib') + os.path.sep
 MODULE_DIR = os.path.join(JS_DIR, 'jit-test', 'modules') + os.path.sep
-JS_CACHE_DIR = os.path.join(JS_DIR, 'jit-test', '.js-cache')
 JS_TESTS_DIR = posixpath.join(JS_DIR, 'tests')
 
 # Backported from Python 3.1 posixpath.py
 
 
 def _relpath(path, start=None):
     """Return a relative version of a path"""
 
@@ -190,17 +190,16 @@ class JitTest:
 
         # For each list of jit flags, make a copy of the test.
         return [self.copy_and_extend_jitflags(v) for v in variants]
 
     COOKIE = '|jit-test|'
 
     # We would use 500019 (5k19), but quit() only accepts values up to 127, due to fuzzers
     SKIPPED_EXIT_STATUS = 59
-    CacheDir = JS_CACHE_DIR
     Directives = {}
 
     @classmethod
     def find_directives(cls, file_name):
         meta = ''
         line = open(file_name).readline()
         i = line.find(cls.COOKIE)
         if i != -1:
@@ -339,17 +338,17 @@ class JitTest:
         # Don't merge the expressions: We want separate -e arguments to avoid
         # semicolons in the command line, bug 1351607.
         exprs = ["const platform={}".format(js_quote(quotechar, sys.platform)),
                  "const libdir={}".format(js_quote(quotechar, libdir)),
                  "const scriptdir={}".format(js_quote(quotechar, scriptdir_var))]
 
         # We may have specified '-a' or '-d' twice: once via --jitflags, once
         # via the "|jit-test|" line.  Remove dups because they are toggles.
-        cmd = prefix + ['--js-cache', JitTest.CacheDir]
+        cmd = prefix + []
         cmd += list(set(self.jitflags))
         for expr in exprs:
             cmd += ['-e', expr]
         for inc in self.other_includes:
             cmd += ['-f', libdir + inc]
         if self.skip_if_cond:
             cmd += ['-e', "if ({}) quit({})".format(self.skip_if_cond, self.SKIPPED_EXIT_STATUS)]
         cmd += ['--module-load-path', moduledir]
@@ -404,17 +403,17 @@ def find_tests(substring=None, run_binas
             test = os.path.join(dirpath, filename)
             if substring is None \
                or substring in os.path.relpath(test, TEST_DIR):
                 ans.append(test)
     return ans
 
 
 def run_test_remote(test, device, prefix, options):
-    from mozdevice import ADBDevice, ADBProcessError, ADBTimeoutError
+    from mozdevice import ADBDevice, ADBProcessError
 
     if options.test_reflect_stringify:
         raise ValueError("can't run Reflect.stringify tests remotely")
     cmd = test.command(prefix,
                        posixpath.join(options.remote_test_root, 'lib/'),
                        posixpath.join(options.remote_test_root, 'modules/'),
                        posixpath.join(options.remote_test_root, 'tests'))
     if options.show_cmd:
@@ -424,25 +423,33 @@ def run_test_remote(test, device, prefix
     if test.tz_pacific:
         env['TZ'] = 'PST8PDT'
 
     env['LD_LIBRARY_PATH'] = options.remote_test_root
 
     cmd = ADBDevice._escape_command_line(cmd)
     start = datetime.now()
     try:
+        # Allow ADBError or ADBTimeoutError to terminate the test run,
+        # but handle ADBProcessError in order to support the use of
+        # non-zero exit codes in the JavaScript shell tests.
         out = device.shell_output(cmd, env=env,
                                   cwd=options.remote_test_root,
                                   timeout=int(options.timeout))
         returncode = 0
-    except ADBTimeoutError:
-        raise
     except ADBProcessError as e:
+        # Treat ignorable intermittent adb communication errors as
+        # skipped tests.
         out = str(e.adb_process.stdout)
         returncode = e.adb_process.exitcode
+        re_ignore = re.compile(r'error: (closed|device .* not found)')
+        if returncode == 1 and re_ignore.search(out):
+            print("Skipping {} due to ignorable adb error {}".format(test.path, out))
+            test.skip_if_cond = "true"
+            returncode = test.SKIPPED_EXIT_STATUS
 
     elapsed = (datetime.now() - start).total_seconds()
 
     # We can't distinguish between stdout and stderr so we pass
     # the same buffer to both.
     return TestOutput(test, cmd, out, out, returncode, elapsed, False)
 
 
@@ -788,49 +795,56 @@ def push_progs(options, device, progs):
 def init_remote_dir(device, path, root=True):
     device.rm(path, recursive=True, force=True, root=root)
     device.mkdir(path, parents=True, root=root)
     device.chmod(path, recursive=True, root=root)
 
 
 def run_tests_remote(tests, num_tests, prefix, options, slog):
     # Setup device with everything needed to run our tests.
-    from mozdevice import ADBDevice
-    device = ADBDevice(device=options.device_serial,
-                       test_root=options.remote_test_root)
+    from mozdevice import ADBDevice, ADBError, ADBTimeoutError
+    try:
+        device = ADBDevice(device=options.device_serial,
+                           test_root=options.remote_test_root)
 
-    init_remote_dir(device, options.remote_test_root)
+        init_remote_dir(device, options.remote_test_root)
 
-    # Update the test root to point to our test directory.
-    jit_tests_dir = posixpath.join(options.remote_test_root, 'jit-tests')
-    options.remote_test_root = posixpath.join(jit_tests_dir, 'jit-tests')
+        # Update the test root to point to our test directory.
+        jit_tests_dir = posixpath.join(options.remote_test_root, 'jit-tests')
+        options.remote_test_root = posixpath.join(jit_tests_dir, 'jit-tests')
 
-    # Push js shell and libraries.
-    init_remote_dir(device, jit_tests_dir)
-    push_libs(options, device)
-    push_progs(options, device, [prefix[0]])
-    device.chmod(options.remote_test_root, recursive=True, root=True)
-
-    JitTest.CacheDir = posixpath.join(options.remote_test_root, '.js-cache')
-    init_remote_dir(device, JitTest.CacheDir)
+        # Push js shell and libraries.
+        init_remote_dir(device, jit_tests_dir)
+        push_libs(options, device)
+        push_progs(options, device, [prefix[0]])
+        device.chmod(options.remote_test_root, recursive=True, root=True)
 
-    jtd_tests = posixpath.join(jit_tests_dir, 'tests')
-    init_remote_dir(device, jtd_tests)
-    device.push(JS_TESTS_DIR, jtd_tests, timeout=600)
-    device.chmod(jtd_tests, recursive=True, root=True)
+        jtd_tests = posixpath.join(jit_tests_dir, 'tests')
+        init_remote_dir(device, jtd_tests)
+        device.push(JS_TESTS_DIR, jtd_tests, timeout=600)
+        device.chmod(jtd_tests, recursive=True, root=True)
 
-    device.push(os.path.dirname(TEST_DIR), options.remote_test_root,
-                timeout=600)
-    device.chmod(options.remote_test_root, recursive=True, root=True)
-    prefix[0] = os.path.join(options.remote_test_root, 'js')
+        device.push(os.path.dirname(TEST_DIR), options.remote_test_root,
+                    timeout=600)
+        device.chmod(options.remote_test_root, recursive=True, root=True)
+        prefix[0] = os.path.join(options.remote_test_root, 'js')
+    except (ADBError, ADBTimeoutError):
+        print("TEST-UNEXPECTED-FAIL | jit_test.py" +
+              " : Device initialization failed")
+        raise
 
     # Run all tests.
     pb = create_progressbar(num_tests, options)
-    gen = get_remote_results(tests, device, prefix, options)
-    ok = process_test_results(gen, num_tests, pb, options, slog)
+    try:
+        gen = get_remote_results(tests, device, prefix, options)
+        ok = process_test_results(gen, num_tests, pb, options, slog)
+    except (ADBError, ADBTimeoutError):
+        print("TEST-UNEXPECTED-FAIL | jit_test.py" +
+              " : Device error during test")
+        raise
     return ok
 
 
 def platform_might_be_android():
     try:
         # The python package for SL4A provides an |android| module.
         # If that module is present, we're likely in SL4A-python on
         # device.  False positives and negatives are possible,
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -225,17 +225,16 @@ struct JSContext : public JS::RootingCon
   }
   bool permanentAtomsPopulated() { return runtime_->permanentAtomsPopulated(); }
   const js::FrozenAtomSet& permanentAtoms() {
     return *runtime_->permanentAtoms();
   }
   js::WellKnownSymbols& wellKnownSymbols() {
     return *runtime_->wellKnownSymbols;
   }
-  const JS::AsmJSCacheOps& asmJSCacheOps() { return runtime_->asmJSCacheOps; }
   js::PropertyName* emptyString() { return runtime_->emptyString; }
   js::FreeOp* defaultFreeOp() { return runtime_->defaultFreeOp(); }
   void* stackLimitAddress(JS::StackKind kind) {
     return &nativeStackLimit[kind];
   }
   void* stackLimitAddressForJitCode(JS::StackKind kind);
   uintptr_t stackLimit(JS::StackKind kind) { return nativeStackLimit[kind]; }
   uintptr_t stackLimitForJitCode(JS::StackKind kind);
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -394,20 +394,16 @@ struct JSRuntime : public js::MallocProv
       mozilla::LinkedList<JS::PersistentRooted<void*>>>>
       heapRoots;
 
   void tracePersistentRoots(JSTracer* trc);
   void finishPersistentRoots();
 
   void finishRoots();
 
- public:
-  /* AsmJSCache callbacks are runtime-wide. */
-  js::UnprotectedData<JS::AsmJSCacheOps> asmJSCacheOps;
-
  private:
   js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
 
  public:
   void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
   const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
 
   js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -255,18 +255,16 @@ class AsmJSGlobal {
   ConstantKind constantKind() const {
     MOZ_ASSERT(pod.which_ == Constant);
     return pod.u.constant.kind_;
   }
   double constantValue() const {
     MOZ_ASSERT(pod.which_ == Constant);
     return pod.u.constant.value_;
   }
-
-  WASM_DECLARE_SERIALIZABLE(AsmJSGlobal);
 };
 
 typedef Vector<AsmJSGlobal, 0, SystemAllocPolicy> AsmJSGlobalVector;
 
 // An AsmJSImport is slightly different than an asm.js FFI function: a single
 // asm.js FFI function can be called with many different signatures. When
 // compiled to wasm, each unique FFI function paired with signature generates a
 // wasm import.
@@ -300,18 +298,16 @@ class AsmJSExport {
         endOffsetInModule_(endOffsetInModule) {}
   uint32_t funcIndex() const { return funcIndex_; }
   uint32_t startOffsetInModule() const { return startOffsetInModule_; }
   uint32_t endOffsetInModule() const { return endOffsetInModule_; }
 };
 
 typedef Vector<AsmJSExport, 0, SystemAllocPolicy> AsmJSExportVector;
 
-enum class CacheResult { Hit, Miss };
-
 // Holds the immutable guts of an AsmJSModule.
 //
 // AsmJSMetadata is built incrementally by ModuleValidator and then shared
 // immutably between AsmJSModules.
 
 struct AsmJSMetadataCacheablePod {
   uint32_t numFFIs = 0;
   uint32_t srcLength = 0;
@@ -324,18 +320,16 @@ struct js::AsmJSMetadata : Metadata, Asm
   AsmJSGlobalVector asmJSGlobals;
   AsmJSImportVector asmJSImports;
   AsmJSExportVector asmJSExports;
   CacheableCharsVector asmJSFuncNames;
   CacheableChars globalArgumentName;
   CacheableChars importArgumentName;
   CacheableChars bufferArgumentName;
 
-  CacheResult cacheResult;
-
   // These values are not serialized since they are relative to the
   // containing script which can be different between serialization and
   // deserialization contexts. Thus, they must be set explicitly using the
   // ambient Parser/ScriptSource after deserialization.
   //
   // srcStart refers to the offset in the ScriptSource to the beginning of
   // the asm.js module function. If the function has been created with the
   // Function constructor, this will be the first character in the function
@@ -348,17 +342,16 @@ struct js::AsmJSMetadata : Metadata, Asm
 
   uint32_t srcEndBeforeCurly() const { return srcStart + srcLength; }
   uint32_t srcEndAfterCurly() const {
     return srcStart + srcLengthWithRightBrace;
   }
 
   AsmJSMetadata()
       : Metadata(ModuleKind::AsmJS),
-        cacheResult(CacheResult::Miss),
         toStringStart(0),
         srcStart(0),
         strict(false) {}
   ~AsmJSMetadata() override {}
 
   const AsmJSExport& lookupAsmJSExport(uint32_t funcIndex) const {
     // The AsmJSExportVector isn't stored in sorted order so do a linear
     // search. This is for the super-cold and already-expensive toString()
@@ -388,18 +381,16 @@ struct js::AsmJSMetadata : Metadata, Asm
     if (!p) {
       return true;
     }
     return name->append(p, strlen(p));
   }
 
   AsmJSMetadataCacheablePod& pod() { return *this; }
   const AsmJSMetadataCacheablePod& pod() const { return *this; }
-
-  WASM_DECLARE_SERIALIZABLE_OVERRIDE(AsmJSMetadata)
 };
 
 typedef RefPtr<AsmJSMetadata> MutableAsmJSMetadata;
 
 /*****************************************************************************/
 // ParseNode utilities
 
 static inline ParseNode* NextNode(ParseNode* pn) { return pn->pn_next; }
@@ -6992,88 +6983,16 @@ static JSFunction* NewAsmJSModuleFunctio
   moduleFun->setExtendedSlot(FunctionExtended::ASMJS_MODULE_SLOT,
                              ObjectValue(*moduleObj));
 
   MOZ_ASSERT(IsAsmJSModule(moduleFun));
   return moduleFun;
 }
 
 /*****************************************************************************/
-// Caching and cloning
-
-size_t AsmJSGlobal::serializedSize() const {
-  return sizeof(pod) + field_.serializedSize();
-}
-
-uint8_t* AsmJSGlobal::serialize(uint8_t* cursor) const {
-  cursor = WriteBytes(cursor, &pod, sizeof(pod));
-  cursor = field_.serialize(cursor);
-  return cursor;
-}
-
-const uint8_t* AsmJSGlobal::deserialize(const uint8_t* cursor) {
-  (cursor = ReadBytes(cursor, &pod, sizeof(pod))) &&
-      (cursor = field_.deserialize(cursor));
-  return cursor;
-}
-
-size_t AsmJSGlobal::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const {
-  return field_.sizeOfExcludingThis(mallocSizeOf);
-}
-
-size_t AsmJSMetadata::serializedSize() const {
-  return Metadata::serializedSize() + sizeof(pod()) +
-         SerializedVectorSize(asmJSGlobals) +
-         SerializedPodVectorSize(asmJSImports) +
-         SerializedPodVectorSize(asmJSExports) +
-         SerializedVectorSize(asmJSFuncNames) +
-         globalArgumentName.serializedSize() +
-         importArgumentName.serializedSize() +
-         bufferArgumentName.serializedSize();
-}
-
-uint8_t* AsmJSMetadata::serialize(uint8_t* cursor) const {
-  cursor = Metadata::serialize(cursor);
-  cursor = WriteBytes(cursor, &pod(), sizeof(pod()));
-  cursor = SerializeVector(cursor, asmJSGlobals);
-  cursor = SerializePodVector(cursor, asmJSImports);
-  cursor = SerializePodVector(cursor, asmJSExports);
-  cursor = SerializeVector(cursor, asmJSFuncNames);
-  cursor = globalArgumentName.serialize(cursor);
-  cursor = importArgumentName.serialize(cursor);
-  cursor = bufferArgumentName.serialize(cursor);
-  return cursor;
-}
-
-const uint8_t* AsmJSMetadata::deserialize(const uint8_t* cursor) {
-  (cursor = Metadata::deserialize(cursor)) &&
-      (cursor = ReadBytes(cursor, &pod(), sizeof(pod()))) &&
-      (cursor = DeserializeVector(cursor, &asmJSGlobals)) &&
-      (cursor = DeserializePodVector(cursor, &asmJSImports)) &&
-      (cursor = DeserializePodVector(cursor, &asmJSExports)) &&
-      (cursor = DeserializeVector(cursor, &asmJSFuncNames)) &&
-      (cursor = globalArgumentName.deserialize(cursor)) &&
-      (cursor = importArgumentName.deserialize(cursor)) &&
-      (cursor = bufferArgumentName.deserialize(cursor));
-  cacheResult = CacheResult::Hit;
-  return cursor;
-}
-
-size_t AsmJSMetadata::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const {
-  return Metadata::sizeOfExcludingThis(mallocSizeOf) +
-         SizeOfVectorExcludingThis(asmJSGlobals, mallocSizeOf) +
-         asmJSImports.sizeOfExcludingThis(mallocSizeOf) +
-         asmJSExports.sizeOfExcludingThis(mallocSizeOf) +
-         SizeOfVectorExcludingThis(asmJSFuncNames, mallocSizeOf) +
-         globalArgumentName.sizeOfExcludingThis(mallocSizeOf) +
-         importArgumentName.sizeOfExcludingThis(mallocSizeOf) +
-         bufferArgumentName.sizeOfExcludingThis(mallocSizeOf);
-}
-
-/*****************************************************************************/
 // Top-level js::CompileAsmJS
 
 static bool NoExceptionPending(JSContext* cx) {
   return cx->helperThread() || !cx->isExceptionPending();
 }
 
 static bool SuccessfulValidation(frontend::ParserBase& parser,
                                  unsigned compilationTime) {
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -1031,17 +1031,17 @@ void BaseLocalIter::settle() {
   if (index_ < argsLength_) {
     MOZ_ASSERT(!argsIter_.done());
     mirType_ = argsIter_.mirType();
     switch (mirType_) {
       case MIRType::Int32:
       case MIRType::Int64:
       case MIRType::Double:
       case MIRType::Float32:
-      case MIRType::Pointer:
+      case MIRType::RefOrNull:
         if (argsIter_->argInRegister()) {
           frameOffset_ = pushLocal(MIRTypeToSize(mirType_));
         } else {
           frameOffset_ = -(argsIter_->offsetFromArgBase() + sizeof(Frame));
         }
         break;
       default:
         MOZ_CRASH("Argument type");
@@ -2140,17 +2140,17 @@ struct StackMapGenerator {
     // registers in the MachineState.  See MachineState::MachineState().
     MOZ_ASSERT(trapExitLayoutNumWords_ < 0x100);
 
     if (!extras.appendN(false, trapExitLayoutNumWords_)) {
       return false;
     }
 
     for (ABIArgIter<const ValTypeVector> i(args); !i.done(); i++) {
-      if (!i->argInRegister() || i.mirType() != MIRType::Pointer) {
+      if (!i->argInRegister() || i.mirType() != MIRType::RefOrNull) {
         continue;
       }
 
       size_t offsetFromTop =
           reinterpret_cast<size_t>(trapExitLayout_.address(i->gpr()));
 
       // If this doesn't hold, the associated register wasn't saved by
       // the trap exit stub.  Better to crash now than much later, in
@@ -2515,20 +2515,20 @@ class BaseCompiler final : public BaseCo
   BCESet
       bceSafe_;  // Locals that have been bounds checked and not updated since
   ValTypeVector SigD_;
   ValTypeVector SigF_;
   MIRTypeVector SigP_;
   MIRTypeVector SigPI_;
   MIRTypeVector SigPL_;
   MIRTypeVector SigPII_;
-  MIRTypeVector SigPIPI_;
+  MIRTypeVector SigPIRI_;
   MIRTypeVector SigPIII_;
   MIRTypeVector SigPIIL_;
-  MIRTypeVector SigPIIP_;
+  MIRTypeVector SigPIIR_;
   MIRTypeVector SigPILL_;
   MIRTypeVector SigPIIII_;
   MIRTypeVector SigPIIIII_;
   NonAssertingLabel returnLabel_;
 
   LatentOp latentOp_;   // Latent operation for branch (seen next)
   ValType latentType_;  // Operand type, if latentOp_ is true
   Assembler::Condition
@@ -2926,17 +2926,17 @@ class BaseCompiler final : public BaseCo
     moveImmRef(src.refval(), dest);
   }
 
   void loadMemRef(const Stk& src, RegPtr dest) {
     fr.loadStackPtr(src.offs(), dest);
   }
 
   void loadLocalRef(const Stk& src, RegPtr dest) {
-    fr.loadLocalPtr(localFromSlot(src.slot(), MIRType::Pointer), dest);
+    fr.loadLocalPtr(localFromSlot(src.slot(), MIRType::RefOrNull), dest);
   }
 
   void loadRegisterRef(const Stk& src, RegPtr dest) {
     moveRef(src.refReg(), dest);
   }
 
   void loadConstF64(const Stk& src, RegF64 dest) {
     double d;
@@ -4045,21 +4045,19 @@ class BaseCompiler final : public BaseCo
 
     MOZ_ASSERT(smgen_.mst_.length() == 0);
     if (!smgen_.mst_.pushNonGCPointers(smgen_.numStackArgWords_)) {
       return false;
     }
 
     for (ABIArgIter<const ValTypeVector> i(argTys); !i.done(); i++) {
       ABIArg argLoc = *i;
-      if (argLoc.kind() != ABIArg::Stack) {
-        continue;
-      }
       const ValType& ty = argTys[i.index()];
-      if (!ty.isReference()) {
+      MOZ_ASSERT(ToMIRType(ty) != MIRType::Pointer);
+      if (argLoc.kind() != ABIArg::Stack || !ty.isReference()) {
         continue;
       }
       uint32_t offset = argLoc.offsetFromArgBase();
       MOZ_ASSERT(offset < nStackArgBytes);
       MOZ_ASSERT(offset % sizeof(void*) == 0);
       smgen_.mst_.setGCPointer(offset / sizeof(void*));
     }
 
@@ -4140,17 +4138,17 @@ class BaseCompiler final : public BaseCo
       Local& l = localInfo_[i.index()];
       switch (i.mirType()) {
         case MIRType::Int32:
           fr.storeLocalI32(RegI32(i->gpr()), l);
           break;
         case MIRType::Int64:
           fr.storeLocalI64(RegI64(i->gpr64()), l);
           break;
-        case MIRType::Pointer: {
+        case MIRType::RefOrNull: {
           uint32_t offs = fr.localOffset(l);
           MOZ_ASSERT(0 == (offs % sizeof(void*)));
           fr.storeLocalPtr(RegPtr(i->gpr()), l);
           smgen_.mst_.setGCPointer(offs / sizeof(void*));
           break;
         }
         case MIRType::Double:
           fr.storeLocalF64(RegF64(i->fpu()), l);
@@ -4545,17 +4543,17 @@ class BaseCompiler final : public BaseCo
 #endif
           case ABIArg::Uninitialized:
             MOZ_CRASH("Uninitialized ABIArg kind");
         }
         break;
       }
       case ValType::Ref:
       case ValType::AnyRef: {
-        ABIArg argLoc = call->abi.next(MIRType::Pointer);
+        ABIArg argLoc = call->abi.next(MIRType::RefOrNull);
         if (argLoc.kind() == ABIArg::Stack) {
           ScratchPtr scratch(*this);
           loadRef(arg, scratch);
           masm.storePtr(scratch, Address(masm.getStackPointer(),
                                          argLoc.offsetFromArgBase()));
         } else {
           loadRef(arg, RegPtr(argLoc.gpr()));
         }
@@ -9052,17 +9050,17 @@ bool BaseCompiler::emitSetOrTeeLocal(uin
         pushF32(rv);
       }
       break;
     }
     case ValType::Ref:
     case ValType::AnyRef: {
       RegPtr rv = popRef();
       syncLocal(slot);
-      fr.storeLocalPtr(rv, localFromSlot(slot, MIRType::Pointer));
+      fr.storeLocalPtr(rv, localFromSlot(slot, MIRType::RefOrNull));
       if (isSetLocal) {
         freeRef(rv);
       } else {
         pushRef(rv);
       }
       break;
     }
     case ValType::NullRef:
@@ -9757,17 +9755,17 @@ bool BaseCompiler::emitInstanceCall(uint
     ValType t;
     switch (sig[i]) {
       case MIRType::Int32:
         t = ValType::I32;
         break;
       case MIRType::Int64:
         t = ValType::I64;
         break;
-      case MIRType::Pointer:
+      case MIRType::RefOrNull:
         t = ValType::AnyRef;
         break;
       default:
         MOZ_CRASH("Unexpected type");
     }
     passArg(t, peek(numArgs - i), &baselineCall);
   }
   CodeOffset raOffset =
@@ -10362,17 +10360,17 @@ bool BaseCompiler::emitTableGrow() {
   }
   if (deadCode_) {
     return true;
   }
   // grow(delta:u32, initValue:anyref, table:u32) -> u32
   //
   // infallible.
   pushI32(tableIndex);
-  return emitInstanceCall(lineOrBytecode, SigPIPI_, ExprType::I32,
+  return emitInstanceCall(lineOrBytecode, SigPIRI_, ExprType::I32,
                           SymbolicAddress::TableGrow);
 }
 
 MOZ_MUST_USE
 bool BaseCompiler::emitTableSet() {
   uint32_t lineOrBytecode = readCallSiteLineOrBytecode();
   Nothing index, value;
   uint32_t tableIndex;
@@ -10381,17 +10379,17 @@ bool BaseCompiler::emitTableSet() {
   }
   if (deadCode_) {
     return true;
   }
   // set(index:u32, value:ref, table:u32) -> i32
   //
   // Returns -1 on range error, otherwise 0 (which is then ignored).
   pushI32(tableIndex);
-  if (!emitInstanceCall(lineOrBytecode, SigPIPI_, ExprType::Void,
+  if (!emitInstanceCall(lineOrBytecode, SigPIRI_, ExprType::Void,
                         SymbolicAddress::TableSet)) {
     return false;
   }
   Label noTrap;
   masm.branchTest32(Assembler::NotSigned, ReturnReg, ReturnReg, &noTrap);
   trap(Trap::ThrowReported);
   masm.bind(&noTrap);
   return true;
@@ -10765,17 +10763,17 @@ bool BaseCompiler::emitStructNarrow() {
   //
   // Infallible.
   const StructType& outputStruct =
       env_.types[outputType.refTypeIndex()].structType();
 
   pushI32(mustUnboxAnyref);
   pushI32(outputStruct.moduleIndex_);
   pushRef(rp);
-  return emitInstanceCall(lineOrBytecode, SigPIIP_, ExprType::AnyRef,
+  return emitInstanceCall(lineOrBytecode, SigPIIR_, ExprType::AnyRef,
                           SymbolicAddress::StructNarrow);
 }
 
 bool BaseCompiler::emitBody() {
   MOZ_ASSERT(smgen_.framePushedAtEntryToBody_.isSome());
 
   if (!iter_.readFunctionStart(funcType().ret())) {
     return false;
@@ -11856,30 +11854,32 @@ bool BaseCompiler::init() {
   }
   if (!SigPL_.append(MIRType::Pointer) || !SigPL_.append(MIRType::Int64)) {
     return false;
   }
   if (!SigPII_.append(MIRType::Pointer) || !SigPII_.append(MIRType::Int32) ||
       !SigPII_.append(MIRType::Int32)) {
     return false;
   }
-  if (!SigPIPI_.append(MIRType::Pointer) || !SigPIPI_.append(MIRType::Int32) ||
-      !SigPIPI_.append(MIRType::Pointer) || !SigPIPI_.append(MIRType::Int32)) {
+  if (!SigPIRI_.append(MIRType::Pointer) || !SigPIRI_.append(MIRType::Int32) ||
+      !SigPIRI_.append(MIRType::RefOrNull) ||
+      !SigPIRI_.append(MIRType::Int32)) {
     return false;
   }
   if (!SigPIII_.append(MIRType::Pointer) || !SigPIII_.append(MIRType::Int32) ||
       !SigPIII_.append(MIRType::Int32) || !SigPIII_.append(MIRType::Int32)) {
     return false;
   }
   if (!SigPIIL_.append(MIRType::Pointer) || !SigPIIL_.append(MIRType::Int32) ||
       !SigPIIL_.append(MIRType::Int32) || !SigPIIL_.append(MIRType::Int64)) {
     return false;
   }
-  if (!SigPIIP_.append(MIRType::Pointer) || !SigPIIP_.append(MIRType::Int32) ||
-      !SigPIIP_.append(MIRType::Int32) || !SigPIIP_.append(MIRType::Pointer)) {
+  if (!SigPIIR_.append(MIRType::Pointer) || !SigPIIR_.append(MIRType::Int32) ||
+      !SigPIIR_.append(MIRType::Int32) ||
+      !SigPIIR_.append(MIRType::RefOrNull)) {
     return false;
   }
   if (!SigPILL_.append(MIRType::Pointer) || !SigPILL_.append(MIRType::Int32) ||
       !SigPILL_.append(MIRType::Int64) || !SigPILL_.append(MIRType::Int64)) {
     return false;
   }
   if (!SigPIIII_.append(MIRType::Pointer) ||
       !SigPIIII_.append(MIRType::Int32) || !SigPIIII_.append(MIRType::Int32) ||
--- a/js/src/wasm/WasmCode.h
+++ b/js/src/wasm/WasmCode.h
@@ -387,17 +387,17 @@ struct Metadata : public ShareableBase<M
 
   bool getFuncNameStandalone(uint32_t funcIndex, UTF8Bytes* name) const {
     return getFuncName(NameContext::Standalone, funcIndex, name);
   }
   bool getFuncNameBeforeLocation(uint32_t funcIndex, UTF8Bytes* name) const {
     return getFuncName(NameContext::BeforeLocation, funcIndex, name);
   }
 
-  WASM_DECLARE_SERIALIZABLE_VIRTUAL(Metadata);
+  WASM_DECLARE_SERIALIZABLE(Metadata);
 };
 
 typedef RefPtr<Metadata> MutableMetadata;
 typedef RefPtr<const Metadata> SharedMetadata;
 
 struct MetadataTier {
   explicit MetadataTier(Tier tier) : tier(tier) {}
 
--- a/js/src/wasm/WasmStubs.cpp
+++ b/js/src/wasm/WasmStubs.cpp
@@ -191,17 +191,17 @@ static void SetupABIArguments(MacroAssem
     Address src(argv, argOffset);
     MIRType type = iter.mirType();
     switch (iter->kind()) {
       case ABIArg::GPR:
         if (type == MIRType::Int32) {
           masm.load32(src, iter->gpr());
         } else if (type == MIRType::Int64) {
           masm.load64(src, iter->gpr64());
-        } else if (type == MIRType::Pointer) {
+        } else if (type == MIRType::RefOrNull) {
           masm.loadPtr(src, iter->gpr());
         } else {
           MOZ_CRASH("unknown GPR type");
         }
         break;
 #ifdef JS_CODEGEN_REGISTER_PAIR
       case ABIArg::GPR_PAIR:
         if (type == MIRType::Int64) {
@@ -245,17 +245,17 @@ static void SetupABIArguments(MacroAssem
                          HighWord(Address(sp, iter->offsetFromArgBase())));
 #else
             Register64 scratch64(scratch);
             masm.load64(src, scratch64);
             masm.store64(scratch64, Address(sp, iter->offsetFromArgBase()));
 #endif
             break;
           }
-          case MIRType::Pointer:
+          case MIRType::RefOrNull:
             masm.loadPtr(src, scratch);
             masm.storePtr(scratch, Address(masm.getStackPointer(),
                                            iter->offsetFromArgBase()));
             break;
           case MIRType::Double: {
             ScratchDoubleScope fpscratch(masm);
             masm.loadDouble(src, fpscratch);
             masm.storeDouble(fpscratch, Address(masm.getStackPointer(),
@@ -1167,31 +1167,32 @@ static void StackCopy(MacroAssembler& ma
     masm.store32(scratch, HighWord(dst));
     GenPrintf(DebugChannel::Import, masm, ") ");
 #else
     Register64 scratch64(scratch);
     masm.load64(src, scratch64);
     GenPrintIsize(DebugChannel::Import, masm, scratch);
     masm.store64(scratch64, dst);
 #endif
-  } else if (type == MIRType::Pointer) {
+  } else if (type == MIRType::RefOrNull) {
     masm.loadPtr(src, scratch);
     GenPrintPtr(DebugChannel::Import, masm, scratch);
     masm.storePtr(scratch, dst);
   } else if (type == MIRType::Float32) {
     ScratchFloat32Scope fpscratch(masm);
     masm.loadFloat32(src, fpscratch);
     GenPrintF32(DebugChannel::Import, masm, fpscratch);
     masm.storeFloat32(fpscratch, dst);
-  } else {
-    MOZ_ASSERT(type == MIRType::Double);
+  } else if (type == MIRType::Double) {
     ScratchDoubleScope fpscratch(masm);
     masm.loadDouble(src, fpscratch);
     GenPrintF64(DebugChannel::Import, masm, fpscratch);
     masm.storeDouble(fpscratch, dst);
+  } else {
+    MOZ_CRASH("StackCopy: unexpected type");
   }
 }
 
 typedef bool ToValue;
 
 static void FillArgumentArray(MacroAssembler& masm, unsigned funcImportIndex,
                               const ValTypeVector& args,
                               unsigned argOffset,
@@ -1214,22 +1215,24 @@ static void FillArgumentArray(MacroAssem
         } else if (type == MIRType::Int64) {
           // We can't box int64 into Values (yet).
           if (toValue) {
             masm.breakpoint();
           } else {
             GenPrintI64(DebugChannel::Import, masm, i->gpr64());
             masm.store64(i->gpr64(), dst);
           }
-        } else if (type == MIRType::Pointer) {
+        } else if (type == MIRType::RefOrNull) {
           if (toValue) {
             MOZ_CRASH("generating a jit exit for anyref NYI");
           }
           GenPrintPtr(DebugChannel::Import, masm, i->gpr());
           masm.storePtr(i->gpr(), dst);
+        } else {
+          MOZ_CRASH("FillArgumentArray, ABIArg::GPR: unexpected type");
         }
         break;
 #ifdef JS_CODEGEN_REGISTER_PAIR
       case ABIArg::GPR_PAIR:
         if (type == MIRType::Int64) {
           GenPrintI64(DebugChannel::Import, masm, i->gpr64());
           masm.store64(i->gpr64(), dst);
         } else {
@@ -1275,31 +1278,32 @@ static void FillArgumentArray(MacroAssem
         if (toValue) {
           if (type == MIRType::Int32) {
             masm.load32(src, scratch);
             GenPrintIsize(DebugChannel::Import, masm, scratch);
             masm.storeValue(JSVAL_TYPE_INT32, scratch, dst);
           } else if (type == MIRType::Int64) {
             // We can't box int64 into Values (yet).
             masm.breakpoint();
-          } else if (type == MIRType::Pointer) {
+          } else if (type == MIRType::RefOrNull) {
             MOZ_CRASH("generating a jit exit for anyref NYI");
-          } else {
-            MOZ_ASSERT(IsFloatingPointType(type));
+          } else if (IsFloatingPointType(type)) {
             ScratchDoubleScope dscratch(masm);
             FloatRegister fscratch = dscratch.asSingle();
             if (type == MIRType::Float32) {
               masm.loadFloat32(src, fscratch);
               masm.convertFloat32ToDouble(fscratch, dscratch);
             } else {
               masm.loadDouble(src, dscratch);
             }
             masm.canonicalizeDouble(dscratch);
             GenPrintF64(DebugChannel::Import, masm, dscratch);
             masm.storeDouble(dscratch, dst);
+          } else {
+            MOZ_CRASH("FillArgumentArray, ABIArg::Stack: unexpected type");
           }
         } else {
           StackCopy(masm, type, scratch, src, dst);
         }
         break;
       }
       case ABIArg::Uninitialized:
         MOZ_CRASH("Uninitialized ABIArg kind");
--- a/js/src/wasm/WasmTypes.cpp
+++ b/js/src/wasm/WasmTypes.cpp
@@ -682,17 +682,17 @@ bool DebugFrame::getLocal(uint32_t local
       vp.set(NumberValue((double)*static_cast<int64_t*>(dataPtr)));
       break;
     case jit::MIRType::Float32:
       vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<float*>(dataPtr))));
       break;
     case jit::MIRType::Double:
       vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<double*>(dataPtr))));
       break;
-    case jit::MIRType::Pointer:
+    case jit::MIRType::RefOrNull:
       vp.set(ObjectOrNullValue(*(JSObject**)dataPtr));
       break;
     default:
       MOZ_CRASH("local type");
   }
   return true;
 }
 
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -133,28 +133,16 @@ typedef Vector<UniqueChars, 0, SystemAll
 // containing Module.
 
 #define WASM_DECLARE_SERIALIZABLE(Type)              \
   size_t serializedSize() const;                     \
   uint8_t* serialize(uint8_t* cursor) const;         \
   const uint8_t* deserialize(const uint8_t* cursor); \
   size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
-#define WASM_DECLARE_SERIALIZABLE_VIRTUAL(Type)              \
-  virtual size_t serializedSize() const;                     \
-  virtual uint8_t* serialize(uint8_t* cursor) const;         \
-  virtual const uint8_t* deserialize(const uint8_t* cursor); \
-  virtual size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
-
-#define WASM_DECLARE_SERIALIZABLE_OVERRIDE(Type)              \
-  size_t serializedSize() const override;                     \
-  uint8_t* serialize(uint8_t* cursor) const override;         \
-  const uint8_t* deserialize(const uint8_t* cursor) override; \
-  size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const override;
-
 template <class T>
 struct SerializableRefPtr : RefPtr<T> {
   using RefPtr<T>::operator=;
 
   SerializableRefPtr() = default;
 
   template <class U>
   MOZ_IMPLICIT SerializableRefPtr(U&& u) : RefPtr<T>(std::forward<U>(u)) {}
@@ -467,21 +455,19 @@ static inline jit::MIRType ToMIRType(Val
       return jit::MIRType::Int32;
     case ValType::I64:
       return jit::MIRType::Int64;
     case ValType::F32:
       return jit::MIRType::Float32;
     case ValType::F64:
       return jit::MIRType::Double;
     case ValType::Ref:
-      return jit::MIRType::Pointer;
     case ValType::AnyRef:
-      return jit::MIRType::Pointer;
     case ValType::NullRef:
-      return jit::MIRType::Pointer;
+      return jit::MIRType::RefOrNull;
   }
   MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type");
 }
 
 static inline bool IsNumberType(ValType vt) { return !vt.isReference(); }
 
 // ExprType utilities
 
--- a/layout/generic/ScrollAnchorContainer.cpp
+++ b/layout/generic/ScrollAnchorContainer.cpp
@@ -340,25 +340,23 @@ void ScrollAnchorContainer::ApplyAdjustm
       physicalAdjustment.x = logicalAdjustment;
       break;
     }
     case WritingMode::eBlockRL: {
       physicalAdjustment.x = -logicalAdjustment;
       break;
     }
   }
-  nsIntPoint physicalDevicePixels = physicalAdjustment.ToNearestPixels(
-      Frame()->PresContext()->AppUnitsPerDevPixel());
 
   MOZ_ASSERT(!mApplyingAnchorAdjustment);
   // We should use AutoRestore here, but that doesn't work with bitfields
   mApplyingAnchorAdjustment = true;
-  mScrollFrame->ScrollBy(
-      physicalDevicePixels, nsIScrollableFrame::DEVICE_PIXELS,
-      nsIScrollableFrame::INSTANT, nullptr, nsGkAtoms::relative);
+  mScrollFrame->ScrollTo(
+      mScrollFrame->GetScrollPosition() + physicalAdjustment,
+      nsIScrollableFrame::INSTANT, nsGkAtoms::relative);
   mApplyingAnchorAdjustment = false;
 
   nsPresContext* pc = Frame()->PresContext();
   Document* doc = pc->Document();
   doc->UpdateForScrollAnchorAdjustment(logicalAdjustment);
 
   // The anchor position may not be in the same relative position after
   // adjustment. Update ourselves so we have consistent state.