Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 18 Feb 2015 20:29:54 -0500
changeset 256845 360b5f21118017db0bbaf2b55ef04ce003d812d8
parent 256752 551febba68bc0410889ea83734cf6968e449f33b (current diff)
parent 256844 9f6ba4598996042ec9648472dac8103bc2a6af08 (diff)
child 256887 8940026f4214c9302decff57913f46b66a7c4894
child 256895 54a5226f99f2fb233b5d1956b363b30a2e556e91
child 256903 c0b119d6e85f6c743ce730f5d5e6c17a407fa82e
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone38.0a1
first release with
nightly linux32
360b5f211180 / 38.0a1 / 20150219030204 / files
nightly linux64
360b5f211180 / 38.0a1 / 20150219030204 / files
nightly mac
360b5f211180 / 38.0a1 / 20150219030204 / files
nightly win32
360b5f211180 / 38.0a1 / 20150219030204 / files
nightly win64
360b5f211180 / 38.0a1 / 20150219030204 / 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 m-c. a=merge
configure.in
docshell/base/LoadInfo.cpp
docshell/base/LoadInfo.h
docshell/base/nsILoadInfo.idl
dom/media/test/short-cenc.mp4
dom/media/test/short-cenc.xml
js/src/tests/ecma_6/String/normalize-generateddata.js
netwerk/dns/Makefile.in
toolkit/modules/AddonWatcher.jsm
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedConverter.js
@@ -543,32 +543,30 @@ GenericProtocolHandler.prototype = {
     if (netutil.URIChainHasFlags(inner, URI_INHERITS_SECURITY_CONTEXT))
       throw Cr.NS_ERROR_MALFORMED_URI;
 
     var uri = netutil.newSimpleNestedURI(inner);
     uri.spec = inner.spec.replace(prefix, scheme);
     return uri;
   },
   
-  newChannel: function GPH_newChannel(aUri) {
+  newChannel2: function GPH_newChannel(aUri, aLoadInfo) {
     var inner = aUri.QueryInterface(Ci.nsINestedURI).innerURI;
     var channel = Cc["@mozilla.org/network/io-service;1"].
-                  getService(Ci.nsIIOService).newChannelFromURI2(inner,
-                                                                 null,      // aLoadingNode
-                                                                 Services.scriptSecurityManager.getSystemPrincipal(),
-                                                                 null,      // aTriggeringPrincipal
-                                                                 Ci.nsILoadInfo.SEC_NORMAL,
-                                                                 Ci.nsIContentPolicy.TYPE_OTHER);
+                  getService(Ci.nsIIOService).
+                  newChannelFromURIWithLoadInfo(inner, aLoadInfo);
+
     if (channel instanceof Components.interfaces.nsIHttpChannel)
       // Set this so we know this is supposed to be a feed
       channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
     channel.originalURI = aUri;
     return channel;
   },
   
+
   QueryInterface: function GPH_QueryInterface(iid) {
     if (iid.equals(Ci.nsIProtocolHandler) ||
         iid.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   }  
 };
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -114,16 +114,23 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
                                   "resource:///modules/ContentSearch.jsm");
 
 #ifdef E10S_TESTING_ONLY
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
                                   "resource://gre/modules/UpdateChannel.jsm");
 #endif
 
+
+#if defined(MOZ_UPDATE_CHANNEL) && MOZ_UPDATE_CHANNEL != release
+#define MOZ_DEBUG_UA // Shorthand define for subsequent conditional sections.
+XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides",
+                                  "resource://gre/modules/UserAgentOverrides.jsm");
+#endif
+
 XPCOMUtils.defineLazyGetter(this, "ShellService", function() {
   try {
     return Cc["@mozilla.org/browser/shell-service;1"].
            getService(Ci.nsIShellService);
   }
   catch(ex) {
     return null;
   }
@@ -133,19 +140,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource:///modules/FormValidationHandler.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
                                   "resource://gre/modules/WebChannel.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ReaderParent",
                                   "resource:///modules/ReaderParent.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "AddonWatcher",
-                                  "resource://gre/modules/AddonWatcher.jsm");
-
 const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
 const PREF_PLUGINS_UPDATEURL  = "plugins.update.url";
 
 // Seconds of idle before trying to create a bookmarks backup.
 const BOOKMARKS_BACKUP_IDLE_TIME_SEC = 8 * 60;
 // Minimum interval between backups.  We try to not create more than one backup
 // per interval.
 const BOOKMARKS_BACKUP_MIN_INTERVAL_DAYS = 1;
@@ -562,86 +566,16 @@ BrowserGlue.prototype = {
   },
 
   _onAppDefaults: function BG__onAppDefaults() {
     // apply distribution customizations (prefs)
     // other customizations are applied in _finalUIStartup()
     this._distributionCustomizer.applyPrefDefaults();
   },
 
-  _notifySlowAddon: function BG_notifySlowAddon(addonId) {
-    let addonCallback = function(addon) {
-      if (!addon) {
-        Cu.reportError("couldn't look up addon: " + addonId);
-        return;
-      }
-      let win = RecentWindow.getMostRecentBrowserWindow();
-
-      if (!win) {
-        return;
-      }
-
-      let brandBundle = win.document.getElementById("bundle_brand");
-      let brandShortName = brandBundle.getString("brandShortName");
-      let message = win.gNavigatorBundle.getFormattedString("addonwatch.slow", [addon.name, brandShortName]);
-      let notificationBox = win.document.getElementById("global-notificationbox");
-      let notificationId = 'addon-slow:' + addonId;
-      let notification = notificationBox.getNotificationWithValue(notificationId);
-      if(notification) {
-        notification.label = message;
-      } else {
-        let buttons = [
-          {
-            label: win.gNavigatorBundle.getFormattedString("addonwatch.disable.label", [addon.name]),
-            accessKey: win.gNavigatorBundle.getString("addonwatch.disable.accesskey"),
-            callback: function() {
-              addon.userDisabled = true;
-              if (addon.pendingOperations != addon.PENDING_NONE) {
-                let restartMessage = win.gNavigatorBundle.getFormattedString("addonwatch.restart.message", [addon.name, brandShortName]);
-                let restartButton = [
-                  {
-                    label: win.gNavigatorBundle.getFormattedString("addonwatch.restart.label", [brandShortName]),
-                    accessKey: win.gNavigatorBundle.getString("addonwatch.restart.accesskey"),
-                    callback: function() {
-                      let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
-                        .getService(Ci.nsIAppStartup);
-                      appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
-                    }
-                  }
-                ];
-                const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
-                notificationBox.appendNotification(restartMessage, "restart-" + addonId, "",
-                                                   priority, restartButton);
-              }
-            }
-          },
-          {
-            label: win.gNavigatorBundle.getString("addonwatch.ignoreSession.label"),
-            accessKey: win.gNavigatorBundle.getString("addonwatch.ignoreSession.accesskey"),
-            callback: function() {
-              AddonWatcher.ignoreAddonForSession(addonId);
-            }
-          },
-          {
-            label: win.gNavigatorBundle.getString("addonwatch.ignorePerm.label"),
-            accessKey: win.gNavigatorBundle.getString("addonwatch.ignorePerm.accesskey"),
-            callback: function() {
-              AddonWatcher.ignoreAddonPermanently(addonId);
-            }
-          },
-        ];
-
-        const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
-        notificationBox.appendNotification(message, notificationId, "",
-                                             priority, buttons);
-      }
-    };
-    AddonManager.getAddonByID(addonId, addonCallback);
-  },
-
   // runs on startup, before the first command line handler is invoked
   // (i.e. before the first window is opened)
   _finalUIStartup: function BG__finalUIStartup() {
     this._sanitizer.onStartup();
     // check if we're in safe mode
     if (Services.appinfo.inSafeMode) {
       Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul", 
                              "_blank", "chrome,centerscreen,modal,resizable=no", null);
@@ -679,19 +613,22 @@ BrowserGlue.prototype = {
 
     LoginManagerParent.init();
     ReaderParent.init();
 
 #ifdef NIGHTLY_BUILD
     Services.prefs.addObserver(POLARIS_ENABLED, this, false);
 #endif
 
-    Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
+#ifdef MOZ_DEBUG_UA
+    UserAgentOverrides.init();
+    DebugUserAgent.init();
+#endif
 
-    AddonWatcher.init(this._notifySlowAddon);
+    Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
   },
 
   _checkForOldBuildUpdates: function () {
     // check for update if our build is old
     if (Services.prefs.getBoolPref("app.update.enabled") &&
         Services.prefs.getBoolPref("app.update.checkInstallTime")) {
 
       let buildID = Services.appinfo.appBuildID;
@@ -913,16 +850,19 @@ BrowserGlue.prototype = {
 
     CustomizationTabPreloader.uninit();
     WebappManager.uninit();
 #ifdef NIGHTLY_BUILD
     if (Services.prefs.getBoolPref("dom.identity.enabled")) {
       SignInToWebsiteUX.uninit();
     }
 #endif
+#ifdef MOZ_DEBUG_UA
+    UserAgentOverrides.uninit();
+#endif
     webrtcUI.uninit();
     FormValidationHandler.uninit();
   },
 
   _initServiceDiscovery: function () {
     var rokuDevice = {
       id: "roku:ecp",
       target: "roku:ecp",
@@ -2830,8 +2770,41 @@ this.NSGetFactory = XPCOMUtils.generateN
 
 // Listen for UITour messages.
 // Do it here instead of the UITour module itself so that the UITour module is lazy loaded
 // when the first message is received.
 let globalMM = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
 globalMM.addMessageListener("UITour:onPageEvent", function(aMessage) {
   UITour.onPageEvent(aMessage, aMessage.data);
 });
+
+#ifdef MOZ_DEBUG_UA
+// Modify the user agent string for specific domains
+// to route debug information through their logging.
+var DebugUserAgent = {
+  DEBUG_UA: null,
+  DOMAINS: [
+    'youtube.com',
+    'www.youtube.com',
+    'youtube-nocookie.com',
+    'www.youtube-nocookie.com',
+  ],
+
+  init: function() {
+    // Only run if the MediaSource Extension API is available.
+    if (!Services.prefs.getBoolPref("media.mediasource.enabled")) {
+      return;
+    }
+    // Install our override filter.
+    UserAgentOverrides.addComplexOverride(this.onRequest.bind(this));
+    let ua = Cc["@mozilla.org/network/protocol;1?name=http"]
+                .getService(Ci.nsIHttpProtocolHandler).userAgent;
+    this.DEBUG_UA = ua + " Build/" + Services.appinfo.appBuildID;
+  },
+
+  onRequest: function(channel, defaultUA) {
+    if (this.DOMAINS.indexOf(channel.URI.host) != -1) {
+      return this.DEBUG_UA;
+    }
+    return null;
+  },
+};
+#endif // MOZ_DEBUG_UA
--- a/browser/devtools/netmonitor/test/browser_net_security-state.js
+++ b/browser/devtools/netmonitor/test/browser_net_security-state.js
@@ -11,16 +11,22 @@
 add_task(function* () {
   const EXPECTED_SECURITY_STATES = {
     "test1.example.com": "security-state-insecure",
     "example.com": "security-state-secure",
     "nocert.example.com": "security-state-broken",
     "rc4.example.com": "security-state-weak",
   };
 
+  yield new promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [
+      ["security.tls.insecure_fallback_hosts", "rc4.example.com"]
+    ]}, resolve);
+  });
+
   let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
   let { $, EVENTS, NetMonitorView } = monitor.panelWin;
   let { RequestsMenu } = NetMonitorView;
   RequestsMenu.lazyUpdate = false;
 
   yield performRequests();
 
   for (let item of RequestsMenu.items) {
--- a/browser/devtools/netmonitor/test/browser_net_security-warnings.js
+++ b/browser/devtools/netmonitor/test/browser_net_security-warnings.js
@@ -35,19 +35,22 @@ const TEST_CASES = [
 ];
 
 add_task(function* () {
   let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
   let { $, EVENTS, NetMonitorView } = monitor.panelWin;
   let { RequestsMenu, NetworkDetails } = NetMonitorView;
   RequestsMenu.lazyUpdate = false;
 
-  info("Enabling SSLv3 for the test.");
+  info("Enabling SSLv3 and RC4 for the test.");
   yield new promise(resolve => {
-    SpecialPowers.pushPrefEnv({"set": [["security.tls.version.min", 0]]}, resolve);
+    SpecialPowers.pushPrefEnv({"set": [
+      ["security.tls.version.min", 0],
+      ["security.tls.insecure_fallback_hosts", "rc4.example.com,ssl3rc4.example.com"]
+    ]}, resolve);
   });
 
   let cipher = $("#security-warning-cipher");
   let sslv3 = $("#security-warning-sslv3");
 
   for (let test of TEST_CASES) {
     info("Testing site with " + test.desc);
 
--- a/browser/devtools/performance/test/browser_profiler_tree-frame-node.js
+++ b/browser/devtools/performance/test/browser_profiler_tree-frame-node.js
@@ -2,16 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Verifies if FrameNodes retain and parse their data appropriately.
  */
 
 function test() {
   let { FrameNode } = devtools.require("devtools/shared/profiler/tree-model");
+  let { CATEGORY_OTHER } = devtools.require("devtools/shared/profiler/global");
 
   let frame1 = new FrameNode({
     location: "hello/<.world (http://foo/bar.js:123:987)",
     line: 456
   });
 
   is(frame1.getInfo().nodeType, "Frame",
     "The first frame node has the correct type.");
@@ -127,17 +128,17 @@ function test() {
     "The fifth frame node has the correct category data.");
   is(frame5.getInfo().isContent, false,
     "The fifth frame node has the correct content flag.");
 
   let frame6 = new FrameNode({
     location: "Foo::Bar::Baz",
     line: 456,
     column: 123,
-    category: 8
+    category: CATEGORY_OTHER
   });
 
   is(frame6.getInfo().nodeType, "Frame",
     "The sixth frame node has the correct type.");
   is(frame6.getInfo().functionName, "Foo::Bar::Baz",
     "The sixth frame node has the correct function name.");
   is(frame6.getInfo().fileName, null,
     "The sixth frame node has the correct file name.");
--- a/browser/devtools/performance/test/browser_profiler_tree-view-02.js
+++ b/browser/devtools/performance/test/browser_profiler_tree-view-02.js
@@ -1,16 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests if the profiler's tree view implementation works properly and
  * creates the correct column structure after expanding some of the nodes.
  */
 
+let { CATEGORY_MASK } = devtools.require("devtools/shared/profiler/global");
+
 function test() {
   let { ThreadNode } = devtools.require("devtools/shared/profiler/tree-model");
   let { CallView } = devtools.require("devtools/shared/profiler/tree-view");
 
   let threadNode = new ThreadNode(gSamples);
   let treeRoot = new CallView({ frame: threadNode });
 
   let container = document.createElement("vbox");
@@ -121,38 +123,38 @@ function test() {
     "The .A.E node's function cell displays the correct category.");
 
   finish();
 }
 
 let gSamples = [{
   time: 5,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 32, location: "C (http://foo/bar/baz:56)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('js'),     location: "C (http://foo/bar/baz:56)" }
   ]
 }, {
   time: 5 + 1,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 64, location: "D (http://foo/bar/baz:78)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('gc', 1),  location: "D (http://foo/bar/baz:78)" }
   ]
 }, {
   time: 5 + 1 + 2,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 64, location: "D (http://foo/bar/baz:78)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('gc', 1),  location: "D (http://foo/bar/baz:78)" }
   ]
 }, {
   time: 5 + 1 + 2 + 7,
   frames: [
-    { category: 8,   location: "(root)" },
-    { category: 8,   location: "A (http://foo/bar/baz:12)" },
-    { category: 128, location: "E (http://foo/bar/baz:90)" },
-    { category: 256, location: "F (http://foo/bar/baz:99)" }
+    { category: CATEGORY_MASK('other'),   location: "(root)" },
+    { category: CATEGORY_MASK('other'),   location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('gc', 2),   location: "E (http://foo/bar/baz:90)" },
+    { category: CATEGORY_MASK('network'), location: "F (http://foo/bar/baz:99)" }
   ]
 }];
--- a/browser/devtools/performance/test/browser_profiler_tree-view-04.js
+++ b/browser/devtools/performance/test/browser_profiler_tree-view-04.js
@@ -1,16 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests if the profiler's tree view implementation works properly and
  * creates the correct DOM nodes in the correct order.
  */
 
+let { CATEGORY_MASK } = devtools.require("devtools/shared/profiler/global");
+
 function test() {
   let { ThreadNode } = devtools.require("devtools/shared/profiler/tree-model");
   let { CallView } = devtools.require("devtools/shared/profiler/tree-view");
 
   let threadNode = new ThreadNode(gSamples);
   let treeRoot = new CallView({ frame: threadNode });
 
   let container = document.createElement("vbox");
@@ -85,39 +87,38 @@ function test() {
     "The eight node displayed for function cells is correct.");
 
   finish();
 }
 
 let gSamples = [{
   time: 5,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 32, location: "C (http://foo/bar/baz:56)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('js'),     location: "C (http://foo/bar/baz:56)" }
   ]
 }, {
   time: 5 + 1,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 64, location: "D (http://foo/bar/baz:78)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('gc', 1),  location: "D (http://foo/bar/baz:78)" }
   ]
 }, {
   time: 5 + 1 + 2,
   frames: [
-    { category: 8,  location: "(root)" },
-    { category: 8,  location: "A (http://foo/bar/baz:12)" },
-    { category: 16, location: "B (http://foo/bar/baz:34)" },
-    { category: 64, location: "D (http://foo/bar/baz:78)" }
+    { category: CATEGORY_MASK('other'),  location: "(root)" },
+    { category: CATEGORY_MASK('other'),  location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('css'),    location: "B (http://foo/bar/baz:34)" },
+    { category: CATEGORY_MASK('gc', 1),  location: "D (http://foo/bar/baz:78)" }
   ]
 }, {
   time: 5 + 1 + 2 + 7,
   frames: [
-    { category: 8,   location: "(root)" },
-    { category: 8,   location: "A (http://foo/bar/baz:12)" },
-    { category: 128, location: "E (http://foo/bar/baz:90)" },
-    { category: 256, location: "F (http://foo/bar/baz:99)" }
+    { category: CATEGORY_MASK('other'),   location: "(root)" },
+    { category: CATEGORY_MASK('other'),   location: "A (http://foo/bar/baz:12)" },
+    { category: CATEGORY_MASK('gc', 2),   location: "E (http://foo/bar/baz:90)" },
+    { category: CATEGORY_MASK('network'), location: "F (http://foo/bar/baz:99)" }
   ]
 }];
-
--- a/browser/devtools/shared/profiler/global.js
+++ b/browser/devtools/shared/profiler/global.js
@@ -28,34 +28,81 @@ const CATEGORIES = [
   { ordinal: 3, color: "#d99b28", abbrev: "events", label: L10N.getStr("category.events") }
 ];
 
 /**
  * Mapping from category bitmasks in the profiler data to additional details.
  * To be kept in sync with the js::ProfileEntry::Category in ProfilingStack.h
  */
 const CATEGORY_MAPPINGS = {
-  "8": CATEGORIES[0],    // js::ProfileEntry::Category::OTHER
-  "16": CATEGORIES[1],   // js::ProfileEntry::Category::CSS
-  "32": CATEGORIES[2],   // js::ProfileEntry::Category::JS
-  "64": CATEGORIES[3],   // js::ProfileEntry::Category::GC
-  "128": CATEGORIES[3],  // js::ProfileEntry::Category::CC
-  "256": CATEGORIES[4],  // js::ProfileEntry::Category::NETWORK
-  "512": CATEGORIES[5],  // js::ProfileEntry::Category::GRAPHICS
-  "1024": CATEGORIES[6], // js::ProfileEntry::Category::STORAGE
-  "2048": CATEGORIES[7], // js::ProfileEntry::Category::EVENTS
+  "16": CATEGORIES[0],      // js::ProfileEntry::Category::OTHER
+  "32": CATEGORIES[1],      // js::ProfileEntry::Category::CSS
+  "64": CATEGORIES[2],      // js::ProfileEntry::Category::JS
+  "128": CATEGORIES[3],     // js::ProfileEntry::Category::GC
+  "256": CATEGORIES[3],     // js::ProfileEntry::Category::CC
+  "512": CATEGORIES[4],     // js::ProfileEntry::Category::NETWORK
+  "1024": CATEGORIES[5],    // js::ProfileEntry::Category::GRAPHICS
+  "2048": CATEGORIES[6],    // js::ProfileEntry::Category::STORAGE
+  "4096": CATEGORIES[7],    // js::ProfileEntry::Category::EVENTS
 };
 
+/**
+ * Get the numeric bitmask (or set of masks) for the given category
+ * abbreviation. See CATEGORIES and CATEGORY_MAPPINGS above.
+ *
+ * CATEGORY_MASK can be called with just a name if it is expected that the
+ * category is mapped to by exactly one bitmask.  If the category is mapped
+ * to by multiple masks, CATEGORY_MASK for that name must be called with
+ * an additional argument specifying the desired id (in ascending order).
+ */
+const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
+  let mappings = {};
+  for (let category of CATEGORIES) {
+    let numList = Object.keys(CATEGORY_MAPPINGS)
+          .filter(k => CATEGORY_MAPPINGS[k] == category)
+          .map(k => +k);
+    numList.sort();
+    mappings[category.abbrev] = numList;
+  }
+
+  return [
+    function (name, num) {
+      if (!(name in mappings)) {
+        throw new Error(`Category abbreviation '${name}' does not exist.`);
+      }
+      if (arguments.length == 1) {
+        if (mappings[name].length != 1) {
+          throw new Error(`Expected exactly one category number for '${name}'.`);
+        }
+        return mappings[name][0];
+      }
+      if (num > mappings[name].length) {
+        throw new Error(`Num '${num}' too high for category '${name}'.`);
+      }
+      return mappings[name][num - 1];
+    },
+
+    function (name) {
+      if (!(name in mappings)) {
+        throw new Error(`Category abbreviation '${name}' does not exist.`);
+      }
+      return mappings[name];
+    }
+  ];
+})();
+
 // Human-readable "other" category bitmask. Older Geckos don't have all the
 // necessary instrumentation in the sampling profiler backend for creating
 // a categories graph, in which case we default to the "other" category.
-const CATEGORY_OTHER = 8;
+const CATEGORY_OTHER = CATEGORY_MASK('other');
 
 // Human-readable JIT category bitmask. Certain pseudo-frames in a sample,
 // like "EnterJIT", don't have any associated `cateogry` information.
-const CATEGORY_JIT = 32;
+const CATEGORY_JIT = CATEGORY_MASK('js');
 
 // Exported symbols.
 exports.L10N = L10N;
 exports.CATEGORIES = CATEGORIES;
 exports.CATEGORY_MAPPINGS = CATEGORY_MAPPINGS;
 exports.CATEGORY_OTHER = CATEGORY_OTHER;
 exports.CATEGORY_JIT = CATEGORY_JIT;
+exports.CATEGORY_MASK = CATEGORY_MASK;
+exports.CATEGORY_MASK_LIST = CATEGORY_MASK_LIST;
--- a/browser/devtools/webconsole/test/browser_webconsole_output_01.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_01.js
@@ -77,38 +77,35 @@ let inputTests = [
   },
 
   // 8
   {
     input: "/foobar/",
     output: "/foobar/",
     inspectable: true,
   },
-];
 
-if (typeof Symbol !== "undefined") {
-  inputTests.push(
-    // 9
-    {
-      input: "Symbol()",
-      output: "Symbol()"
-    },
+  // 9
+  {
+    input: "Symbol()",
+    output: "Symbol()"
+  },
 
-    // 10
-    {
-      input: "Symbol('foo')",
-      output: "Symbol(foo)"
-    },
+  // 10
+  {
+    input: "Symbol('foo')",
+    output: "Symbol(foo)"
+  },
 
-    // 11
-    {
-      input: "Symbol.iterator",
-      output: "Symbol(Symbol.iterator)"
-    });
-}
+  // 11
+  {
+    input: "Symbol.iterator",
+    output: "Symbol(Symbol.iterator)"
+  },
+];
 
 longString = initialString = null;
 
 function test() {
   requestLongerTimeout(2);
 
   registerCleanupFunction(() => {
     DebuggerServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH;
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -35,27 +35,16 @@ xpinstallDisabledButton.accesskey=n
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # Also see https://bugzilla.mozilla.org/show_bug.cgi?id=570012 for mockups
 addonDownloading=Add-on downloading;Add-ons downloading
 addonDownloadCancelled=Add-on download cancelled.;Add-on downloads cancelled.
 addonDownloadRestart=Restart Download;Restart Downloads
 addonDownloadRestart.accessKey=R
 addonDownloadCancelTooltip=Cancel
 
-addonwatch.slow=%S might be making %S run slowly
-addonwatch.disable.label=Disable %S
-addonwatch.disable.accesskey=D
-addonwatch.ignoreSession.label=Ignore for now
-addonwatch.ignoreSession.accesskey=I
-addonwatch.ignorePerm.label=Ignore permanently
-addonwatch.ignorePerm.accesskey=p
-addonwatch.restart.message=To disable %S you must restart %S
-addonwatch.restart.label=Restart %s
-addonwatch.restart.accesskey=R
-
 # LOCALIZATION NOTE (addonsInstalled, addonsInstalledNeedsRestart):
 # Semicolon-separated list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 first add-on's name, #2 number of add-ons, #3 application name
 addonsInstalled=#1 has been installed successfully.;#2 add-ons have been installed successfully.
 addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
 addonInstallRestartButton=Restart Now
 addonInstallRestartButton.accesskey=R
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -28,17 +28,17 @@ DEFINES += -DAPP_BUILDID=$(APP_BUILDID)
 
 APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
 
 MOZ_SOURCE_STAMP := $(firstword $(shell cd $(topsrcdir)/$(MOZ_BUILD_APP)/.. && hg parent --template='{node|short}\n' 2>/dev/null))
 ifdef MOZ_SOURCE_STAMP
 DEFINES += -DMOZ_SOURCE_STAMP='$(MOZ_SOURCE_STAMP)'
 endif
 
-ifdef MOZILLA_OFFICIAL
+ifdef MOZ_INCLUDE_SOURCE_INFO
 source_repo ?= $(call getSourceRepo,$(topsrcdir)/$(MOZ_BUILD_APP)/..)
 ifneq (,$(source_repo))
   DEFINES += -DMOZ_SOURCE_REPO='$(source_repo)'
 endif
 endif
 
 endif
 
--- a/configure.in
+++ b/configure.in
@@ -2299,16 +2299,21 @@ ia64*-hpux*)
         dnl with the linker doing most of the work in the whole-program
         dnl optimization/PGO case. I think it's probably a compiler bug,
         dnl but we work around it here.
         PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952"
         dnl XXX: should be -LTCG:PGOPTIMIZE, but that fails on libxul.
         dnl Probably also a compiler bug, but what can you do?
         PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE"
         LDFLAGS="$LDFLAGS -DYNAMICBASE"
+        if test "$_CC_MAJOR_VERSION" = "18" -a "$_CC_BUILD_VERSION" = "31101"; then
+            dnl Use MaxILKSize as a workaround for LNK1248 in VS2013update4
+            dnl See https://connect.microsoft.com/VisualStudio/feedback/details/1044914/fatal-error-lnk1248
+            LDFLAGS="$LDFLAGS -MaxILKSize:2147483647"
+        fi
         dnl Minimum reqiurement of Gecko is VS2010 or later which supports
         dnl both SSSE3 and SSE4.1.
         HAVE_TOOLCHAIN_SUPPORT_MSSSE3=1
         HAVE_TOOLCHAIN_SUPPORT_MSSE4_1=1
         dnl allow AVX2 code from VS2012
         HAVE_X86_AVX2=1
         MOZ_MEMORY=1
     fi
@@ -8689,16 +8694,23 @@ if test -n "$MOZ_UA_OS_AGNOSTIC"; then
 fi
 
 AC_SUBST(MOZ_APP_STATIC_INI)
 
 AC_SUBST(MOZ_PKG_SPECIAL)
 
 AC_SUBST(MOZILLA_OFFICIAL)
 
+# Build revisions should always be present in official builds
+if test "$MOZILLA_OFFICIAL"; then
+    MOZ_INCLUDE_SOURCE_INFO=1
+fi
+
+AC_SUBST(MOZ_INCLUDE_SOURCE_INFO)
+
 AC_DEFINE_UNQUOTED(MOZ_TELEMETRY_DISPLAY_REV, 2)
 AC_SUBST(MOZ_TELEMETRY_DISPLAY_REV)
 
 if test "$MOZ_TELEMETRY_REPORTING"; then
     AC_DEFINE(MOZ_TELEMETRY_REPORTING)
 
     # Enable Telemetry by default for nightly and aurora channels
     if test -z "$RELEASE_BUILD"; then
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -15,17 +15,16 @@ XPIDL_SOURCES += [
     'nsIDocShell.idl',
     'nsIDocShellLoadInfo.idl',
     'nsIDocShellTreeItem.idl',
     'nsIDocShellTreeOwner.idl',
     'nsIDocumentLoaderFactory.idl',
     'nsIDownloadHistory.idl',
     'nsIGlobalHistory2.idl',
     'nsILoadContext.idl',
-    'nsILoadInfo.idl',
     'nsIPrivacyTransitionObserver.idl',
     'nsIReflowObserver.idl',
     'nsIRefreshURI.idl',
     'nsIScrollable.idl',
     'nsITextScroll.idl',
     'nsIURIFixup.idl',
     'nsIWebNavigation.idl',
     'nsIWebNavigationInfo.idl',
@@ -40,22 +39,20 @@ EXPORTS += [
     'nsIScrollObserver.h',
     'nsIWebShellServices.h',
     'SerializedLoadContext.h',
 ]
 
 EXPORTS.mozilla += [
     'IHistory.h',
     'LoadContext.h',
-    'LoadInfo.h',
 ]
 
 UNIFIED_SOURCES += [
     'LoadContext.cpp',
-    'LoadInfo.cpp',
     'nsAboutRedirector.cpp',
     'nsDefaultURIFixup.cpp',
     'nsDocShell.cpp',
     'nsDocShellEditorData.cpp',
     'nsDocShellEnumerator.cpp',
     'nsDocShellLoadInfo.cpp',
     'nsDocShellTransferableHooks.cpp',
     'nsDownloadHistory.cpp',
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -2435,16 +2435,30 @@ Navigator::HasTVSupport(JSContext* aCx, 
     return false;
   }
 
   // Only support TV Manager API for certified apps for now.
   return status == nsIPrincipal::APP_STATUS_CERTIFIED;
 }
 
 /* static */
+bool
+Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal)
+{
+  return XRE_GetProcessType() == GeckoProcessType_Content;
+}
+
+bool
+Navigator::MozE10sEnabled()
+{
+  // This will only be called if IsE10sEnabled() is true.
+  return true;
+}
+
+/* static */
 already_AddRefed<nsPIDOMWindow>
 Navigator::GetWindowFromGlobal(JSObject* aGlobal)
 {
   nsCOMPtr<nsPIDOMWindow> win =
     do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
   MOZ_ASSERT(!win || win->IsInnerWindow());
   return win.forget();
 }
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -282,16 +282,18 @@ public:
 
   bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
                  JS::Handle<jsid> aId,
                  JS::MutableHandle<JSPropertyDescriptor> aDesc);
   void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
                            ErrorResult& aRv);
   void GetLanguages(nsTArray<nsString>& aLanguages);
 
+  bool MozE10sEnabled();
+
   static void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
 
   // WebIDL helper methods
   static bool HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */);
   static bool HasCameraSupport(JSContext* /* unused */,
                                JSObject* aGlobal);
   static bool HasWifiManagerSupport(JSContext* /* unused */,
                                   JSObject* aGlobal);
@@ -310,16 +312,18 @@ public:
   static bool HasDataStoreSupport(JSContext* cx, JSObject* aGlobal);
 
 #ifdef MOZ_B2G
   static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal);
 #endif
 
   static bool HasTVSupport(JSContext* aCx, JSObject* aGlobal);
 
+  static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
+
   nsPIDOMWindow* GetParentObject() const
   {
     return GetWindow();
   }
 
   virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
 
   // GetWindowFromGlobal returns the inner window for this global, if
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2199,18 +2199,21 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::G
                                              nullptr,
                                              NS_FULL_GC_DELAY,
                                              nsITimer::TYPE_ONE_SHOT);
         }
       } else {
         nsJSContext::KillFullGCTimer();
 
         // Avoid shrinking during heavy activity, which is suggested by
-        // compartment GC.
-        nsJSContext::PokeShrinkGCBuffers();
+        // compartment GC. We don't need to shrink after a shrinking GC as this
+        // happens automatically in this case.
+        if (aDesc.invocationKind_ == GC_NORMAL) {
+          nsJSContext::PokeShrinkGCBuffers();
+        }
       }
 
       if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
         nsCycleCollector_dispatchDeferredDeletion();
       }
 
       break;
     }
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -66,8 +66,9 @@ MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR,
 MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
 MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")
 MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
 MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, JSEXN_TYPEERR, "Not allowed to define a non-configurable property on the WindowProxy object")
 MSG_DEF(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, 0, JSEXN_RANGEERR, "Invalid zoom and pan value.")
 MSG_DEF(MSG_INVALID_TRANSFORM_ANGLE_ERROR, 0, JSEXN_RANGEERR, "Invalid transform angle.")
 MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid response status code.")
 MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")
+MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -534,17 +534,34 @@ BrowserElementParent.prototype = {
     if (!this._isAlive()) {
       throw Components.Exception("Dead content process",
                                  Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
     }
 
     return this._frameLoader.visible;
   },
 
+  getChildProcessOffset: function() {
+    let offset = { x: 0, y: 0 };
+    let tabParent = this._frameLoader.tabParent;
+    if (tabParent) {
+      let offsetX = {};
+      let offsetY = {};
+      tabParent.getChildProcessOffset(offsetX, offsetY);
+      offset.x = offsetX.value;
+      offset.y = offsetY.value;
+    }
+    return offset;
+  },
+
   sendMouseEvent: defineNoReturnMethod(function(type, x, y, button, clickCount, modifiers) {
+    let offset = this.getChildProcessOffset();
+    x += offset.x;
+    y += offset.y;
+
     this._sendAsyncMsg("send-mouse-event", {
       "type": type,
       "x": x,
       "y": y,
       "button": button,
       "clickCount": clickCount,
       "modifiers": modifiers
     });
@@ -562,16 +579,23 @@ BrowserElementParent.prototype = {
                                  touchesY,
                                  radiisX,
                                  radiisY,
                                  rotationAngles,
                                  forces,
                                  count,
                                  modifiers);
     } else {
+      let offset = this.getChildProcessOffset();
+      for (var i = 0; i < touchesX.length; i++) {
+        touchesX[i] += offset.x;
+      }
+      for (var i = 0; i < touchesY.length; i++) {
+        touchesY[i] += offset.y;
+      }
       this._sendAsyncMsg("send-touch-event", {
         "type": type,
         "identifiers": identifiers,
         "touchesX": touchesX,
         "touchesY": touchesY,
         "radiisX": radiisX,
         "radiisY": radiisY,
         "rotationAngles": rotationAngles,
--- a/dom/browser-element/mochitest/browserElement_SendEvent.js
+++ b/dom/browser-element/mochitest/browserElement_SendEvent.js
@@ -7,59 +7,76 @@
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 
 function runTest() {
   var iframe = document.createElement("iframe");
   iframe.setAttribute('mozbrowser', 'true');
   document.body.appendChild(iframe);
+  var x = 10;
+  var y = 10;
+  // First we force a reflow so that getChildProcessOffset actually returns
+  // meaningful data.
+  iframe.getBoundingClientRect();
+  // We need to make sure the event coordinates are actually inside the iframe,
+  // relative to the chome window.
+  var tabParent = SpecialPowers.wrap(iframe)
+                  .QueryInterface(SpecialPowers.Ci.nsIFrameLoaderOwner)
+                  .frameLoader.tabParent;
+  if (tabParent) {
+    let offsetX = {};
+    let offsetY = {};
+    tabParent.getChildProcessOffset(offsetX, offsetY);
+    x -= offsetX.value;
+    y -= offsetY.value;
+  }
 
   iframe.addEventListener("mozbrowserloadend", function onloadend(e) {
-    iframe.sendMouseEvent("mousedown", 10, 10, 0, 1, 0);
+    iframe.sendMouseEvent("mousedown", x, y, 0, 1, 0);
   });
 
   iframe.addEventListener("mozbrowserlocationchange", function onlocchange(e) {
     var a = document.createElement("a");
     a.href = e.detail;
 
     switch (a.hash) {
       case "#mousedown":
         ok(true, "Receive a mousedown event.");
-        iframe.sendMouseEvent("mousemove", 10, 10, 0, 0, 0);
+        iframe.sendMouseEvent("mousemove", x, y, 0, 0, 0);
         break;
       case "#mousemove":
         ok(true, "Receive a mousemove event.");
-        iframe.sendMouseEvent("mouseup", 10, 10, 0, 1, 0);
+        iframe.sendMouseEvent("mouseup", x, y, 0, 1, 0);
         break;
       case "#mouseup":
         ok(true, "Receive a mouseup event.");
         break;
       case "#click":
         ok(true, "Receive a click event.");
         if (SpecialPowers.getIntPref("dom.w3c_touch_events.enabled") != 0) {
-          iframe.sendTouchEvent("touchstart", [1], [10], [10], [2], [2],
+          iframe.sendTouchEvent("touchstart", [1], [x], [y], [2], [2],
                                 [20], [0.5], 1, 0);
         } else {
           iframe.removeEventListener('mozbrowserlocationchange', onlocchange);
           SimpleTest.finish();
         }
         break;
       case "#touchstart":
         ok(true, "Receive a touchstart event.");
-        iframe.sendTouchEvent("touchmove", [1], [10], [10], [2], [2],
+        iframe.sendTouchEvent("touchmove", [1], [x], [y], [2], [2],
                               [20], [0.5], 1, 0);
       case "#touchmove":
         ok(true, "Receive a touchmove event.");
-        iframe.sendTouchEvent("touchend", [1], [10], [10], [2], [2],
+        iframe.sendTouchEvent("touchend", [1], [x], [y], [2], [2],
                               [20], [0.5], 1, 0);
         break;
       case "#touchend":
         ok(true, "Receive a touchend event.");
-        iframe.sendTouchEvent("touchcancel", [1], [10], [10], [2], [2],
+        iframe.sendTouchEvent("touchcancel", [1], [x], [y], [2], [2],
                               [20], [0.5], 1, 0);
         iframe.removeEventListener('mozbrowserlocationchange', onlocchange);
         SimpleTest.finish();
         break;
     }
   });
 
   iframe.src = "data:text/html,<html><body>" +
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -512,19 +512,21 @@ FetchDriver::ContinueHttpFetchAfterNetwo
 
   return SucceedWithResponse();
 }
 
 already_AddRefed<InternalResponse>
 FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
 {
   MOZ_ASSERT(aResponse);
-  nsAutoCString reqURL;
-  mRequest->GetURL(reqURL);
-  aResponse->SetUrl(reqURL);
+  if (!aResponse->FinalURL()) {
+    nsAutoCString reqURL;
+    mRequest->GetURL(reqURL);
+    aResponse->SetUrl(reqURL);
+  }
 
   // FIXME(nsm): Handle mixed content check, step 7 of fetch.
 
   nsRefPtr<InternalResponse> filteredResponse;
   switch (mRequest->GetResponseTainting()) {
     case InternalRequest::RESPONSETAINT_BASIC:
       filteredResponse = InternalResponse::BasicResponse(aResponse);
       break;
--- a/dom/fetch/InternalResponse.cpp
+++ b/dom/fetch/InternalResponse.cpp
@@ -9,28 +9,30 @@
 
 #include "mozilla/dom/InternalHeaders.h"
 
 namespace mozilla {
 namespace dom {
 
 InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
   : mType(ResponseType::Default)
+  , mFinalURL(false)
   , mStatus(aStatus)
   , mStatusText(aStatusText)
   , mHeaders(new InternalHeaders(HeadersGuardEnum::Response))
 {
 }
 
 // Headers are not copied since BasicResponse and CORSResponse both need custom
 // header handling.
 InternalResponse::InternalResponse(const InternalResponse& aOther)
   : mType(aOther.mType)
   , mTerminationReason(aOther.mTerminationReason)
   , mURL(aOther.mURL)
+  , mFinalURL(aOther.mFinalURL)
   , mStatus(aOther.mStatus)
   , mStatusText(aOther.mStatusText)
   , mBody(aOther.mBody)
   , mContentType(aOther.mContentType)
 {
 }
 
 // static
--- a/dom/fetch/InternalResponse.h
+++ b/dom/fetch/InternalResponse.h
@@ -71,16 +71,28 @@ public:
   }
 
   void
   SetUrl(const nsACString& aURL)
   {
     mURL.Assign(aURL);
   }
 
+  bool
+  FinalURL() const
+  {
+    return mFinalURL;
+  }
+
+  void
+  SetFinalURL(bool aFinalURL)
+  {
+    mFinalURL = aFinalURL;
+  }
+
   uint16_t
   GetStatus() const
   {
     return mStatus;
   }
 
   const nsCString&
   GetStatusText() const
@@ -115,16 +127,17 @@ private:
 
   // Used to create filtered responses.
   // Does not copy headers.
   explicit InternalResponse(const InternalResponse& aOther);
 
   ResponseType mType;
   nsCString mTerminationReason;
   nsCString mURL;
+  bool mFinalURL;
   const uint16_t mStatus;
   const nsCString mStatusText;
   nsRefPtr<InternalHeaders> mHeaders;
   nsCOMPtr<nsIInputStream> mBody;
   nsCString mContentType;
 };
 
 } // namespace dom
--- a/dom/fetch/Response.cpp
+++ b/dom/fetch/Response.cpp
@@ -210,10 +210,23 @@ Headers*
 Response::Headers_()
 {
   if (!mHeaders) {
     mHeaders = new Headers(mOwner, mInternalResponse->Headers());
   }
 
   return mHeaders;
 }
+
+void
+Response::SetFinalURL(bool aFinalURL, ErrorResult& aRv)
+{
+  nsCString url;
+  mInternalResponse->GetUrl(url);
+  if (url.IsEmpty()) {
+    aRv.ThrowTypeError(MSG_RESPONSE_URL_IS_NULL);
+    return;
+  }
+
+  mInternalResponse->SetFinalURL(aFinalURL);
+}
 } // namespace dom
 } // namespace mozilla
--- a/dom/fetch/Response.h
+++ b/dom/fetch/Response.h
@@ -51,16 +51,25 @@ public:
   void
   GetUrl(DOMString& aUrl) const
   {
     nsCString url;
     mInternalResponse->GetUrl(url);
     aUrl.AsAString() = NS_ConvertUTF8toUTF16(url);
   }
 
+  bool
+  GetFinalURL(ErrorResult& aRv) const
+  {
+    return mInternalResponse->FinalURL();
+  }
+
+  void
+  SetFinalURL(bool aFinalURL, ErrorResult& aRv);
+
   uint16_t
   Status() const
   {
     return mInternalResponse->GetStatus();
   }
 
   bool
   Ok() const
--- a/dom/html/nsHTMLDNSPrefetch.cpp
+++ b/dom/html/nsHTMLDNSPrefetch.cpp
@@ -306,31 +306,39 @@ nsHTMLDNSPrefetch::nsDeferrals::SubmitQu
 
   while (mHead != mTail) {
     nsCOMPtr<nsIContent> content = do_QueryReferent(mEntries[mTail].mElement);
     if (content) {
       nsCOMPtr<Link> link = do_QueryInterface(content);
       // Only prefetch here if request was deferred and deferral not cancelled
       if (link && link->HasDeferredDNSPrefetchRequest()) {
         nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nullptr);
-        if (hrefURI)
+        bool isLocalResource = false;
+        nsresult rv;
+
+        hostName.Truncate();
+        if (hrefURI) {
           hrefURI->GetAsciiHost(hostName);
+          rv = NS_URIChainHasFlags(hrefURI,
+                                   nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
+                                   &isLocalResource);
+        }
 
-        if (!hostName.IsEmpty()) {
+        if (!hostName.IsEmpty() && NS_SUCCEEDED(rv) && !isLocalResource) {
           if (IsNeckoChild()) {
             gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName),
                                            mEntries[mTail].mFlags);
           } else {
             nsCOMPtr<nsICancelable> tmpOutstanding;
 
-            nsresult rv = sDNSService->AsyncResolve(hostName, 
-                                    mEntries[mTail].mFlags
-                                    | nsIDNSService::RESOLVE_SPECULATE,
-                                    sDNSListener, nullptr,
-                                    getter_AddRefs(tmpOutstanding));
+            rv = sDNSService->AsyncResolve(hostName,
+                                           mEntries[mTail].mFlags
+                                           | nsIDNSService::RESOLVE_SPECULATE,
+                                           sDNSListener, nullptr,
+                                           getter_AddRefs(tmpOutstanding));
             // Tell link that deferred prefetch was requested
             if (NS_SUCCEEDED(rv))
               link->OnDNSPrefetchRequested();
           }
         }
       }
     }
     
--- a/dom/interfaces/base/nsITabParent.idl
+++ b/dom/interfaces/base/nsITabParent.idl
@@ -1,27 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "domstubs.idl"
 
-[scriptable, uuid(30361a5b-a3b8-4dbc-b464-e08761abb123)]
+[scriptable, uuid(b19038ba-0d75-40d2-be35-742e26d33bf9)]
 interface nsITabParent : nsISupports
 {
   void injectTouchEvent(in AString aType,
                         [array, size_is(count)] in uint32_t aIdentifiers,
                         [array, size_is(count)] in int32_t aXs,
                         [array, size_is(count)] in int32_t aYs,
                         [array, size_is(count)] in uint32_t aRxs,
                         [array, size_is(count)] in uint32_t aRys,
                         [array, size_is(count)] in float aRotationAngles,
                         [array, size_is(count)] in float aForces,
                         in uint32_t count,
                         in long aModifiers);
 
+  void getChildProcessOffset(out int32_t aCssX, out int32_t aCssY);
+
   readonly attribute boolean useAsyncPanZoom;
 
   void setIsDocShellActive(in bool aIsActive);
 
   readonly attribute uint64_t tabId;
 };
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1155,33 +1155,31 @@ bool TabParent::SendRealMouseEvent(Widge
   }
   event.refPoint += GetChildProcessOffset();
   if (event.message == NS_MOUSE_MOVE) {
     return SendRealMouseMoveEvent(event);
   }
   return SendRealMouseButtonEvent(event);
 }
 
-CSSPoint TabParent::AdjustTapToChildWidget(const CSSPoint& aPoint)
+LayoutDeviceToCSSScale
+TabParent::GetLayoutDeviceToCSSScale()
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
-
-  if (!content || !content->OwnerDoc()) {
-    return aPoint;
-  }
-
-  nsIDocument* doc = content->OwnerDoc();
-  if (!doc || !doc->GetShell()) {
-    return aPoint;
-  }
-  nsPresContext* presContext = doc->GetShell()->GetPresContext();
-
-  return aPoint + CSSPoint(
-    presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.x),
-    presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.y));
+  nsIDocument* doc = (content ? content->OwnerDoc() : nullptr);
+  nsIPresShell* shell = (doc ? doc->GetShell() : nullptr);
+  nsPresContext* ctx = (shell ? shell->GetPresContext() : nullptr);
+  return LayoutDeviceToCSSScale(ctx
+    ? (float)ctx->AppUnitsPerDevPixel() / nsPresContext::AppUnitsPerCSSPixel()
+    : 0.0f);
+}
+
+CSSPoint TabParent::AdjustTapToChildWidget(const CSSPoint& aPoint)
+{
+  return aPoint + (LayoutDevicePoint(mChildProcessOffsetAtTouchStart) * GetLayoutDeviceToCSSScale());
 }
 
 bool TabParent::SendHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
 {
   if (mIsDestroyed) {
     return false;
   }
 
@@ -1754,16 +1752,28 @@ TabParent::RecvEnableDisableCommands(con
     remoteBrowser->EnableDisableCommands(aAction,
                                          aEnabledCommands.Length(), enabledCommands,
                                          aDisabledCommands.Length(), disabledCommands);
   }
 
   return true;
 }
 
+NS_IMETHODIMP
+TabParent::GetChildProcessOffset(int32_t* aOutCssX, int32_t* aOutCssY)
+{
+  NS_ENSURE_ARG(aOutCssX);
+  NS_ENSURE_ARG(aOutCssY);
+  CSSPoint offset = LayoutDevicePoint(GetChildProcessOffset())
+      * GetLayoutDeviceToCSSScale();
+  *aOutCssX = offset.x;
+  *aOutCssY = offset.y;
+  return NS_OK;
+}
+
 LayoutDeviceIntPoint
 TabParent::GetChildProcessOffset()
 {
   // The "toplevel widget" in child processes is always at position
   // 0,0.  Map the event coordinates to match that.
 
   LayoutDeviceIntPoint offset(0, 0);
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -259,16 +259,17 @@ public:
                               APZStateChange aChange,
                               int aArg);
     void Activate();
     void Deactivate();
 
     bool MapEventCoordinatesForChildProcess(mozilla::WidgetEvent* aEvent);
     void MapEventCoordinatesForChildProcess(const LayoutDeviceIntPoint& aOffset,
                                             mozilla::WidgetEvent* aEvent);
+    LayoutDeviceToCSSScale GetLayoutDeviceToCSSScale();
 
     virtual bool RecvRequestNativeKeyBindings(const mozilla::WidgetKeyboardEvent& aEvent,
                                               MaybeNativeKeyBinding* aBindings) MOZ_OVERRIDE;
 
     void SendMouseEvent(const nsAString& aType, float aX, float aY,
                         int32_t aButton, int32_t aClickCount,
                         int32_t aModifiers, bool aIgnoreRootScrollFrame);
     void SendKeyEvent(const nsAString& aType, int32_t aKeyCode,
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp
+++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp
@@ -200,17 +200,17 @@ public:
   AudioDataDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, MediaFormat::Param aFormat, MediaDataDecoderCallback* aCallback)
     : MediaCodecDataDecoder(MediaData::Type::AUDIO_DATA, aConfig.mime_type, aFormat, aCallback)
   {
     JNIEnv* env = GetJNIForThread();
 
     jni::Object::LocalRef buffer(env);
     NS_ENSURE_SUCCESS_VOID(aFormat->GetByteBuffer(NS_LITERAL_STRING("csd-0"), &buffer));
 
-    if (!buffer) {
+    if (!buffer && aConfig.audio_specific_config->Length() >= 2) {
       csd0[0] = (*aConfig.audio_specific_config)[0];
       csd0[1] = (*aConfig.audio_specific_config)[1];
 
       buffer = jni::Object::LocalRef::Adopt(env, env->NewDirectByteBuffer(csd0, 2));
       NS_ENSURE_SUCCESS_VOID(aFormat->SetByteBuffer(NS_LITERAL_STRING("csd-0"), buffer));
     }
   }
 
--- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp
+++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp
@@ -242,9 +242,19 @@ GonkAudioDecoderManager::Output(int64_t 
 
 void GonkAudioDecoderManager::ReleaseAudioBuffer() {
   if (mAudioBuffer) {
     mDecoder->ReleaseMediaBuffer(mAudioBuffer);
     mAudioBuffer = nullptr;
   }
 }
 
+nsresult
+GonkAudioDecoderManager::Flush()
+{
+  GonkDecoderManager::Flush();
+  status_t err = mDecoder->flush();
+  if (err != OK) {
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
 } // namespace mozilla
--- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.h
+++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.h
@@ -27,16 +27,18 @@ public:
                           const mp4_demuxer::AudioDecoderConfig& aConfig);
   ~GonkAudioDecoderManager();
 
   virtual android::sp<MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
 
   virtual nsresult Output(int64_t aStreamOffset,
                           nsRefPtr<MediaData>& aOutput) MOZ_OVERRIDE;
 
+  virtual nsresult Flush() MOZ_OVERRIDE;
+
 protected:
   virtual bool PerformFormatSpecificProcess(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
 
   virtual status_t SendSampleToOMX(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
 
 private:
 
   nsresult CreateAudioData(int64_t aStreamOffset,
--- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
+++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
@@ -229,17 +229,17 @@ GonkMediaDataDecoder::ProcessOutput()
 nsresult
 GonkMediaDataDecoder::Flush()
 {
   // Flush the input task queue. This cancels all pending Decode() calls.
   // Note this blocks until the task queue finishes its current job, if
   // it's executing at all. Note the MP4Reader ignores all output while
   // flushing.
   mTaskQueue->Flush();
-
+  mDrainComplete = false;
   return mManager->Flush();
 }
 
 void
 GonkMediaDataDecoder::ProcessDrain()
 {
   // Notify decoder input EOS by sending a null data.
   ProcessDecode(nullptr);
--- a/dom/media/gstreamer/GStreamerFormatHelper.cpp
+++ b/dom/media/gstreamer/GStreamerFormatHelper.cpp
@@ -219,52 +219,50 @@ GStreamerFormatHelper::IsBlacklistEnable
                                  "media.gstreamer.enable-blacklist", true);
     sBlacklistEnabledCached = true;
   }
 
   return sBlacklistEnabled;
 }
 
 /* static */ bool
-GStreamerFormatHelper::IsPluginFeatureBlacklisted(GstPluginFeature *aFeature,
-                                                  FactoryType aTypes)
+GStreamerFormatHelper::IsPluginFeatureBlacklisted(GstPluginFeature *aFeature)
 {
   if (!IsBlacklistEnabled()) {
     return false;
   }
 
-  const gchar *className =
-    gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));
-
   const gchar *factoryName =
     gst_plugin_feature_get_name(aFeature);
 
-  if ((!(aTypes & FactoryTypeDecoder) && strstr(className, "Decoder")) ||
-      (!(aTypes & FactoryTypeDemuxer) && strstr(className, "Demuxer")) ||
-      (!(aTypes & FactoryTypeParser) && strstr(className, "Parser"))) {
-    return false;
-  }
-
   for (unsigned int i = 0; i < G_N_ELEMENTS(sPluginBlacklist); i++) {
     if (!strcmp(factoryName, sPluginBlacklist[i])) {
       return true;
     }
   }
 
   return false;
 }
 
 static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer)
 {
   if (!GST_IS_ELEMENT_FACTORY(aFeature)) {
     return FALSE;
   }
 
-  return !GStreamerFormatHelper::IsPluginFeatureBlacklisted(aFeature,
-                                                            (FactoryType)(FactoryTypeDecoder|FactoryTypeDemuxer));
+  const gchar *className =
+    gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));
+
+  if (!strstr(className, "Decoder") && !strstr(className, "Demux")) {
+    return FALSE;
+  }
+
+  return
+    gst_plugin_feature_get_rank(aFeature) >= GST_RANK_MARGINAL &&
+    !GStreamerFormatHelper::IsPluginFeatureBlacklisted(aFeature);
 }
 
 /**
  * Returns true if any |aFactory| caps intersect with |aCaps|
  */
 static bool SupportsCaps(GstElementFactory *aFactory, GstCaps *aCaps)
 {
   for (const GList *iter = gst_element_factory_get_static_pad_templates(aFactory); iter; iter = iter->next) {
--- a/dom/media/gstreamer/GStreamerFormatHelper.h
+++ b/dom/media/gstreamer/GStreamerFormatHelper.h
@@ -8,23 +8,16 @@
 #define GStreamerFormatHelper_h_
 
 #include <gst/gst.h>
 #include <mozilla/Types.h>
 #include "nsXPCOMStrings.h"
 
 namespace mozilla {
 
-enum FactoryType {
-  FactoryTypeDecoder  = 1 << 0,
-  FactoryTypeDemuxer  = 1 << 1,
-  FactoryTypeParser   = 1 << 2,
-  FactoryTypeAll      = FactoryTypeDecoder|FactoryTypeDemuxer|FactoryTypeParser
-};
-
 class GStreamerFormatHelper {
   /* This class can be used to query the GStreamer registry for the required
    * demuxers/decoders from nsHTMLMediaElement::CanPlayType.
    * It implements looking at the GstRegistry to check if elements to
    * demux/decode the formats passed to CanPlayType() are actually installed.
    */
   public:
     static GStreamerFormatHelper* Instance();
@@ -32,18 +25,17 @@ class GStreamerFormatHelper {
 
     bool CanHandleMediaType(const nsACString& aMIMEType,
                             const nsAString* aCodecs);
 
     bool CanHandleContainerCaps(GstCaps* aCaps);
     bool CanHandleCodecCaps(GstCaps* aCaps);
 
     static bool IsBlacklistEnabled();
-    static bool IsPluginFeatureBlacklisted(GstPluginFeature *aFeature,
-                                           FactoryType aTypes = FactoryTypeAll);
+    static bool IsPluginFeatureBlacklisted(GstPluginFeature *aFeature);
 
     static GstCaps* ConvertFormatsToCaps(const char* aMIMEType,
                                          const nsAString* aCodecs);
 
     static void Shutdown();
 
   private:
     GStreamerFormatHelper();
--- a/dom/media/gtest/TestMP4Demuxer.cpp
+++ b/dom/media/gtest/TestMP4Demuxer.cpp
@@ -82,77 +82,16 @@ ToCryptoString(CryptoSample& aCrypto)
                        aCrypto.encrypted_sizes[i]);
     }
   } else {
     res.Append("no crypto");
   }
   return res;
 }
 
-TEST(MP4Demuxer, CENC)
-{
-  nsRefPtr<MP4DemuxerBinding> b = new MP4DemuxerBinding("short-cenc.mp4");
-  MonitorAutoLock mon(b->mMonitor);
-  MP4Demuxer* d = b->demuxer;
-
-  EXPECT_TRUE(d->Init());
-
-  const char* video[] = {
-    "1 16 7e571d017e571d017e571d017e571d01 00000000000000000000000000000000 5,686 5,388",
-    "1 16 7e571d017e571d017e571d017e571d01 00000000000000000000000000000044 5,717",
-    "1 16 7e571d017e571d017e571d017e571d01 00000000000000000000000000000071 5,613",
-    "1 16 7e571d017e571d017e571d017e571d01 00000000000000000000000000000098 5,196",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000a5 5,213",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000b3 5,213",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000c1 5,384",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000d9 5,256",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000e9 5,245",
-    "1 16 7e571d017e571d017e571d017e571d01 000000000000000000000000000000f9 5,251",
-  };
-
-  MP4Sample* sample;
-  size_t i = 0;
-  while (!!(sample = d->DemuxVideoSample())) {
-    nsCString text = ToCryptoString(sample->crypto);
-    EXPECT_STREQ(video[i++], text.get());
-  }
-  EXPECT_EQ(ArrayLength(video), i);
-
-  const char* audio[] = {
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000000 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000018 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000030 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000048 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000060 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000078 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000090 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000000a8 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000000c0 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000000d8 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000000f0 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000108 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000120 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000138 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000150 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000168 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000180 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 00000000000000000000000000000198 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000001b0 0,371",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000001c8 0,372",
-    "1 16 7e571d027e571d027e571d027e571d02 000000000000000000000000000001e0 0,371",
-  };
-
-  i = 0;
-  while (!!(sample = d->DemuxAudioSample())) {
-    nsCString text = ToCryptoString(sample->crypto);
-    EXPECT_STREQ(audio[i++], text.get());
-  }
-  EXPECT_EQ(ArrayLength(audio), i);
-}
-
 TEST(MP4Demuxer, CENCFrag)
 {
   nsRefPtr<MP4DemuxerBinding> b = new MP4DemuxerBinding("gizmo-frag.mp4");
   MonitorAutoLock mon(b->mMonitor);
   MP4Demuxer* d = b->demuxer;
 
   EXPECT_TRUE(d->Init());
 
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -20,17 +20,16 @@ if CONFIG['MOZ_WEBM_ENCODER']:
         'TestVideoTrackEncoder.cpp',
         'TestVorbisTrackEncoder.cpp',
         'TestWebMWriter.cpp',
     ]
 
 TEST_HARNESS_FILES.gtest += [
     '../test/gizmo-frag.mp4',
     '../test/gizmo.mp4',
-    '../test/short-cenc.mp4',
     'dash_dashinit.mp4',
     'mediasource_test.mp4',
     'test.webm',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -641,39 +641,16 @@ var gMetadataTests = [
   },
   { name:"wavedata_u8.wav", tags: { }
   },
 ];
 
 // Test files for Encrypted Media Extensions
 var gEMETests = [
   {
-    name:"short-cenc.mp4",
-    type:"video/mp4; codecs=\"avc1.64000d,mp4a.40.2\"",
-    keys: {
-      // "keyid" : "key"
-      "7e571d017e571d017e571d017e571d01" : "7e5711117e5711117e5711117e571111",
-      "7e571d027e571d027e571d027e571d02" : "7e5722227e5722227e5722227e572222",
-    },
-    sessionType:"temporary",
-    duration:0.47
-  },
-  {
-    name:"short-cenc.mp4",
-    type:"video/mp4; codecs=\"avc1.64000d,mp4a.40.2\"",
-    keys: {
-      // "keyid" : "key"
-      "7e571d017e571d017e571d017e571d01" : "7e5711117e5711117e5711117e571111",
-      "7e571d027e571d027e571d027e571d02" : "7e5722227e5722227e5722227e572222",
-    },
-    sessionType:"temporary",
-    duration:0.47,
-    crossOrigin:true,
-  },
-  {
     name:"gizmo-frag-cencinit.mp4",
     fragments: [ "gizmo-frag-cencinit.mp4", "gizmo-frag-cenc1.m4s", "gizmo-frag-cenc2.m4s" ],
     type:"video/mp4; codecs=\"avc1.64000d,mp4a.40.2\"",
     keys: {
       // "keyid" : "key"
       "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
       "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
     },
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -228,17 +228,16 @@ support-files =
   seek.webm
   seek.webm^headers^
   seek.yuv
   seek_support.js
   seekLies.sjs
   seek_with_sound.ogg^headers^
   sine.webm
   sine.webm^headers^
-  short-cenc.mp4
   short-video.ogv
   short-video.ogv^headers^
   small-shot-mp3.mp4
   small-shot-mp3.mp4^headers^
   small-shot.m4a
   small-shot.mp3
   small-shot.mp3^headers^
   small-shot.ogg
deleted file mode 100644
index aa44c3b9a187b78c7a7a0a0bbfeb546f6ee3d96a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/dom/media/test/short-cenc.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  This XML file describes the encryption applied to short-cenc.mp4. To generate
-  short-cenc, run the following command:
-
-    MP4Box -crypt short-cenc.xml -out short-cenc.mp4 short.mp4
--->
-
-<GPACDRM type="CENC AES-CTR">
-
-  <DRMInfo type="pssh" version="1">
-    <!--
-    SystemID specified in
-    https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html
-    -->
-    <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b" />
-    <!-- Number of KeyIDs = 2 -->
-    <BS bits="32" value="2" />
-    <!-- KeyID -->
-    <BS ID128="0x7e571d017e571d017e571d017e571d01" />
-    <BS ID128="0x7e571d027e571d027e571d027e571d02" />
-  </DRMInfo>
-
-  <CrypTrack trackID="1" isEncrypted="1" IV_size="16" saiSavedBox="senc"
-    first_IV="0x00000000000000000000000000000000">
-    <key KID="0x7e571d017e571d017e571d017e571d01"
-      value="0x7e5711117e5711117e5711117e571111" />
-  </CrypTrack>
-
-  <CrypTrack trackID="2" isEncrypted="1" IV_size="16" saiSavedBox="senc"
-    first_IV="0x00000000000000000000000000000000">
-    <key KID="0x7e571d027e571d027e571d027e571d02"
-      value="0x7e5722227e5722227e5722227e572222" />
-  </CrypTrack>
-
-</GPACDRM>
--- a/dom/svg/SVGPathData.cpp
+++ b/dom/svg/SVGPathData.cpp
@@ -532,19 +532,19 @@ AngleOfVector(const Point& aVector)
   // defined value". In the case of atan2 the implementation-defined value
   // seems to commonly be zero, but it could just as easily be a NaN value.
   // We specifically want zero in this case, hence the check:
 
   return (aVector != Point(0.0, 0.0)) ? atan2(aVector.y, aVector.x) : 0.0;
 }
 
 static float
-AngleOfVectorF(const Point& aVector)
+AngleOfVector(const Point& cp1, const Point& cp2)
 {
-  return static_cast<float>(AngleOfVector(aVector));
+  return static_cast<float>(AngleOfVector(cp1 - cp2));
 }
 
 void
 SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
 {
   // This code should assume that ANY type of segment can appear at ANY index.
   // It should also assume that segments such as M and Z can appear in weird
   // places, and repeat multiple times consecutively.
@@ -568,41 +568,41 @@ SVGPathData::GetMarkerPositioningData(ns
     Point& segStart = prevSegEnd;
     Point segEnd;
     float segStartAngle, segEndAngle;
 
     switch (segType) // to find segStartAngle, segEnd and segEndAngle
     {
     case PATHSEG_CLOSEPATH:
       segEnd = pathStart;
-      segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+      segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
       break;
 
     case PATHSEG_MOVETO_ABS:
     case PATHSEG_MOVETO_REL:
       if (segType == PATHSEG_MOVETO_ABS) {
         segEnd = Point(mData[i], mData[i+1]);
       } else {
         segEnd = segStart + Point(mData[i], mData[i+1]);
       }
       pathStart = segEnd;
       // If authors are going to specify multiple consecutive moveto commands
       // with markers, me might as well make the angle do something useful:
-      segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+      segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
       i += 2;
       break;
 
     case PATHSEG_LINETO_ABS:
     case PATHSEG_LINETO_REL:
       if (segType == PATHSEG_LINETO_ABS) {
         segEnd = Point(mData[i], mData[i+1]);
       } else {
         segEnd = segStart + Point(mData[i], mData[i+1]);
       }
-      segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+      segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
       i += 2;
       break;
 
     case PATHSEG_CURVETO_CUBIC_ABS:
     case PATHSEG_CURVETO_CUBIC_REL:
     {
       Point cp1, cp2; // control points
       if (segType == PATHSEG_CURVETO_CUBIC_ABS) {
@@ -610,42 +610,38 @@ SVGPathData::GetMarkerPositioningData(ns
         cp2 = Point(mData[i+2], mData[i+3]);
         segEnd = Point(mData[i+4], mData[i+5]);
       } else {
         cp1 = segStart + Point(mData[i], mData[i+1]);
         cp2 = segStart + Point(mData[i+2], mData[i+3]);
         segEnd = segStart + Point(mData[i+4], mData[i+5]);
       }
       prevCP = cp2;
-      if (cp1 == segStart) {
-        cp1 = cp2;
-      }
-      if (cp2 == segEnd) {
-        cp2 = cp1;
-      }
-      segStartAngle = AngleOfVectorF(cp1 - segStart);
-      segEndAngle = AngleOfVectorF(segEnd - cp2);
+      segStartAngle =
+        AngleOfVector(cp1 == segStart ? (cp1 == cp2 ? segEnd : cp2) : cp1, segStart);
+      segEndAngle =
+        AngleOfVector(segEnd, cp2 == segEnd ? (cp1 == cp2 ? segStart : cp1) : cp2);
       i += 6;
       break;
     }
 
     case PATHSEG_CURVETO_QUADRATIC_ABS:
     case PATHSEG_CURVETO_QUADRATIC_REL:
     {
-      Point cp1, cp2; // control points
+      Point cp1; // control point
       if (segType == PATHSEG_CURVETO_QUADRATIC_ABS) {
         cp1 = Point(mData[i], mData[i+1]);
         segEnd = Point(mData[i+2], mData[i+3]);
       } else {
         cp1 = segStart + Point(mData[i], mData[i+1]);
         segEnd = segStart + Point(mData[i+2], mData[i+3]);
       }
       prevCP = cp1;
-      segStartAngle = AngleOfVectorF(cp1 - segStart);
-      segEndAngle = AngleOfVectorF(segEnd - cp1);
+      segStartAngle = AngleOfVector(cp1 == segStart ? segEnd : cp1, segStart);
+      segEndAngle = AngleOfVector(segEnd, cp1 == segEnd ? segStart : cp1);
       i += 4;
       break;
     }
 
     case PATHSEG_ARC_ABS:
     case PATHSEG_ARC_REL:
     {
       double rx = mData[i];
@@ -675,17 +671,17 @@ SVGPathData::GetMarkerPositioningData(ns
       }
 
       // Below we have funny interleaving of F.6.6 (Correction of out-of-range
       // radii) and F.6.5 (Conversion from endpoint to center parameterization)
       // which is designed to avoid some unnecessary calculations.
 
       if (rx == 0.0 || ry == 0.0) {
         // F.6.6 step 1 - straight line or coincidental points
-        segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+        segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
         i += 7;
         break;
       }
       rx = fabs(rx); // F.6.6.1
       ry = fabs(ry);
 
       // F.6.5.1:
       angle = angle * M_PI/180.0;
@@ -750,69 +746,64 @@ SVGPathData::GetMarkerPositioningData(ns
 
     case PATHSEG_LINETO_HORIZONTAL_ABS:
     case PATHSEG_LINETO_HORIZONTAL_REL:
       if (segType == PATHSEG_LINETO_HORIZONTAL_ABS) {
         segEnd = Point(mData[i++], segStart.y);
       } else {
         segEnd = segStart + Point(mData[i++], 0.0f);
       }
-      segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+      segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
       break;
 
     case PATHSEG_LINETO_VERTICAL_ABS:
     case PATHSEG_LINETO_VERTICAL_REL:
       if (segType == PATHSEG_LINETO_VERTICAL_ABS) {
         segEnd = Point(segStart.x, mData[i++]);
       } else {
         segEnd = segStart + Point(0.0f, mData[i++]);
       }
-      segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
+      segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
       break;
 
     case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
     case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
     {
       Point cp1 = SVGPathSegUtils::IsCubicType(prevSegType) ?
                        segStart * 2 - prevCP : segStart;
       Point cp2;
       if (segType == PATHSEG_CURVETO_CUBIC_SMOOTH_ABS) {
         cp2 = Point(mData[i], mData[i+1]);
         segEnd = Point(mData[i+2], mData[i+3]);
       } else {
         cp2 = segStart + Point(mData[i], mData[i+1]);
         segEnd = segStart + Point(mData[i+2], mData[i+3]);
       }
       prevCP = cp2;
-      if (cp1 == segStart) {
-        cp1 = cp2;
-      }
-      if (cp2 == segEnd) {
-        cp2 = cp1;
-      }
-      segStartAngle = AngleOfVectorF(cp1 - segStart);
-      segEndAngle = AngleOfVectorF(segEnd - cp2);
+      segStartAngle =
+        AngleOfVector(cp1 == segStart ? (cp1 == cp2 ? segEnd : cp2) : cp1, segStart);
+      segEndAngle =
+        AngleOfVector(segEnd, cp2 == segEnd ? (cp1 == cp2 ? segStart : cp1) : cp2);
       i += 4;
       break;
     }
 
     case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
     case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
     {
       Point cp1 = SVGPathSegUtils::IsQuadraticType(prevSegType) ?
                        segStart * 2 - prevCP : segStart;
-      Point cp2;
       if (segType == PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS) {
         segEnd = Point(mData[i], mData[i+1]);
       } else {
         segEnd = segStart + Point(mData[i], mData[i+1]);
       }
       prevCP = cp1;
-      segStartAngle = AngleOfVectorF(cp1 - segStart);
-      segEndAngle = AngleOfVectorF(segEnd - cp1);
+      segStartAngle = AngleOfVector(cp1 == segStart ? segEnd : cp1, segStart);
+      segEndAngle = AngleOfVector(segEnd, cp1 == segEnd ? segStart : cp1);
       i += 2;
       break;
     }
 
     default:
       // Leave any existing marks in aMarks so we have a visual indication of
       // when things went wrong.
       MOZ_ASSERT(false, "Unknown segment type - path corruption?");
--- a/dom/tests/mochitest/ajax/offline/test_lowDeviceStorage.html
+++ b/dom/tests/mochitest/ajax/offline/test_lowDeviceStorage.html
@@ -37,21 +37,21 @@ function finish() {
 
 if (OfflineTest.setup()) {
   obs.notifyObservers(updateService, "disk-space-watcher", "full");
 
   var updateObserver = {
     updateStateChanged: function (aUpdate, aState) {
       switch(aState) {
         case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
-          aUpdate.removeObserver(this);
           errorReceived = true;
           OfflineTest.ok(true, "Expected error. Update canceled");
         break;
         case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
+          aUpdate.removeObserver(this);
           OfflineTest.ok(errorReceived,
                          "Finished after receiving the expected error");
           finish();
         break;
         case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
           aUpdate.removeObserver(this);
           OfflineTest.ok(false, "No update");
           finish();
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -83,36 +83,31 @@ var ecmaGlobals =
     {name: "SharedInt32Array", nightly: true},
     {name: "SharedUint32Array", nightly: true},
     {name: "SharedFloat32Array", nightly: true},
     {name: "SharedFloat64Array", nightly: true},
     {name: "SIMD", nightly: true},
     {name: "Atomics", nightly: true},
     "StopIteration",
     "String",
+    "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
     "Uint8Array",
     "Uint8ClampedArray",
     "URIError",
     "WeakMap",
     "WeakSet",
   ];
 // IMPORTANT: Do not change the list above without review from
 //            a JavaScript Engine peer!
 
-// Symbol is conditionally defined.
-// If it's defined, insert "Symbol" before "SyntaxError".
-if (typeof Symbol === "function") {
-  ecmaGlobals.splice(ecmaGlobals.indexOf("SyntaxError"), 0, "Symbol");
-}
-
 // IMPORTANT: Do not change the list below without review from a DOM peer,
 //            except to remove items from it!
 //
 // This is a list of interfaces that were prefixed with 'moz' instead of 'Moz'.
 // We should never to that again, interfaces in the DOM start with an uppercase
 // letter. If you think you need to add an interface here, DON'T. Rename your
 // interface.
 var legacyMozPrefixedInterfaces =
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -415,8 +415,15 @@ partial interface Navigator {
 #ifdef MOZ_EME
 partial interface Navigator {
   [Pref="media.eme.apiVisible", NewObject]
   Promise<MediaKeySystemAccess>
   requestMediaKeySystemAccess(DOMString keySystem,
                               optional sequence<MediaKeySystemOptions> supportedConfigurations);
 };
 #endif
+
+#ifdef NIGHTLY_BUILD
+partial interface Navigator {
+  [Func="Navigator::IsE10sEnabled"]
+  readonly attribute boolean mozE10sEnabled;
+};
+#endif
--- a/dom/webidl/Response.webidl
+++ b/dom/webidl/Response.webidl
@@ -13,16 +13,18 @@
 interface Response {
   [NewObject] static Response error();
   [Throws,
    NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
 
   readonly attribute ResponseType type;
 
   readonly attribute USVString url;
+  [Throws]
+           attribute boolean finalURL;
   readonly attribute unsigned short status;
   readonly attribute boolean ok;
   readonly attribute ByteString statusText;
   [SameObject] readonly attribute Headers headers;
 
   [NewObject] Response clone();
 };
 Response implements Body;
--- a/dom/workers/test/fetch/worker_test_response.js
+++ b/dom/workers/test/fetch/worker_test_response.js
@@ -61,16 +61,35 @@ function testOk() {
 
   var r3 = new Response("", { status: 299});
   ok(r3.ok, "Response with status 299 should have ok true");
 
   var r4 = new Response("", { status: 302});
   ok(!r4.ok, "Response with status 302 should have ok false");
 }
 
+// It is not possible to test setting finalURL until we have ServiceWorker
+// interception. This is because synthetic Responses do not have a url, the url
+// is set based on the request, so a SW could initiate a fetch() on behalf of
+// a client and set the resulting Response's finalURL before returning it to
+// the client, in which case the "set response's url to request's url" from the
+// client's point of view would not happen. A test for this will be added by
+// Bug 1134352.
+function testFinalURL() {
+  var r1 = new Response();
+  ok(!r1.finalURL, "Response.finalURL is false by default.");
+
+  try {
+    r1.finalURL = true;
+    ok(false, "Setting Response.finalURL of Response with null url should fail.");
+  } catch(e) {
+    ok(true, "Setting Response.finalURL of Response with null url should fail.");
+  }
+}
+
 function testBodyUsed() {
   var res = new Response("Sample body");
   ok(!res.bodyUsed, "bodyUsed is initially false.");
   return res.text().then((v) => {
     is(v, "Sample body", "Body should match");
     ok(res.bodyUsed, "After reading body, bodyUsed should be true.");
   }).then(() => {
     return res.blob().then((v) => {
@@ -148,16 +167,17 @@ function testBodyExtraction() {
 
 onmessage = function() {
   var done = function() { postMessage({ type: 'finish' }) }
 
   testDefaultCtor();
   testClone();
   testRedirect();
   testOk();
+  testFinalURL();
 
   Promise.resolve()
     .then(testBodyCreation)
     .then(testBodyUsed)
     .then(testBodyExtraction)
     // Put more promise based tests here.
     .then(done)
     .catch(function(e) {
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -57,36 +57,31 @@ var ecmaGlobals =
     {name: "SharedInt32Array", nightly: true},
     {name: "SharedUint32Array", nightly: true},
     {name: "SharedFloat32Array", nightly: true},
     {name: "SharedFloat64Array", nightly: true},
     {name: "SIMD", nightly: true},
     {name: "Atomics", nightly: true},
     "StopIteration",
     "String",
+    "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
     "Uint8Array",
     "Uint8ClampedArray",
     "URIError",
     "WeakMap",
     "WeakSet",
   ];
 // IMPORTANT: Do not change the list above without review from
 //            a JavaScript Engine peer!
 
-// Symbol is conditionally defined.
-// If it's defined, insert "Symbol" before "SyntaxError".
-if (typeof Symbol === "function") {
-  ecmaGlobals.splice(ecmaGlobals.indexOf("SyntaxError"), 0, "Symbol");
-}
-
 // IMPORTANT: Do not change the list below without review from a DOM peer!
 var interfaceNamesInGlobalScope =
   [
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Blob",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "BroadcastChannel", pref: "dom.broadcastChannel.enabled" },
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -81,17 +81,16 @@ class TextureChild MOZ_FINAL : public PT
 {
   ~TextureChild() {}
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
 
   TextureChild()
   : mForwarder(nullptr)
   , mTextureClient(nullptr)
-  , mKeep(nullptr)
   , mIPCOpen(false)
   {
   }
 
   bool Recv__delete__() MOZ_OVERRIDE;
 
   bool RecvCompositorRecycle() MOZ_OVERRIDE
   {
@@ -130,17 +129,17 @@ private:
     MOZ_ASSERT(mIPCOpen == true);
     mIPCOpen = false;
     Release();
   }
 
   RefPtr<CompositableForwarder> mForwarder;
   RefPtr<TextureClient> mWaitForRecycle;
   TextureClient* mTextureClient;
-  KeepAlive* mKeep;
+  UniquePtr<KeepAlive> mKeep;
   bool mIPCOpen;
 
   friend class TextureClient;
 };
 
 bool
 TextureChild::Recv__delete__()
 {
@@ -149,17 +148,17 @@ TextureChild::Recv__delete__()
 
 void
 TextureChild::ActorDestroy(ActorDestroyReason why)
 {
   if (mTextureClient) {
     mTextureClient->mActor = nullptr;
   }
   mWaitForRecycle = nullptr;
-  delete mKeep;
+  mKeep = nullptr;
 }
 
 // static
 PTextureChild*
 TextureClient::CreateIPDLActor()
 {
   TextureChild* c = new TextureChild();
   c->AddIPDLReference();
@@ -491,21 +490,21 @@ TextureClient::TextureClient(ISurfaceAll
 
 TextureClient::~TextureClient()
 {
   // All the destruction code that may lead to virtual method calls must
   // be in Finalize() which is called just before the destructor.
 }
 
 void
-TextureClient::KeepUntilFullDeallocation(KeepAlive* aKeep)
+TextureClient::KeepUntilFullDeallocation(UniquePtr<KeepAlive> aKeep)
 {
   MOZ_ASSERT(mActor);
   MOZ_ASSERT(!mActor->mKeep);
-  mActor->mKeep = aKeep;
+  mActor->mKeep = Move(aKeep);
 }
 
 void TextureClient::ForceRemove(bool sync)
 {
   if (mValid && mActor) {
     if (sync || GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
       MOZ_PERFORMANCE_WARNING("gfx", "TextureClient/Host pair requires synchronous deallocation");
       if (mActor->IPCOpen()) {
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -398,17 +398,17 @@ public:
   bool IsAddedToCompositableClient() const { return mAddedToCompositableClient; }
 
   /**
    * kee the passed object alive until the IPDL actor is destroyed. This can
    * help avoid race conditions in some cases.
    * It's a temporary hack to ensure that DXGI textures don't get destroyed
    * between serialization and deserialization.
    */
-  void KeepUntilFullDeallocation(KeepAlive* aKeep);
+  void KeepUntilFullDeallocation(UniquePtr<KeepAlive> aKeep);
 
   /**
    * Create and init the TextureChild/Parent IPDL actor pair.
    *
    * Should be called only once per TextureClient.
    */
   bool InitIPDLActor(CompositableForwarder* aForwarder);
 
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -174,19 +174,19 @@ TextureClientD3D11::TextureClientD3D11(I
   , mNeedsClear(false)
   , mNeedsClearWhite(false)
 {}
 
 TextureClientD3D11::~TextureClientD3D11()
 {
   if (mActor) {
     if (mTexture) {
-      KeepUntilFullDeallocation(new TKeepAlive<ID3D10Texture2D>(mTexture10));
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D10Texture2D>>(mTexture10));
     } else if (mTexture10) {
-      KeepUntilFullDeallocation(new TKeepAlive<ID3D11Texture2D>(mTexture));
+      KeepUntilFullDeallocation(MakeUnique<TKeepAlive<ID3D11Texture2D>>(mTexture));
     }
   }
 #ifdef DEBUG
   // An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
   // when it calls EndDraw. This EndDraw should not execute anything so it
   // shouldn't -really- need the lock but the debug layer chokes on this.
   if (mDrawTarget) {
     MOZ_ASSERT(!mIsLocked);
--- a/gfx/layers/d3d9/TextureD3D9.cpp
+++ b/gfx/layers/d3d9/TextureD3D9.cpp
@@ -734,17 +734,17 @@ SharedTextureClientD3D9::SharedTextureCl
   , mIsLocked(false)
 {
   MOZ_COUNT_CTOR(SharedTextureClientD3D9);
 }
 
 SharedTextureClientD3D9::~SharedTextureClientD3D9()
 {
   if (mTexture && mActor) {
-    KeepUntilFullDeallocation(new TKeepAlive<IDirect3DTexture9>(mTexture));
+    KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
   }
   if (mTexture) {
     gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
   }
   MOZ_COUNT_DTOR(SharedTextureClientD3D9);
 }
 
 bool
--- a/gfx/layers/d3d9/TextureD3D9.h
+++ b/gfx/layers/d3d9/TextureD3D9.h
@@ -261,17 +261,19 @@ public:
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
 
   void InitWith(IDirect3DTexture9* aTexture, HANDLE aSharedHandle, D3DSURFACE_DESC aDesc)
   {
     MOZ_ASSERT(!mTexture);
     mTexture = aTexture;
     mHandle = aSharedHandle;
     mDesc = aDesc;
-    gfxWindowsPlatform::sD3D9SharedTextureUsed += mDesc.Width * mDesc.Height * 4;
+    if (mTexture) {
+      gfxWindowsPlatform::sD3D9SharedTextureUsed += mDesc.Width * mDesc.Height * 4;
+    }
   }
 
   virtual gfx::IntSize GetSize() const
   {
     return gfx::IntSize(mDesc.Width, mDesc.Height);
   }
 
   virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..39f49689a0ab5ce727666a278e69e946ed4f4776
GIT binary patch
literal 634
zc${<hbhEHbJi%~+;UfdX|NsBb{QnQ685kH8|8x7fh6Fo12DlpO889<~gnqKHZ~-NC
zfNTbk76zvOE&VG`zvW*%XUnbb&G+{F=5KrCG3{CBvR9|Jz2iRq$>;jF-siv0egDVL
z!_|Id(Z>!St?6f$edg@-T7G5K*RHc!+wZLV&dt|-{K=-DJ$|dNzuESixBv9>FT4Ks
zoqzrP&%Xcs5*ijB5g8R7Ggj<4apT1g4oOW*&&bTm&Y3HBp1k?;C#RH_l~+_&RoARl
zyH4GD^@~ed+uA!iySjV!>fNVrzy8fFqhsR}lT*_(XU(27ci#Nrk=3>Jjm@p?ox67L
z*}HH5^2+Ji`Niec_03zi@7%q2|M=wf?fv8P>-*=g-+%u8`~Um~3l220a7)>A7%V*0
x$|G%6!(q7SNT-N))SeE*#m9QtWUQ-ng3*G85eONWn0y$qhS-$R5CesnH2@{PH|zia
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/bug1132427.html
@@ -0,0 +1,6 @@
+<html>
+<body onload="opener.doTest();">
+  <img id="left" style="width: 201px; height: 201px;" src="bug1132427.gif">
+  <img id="right" src="bug1132427.gif">
+</body>
+</html>
--- a/image/test/mochitest/chrome.ini
+++ b/image/test/mochitest/chrome.ini
@@ -23,16 +23,18 @@ support-files =
   opaque.bmp
   purple.gif
   red.gif
   red.png
   ref-iframe.html
   rillybad.jpg
   transparent.gif
   transparent.png
+  bug1132427.html
+  bug1132427.gif
 
 [test_animSVGImage.html]
 [test_animSVGImage2.html]
 [test_animation.html]
 disabled = bug 1100497
 [test_animation2.html]
 disabled = bug 1101415
 [test_background_image_anim.html]
@@ -45,8 +47,9 @@ disabled = bug 1101415
 [test_removal_onload.html]
 [test_staticClone.html]
 [test_svg_animatedGIF.html]
 [test_svg_filter_animation.html]
 [test_synchronized_animation.html]
 [test_undisplayed_iframe.html]
 disabled = bug 1060869
 [test_xultree_animation.xhtml]
+[test_bug1132427.html]
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/test_bug1132427.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for scrolling selection into view</title>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// We open a window which contains two copies of the same gif. One at a scaled size, one at the
+// natural image size. We rely on the bug only showing up in the scaled image. The gif has three
+// frames and a delay of 100ms. The first is all white. The second has a very small update area
+// in the upper left, it changes the pixels to slightly off white. The third changes all the
+// pixels to blue. When the bug appears we only update the upper left pixels when looping around
+// from the last frame to the first frame. We compare a middle pixel of the two images to make
+// sure that they are the same at 100ms for a second. If the bug appears then the middle pixel
+// on the scaled image will always be blue and so should not match the middle pixel on the
+// unscaled image which should be white two thirds of the time. If the timers fire at bad times
+// and only fire when both frames are displaying blue we won't be able to detect this bug and the
+// test will pass without testing anything important, but that's not a big deal. That should be
+// rare enough, and the next time the test is run will should do proper testing.
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(openWindow);
+
+var win = null;
+
+function openWindow() {
+  win = window.open("bug1132427.html",
+                "", "scrollbars=yes,toolbar,menubar,width=600,height=800");
+  win.addEventListener("load", doTest, false);
+  win.focus();
+}
+
+function doTest() {
+  setTimeout(continueTest, 1000);
+}
+
+function checkPixel(canvas, context, x1, y1, x2, y2) {
+  var pix = context.getImageData(0, 0, canvas.width, canvas.height).data;
+  for (var i = 0; i < 4; i++) {
+    is(pix[4 * (y1 * canvas.width + x1) + i], pix[4 * (y2 * canvas.width + x2) + i], "pixels should match");
+  }
+}
+
+var iterationsLeft = 10;
+
+function continueTest() {
+  // we need to drawWindow the chrome window so we can get a dump of the retained widget layers
+  // if we have to repaint to fulfill this drawWindow request then it will be impossible to
+  // observe the bug
+  var chromewin = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                     .getInterface(Components.interfaces.nsIWebNavigation)
+                     .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
+                     .rootTreeItem
+                     .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                     .getInterface(Components.interfaces.nsIDOMWindow);
+
+  var el = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+  el.width = chromewin.innerWidth;
+  el.height = chromewin.innerHeight;
+  var ctx = el.getContext("2d");
+  // pass the correct flags so we don't have to flush the retained layers
+  ctx.drawWindow(chromewin, 0, 0, chromewin.innerWidth, chromewin.innerHeight, "rgba(0,0,0,0)",
+    ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_DRAW_CARET);
+
+  var leftbox = win.document.getElementById("left").getBoundingClientRect();
+  var rightbox = win.document.getElementById("right").getBoundingClientRect();
+  // this is actually chrome on left and right, but in practice we have none so it doesn't matter
+  var chromeleft = win.outerWidth - win.innerWidth;
+  // this is actually chrome on top and bottom, but bottom chrome is usually small to none and we have
+  // 100px to spare in hitting the middle of the image elements (they are 200x200)
+  var chrometop = win.outerHeight - win.innerHeight;
+
+  // compare the middle of the two image elements
+  checkPixel(el, ctx, chromeleft + leftbox.left + Math.floor(leftbox.width/2), chrometop + leftbox.top + Math.floor(leftbox.height/2),
+                      chromeleft + rightbox.left + Math.floor(rightbox.width/2), chrometop + rightbox.top + Math.floor(rightbox.height/2));
+
+  iterationsLeft--;
+  if (iterationsLeft > 0) {
+    // now test 100ms later, we should have the next frame of the gif then
+    setTimeout(continueTest, 100);
+  } else {
+    win.close();
+    SimpleTest.finish();
+  }
+}
+</script>
+</pre>
+</body>
+
+</html>
--- a/intl/hyphenation/nsHyphenator.cpp
+++ b/intl/hyphenation/nsHyphenator.cpp
@@ -75,19 +75,57 @@ nsHyphenator::Hyphenate(const nsAString&
       }
       wordLimit = i + chLen;
       if (i + chLen < aString.Length()) {
         continue;
       }
     }
 
     if (inWord) {
-      const char16_t *begin = aString.BeginReading();
-      NS_ConvertUTF16toUTF8 utf8(begin + wordStart,
-                                 wordLimit - wordStart);
+      // Convert the word to utf-8 for libhyphen, lowercasing it as we go
+      // so that it will match the (lowercased) patterns (bug 1105644).
+      nsAutoCString utf8;
+      const char16_t* const begin = aString.BeginReading();
+      const char16_t *cur = begin + wordStart;
+      const char16_t *end = begin + wordLimit;
+      while (cur < end) {
+        uint32_t ch = *cur++;
+
+        if (NS_IS_HIGH_SURROGATE(ch)) {
+          if (cur < end && NS_IS_LOW_SURROGATE(*cur)) {
+            ch = SURROGATE_TO_UCS4(ch, *cur++);
+          } else {
+            ch = 0xfffd; // unpaired surrogate, treat as REPLACEMENT CHAR
+          }
+        } else if (NS_IS_LOW_SURROGATE(ch)) {
+          ch = 0xfffd; // unpaired surrogate
+        }
+
+        // XXX What about language-specific casing? Consider Turkish I/i...
+        // In practice, it looks like the current patterns will not be
+        // affected by this, as they treat dotted and undotted i similarly.
+        ch = ToLowerCase(ch);
+
+        if (ch < 0x80) { // U+0000 - U+007F
+          utf8.Append(ch);
+        } else if (ch < 0x0800) { // U+0100 - U+07FF
+          utf8.Append(0xC0 | (ch >> 6));
+          utf8.Append(0x80 | (0x003F & ch));
+        } else if (ch < 0x10000) { // U+0800 - U+D7FF,U+E000 - U+FFFF
+          utf8.Append(0xE0 | (ch >> 12));
+          utf8.Append(0x80 | (0x003F & (ch >> 6)));
+          utf8.Append(0x80 | (0x003F & ch));
+        } else {
+          utf8.Append(0xF0 | (ch >> 18));
+          utf8.Append(0x80 | (0x003F & (ch >> 12)));
+          utf8.Append(0x80 | (0x003F & (ch >> 6)));
+          utf8.Append(0x80 | (0x003F & ch));
+        }
+      }
+
       nsAutoTArray<char,200> utf8hyphens;
       utf8hyphens.SetLength(utf8.Length() + 5);
       char **rep = nullptr;
       int *pos = nullptr;
       int *cut = nullptr;
       int err = hnj_hyphen_hyphenate2((HyphenDict*)mDict,
                                       utf8.BeginReading(), utf8.Length(),
                                       utf8hyphens.Elements(), nullptr,
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -258,19 +258,20 @@ enum GCProgress {
     GC_CYCLE_BEGIN,
     GC_SLICE_BEGIN,
     GC_SLICE_END,
     GC_CYCLE_END
 };
 
 struct JS_PUBLIC_API(GCDescription) {
     bool isCompartment_;
+    JSGCInvocationKind invocationKind_;
 
-    explicit GCDescription(bool isCompartment)
-      : isCompartment_(isCompartment) {}
+    GCDescription(bool isCompartment, JSGCInvocationKind kind)
+      : isCompartment_(isCompartment), invocationKind_(kind) {}
 
     char16_t *formatMessage(JSRuntime *rt) const;
     char16_t *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
 };
 
 typedef void
 (* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
 
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -1012,33 +1012,34 @@ Select(JSContext *cx, unsigned argc, Val
         result[i] = mask[i] < 0 ? tv[i] : fv[i];
 
     return StoreResult<V>(cx, args, result);
 }
 
 template<class VElem, unsigned NumElem>
 static bool
 TypedArrayFromArgs(JSContext *cx, const CallArgs &args,
-                   MutableHandle<TypedArrayObject*> typedArray, int32_t *byteStart)
+                   MutableHandleObject typedArray, int32_t *byteStart)
 {
     if (!args[0].isObject())
         return ErrorBadArgs(cx);
 
     JSObject &argobj = args[0].toObject();
-    if (!argobj.is<TypedArrayObject>())
+    if (!IsAnyTypedArray(&argobj))
         return ErrorBadArgs(cx);
 
-    typedArray.set(&argobj.as<TypedArrayObject>());
+    typedArray.set(&argobj);
 
     int32_t index;
     if (!ToInt32(cx, args[1], &index))
         return false;
 
-    *byteStart = index * typedArray->bytesPerElement();
-    if (*byteStart < 0 || (uint32_t(*byteStart) + NumElem * sizeof(VElem)) > typedArray->byteLength())
+    *byteStart = index * AnyTypedArrayBytesPerElement(typedArray);
+    if (*byteStart < 0 ||
+        (uint32_t(*byteStart) + NumElem * sizeof(VElem)) > AnyTypedArrayByteLength(typedArray))
     {
         // Keep in sync with AsmJS OnOutOfBounds function.
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
         return false;
     }
 
     return true;
 }
@@ -1049,27 +1050,27 @@ Load(JSContext *cx, unsigned argc, Value
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 2)
         return ErrorBadArgs(cx);
 
     int32_t byteStart;
-    Rooted<TypedArrayObject*> typedArray(cx);
+    RootedObject typedArray(cx);
     if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
         return false;
 
     Rooted<TypeDescr*> typeDescr(cx, &V::GetTypeDescr(*cx->global()));
     MOZ_ASSERT(typeDescr);
     Rooted<TypedObject *> result(cx, TypedObject::createZeroed(cx, typeDescr, 0));
     if (!result)
         return false;
 
-    Elem *src = reinterpret_cast<Elem*>(static_cast<char*>(typedArray->viewData()) + byteStart);
+    Elem *src = reinterpret_cast<Elem*>(static_cast<char*>(AnyTypedArrayViewData(typedArray)) + byteStart);
     Elem *dst = reinterpret_cast<Elem*>(result->typedMem());
     memcpy(dst, src, sizeof(Elem) * NumElem);
 
     args.rval().setObject(*result);
     return true;
 }
 
 template<class V, unsigned NumElem>
@@ -1078,25 +1079,25 @@ Store(JSContext *cx, unsigned argc, Valu
 {
     typedef typename V::Elem Elem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 3)
         return ErrorBadArgs(cx);
 
     int32_t byteStart;
-    Rooted<TypedArrayObject*> typedArray(cx);
+    RootedObject typedArray(cx);
     if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
         return false;
 
     if (!IsVectorObject<V>(args[2]))
         return ErrorBadArgs(cx);
 
     Elem *src = TypedObjectMemory<Elem*>(args[2]);
-    Elem *dst = reinterpret_cast<Elem*>(static_cast<char*>(typedArray->viewData()) + byteStart);
+    Elem *dst = reinterpret_cast<Elem*>(static_cast<char*>(AnyTypedArrayViewData(typedArray)) + byteStart);
     memcpy(dst, src, sizeof(Elem) * NumElem);
 
     args.rval().setObject(args[2].toObject());
     return true;
 }
 
 #define DEFINE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags) \
 bool                                                                \
--- a/js/src/devtools/automation/autospider.sh
+++ b/js/src/devtools/automation/autospider.sh
@@ -106,39 +106,32 @@ else
     export AR=ar
   fi
 fi
 
 $SOURCE/js/src/configure $CONFIGURE_ARGS --enable-nspr-build --prefix=$OBJDIR/dist || exit 2
 $MAKE -s -w -j4 || exit 2
 cp -p $SOURCE/build/unix/run-mozilla.sh $OBJDIR/dist/bin
 
-# The root analysis tests run in a special GC Zeal mode and disable ASLR to
-# make tests reproducible.
 COMMAND_PREFIX=''
+
+# On Linux, disable ASLR to make shell builds a bit more reproducible.
+if type setarch >/dev/null 2>&1; then
+    COMMAND_PREFIX="setarch $(uname -m) -R "
+fi
+
 if [[ "$VARIANT" = "rootanalysis" ]]; then
     export JS_GC_ZEAL=7
 
-    # rootanalysis builds are currently only done on Linux, which should have
-    # setarch, but just in case we enable them on another platform:
-    if type setarch >/dev/null 2>&1; then
-        COMMAND_PREFIX="setarch $(uname -m) -R "
-    fi
 elif [[ "$VARIANT" = "generational" ]]; then
     # Generational is currently being used for compacting GC
     export JS_GC_ZEAL=14
 
     # Ignore timeouts from tests that are known to take too long with this zeal mode
     export JITTEST_EXTRA_ARGS=--ignore-timeouts=$ABSDIR/cgc-jittest-timeouts.txt
-
-    # rootanalysis builds are currently only done on Linux, which should have
-    # setarch, but just in case we enable them on another platform:
-    if type setarch >/dev/null 2>&1; then
-        COMMAND_PREFIX="setarch $(uname -m) -R "
-    fi
 fi
 
 $COMMAND_PREFIX $MAKE check || exit 1
 $COMMAND_PREFIX $MAKE check-jit-test || exit 1
 if [[ "$VARIANT" != "generational" ]]; then
     $COMMAND_PREFIX $MAKE check-jstests || exit 1
 fi
 $COMMAND_PREFIX $OBJDIR/dist/bin/jsapi-tests || exit 1
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6287,17 +6287,20 @@ Parser<ParseHandler>::assignExpr(Invoked
         tokenStream.ungetToken();
         return lhs;
     }
 
     AssignmentFlavor flavor = kind == PNK_ASSIGN ? PlainAssignment : CompoundAssignment;
     if (!checkAndMarkAsAssignmentLhs(lhs, flavor))
         return null();
 
+    bool saved = pc->inDeclDestructuring;
+    pc->inDeclDestructuring = false;
     Node rhs = assignExpr();
+    pc->inDeclDestructuring = saved;
     if (!rhs)
         return null();
 
     return handler.newAssignment(kind, lhs, rhs, pc, op);
 }
 
 static const char incop_name_str[][10] = {"increment", "decrement"};
 
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -1000,17 +1000,17 @@ Statistics::beginSlice(const ZoneGCStats
 
     runtime->addTelemetry(JS_TELEMETRY_GC_REASON, reason);
 
     // Slice callbacks should only fire for the outermost level
     if (++gcDepth == 1) {
         bool wasFullGC = zoneStats.isCollectingAllZones();
         if (sliceCallback)
             (*sliceCallback)(runtime, first ? JS::GC_CYCLE_BEGIN : JS::GC_SLICE_BEGIN,
-                             JS::GCDescription(!wasFullGC));
+                             JS::GCDescription(!wasFullGC, gckind));
     }
 }
 
 void
 Statistics::endSlice()
 {
     if (!aborted) {
         slices.back().end = PRMJ_Now();
@@ -1024,17 +1024,17 @@ Statistics::endSlice()
     if (last)
         endGC();
 
     // Slice callbacks should only fire for the outermost level
     if (--gcDepth == 0) {
         bool wasFullGC = zoneStats.isCollectingAllZones();
         if (sliceCallback)
             (*sliceCallback)(runtime, last ? JS::GC_CYCLE_END : JS::GC_SLICE_END,
-                             JS::GCDescription(!wasFullGC));
+                             JS::GCDescription(!wasFullGC, gckind));
     }
 
     /* Do this after the slice callback since it uses these values. */
     if (last)
         PodArrayZero(counts);
 }
 
 void
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/destructuring-default-value-scope.js
@@ -0,0 +1,10 @@
+var a = 10;
+function f1(a,
+            [b=(assertEq(a, 1), a=2, 42)],
+            {c:c=(assertEq(a, 2), a=3, 43)}) {
+  assertEq(a, 3);
+  assertEq(b, 42);
+  assertEq(c, 43);
+}
+f1(1, [], {});
+assertEq(a, 10);
--- a/js/src/jit-test/tests/asm.js/simd-fbirds.js
+++ b/js/src/jit-test/tests/asm.js/simd-fbirds.js
@@ -39,40 +39,40 @@ function addBird(pos, vel) {
 
 function getActualBirds() {
     return actualBirds;
 }
 
 var code = `
     "use asm";
     var toF = global.Math.fround;
+    var u8 = new global.Uint8Array(buffer);
     var f32 = new global.Float32Array(buffer);
     const maxBirds = 100000;
     const maxBirdsx4 = 400000;
-    const maxBirdsx4Plus4 = 400004;
-    const maxBirdsx4Plus8 = 400008;
-    const maxBirdsx4Plus12 = 400012;
     const maxBirdsx8 = 800000;
     const accelMask = 0x3c;
-    const mk2 = 0x000ffffc;
+    const mk4 = 0x000ffff0;
 
     const getMaxPos = 1000.0;
     const getAccelDataSteps = imp.accelDataSteps | 0;
     var getActualBirds = imp.getActualBirds;
 
     var i4 = global.SIMD.int32x4;
     var f4 = global.SIMD.float32x4;
     var i4add = i4.add;
     var i4and = i4.and;
     var f4select = f4.select;
     var f4add = f4.add;
     var f4sub = f4.sub;
     var f4mul = f4.mul;
     var f4greaterThan = f4.greaterThan;
     var f4splat = f4.splat;
+    var f4load = f4.load;
+    var f4store = f4.store;
 
     const zerox4 = f4(0.0,0.0,0.0,0.0);
 
     function declareHeapSize() {
         f32[0x0007ffff] = toF(0.0);
     }
 
     function update(timeDelta) {
@@ -105,50 +105,36 @@ var code = `
         maxPosx4 = f4splat(maxPos);
         subTimeDeltax4 = f4splat(subTimeDelta);
         subTimeDeltaSquaredx4 = f4mul(subTimeDeltax4, subTimeDeltax4);
 
         len = ((actualBirds + 3) >> 2) << 4;
 
         for (i = 0; (i | 0) < (len | 0); i = (i + 16) | 0) {
             accelIndex = 0;
-            // Work around unimplemented Float32x4Array
-            newPosx4 = f4(toF(f32[(i & mk2) >> 2]),
-                    toF(f32[(i & mk2) + 4 >> 2]),
-                    toF(f32[(i & mk2) + 8 >> 2]),
-                    toF(f32[(i & mk2) + 12 >> 2]));
-            newVelx4 = f4(toF(f32[(i & mk2) + maxBirdsx4 >> 2]),
-                    toF(f32[(i & mk2) + maxBirdsx4Plus4 >> 2]),
-                    toF(f32[(i & mk2) + maxBirdsx4Plus8 >> 2]),
-                    toF(f32[(i & mk2) + maxBirdsx4Plus12 >> 2]));
+            newPosx4 = f4load(u8, i & mk4);
+            newVelx4 = f4load(u8, (i & mk4) + maxBirdsx4);
             for (a = 0; (a | 0) < (steps | 0); a = (a + 1) | 0) {
                 accel = toF(f32[(accelIndex & accelMask) + maxBirdsx8 >> 2]);
                 accelx4 = f4splat(accel);
                 accelIndex = (accelIndex + 4) | 0;
                 posDeltax4 = f4mul(point5x4, f4mul(accelx4, subTimeDeltaSquaredx4));
                 posDeltax4 = f4add(posDeltax4, f4mul(newVelx4, subTimeDeltax4));
                 newPosx4 = f4add(newPosx4, posDeltax4);
                 newVelx4 = f4add(newVelx4, f4mul(accelx4, subTimeDeltax4));
                 cmpx4 = f4greaterThan(newPosx4, maxPosx4);
 
                 if (cmpx4.signMask) {
                     // Work around unimplemented 'neg' operation, using 0 - x.
                     newVelTruex4 = f4sub(zerox4, newVelx4);
                     newVelx4 = f4select(cmpx4, newVelTruex4, newVelx4);
                 }
             }
-            // Work around unimplemented Float32x4Array
-            f32[(i & mk2) >> 2] = newPosx4.x;
-            f32[(i & mk2) + 4 >> 2] = newPosx4.y;
-            f32[(i & mk2) + 8 >> 2] = newPosx4.z;
-            f32[(i & mk2) + 12 >> 2] = newPosx4.w;
-            f32[(i & mk2) + maxBirdsx4 >> 2] = newVelx4.x;
-            f32[(i & mk2) + maxBirdsx4Plus4 >> 2] = newVelx4.y;
-            f32[(i & mk2) + maxBirdsx4Plus8 >> 2] = newVelx4.z;
-            f32[(i & mk2) + maxBirdsx4Plus12 >> 2] = newVelx4.w;
+            f4store(u8, i & mk4, newPosx4);
+            f4store(u8, (i & mk4) + maxBirdsx4, newVelx4);
         }
     }
 
     return update;
 `
 
 var ffi = {
     getActualBirds,
--- a/js/src/jit-test/tests/asm.js/testFFI.js
+++ b/js/src/jit-test/tests/asm.js/testFFI.js
@@ -146,20 +146,18 @@ function ffiOOLConvertInt(n) { if (n == 
 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i >> 0) | 0; } return f'), null, {ffi:ffiOOLConvertInt});
 for (var i = 0; i < 40; i++)
     assertEq(f(i), 42);
 valueToConvert = INT32_MAX + 1;
 assertEq(f(40), INT32_MAX + 1 | 0);
 function testBadConversions(f) {
     valueToConvert = {valueOf: function () { throw "FAIL"; }};
     assertThrowsValue(() => f(40), "FAIL");
-    if (typeof Symbol === "function") {
-        valueToConvert = Symbol();
-        assertThrowsInstanceOf(() => f(40), TypeError);
-    }
+    valueToConvert = Symbol();
+    assertThrowsInstanceOf(() => f(40), TypeError);
 }
 testBadConversions(f);
 
 function ffiOOLConvertDouble(n) { if (n == 40) return valueToConvert; return 42.5; }
 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return +ffi(i >> 0); } return f'), null, {ffi:ffiOOLConvertDouble});
 for (var i = 0; i < 40; i++)
     assertEq(f(i), 42.5);
 valueToConvert = {valueOf: function() { return 13.37 }};
--- a/js/src/jit-test/tests/asm.js/testGlobals.js
+++ b/js/src/jit-test/tests/asm.js/testGlobals.js
@@ -111,21 +111,19 @@ assertEq(asmLink(asmCompile('global', 'i
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4);
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4);
 assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var i=42; while (1) { break; } g = i; return g|0 } return f"))(), 42);
 assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}});
 assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}});
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f'), null, {x:"blah"})(), 0);
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() { return +i} return f'), null, {x:"blah"})(), NaN);
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f'), this, {x:"blah"})(), NaN);
-if (typeof Symbol === "function") {
-    assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f')(null, {x:Symbol("blah")}), TypeError);
-    assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = +foreign.x; function f() { return +i} return f')(null, {x:Symbol("blah")}), TypeError);
-    assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f')(this, {x:Symbol("blah")}), TypeError);
-}
+assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f')(null, {x:Symbol("blah")}), TypeError);
+assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = +foreign.x; function f() { return +i} return f')(null, {x:Symbol("blah")}), TypeError);
+assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f')(this, {x:Symbol("blah")}), TypeError);
 
 // Temporary workaround; this test can be removed when Emscripten is fixed and
 // the fix has propagated out to most apps:
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.i|0; function f() { return i|0} return f'), null, {i:function(){}})(), 0);
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.i; function f() { return +i} return f'), null, {i:function(){}})(), NaN);
 assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.i); function f() { return +i} return f'), this, {i:function(){}})(), NaN);
 var module = asmCompile('glob','foreign', USE_ASM + 'var i = foreign.i|0; function f() { return i|0} return f');
 var fun = function() {}
--- a/js/src/jit-test/tests/basic/symbol-in-loop.js
+++ b/js/src/jit-test/tests/basic/symbol-in-loop.js
@@ -1,9 +1,8 @@
 function f() {
-    if (typeof Symbol === "function")
-        return Object(Symbol());
+    return Object(Symbol());
 }
 
 for (var i = 0; i < 4; i++) {
     f();
     gc();
 }
--- a/js/src/jit-test/tests/debug/Debugger-debuggees-06.js
+++ b/js/src/jit-test/tests/debug/Debugger-debuggees-06.js
@@ -12,17 +12,16 @@ function check(val) {
 
 // Primitive values are invalid.
 check(undefined);
 check(null);
 check(false);
 check(1);
 check(NaN);
 check("ok");
-if (typeof Symbol === "function")
-    check(Symbol("ok"));
+check(Symbol("ok"));
 
 // A Debugger.Object that belongs to a different Debugger object is invalid.
 var g = newGlobal();
 var dbg2 = new Debugger;
 var w = dbg2.addDebuggee(g);
 assertEq(w instanceof Debugger.Object, true);
 check(w);
--- a/js/src/jit-test/tests/debug/Environment-names-02.js
+++ b/js/src/jit-test/tests/debug/Environment-names-02.js
@@ -13,24 +13,22 @@ g.h = function () {
 
 g.eval("" +
        function fill(obj) {
            obj.sanityCheck = 1;
            obj["0xcafe"] = 2;
            obj[" "] = 3;
            obj[""] = 4;
            obj[0] = 5;
-           if (typeof Symbol === "function")
-               obj[Symbol.for("moon")] = 6;
+           obj[Symbol.for("moon")] = 6;
            return obj;
        })
 g.eval("fill(this);\n" +
        "with (fill({})) h();");
 
 for (var names of [withNames, globalNames]) {
     assertEq(names.indexOf("sanityCheck") !== -1, true);
     assertEq(names.indexOf("0xcafe"), -1);
     assertEq(names.indexOf(" "), -1);
     assertEq(names.indexOf(""), -1);
     assertEq(names.indexOf("0"), -1);
-    if (typeof Symbol === "function")
-        assertEq(names.indexOf(Symbol.for("moon")), -1);
+    assertEq(names.indexOf(Symbol.for("moon")), -1);
 }
--- a/js/src/jit-test/tests/debug/Frame-arguments-01.js
+++ b/js/src/jit-test/tests/debug/Frame-arguments-01.js
@@ -17,19 +17,17 @@ dbg.onDebuggerStatement = function (fram
 };
 
 // no formal parameters
 g.eval("function f() { debugger; }");
 
 hits = 0;
 g.eval("args = []; f();");
 g.eval("this.f();");
-g.eval("var world = 'world'; " +
-       "if (typeof Symbol === 'function') " +
-       "    Symbol('world'); " +
+g.eval("var world = Symbol('world'); " +
        "args = ['hello', world, 3.14, true, false, null, undefined]; " +
        "f('hello', world, 3.14, true, false, null, undefined);");
 g.eval("f.apply(undefined, args);");
 g.eval("args = [-0, NaN, -1/0]; this.f(-0, NaN, -1/0);");
 assertEq(hits, 5);
 
 // with formal parameters
 g.eval("function f(a, b) { debugger; }");
--- a/js/src/jit-test/tests/debug/Frame-evalWithBindings-02.js
+++ b/js/src/jit-test/tests/debug/Frame-evalWithBindings-02.js
@@ -10,14 +10,12 @@ dbg.onDebuggerStatement = function (fram
     assertEq(frame.evalWithBindings("obj.toString()", {obj: obj}).return, expected);
     hits++;
 };
 
 g.eval("function f(obj, expected) { debugger; }");
 
 g.eval("f(new Number(-0), '0');");
 g.eval("f(new String('ok'), 'ok');");
-if (typeof Symbol === "function") {
-    g.eval("f(Symbol('still ok'), 'Symbol(still ok)');");
-    g.eval("f(Object(Symbol('still ok')), 'Symbol(still ok)');");
-}
+g.eval("f(Symbol('still ok'), 'Symbol(still ok)');");
+g.eval("f(Object(Symbol('still ok')), 'Symbol(still ok)');");
 g.eval("f({toString: function () { return f; }}, f);");
-assertEq(hits, typeof Symbol === "function" ? 5 : 3);
+assertEq(hits, 5);
--- a/js/src/jit-test/tests/debug/Frame-evalWithBindings-03.js
+++ b/js/src/jit-test/tests/debug/Frame-evalWithBindings-03.js
@@ -7,11 +7,10 @@ dbg.onDebuggerStatement = function (fram
     var argc = frame.arguments.length;
     assertEq(argc, 8);
     assertEq(frame.evalWithBindings("arguments[prop]", {prop: "length"}).return, argc);
     for (var i = 0; i < argc; i++)
         assertEq(frame.evalWithBindings("arguments[i]", {i: i}).return, frame.arguments[i]);
     hits++;
 };
 g.eval("function f() { debugger; }");
-var symbolExpr = typeof Symbol === "function" ? "Symbol('alpha')" : "'alpha'";
-g.eval("f(undefined, -0, NaN, '\uffff', " + symbolExpr + ", Array.prototype, Math, f);");
+g.eval("f(undefined, -0, NaN, '\uffff', Symbol('alpha'), Array.prototype, Math, f);");
 assertEq(hits, 1);
--- a/js/src/jit-test/tests/debug/Frame-onPop-17.js
+++ b/js/src/jit-test/tests/debug/Frame-onPop-17.js
@@ -18,18 +18,17 @@ function test(badValue) {
     g.eval("debugger");
     assertEq(log, "d");
 }
 
 test(null);
 test(false);
 test(1);
 test("stringy");
-if (typeof Symbol === "function")
-    test(Symbol("symbolic"));
+test(Symbol("symbolic"));
 test({});
 test([]);
 
 // Getting and setting the prototype's onPop is an error.
 assertThrowsInstanceOf(function () { Debugger.Frame.prototype.onPop; }, TypeError);
 assertThrowsInstanceOf(
     function () { Debugger.Frame.prototype.onPop = function () {}; },
     TypeError);
--- a/js/src/jit-test/tests/debug/Frame-this-01.js
+++ b/js/src/jit-test/tests/debug/Frame-this-01.js
@@ -11,16 +11,14 @@ dbg.onDebuggerStatement = function (fram
 g.eval("function f() { 'use strict'; debugger; }");
 
 g.eval("Boolean.prototype.f = f; v = true; v.f();");
 g.eval("f.call(v);");
 g.eval("Number.prototype.f = f; v = 3.14; v.f();");
 g.eval("f.call(v);");
 g.eval("String.prototype.f = f; v = 'hello'; v.f();");
 g.eval("f.call(v);");
-if (typeof Symbol === "function") {
-    g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
-    g.eval("f.call(v);");
-}
+g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
+g.eval("f.call(v);");
 g.eval("v = undefined; f.call(v);");
 g.eval("v = null; f.call(v);");
 
-assertEq(hits, typeof Symbol === "function" ? 10 : 8);
+assertEq(hits, 10);
--- a/js/src/jit-test/tests/debug/Frame-this-03.js
+++ b/js/src/jit-test/tests/debug/Frame-this-03.js
@@ -16,16 +16,14 @@ dbg.onDebuggerStatement = function (fram
 g.eval("function f() { debugger; }");
 
 g.eval("Boolean.prototype.f = f; v = true; v.f();");
 g.eval("f.call(v);");
 g.eval("Number.prototype.f = f; v = 3.14; v.f();");
 g.eval("f.call(v);");
 g.eval("String.prototype.f = f; v = 'hello'; v.f();");
 g.eval("f.call(v);");
-if (typeof Symbol === "function") {
-    g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
-    g.eval("f.call(v);");
-}
+g.eval("Symbol.prototype.f = f; v = Symbol('world'); v.f();");
+g.eval("f.call(v);");
 g.eval("v = undefined; f.call(v);");
 g.eval("v = null; f.call(v);");
 
-assertEq(hits, typeof Symbol === "function" ? 10 : 8);
+assertEq(hits, 10);
--- a/js/src/jit-test/tests/debug/Object-getOwnPropertyNames-01.js
+++ b/js/src/jit-test/tests/debug/Object-getOwnPropertyNames-01.js
@@ -21,15 +21,13 @@ test("Object.create({a: 1})");
 test("Object.create({get a() {}, set a(v) {}})");
 test("(function () { var x = {a: 0, b: 1}; delete a; return x; })()");
 test("Object.create(null, {x: {value: 0}})");
 test("[]");
 test("[0, 1, 2]");
 test("[,,,,,]");
 test("/a*a/");
 test("function () {}");
-if (typeof Symbol === "function") {
-    test("(function () {\n" +
-         "    var x = {};\n" +
-         "    x[Symbol()] = 1; x[Symbol.for('moon')] = 2; x[Symbol.iterator] = 3;\n" +
-         "    return x;\n" + 
-         "})()");
-}
+test("(function () {\n" +
+     "    var x = {};\n" +
+     "    x[Symbol()] = 1; x[Symbol.for('moon')] = 2; x[Symbol.iterator] = 3;\n" +
+     "    return x;\n" + 
+     "})()");
--- a/js/src/jit-test/tests/debug/Object-getOwnPropertyNames-02.js
+++ b/js/src/jit-test/tests/debug/Object-getOwnPropertyNames-02.js
@@ -1,13 +1,12 @@
 // obj.getOwnPropertyNames() works when obj's referent is itself a cross-compartment wrapper.
 
 var g = newGlobal();
 var dbg = Debugger();
 var gobj = dbg.addDebuggee(g);
 g.p = {xyzzy: 8};  // makes a cross-compartment wrapper
-if (typeof Symbol === "function")
-    g.p[Symbol.for("plugh")] = 9;
+g.p[Symbol.for("plugh")] = 9;
 var wp = gobj.getOwnPropertyDescriptor("p").value;
 var names = wp.getOwnPropertyNames();
 assertEq(names.length, 1);
 assertEq(names[0], "xyzzy");
 
--- a/js/src/jit-test/tests/debug/Object-makeDebuggeeValue-01.js
+++ b/js/src/jit-test/tests/debug/Object-makeDebuggeeValue-01.js
@@ -33,12 +33,10 @@ assertEq(wx.getOwnPropertyDescriptor("br
 // Non-objects are already debuggee values.
 assertEq(gw.makeDebuggeeValue("foonting turlingdromes"), "foonting turlingdromes");
 assertEq(gw.makeDebuggeeValue(true), true);
 assertEq(gw.makeDebuggeeValue(false), false);
 assertEq(gw.makeDebuggeeValue(null), null);
 assertEq(gw.makeDebuggeeValue(1729), 1729);
 assertEq(gw.makeDebuggeeValue(Math.PI), Math.PI);
 assertEq(gw.makeDebuggeeValue(undefined), undefined);
-if (typeof Symbol === "function") {
-    var s = g.eval("Symbol('Stavromula Beta')");
-    assertEq(gw.makeDebuggeeValue(s), s);
-}
+var s = g.eval("Symbol('Stavromula Beta')");
+assertEq(gw.makeDebuggeeValue(s), s);
--- a/js/src/jit-test/tests/gc/bug-1032206.js
+++ b/js/src/jit-test/tests/gc/bug-1032206.js
@@ -1,5 +1,3 @@
-if (typeof Symbol === "function") {
-    gczeal(4);
-    var symbols = [Symbol(), Symbol("comet"), Symbol.for("moon"), Symbol.iterator, 0];
-    for (var a of symbols) {}
-}
+gczeal(4);
+var symbols = [Symbol(), Symbol("comet"), Symbol.for("moon"), Symbol.iterator, 0];
+for (var a of symbols) {}
--- a/js/src/jit-test/tests/gc/bug-1035371.js
+++ b/js/src/jit-test/tests/gc/bug-1035371.js
@@ -1,5 +1,4 @@
 x = function() {};
 y = new WeakMap;
 selectforgc({});;
-if (typeof Symbol === "function")
-    y.set(x, Symbol());
+y.set(x, Symbol());
--- a/js/src/jit-test/tests/gc/bug-1039516.js
+++ b/js/src/jit-test/tests/gc/bug-1039516.js
@@ -1,8 +1,6 @@
-if (typeof Symbol === "function") {
-    gczeal(9);
-    Symbol.for("a");
-    gcslice(1);
-    var a = Symbol.for("a");
-    gcslice();
-    print(Symbol.keyFor(a));
-}
+gczeal(9);
+Symbol.for("a");
+gcslice(1);
+var a = Symbol.for("a");
+gcslice();
+print(Symbol.keyFor(a));
--- a/js/src/jit-test/tests/heap-analysis/findPath.js
+++ b/js/src/jit-test/tests/heap-analysis/findPath.js
@@ -37,15 +37,13 @@ print(uneval(findPath(gc, o)));
 
 Match.Pattern([{node: {}, edge: "shape"},
                {node: Match.Pattern.ANY, edge: "base"},
                {node: Match.Pattern.ANY, edge: "parent"},
                {node: {}, edge: "o"}])
   .assert(findPath(o, o));
 print(findPath(o, o).map((e) => e.edge).toString());
 
-if (typeof Symbol === "function") {
-    // Check that we can generate ubi::Nodes for Symbols.
-    var so = { sym: Symbol() };
-    Match.Pattern([{node: {}, edge: "sym" }])
-      .assert(findPath(so, so.sym));
-    print(findPath(so, so.sym).map((e) => e.edge).toString());
-}
+// Check that we can generate ubi::Nodes for Symbols.
+var so = { sym: Symbol() };
+Match.Pattern([{node: {}, edge: "sym" }])
+  .assert(findPath(so, so.sym));
+print(findPath(so, so.sym).map((e) => e.edge).toString());
--- a/js/src/jit-test/tests/ion/bug1054753.js
+++ b/js/src/jit-test/tests/ion/bug1054753.js
@@ -1,16 +1,13 @@
 // |jit-test| error: TypeError
-if (typeof Symbol === "function") {
-    g = (function() {
-        var Int32ArrayView = new Int32Array();
-        function f() {
-            Int32ArrayView[Symbol() >> 2]
-        }
-        return f;
-    })();
-    try {
-        g();
-    } catch (e) {}
+g = (function() {
+    var Int32ArrayView = new Int32Array();
+    function f() {
+        Int32ArrayView[Symbol() >> 2]
+    }
+    return f;
+})();
+try {
     g();
-} else {
-    throw new TypeError("pass");
-}
+} catch (e) {}
+g();
+
--- a/js/src/jit-test/tests/ion/testFloat32.js
+++ b/js/src/jit-test/tests/ion/testFloat32.js
@@ -32,16 +32,22 @@
         for (c in this) {
             Array.prototype.unshift.call(x, new ArrayBuffer())
         }
         Array.prototype.sort.call(x, (function (j) {
             y.s = z[2]
         }))
     })();
     //
+    (function() {
+        // bug 1134298
+        for (var k = 0; k < 1; k++) {
+            Math.fround(Math.ceil(Math.fround(Math.acos(3.0))))
+        }
+    })();
 })();
 //
 // ION TESTS
 //
 // The assertFloat32 function is deactivated in --ion-eager mode, as the first time, the function Math.fround
 // would be guarded against modifications (typeguard on Math and then on fround). In this case, Math.fround is
 // not inlined and the compiler will consider the return value to be a double, not a float32, making the
 // assertions fail. Note that as assertFloat32 is declared unsafe for fuzzing, this can't happen in fuzzed code.
--- a/js/src/jit-test/tests/pic/watch5.js
+++ b/js/src/jit-test/tests/pic/watch5.js
@@ -1,29 +1,27 @@
 // test against future pic support for symbols
 
-if (typeof Symbol === "function") {
-    // assignments to watched objects must not be cached
-    var obj = {};
-    var x = Symbol.for("x");
-    obj[x] = 0;
-    var hits = 0;
-    obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
-    for (var i = 0; i < 10; i++)
-        obj[x] = i;
-    assertEq(hits, 10);
+// assignments to watched objects must not be cached
+var obj = {};
+var x = Symbol.for("x");
+obj[x] = 0;
+var hits = 0;
+obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
+for (var i = 0; i < 10; i++)
+    obj[x] = i;
+assertEq(hits, 10);
 
-    // assignments to watched properties via ++ must not be cached
-    hits = 0;
-    for (var i = 0; i < 10; i++)
-        obj[x]++;
-    assertEq(hits, 10);
+// assignments to watched properties via ++ must not be cached
+hits = 0;
+for (var i = 0; i < 10; i++)
+    obj[x]++;
+assertEq(hits, 10);
 
-    // adding assignment + watchpoint vs. caching
-    hits = 0;
-    obj = {};
-    obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
-    for (var i = 0; i < 10; i++) {
-        obj[x] = 1;
-        delete obj[x];
-    }
-    assertEq(hits, 10);
+// adding assignment + watchpoint vs. caching
+hits = 0;
+obj = {};
+obj.watch(x, function (id, oldval, newval) { hits++; return newval; });
+for (var i = 0; i < 10; i++) {
+    obj[x] = 1;
+    delete obj[x];
 }
+assertEq(hits, 10);
--- a/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty1.js
@@ -10,17 +10,14 @@ function testProxy(p, key) {
     });
     var desc = Object.getOwnPropertyDescriptor(target, key);
     assertEq(desc.value, 'bar');
     assertEq(desc.writable, true);
     assertEq(desc.enumerable, false);
     assertEq(desc.configurable, true);
 }
 
-var keys = ['foo'];
-if (typeof Symbol === "function")
-    keys.push(Symbol("quux"));
-for (var key of keys) {
+for (var key of ['foo', Symbol("quux")]) {
     target = {};
     testProxy(new Proxy(target, {}), key);
     target = {};
     testProxy(Proxy.revocable(target, {}).proxy, key);
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty2.js
@@ -18,20 +18,16 @@ var handler = {
 };
 var desc = {
     value: 'bar',
     writable: true,
     enumerable: false,
     configurable: true
 };
 
-function quux() {
-    return typeof Symbol === "function" ? Symbol.for('quux') : 'quux';
-}
-
 for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
     var log = [];
     Object.defineProperty(p, 'foo', desc);
-    Object.defineProperty(p, quux(), desc);
+    Object.defineProperty(p, Symbol.for('quux'), desc);
     assertEq(log.length, 2);
     assertEq(log[0], 'foo');
-    assertEq(log[1], quux());
+    assertEq(log[1], Symbol.for('quux'));
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyGet1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyGet1.js
@@ -1,14 +1,12 @@
 // Forward to the target if the trap is not defined
 var target = { foo: 'bar' };
 for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
     assertEq(p.foo, 'bar');
     assertEq(p['foo'], 'bar');
 }
 
-if (typeof Symbol === "function") {
-    var s = Symbol.for("moon");
-    var obj = {};
-    obj[s] = "dust";
-    for (let p of [new Proxy(obj, {}), Proxy.revocable(obj, {}).proxy])
-        assertEq(p[s], "dust");
-}
+var s = Symbol.for("moon");
+var obj = {};
+obj[s] = "dust";
+for (let p of [new Proxy(obj, {}), Proxy.revocable(obj, {}).proxy])
+    assertEq(p[s], "dust");
--- a/js/src/jit-test/tests/proxy/testDirectProxyGet2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyGet2.js
@@ -1,18 +1,15 @@
 /*
  * Call the trap with the handler as the this value, the target as the first
  * argument, the name of the property as the second argument, and the receiver
  * as the third argument
  */
 var target = {};
-var keys = ['foo'];
-if (typeof Symbol === "function")
-    keys.push(Symbol.iterator);
-for (var key of keys) {
+for (var key of ['foo', Symbol.iterator]) {
     handler = {};
     for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
         handler.get =
             function (target1, name, receiver) {
                 assertEq(this, handler);
                 assertEq(target1, target);
                 assertEq(name, key);
                 assertEq(receiver, p);
--- a/js/src/jit-test/tests/proxy/testDirectProxyGet5.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyGet5.js
@@ -1,20 +1,16 @@
 // Return the trap result
 var target = { foo: 'bar' };
-if (typeof Symbol === "function") {
-    var s1 = Symbol("moon"), s2 = Symbol("sun");
-    target[s1] = "wrong";
-}
+var s1 = Symbol("moon"), s2 = Symbol("sun");
+target[s1] = "wrong";
 
 var handler = { };
 for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
     handler.get = (() => 'baz');
     assertEq(p.foo, 'baz');
 
     handler.get = (() => undefined);
     assertEq(p.foo, undefined);
 
-    if (typeof Symbol === "function") {
-        handler.get = (() => s2);
-        assertEq(p[s1], s2);
-    }
+    handler.get = (() => s2);
+    assertEq(p[s1], s2);
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyGetOwnPropertyNames1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyGetOwnPropertyNames1.js
@@ -16,16 +16,15 @@ var objCD = Object.create(objAB, {
         configurable: true
     },
     d: {
         enumerable: false,
         configurable: true
     }
 });
 
-if (typeof Symbol === "function")
-    objCD[Symbol("moon")] = "something";
+objCD[Symbol("moon")] = "something";
 for (let p of [new Proxy(objCD, {}), Proxy.revocable(objCD, {}).proxy]) {
     var names = Object.getOwnPropertyNames(p);
     assertEq(names.length, 2);
     assertEq(names[0], 'c');
     assertEq(names[1], 'd');
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyHas1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyHas1.js
@@ -9,11 +9,10 @@ var target = Object.create(proto, {
         configurable: true
     }
 });
 
 for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
     assertEq('foo' in p, true);
     assertEq('bar' in p, true);
     assertEq('baz' in p, false);
-    if (typeof Symbol === "function")
-        assertEq(Symbol() in p, false);
+    assertEq(Symbol() in p, false);
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyHas2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyHas2.js
@@ -1,17 +1,14 @@
 /*
  * Call the trap with the handler as the this value, the target as the first
  * argument, and the name of the property as the second argument
  */
 var target = {};
-var keys = ['foo'];
-if (typeof Symbol === "function")
-    keys.push(Symbol('bar'));
-for (var key of keys) {
+for (var key of ['foo', Symbol('bar')]) {
     var called;
     var handler = {
         has: function (target1, name) {
             assertEq(this, handler);
             assertEq(target1, target);
             assertEq(name, key);
             called = true;
         }
--- a/js/src/jit-test/tests/proxy/testDirectProxyHas6.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyHas6.js
@@ -4,11 +4,10 @@
  */
 var target = {};
 Object.preventExtensions(target);
 
 var handler = { has: () => false };
 
 for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
     assertEq('foo' in p, false);
-    if (typeof Symbol === "function")
-        assertEq(Symbol.iterator in p, false);
+    assertEq(Symbol.iterator in p, false);
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxyHasOwnProperty.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyHasOwnProperty.js
@@ -4,29 +4,26 @@ var proto = Object.create(null, {
         configurable: true
     }
 });
 var descs = {
     'bar': {
         configurable: true
     }
 };
-if (typeof Symbol === "function")
-    descs[Symbol.for("quux")] = {configurable: true};
+descs[Symbol.for("quux")] = {configurable: true};
 var target = Object.create(proto, descs);
 
 for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
     assertEq(({}).hasOwnProperty.call(p, 'foo'), false);
     assertEq(({}).hasOwnProperty.call(p, 'bar'), true);
     assertEq(({}).hasOwnProperty.call(p, 'quux'), false);
-    if (typeof Symbol === "function") {
-        assertEq(({}).hasOwnProperty.call(p, Symbol('quux')), false);
-        assertEq(({}).hasOwnProperty.call(p, 'Symbol(quux)'), false);
-        assertEq(({}).hasOwnProperty.call(p, Symbol.for('quux')), true);
-    }
+    assertEq(({}).hasOwnProperty.call(p, Symbol('quux')), false);
+    assertEq(({}).hasOwnProperty.call(p, 'Symbol(quux)'), false);
+    assertEq(({}).hasOwnProperty.call(p, Symbol.for('quux')), true);
 }
 
 // Make sure only the getOwnPropertyDescriptor trap is called, and not the has
 // trap.
 var called;
 var handler = { getOwnPropertyDescriptor: function () { called = true; },
                 has: function () { assertEq(false, true, "has trap must not be called"); }
               }
--- a/js/src/jit-test/tests/proxy/testDirectProxySet1.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxySet1.js
@@ -5,16 +5,14 @@ var target = {
 for (let p of [new Proxy(target, {}), Proxy.revocable(target, {}).proxy]) {
     // The sets from the first iteration will affect target, but it doesn't
     // matter, since the effectiveness of the foo sets is still observable.
     p.foo = 'baz';
     assertEq(target.foo, 'baz');
     p['foo'] = 'buz';
     assertEq(target.foo, 'buz');
 
-    if (typeof Symbol === "function") {
-        var sym = Symbol.for('quux');
-        p[sym] = sym;
-        assertEq(target[sym], sym);
-        // Reset for second iteration
-        target[sym] = undefined;
-    }
+    var sym = Symbol.for('quux');
+    p[sym] = sym;
+    assertEq(target[sym], sym);
+    // Reset for second iteration
+    target[sym] = undefined;
 }
--- a/js/src/jit-test/tests/proxy/testDirectProxySet2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxySet2.js
@@ -1,18 +1,15 @@
 /*
  * Call the trap with the handler as the this value, the target as the first
  * argument, the name of the property as the second argument, the value as the
  * third argument, and the receiver as the fourth argument
  */
 var target = {};
-var keys = ['foo'];
-if (typeof Symbol === "function")
-    keys.push(Symbol.for('quux'));
-for (var key of keys) {
+for (var key of ['foo', Symbol.for('quux')]) {
     var handler = { };
     for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy]) {
         handler.set = function (target1, name, val, receiver) {
             assertEq(this, handler);
             assertEq(target1, target);
             assertEq(name, key);
             assertEq(val, 'baz');
             assertEq(receiver, p);
--- a/js/src/jit-test/tests/proxy/testDirectProxySet3.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxySet3.js
@@ -1,15 +1,12 @@
 load(libdir + "asserts.js");
 
 // Throw a TypeError if the trap sets a non-writable, non-configurable property
-var keys = ['foo'];
-if (typeof Symbol === "function")
-    keys.push(Symbol.for('quux'));
-for (var key of keys) {
+for (var key of ['foo', Symbol.for('quux')]) {
     var target = {};
     Object.defineProperty(target, key, {
         value: 'bar',
         writable: false,
         configurable: false
     });
     var handler = { set: () => true };
     for (let p of [new Proxy(target, handler), Proxy.revocable(target, handler).proxy])
--- a/js/src/jit-test/tests/self-test/assertDeepEq.js
+++ b/js/src/jit-test/tests/self-test/assertDeepEq.js
@@ -9,34 +9,32 @@ function assertNotDeepEq(a, b, options) 
 // primitives
 assertDeepEq(undefined, undefined);
 assertDeepEq("1", "1");
 assertNotDeepEq(1, "1");
 assertNotDeepEq(undefined, null);
 assertNotDeepEq({}, null);
 
 // symbols
-if (typeof Symbol === "function") {
-    assertDeepEq(Symbol(), Symbol());
-    assertNotDeepEq(Symbol(), Symbol(""));
-    assertDeepEq(Symbol("tweedledum"), Symbol("tweedledum"));
-    assertNotDeepEq(Symbol("tweedledum"), Symbol("alice"));
-    assertNotDeepEq(Symbol("what-its-called"), Symbol.for("what-its-called"));
-    assertNotDeepEq(Symbol.iterator, Symbol.for("Symbol.iterator"));
-    assertDeepEq([Symbol(), Symbol(), Symbol()],
-                 [Symbol(), Symbol(), Symbol()]);
-    var sym = Symbol();
-    assertDeepEq([sym, sym], [sym, sym]);
-    assertNotDeepEq([sym, sym], [Symbol(), Symbol()]);
-    assertNotDeepEq([sym, sym], [Symbol(), sym]);
-    var obj1 = {}, obj2 = {};
-    obj1[Symbol("x")] = "y";
-    obj2[Symbol("x")] = "y";
-    assertDeepEq(obj1, obj2);
-}
+assertDeepEq(Symbol(), Symbol());
+assertNotDeepEq(Symbol(), Symbol(""));
+assertDeepEq(Symbol("tweedledum"), Symbol("tweedledum"));
+assertNotDeepEq(Symbol("tweedledum"), Symbol("alice"));
+assertNotDeepEq(Symbol("what-its-called"), Symbol.for("what-its-called"));
+assertNotDeepEq(Symbol.iterator, Symbol.for("Symbol.iterator"));
+assertDeepEq([Symbol(), Symbol(), Symbol()],
+             [Symbol(), Symbol(), Symbol()]);
+var sym = Symbol();
+assertDeepEq([sym, sym], [sym, sym]);
+assertNotDeepEq([sym, sym], [Symbol(), Symbol()]);
+assertNotDeepEq([sym, sym], [Symbol(), sym]);
+var obj1 = {}, obj2 = {};
+obj1[Symbol("x")] = "y";
+obj2[Symbol("x")] = "y";
+assertDeepEq(obj1, obj2);
 
 // objects
 assertDeepEq({}, {});
 assertDeepEq({one: 1, two: 2}, {one: 1, two: 2});
 assertNotDeepEq(Object.freeze({}), {});
 assertDeepEq(Object.create(null), Object.create(null));
 assertNotDeepEq(Object.create(null, {a: {configurable: false, value: 3}}),
                Object.create(null, {a: {configurable: true, value: 3}}));
--- a/js/src/jit-test/tests/symbol/bug-1033856.js
+++ b/js/src/jit-test/tests/symbol/bug-1033856.js
@@ -1,12 +1,6 @@
-function sym() {
-    return typeof Symbol === "function" ? Symbol() : "non-symbol";
-}
-
 function f(x, y) {
     return x == y;
 }
-
 f(1.1, 2.2);
 for (var i=0; i<5; i++)
-    f(1, sym());
-
+    f(1, Symbol());
--- a/js/src/jit-test/tests/symbol/not.js
+++ b/js/src/jit-test/tests/symbol/not.js
@@ -1,14 +1,12 @@
-var sym = this.Symbol || (() => "truthy");
+for (var i = 0; i < 9; i++)
+    assertEq(!Symbol(), false, "symbols are truthy");
 
-for (var i = 0; i < 9; i++)
-    assertEq(!sym(), false, "symbols are truthy");
-
-var a = [0, 0, 0, 0, 0, sym(), sym()];
+var a = [0, 0, 0, 0, 0, Symbol(), Symbol()];
 var b = [];
 function f(i, v) {
     b[i] = !v;
 }
 for (var i = 0; i < a.length; i++)
     f(i, a[i]);
 assertEq(b[b.length - 3], true);
 assertEq(b[b.length - 2], false);
--- a/js/src/jit-test/tests/symbol/toNumber.js
+++ b/js/src/jit-test/tests/symbol/toNumber.js
@@ -1,55 +1,53 @@
 load(libdir + "asserts.js");
 
+var sym = Symbol();
+
 function add2(x) {
     return x + 2;
 }
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => add2(sym), TypeError);
 
 function sqr(x) {
     return x * x;
 }
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => sqr(sym), TypeError);
 
 function bit_or(x) {
     return x | x;
 }
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => bit_or(sym), TypeError);
 
 function bit_not(x) {
     return ~x;
 }
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => bit_not(sym), TypeError);
 
 function plus(x) {
     return +x;
 }
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => plus(sym), TypeError);
 
 function f(a, b) {
     return a + b;
 }
 
 function testPoly() {
     assertEq(f(20, 30), 50);
     assertEq(f("one", "two"), "onetwo");
     assertThrowsInstanceOf(() => f(Symbol("one"), Symbol("two")), TypeError);
     assertThrowsInstanceOf(() => f(Symbol("14"), 14), TypeError);
     assertThrowsInstanceOf(() => f(Symbol("14"), 13.719), TypeError);
     assertThrowsInstanceOf(() => f(14, Symbol("14")), TypeError);
     assertThrowsInstanceOf(() => f(13.719, Symbol("14")), TypeError);
 }
 
-if (typeof Symbol === "function") {
-    var sym = Symbol();
+for (var i = 0; i < 9; i++)
+    testPoly();
 
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => add2(sym), TypeError);
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => sqr(sym), TypeError);
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => bit_or(sym), TypeError);
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => bit_not(sym), TypeError);
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => plus(sym), TypeError);
-    for (var i = 0; i < 9; i++)
-        testPoly();
-
-    for (var i = 0; i < 9; i++)
-        assertThrowsInstanceOf(() => assertEq(f(Symbol("14"), "40"), NaN), TypeError);
-}
+for (var i = 0; i < 9; i++)
+    assertThrowsInstanceOf(() => assertEq(f(Symbol("14"), "40"), NaN), TypeError);
--- a/js/src/jit-test/tests/symbol/toString.js
+++ b/js/src/jit-test/tests/symbol/toString.js
@@ -1,13 +1,11 @@
 // ToString(symbol) throws a TypeError.
 
-if (typeof Symbol === "function") {
-    var N = 10, obj, hits = 0;
-    for (var i = 0; i < N; i++) {
-        try {
-            obj = new String(Symbol());
-        } catch (exc) {
-            hits++;
-        }
+var N = 10, obj, hits = 0;
+for (var i = 0; i < N; i++) {
+    try {
+        obj = new String(Symbol());
+    } catch (exc) {
+        hits++;
     }
-    assertEq(hits, N);
 }
+assertEq(hits, N);
--- a/js/src/jit-test/tests/symbol/truthiness.js
+++ b/js/src/jit-test/tests/symbol/truthiness.js
@@ -1,14 +1,12 @@
-var sym = this.Symbol || (() => "truthy");
+for (var i = 0; i < 9; i++)
+    assertEq(Symbol() ? 1 : 0, 1, "symbols are truthy");
 
-for (var i = 0; i < 9; i++)
-    assertEq(sym() ? 1 : 0, 1, "symbols are truthy");
-
-var a = [0, 0, 0, 0, 0, sym(), sym()];
+var a = [0, 0, 0, 0, 0, Symbol(), Symbol()];
 var b = [];
 function f(i, v) {
     b[i] = v ? "yes" : "no";
 }
 for (var i = 0; i < a.length; i++)
     f(i, a[i]);
 assertEq(b[b.length - 3], "no");
 assertEq(b[b.length - 2], "yes");
--- a/js/src/jit-test/tests/symbol/typed-arrays.js
+++ b/js/src/jit-test/tests/symbol/typed-arrays.js
@@ -1,31 +1,29 @@
 load(libdir + "asserts.js");
 
 var LENGTH = 1024, SYMBOL_INDEX = 999;
 
-if (typeof Symbol === "function") {
-    var big = [];
-    for (var i = 0; i < LENGTH; i++)
-        big[i] = (i === SYMBOL_INDEX ? Symbol.for("comet") : i);
-
-    var progress;
-    function copy(arr, big) {
-        for (var i = 0; i < LENGTH; i++) {
-            arr[i] = big[i];
-            progress = i;
-        }
-    }
+var big = [];
+for (var i = 0; i < LENGTH; i++)
+    big[i] = (i === SYMBOL_INDEX ? Symbol.for("comet") : i);
 
-    for (var T of [Uint8Array, Uint8ClampedArray, Int16Array, Float32Array]) {
-        // Typed array constructors convert symbols using ToNumber, which throws.
-        assertThrowsInstanceOf(() => new T(big), TypeError);
-
-        // Element assignment does the same.
-        var arr = new T(big.length);
-        for (var k = 0; k < 3; k++) {
-            progress = -1;
-            assertThrowsInstanceOf(() => copy(arr, big), TypeError);
-            assertEq(progress, SYMBOL_INDEX - 1);
-            assertEq(arr[SYMBOL_INDEX], 0);
-        }
+var progress;
+function copy(arr, big) {
+    for (var i = 0; i < LENGTH; i++) {
+        arr[i] = big[i];
+        progress = i;
     }
 }
+
+for (var T of [Uint8Array, Uint8ClampedArray, Int16Array, Float32Array]) {
+    // Typed array constructors convert symbols using ToNumber, which throws.
+    assertThrowsInstanceOf(() => new T(big), TypeError);
+
+    // Element assignment does the same.
+    var arr = new T(big.length);
+    for (var k = 0; k < 3; k++) {
+        progress = -1;
+        assertThrowsInstanceOf(() => copy(arr, big), TypeError);
+        assertEq(progress, SYMBOL_INDEX - 1);
+        assertEq(arr[SYMBOL_INDEX], 0);
+    }
+}
--- a/js/src/jit-test/tests/symbol/typeof.js
+++ b/js/src/jit-test/tests/symbol/typeof.js
@@ -1,18 +1,9 @@
-function sym() {
-    return typeof Symbol === "function" ? Symbol() : "symbol";
-}
-
-function typ() {
-    return typeof Symbol === "function" ? "symbol" : "string";
-}
-
-var a = [0, 0, 0, 0, 0, sym(), sym()];
+var a = [0, 0, 0, 0, 0, Symbol(), Symbol()];
 var b = [];
 function f(i, v) {
     b[i] = typeof v;
 }
 for (var i = 0; i < a.length; i++)
     f(i, a[i]);
-assertEq(b[b.length - 2], typ());
-assertEq(b[b.length - 1], typ());
-
+assertEq(b[b.length - 2], "symbol");
+assertEq(b[b.length - 1], "symbol");
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -7104,33 +7104,33 @@ ICGetProp_Primitive::Compiler::generateS
 
 ICGetPropNativeStub *
 ICGetPropNativeCompiler::getStub(ICStubSpace *space)
 {
     switch (kind) {
       case ICStub::GetProp_Native: {
         MOZ_ASSERT(obj_ == holder_);
         RootedShape shape(cx, obj_->lastProperty());
-        return ICGetProp_Native::New(space, getStubCode(), firstMonitorStub_, shape, offset_);
+        return ICStub::New<ICGetProp_Native>(space, getStubCode(), firstMonitorStub_, shape, offset_);
       }
 
       case ICStub::GetProp_NativePrototype: {
         MOZ_ASSERT(obj_ != holder_);
         RootedShape shape(cx, obj_->lastProperty());
         RootedShape holderShape(cx, holder_->lastProperty());
-        return ICGetProp_NativePrototype::New(space, getStubCode(), firstMonitorStub_, shape,
-                                              offset_, holder_, holderShape);
+        return ICStub::New<ICGetProp_NativePrototype>(space, getStubCode(), firstMonitorStub_, shape,
+                                                      offset_, holder_, holderShape);
       }
 
       case ICStub::GetProp_UnboxedPrototype: {
         MOZ_ASSERT(obj_ != holder_);
         RootedObjectGroup group(cx, obj_->group());
         RootedShape holderShape(cx, holder_->lastProperty());
-        return ICGetProp_UnboxedPrototype::New(space, getStubCode(), firstMonitorStub_, group,
-                                               offset_, holder_, holderShape);
+        return ICStub::New<ICGetProp_UnboxedPrototype>(space, getStubCode(), firstMonitorStub_, group,
+                                                       offset_, holder_, holderShape);
       }
 
       default:
         MOZ_CRASH("Bad stub kind");
     }
 }
 
 bool
@@ -7654,32 +7654,32 @@ ICGetPropCallDOMProxyNativeCompiler::get
         expandoVal = expandoAndGeneration->expando;
         generation = expandoAndGeneration->generation;
     }
 
     if (expandoVal.isObject())
         expandoShape = expandoVal.toObject().lastProperty();
 
     if (kind == ICStub::GetProp_CallDOMProxyNative) {
-        return ICGetProp_CallDOMProxyNative::New(
+        return ICStub::New<ICGetProp_CallDOMProxyNative>(
             space, getStubCode(), firstMonitorStub_, shape, proxy_->handler(),
             expandoShape, holder_, holderShape, getter_, pcOffset_);
     }
 
-    return ICGetProp_CallDOMProxyWithGenerationNative::New(
+    return ICStub::New<ICGetProp_CallDOMProxyWithGenerationNative>(
         space, getStubCode(), firstMonitorStub_, shape, proxy_->handler(),
         expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
         pcOffset_);
 }
 
 ICStub *
 ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace *space)
 {
     RootedShape shape(cx, proxy_->lastProperty());
-    return ICGetProp_DOMProxyShadowed::New(space, getStubCode(), firstMonitorStub_, shape,
+    return New<ICGetProp_DOMProxyShadowed>(space, getStubCode(), firstMonitorStub_, shape,
                                            proxy_->handler(), name_, pcOffset_);
 }
 
 static bool
 ProxyGet(JSContext *cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp)
 {
     RootedId id(cx, NameToId(name));
     return Proxy::get(cx, proxy, proxy, id, vp);
@@ -7837,17 +7837,17 @@ ICGetProp_ArgumentsCallee::Compiler::gen
     EmitStubGuardFailure(masm);
     return true;
 }
 
 /* static */ ICGetProp_Generic *
 ICGetProp_Generic::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                          ICGetProp_Generic &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub);
+    return New<ICGetProp_Generic>(space, other.jitCode(), firstMonitorStub);
 }
 
 static bool
 DoGetPropGeneric(JSContext *cx, BaselineFrame *frame, ICGetProp_Generic *stub, MutableHandleValue val, MutableHandleValue res)
 {
     jsbytecode *pc = stub->getChainFallback()->icEntry()->pc(frame->script());
     JSOp op = JSOp(*pc);
     RootedPropertyName name(cx, frame->script()->getName(pc));
@@ -11054,17 +11054,17 @@ ICTableSwitch::Compiler::getStub(ICStubS
         int32_t off = GET_JUMP_OFFSET(pc);
         if (off)
             table[i] = pc_ + off;
         else
             table[i] = defaultpc;
         pc += JUMP_OFFSET_LEN;
     }
 
-    return ICTableSwitch::New(space, code, table, low, length, defaultpc);
+    return ICStub::New<ICTableSwitch>(space, code, table, low, length, defaultpc);
 }
 
 void
 ICTableSwitch::fixupJumpTable(JSScript *script, BaselineScript *baseline)
 {
     defaultTarget_ = baseline->nativeCodeForPC(script, (jsbytecode *) defaultTarget_);
 
     for (int32_t i = 0; i < length_; i++)
@@ -11674,60 +11674,63 @@ ICGetElem_NativePrototypeCallNative::Clo
                                            ICStub *firstMonitorStub,
                                            ICGetElem_NativePrototypeCallNative &other)
 {
     RootedShape shape(cx, other.shape());
     RootedPropertyName name(cx, other.name());
     RootedFunction getter(cx, other.getter());
     RootedObject holder(cx, other.holder());
     RootedShape holderShape(cx, other.holderShape());
-    return New(space, other.jitCode(), firstMonitorStub, shape, name, other.accessType(),
-               other.needsAtomize(), getter, other.pcOffset_, holder, holderShape);
+    return New<ICGetElem_NativePrototypeCallNative>(space, other.jitCode(), firstMonitorStub,
+                                                    shape, name, other.accessType(),
+                                                    other.needsAtomize(), getter, other.pcOffset_,
+                                                    holder, holderShape);
 }
 
 /* static */ ICGetElem_NativePrototypeCallScripted *
 ICGetElem_NativePrototypeCallScripted::Clone(JSContext *cx, ICStubSpace *space,
                                              ICStub *firstMonitorStub,
                                              ICGetElem_NativePrototypeCallScripted &other)
 {
     RootedShape shape(cx, other.shape());
     RootedPropertyName name(cx, other.name());
     RootedFunction getter(cx, other.getter());
     RootedObject holder(cx, other.holder());
     RootedShape holderShape(cx, other.holderShape());
-    return New(space, other.jitCode(), firstMonitorStub, shape, name, other.accessType(),
-               other.needsAtomize(), getter, other.pcOffset_, holder, holderShape);
+    return New<ICGetElem_NativePrototypeCallScripted>(space, other.jitCode(), firstMonitorStub, shape, name,
+                                                      other.accessType(), other.needsAtomize(), getter,
+                                                      other.pcOffset_, holder, holderShape);
 }
 
 ICGetElem_Dense::ICGetElem_Dense(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape)
     : ICMonitoredStub(GetElem_Dense, stubCode, firstMonitorStub),
       shape_(shape)
 { }
 
 /* static */ ICGetElem_Dense *
 ICGetElem_Dense::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                        ICGetElem_Dense &other)
 {
     RootedShape shape(cx, other.shape_);
-    return New(space, other.jitCode(), firstMonitorStub, shape);
+    return New<ICGetElem_Dense>(space, other.jitCode(), firstMonitorStub, shape);
 }
 
 ICGetElem_TypedArray::ICGetElem_TypedArray(JitCode *stubCode, HandleShape shape, Scalar::Type type)
   : ICStub(GetElem_TypedArray, stubCode),
     shape_(shape)
 {
     extra_ = uint16_t(type);
     MOZ_ASSERT(extra_ == type);
 }
 
 /* static */ ICGetElem_Arguments *
 ICGetElem_Arguments::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                            ICGetElem_Arguments &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub, other.which());
+    return New<ICGetElem_Arguments>(space, other.jitCode(), firstMonitorStub, other.which());
 }
 
 ICSetElem_Dense::ICSetElem_Dense(JitCode *stubCode, HandleShape shape, HandleObjectGroup group)
   : ICUpdatedStub(SetElem_Dense, stubCode),
     shape_(shape),
     group_(group)
 { }
 
@@ -11743,17 +11746,17 @@ ICSetElem_DenseAdd::ICSetElem_DenseAdd(J
 template <size_t ProtoChainDepth>
 ICUpdatedStub *
 ICSetElemDenseAddCompiler::getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes)
 {
     RootedObjectGroup group(cx, obj_->getGroup(cx));
     if (!group)
         return nullptr;
     Rooted<JitCode *> stubCode(cx, getStubCode());
-    return ICSetElem_DenseAddImpl<ProtoChainDepth>::New(space, stubCode, group, shapes);
+    return ICStub::New<ICSetElem_DenseAddImpl<ProtoChainDepth>>(space, stubCode, group, shapes);
 }
 
 ICSetElem_TypedArray::ICSetElem_TypedArray(JitCode *stubCode, HandleShape shape, Scalar::Type type,
                                            bool expectOutOfBounds)
   : ICStub(SetElem_TypedArray, stubCode),
     shape_(shape)
 {
     extra_ = uint8_t(type);
@@ -11801,17 +11804,17 @@ ICGetPropNativeStub::ICGetPropNativeStub
     offset_(offset)
 { }
 
 /* static */ ICGetProp_Native *
 ICGetProp_Native::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                         ICGetProp_Native &other)
 {
     RootedShape shape(cx, other.shape());
-    return New(space, other.jitCode(), firstMonitorStub, shape, other.offset());
+    return New<ICGetProp_Native>(space, other.jitCode(), firstMonitorStub, shape, other.offset());
 }
 
 ICGetProp_NativePrototype::ICGetProp_NativePrototype(JitCode *stubCode, ICStub *firstMonitorStub,
                                                      HandleShape shape, uint32_t offset,
                                                      HandleObject holder, HandleShape holderShape)
   : ICGetPropNativeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, offset),
     shape_(shape),
     holder_(holder),
@@ -11820,18 +11823,18 @@ ICGetProp_NativePrototype::ICGetProp_Nat
 
 /* static */ ICGetProp_NativePrototype *
 ICGetProp_NativePrototype::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                  ICGetProp_NativePrototype &other)
 {
     RootedShape shape(cx, other.shape());
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
-    return New(space, other.jitCode(), firstMonitorStub, shape, other.offset(),
-               holder, holderShape);
+    return New<ICGetProp_NativePrototype>(space, other.jitCode(), firstMonitorStub, shape,
+                                          other.offset(), holder, holderShape);
 }
 
 ICGetProp_UnboxedPrototype::ICGetProp_UnboxedPrototype(JitCode *stubCode, ICStub *firstMonitorStub,
                                                        HandleObjectGroup group, uint32_t offset,
                                                        HandleObject holder, HandleShape holderShape)
   : ICGetPropNativeStub(GetProp_UnboxedPrototype, stubCode, firstMonitorStub, offset),
     group_(group),
     holder_(holder),
@@ -11840,18 +11843,18 @@ ICGetProp_UnboxedPrototype::ICGetProp_Un
 
 /* static */ ICGetProp_UnboxedPrototype *
 ICGetProp_UnboxedPrototype::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                   ICGetProp_UnboxedPrototype &other)
 {
     RootedObjectGroup group(cx, other.group());
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
-    return New(space, other.jitCode(), firstMonitorStub, group, other.offset(),
-               holder, holderShape);
+    return New<ICGetProp_UnboxedPrototype>(space, other.jitCode(), firstMonitorStub, group,
+                                           other.offset(), holder, holderShape);
 }
 
 ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist(
         JitCode *stubCode, ICStub *firstMonitorStub, size_t protoChainDepth)
   : ICMonitoredStub(GetProp_NativeDoesNotExist, stubCode, firstMonitorStub)
 {
     MOZ_ASSERT(protoChainDepth <= MAX_PROTO_CHAIN_DEPTH);
     extra_ = protoChainDepth;
@@ -11924,41 +11927,41 @@ ICInstanceOf_Function::ICInstanceOf_Func
 /* static */ ICGetProp_CallScripted *
 ICGetProp_CallScripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                               ICGetProp_CallScripted &other)
 {
     RootedShape receiverShape(cx, other.receiverShape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
-    return New(space, other.jitCode(), firstMonitorStub, receiverShape, holder,
-               holderShape, getter, other.pcOffset_);
+    return New<ICGetProp_CallScripted>(space, other.jitCode(), firstMonitorStub, receiverShape,
+                                       holder, holderShape, getter, other.pcOffset_);
 }
 
 /* static */ ICGetProp_CallNative *
 ICGetProp_CallNative::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                             ICGetProp_CallNative &other)
 {
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
-    return New(space, other.jitCode(), firstMonitorStub, holder, holderShape, getter,
-               other.pcOffset_);
+    return New<ICGetProp_CallNative>(space, other.jitCode(), firstMonitorStub, holder, holderShape,
+                                     getter, other.pcOffset_);
 }
 
 /* static */ ICGetProp_CallNativePrototype *
 ICGetProp_CallNativePrototype::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                      ICGetProp_CallNativePrototype &other)
 {
     RootedShape receiverShape(cx, other.receiverShape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
-    return New(space, other.jitCode(), firstMonitorStub, receiverShape, holder,
-               holderShape, getter, other.pcOffset_);
+    return New<ICGetProp_CallNativePrototype>(space, other.jitCode(), firstMonitorStub, receiverShape,
+                                              holder, holderShape, getter, other.pcOffset_);
 }
 
 ICSetProp_Native::ICSetProp_Native(JitCode *stubCode, HandleObjectGroup group, HandleShape shape,
                                    uint32_t offset)
   : ICUpdatedStub(SetProp_Native, stubCode),
     group_(group),
     shape_(shape),
     offset_(offset)
@@ -11967,17 +11970,17 @@ ICSetProp_Native::ICSetProp_Native(JitCo
 ICSetProp_Native *
 ICSetProp_Native::Compiler::getStub(ICStubSpace *space)
 {
     RootedObjectGroup group(cx, obj_->getGroup(cx));
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, obj_->lastProperty());
-    ICSetProp_Native *stub = ICSetProp_Native::New(space, getStubCode(), group, shape, offset_);
+    ICSetProp_Native *stub = ICStub::New<ICSetProp_Native>(space, getStubCode(), group, shape, offset_);
     if (!stub || !stub->initUpdatingChain(cx, space))
         return nullptr;
     return stub;
 }
 
 ICSetProp_NativeAdd::ICSetProp_NativeAdd(JitCode *stubCode, HandleObjectGroup group,
                                          size_t protoChainDepth,
                                          HandleShape newShape,
@@ -12040,28 +12043,30 @@ ICSetPropCallSetter::ICSetPropCallSetter
 /* static */ ICSetProp_CallScripted *
 ICSetProp_CallScripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *,
                               ICSetProp_CallScripted &other)
 {
     RootedShape shape(cx, other.shape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction setter(cx, other.setter_);
-    return New(space, other.jitCode(), shape, holder, holderShape, setter, other.pcOffset_);
+    return New<ICSetProp_CallScripted>(space, other.jitCode(), shape, holder, holderShape, setter,
+                                       other.pcOffset_);
 }
 
 /* static */ ICSetProp_CallNative *
 ICSetProp_CallNative::Clone(JSContext *cx, ICStubSpace *space, ICStub *,
                             ICSetProp_CallNative &other)
 {
     RootedShape shape(cx, other.shape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction setter(cx, other.setter_);
-    return New(space, other.jitCode(), shape, holder, holderShape, setter, other.pcOffset_);
+    return New<ICSetProp_CallNative>(space, other.jitCode(), shape, holder, holderShape, setter,
+                                     other.pcOffset_);
 }
 
 ICCall_Scripted::ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub,
                                  HandleFunction callee, HandleObject templateObject,
                                  uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_Scripted, stubCode, firstMonitorStub),
     callee_(callee),
     templateObject_(templateObject),
@@ -12069,25 +12074,25 @@ ICCall_Scripted::ICCall_Scripted(JitCode
 { }
 
 /* static */ ICCall_Scripted *
 ICCall_Scripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                        ICCall_Scripted &other)
 {
     RootedFunction callee(cx, other.callee_);
     RootedObject templateObject(cx, other.templateObject_);
-    return New(space, other.jitCode(), firstMonitorStub, callee, templateObject,
-               other.pcOffset_);
+    return New<ICCall_Scripted>(space, other.jitCode(), firstMonitorStub, callee, templateObject,
+                                other.pcOffset_);
 }
 
 /* static */ ICCall_AnyScripted *
 ICCall_AnyScripted::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                           ICCall_AnyScripted &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+    return New<ICCall_AnyScripted>(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
 }
 
 ICCall_Native::ICCall_Native(JitCode *stubCode, ICStub *firstMonitorStub,
                              HandleFunction callee, HandleObject templateObject,
                              uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_Native, stubCode, firstMonitorStub),
     callee_(callee),
     templateObject_(templateObject),
@@ -12103,18 +12108,18 @@ ICCall_Native::ICCall_Native(JitCode *st
 }
 
 /* static */ ICCall_Native *
 ICCall_Native::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                      ICCall_Native &other)
 {
     RootedFunction callee(cx, other.callee_);
     RootedObject templateObject(cx, other.templateObject_);
-    return New(space, other.jitCode(), firstMonitorStub, callee, templateObject,
-               other.pcOffset_);
+    return New<ICCall_Native>(space, other.jitCode(), firstMonitorStub, callee, templateObject,
+                              other.pcOffset_);
 }
 
 ICCall_ClassHook::ICCall_ClassHook(JitCode *stubCode, ICStub *firstMonitorStub,
                                    const Class *clasp, Native native,
                                    HandleObject templateObject, uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_ClassHook, stubCode, firstMonitorStub),
     clasp_(clasp),
     native_(JS_FUNC_TO_DATA_PTR(void *, native)),
@@ -12129,43 +12134,46 @@ ICCall_ClassHook::ICCall_ClassHook(JitCo
 #endif
 }
 
 /* static */ ICCall_ClassHook *
 ICCall_ClassHook::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                         ICCall_ClassHook &other)
 {
     RootedObject templateObject(cx, other.templateObject_);
-    ICCall_ClassHook *res = New(space, other.jitCode(), firstMonitorStub,
-                                other.clasp(), nullptr, templateObject, other.pcOffset_);
+    ICCall_ClassHook *res = New<ICCall_ClassHook>(space, other.jitCode(), firstMonitorStub,
+                                                  other.clasp(), nullptr, templateObject,
+                                                  other.pcOffset_);
     if (res)
         res->native_ = other.native();
     return res;
 }
 
 /* static */ ICCall_ScriptedApplyArray *
 ICCall_ScriptedApplyArray::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                                  ICCall_ScriptedApplyArray &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+    return New<ICCall_ScriptedApplyArray>(space, other.jitCode(), firstMonitorStub,
+                                          other.pcOffset_);
 }
 
 /* static */ ICCall_ScriptedApplyArguments *
 ICCall_ScriptedApplyArguments::Clone(JSContext *, ICStubSpace *space,
                                      ICStub *firstMonitorStub,
                                      ICCall_ScriptedApplyArguments &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+    return New<ICCall_ScriptedApplyArguments>(space, other.jitCode(), firstMonitorStub,
+                                              other.pcOffset_);
 }
 
 /* static */ ICCall_ScriptedFunCall *
 ICCall_ScriptedFunCall::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                               ICCall_ScriptedFunCall &other)
 {
-    return New(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+    return New<ICCall_ScriptedFunCall>(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
 }
 
 ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, JitCode *stubCode,
                                                                  ICStub *firstMonitorStub,
                                                                  HandleShape shape,
                                                                  const BaseProxyHandler *proxyHandler,
                                                                  HandleShape expandoShape,
                                                                  HandleObject holder,
@@ -12202,33 +12210,36 @@ ICGetPropCallDOMProxyNativeCompiler::ICG
 ICGetProp_CallDOMProxyNative::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                     ICGetProp_CallDOMProxyNative &other)
 {
     RootedShape shape(cx, other.shape_);
     RootedShape expandoShape(cx, other.expandoShape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
-    return New(space, other.jitCode(), firstMonitorStub, shape, other.proxyHandler_,
-               expandoShape, holder, holderShape, getter, other.pcOffset_);
+    return New<ICGetProp_CallDOMProxyNative>(space, other.jitCode(), firstMonitorStub, shape,
+                                             other.proxyHandler_, expandoShape, holder,
+                                             holderShape, getter, other.pcOffset_);
 }
 
 /* static */ ICGetProp_CallDOMProxyWithGenerationNative *
 ICGetProp_CallDOMProxyWithGenerationNative::Clone(JSContext *cx, ICStubSpace *space,
                                                   ICStub *firstMonitorStub,
                                                   ICGetProp_CallDOMProxyWithGenerationNative &other)
 {
     RootedShape shape(cx, other.shape_);
     RootedShape expandoShape(cx, other.expandoShape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
-    return New(space, other.jitCode(), firstMonitorStub, shape, other.proxyHandler_,
-               other.expandoAndGeneration_, other.generation_,
-               expandoShape, holder, holderShape, getter, other.pcOffset_);
+    return New<ICGetProp_CallDOMProxyWithGenerationNative>(space, other.jitCode(), firstMonitorStub,
+                                                           shape, other.proxyHandler_,
+                                                           other.expandoAndGeneration_, other.generation_,
+                                                           expandoShape, holder, holderShape, getter,
+                                                           other.pcOffset_);
 }
 
 ICGetProp_DOMProxyShadowed::ICGetProp_DOMProxyShadowed(JitCode *stubCode,
                                                        ICStub *firstMonitorStub,
                                                        HandleShape shape,
                                                        const BaseProxyHandler *proxyHandler,
                                                        HandlePropertyName name,
                                                        uint32_t pcOffset)
@@ -12240,18 +12251,18 @@ ICGetProp_DOMProxyShadowed::ICGetProp_DO
 { }
 
 /* static */ ICGetProp_DOMProxyShadowed *
 ICGetProp_DOMProxyShadowed::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                   ICGetProp_DOMProxyShadowed &other)
 {
     RootedShape shape(cx, other.shape_);
     RootedPropertyName name(cx, other.name_);
-    return New(space, other.jitCode(), firstMonitorStub, shape, other.proxyHandler_,
-               name, other.pcOffset_);
+    return New<ICGetProp_DOMProxyShadowed>(space, other.jitCode(), firstMonitorStub, shape,
+                                           other.proxyHandler_, name, other.pcOffset_);
 }
 
 //
 // Rest_Fallback
 //
 
 static bool DoRestFallback(JSContext *cx, ICRest_Fallback *stub,
                            BaselineFrame *frame, MutableHandleValue res)
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -627,16 +627,23 @@ class ICStub
         MonitoredFallback   = 0x3,
         Updated             = 0x4
     };
 
     void markCode(JSTracer *trc, const char *name);
     void updateCode(JitCode *stubCode);
     void trace(JSTracer *trc);
 
+    template <typename T, typename... Args>
+    static T *New(ICStubSpace *space, JitCode *code, Args&&... args) {
+        if (!code)
+            return nullptr;
+        return space->allocate<T>(code, mozilla::Forward<Args>(args)...);
+    }
+
   protected:
     // The raw jitcode to call for this stub.
     uint8_t *stubCode_;
 
     // Pointer to next IC stub.  This is null for the last IC stub, which should
     // either be a fallback or inert IC stub.
     ICStub *next_;
 
@@ -1197,34 +1204,28 @@ class ICWarmUpCounter_Fallback : public 
 {
     friend class ICStubSpace;
 
     explicit ICWarmUpCounter_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::WarmUpCounter_Fallback, stubCode)
     { }
 
   public:
-    static inline ICWarmUpCounter_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICWarmUpCounter_Fallback>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::WarmUpCounter_Fallback)
         { }
 
         ICWarmUpCounter_Fallback *getStub(ICStubSpace *space) {
-            return ICWarmUpCounter_Fallback::New(space, getStubCode());
+            return ICStub::New<ICWarmUpCounter_Fallback>(space, getStubCode());
         }
     };
 };
 
 
 // TypeCheckPrimitiveSetStub
 //   Base class for IC stubs (TypeUpdate or TypeMonitor) that check that a given
 //   value's type falls within a set of primitive types.
@@ -1375,25 +1376,16 @@ class ICTypeMonitor_Fallback : public IC
             MOZ_ASSERT(firstMonitorStub_ != nullptr);
         }
 
         lastMonitorStubPtrAddr_ = stub->addressOfNext();
         numOptimizedMonitorStubs_++;
     }
 
   public:
-    static inline ICTypeMonitor_Fallback *New(
-        ICStubSpace *space, JitCode *code, ICMonitoredFallbackStub *mainFbStub,
-        uint32_t argumentIndex)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeMonitor_Fallback>(code, mainFbStub, argumentIndex);
-    }
-
     bool hasStub(ICStub::Kind kind) {
         ICStub *stub = firstMonitorStub_;
         do {
             if (stub->kind() == kind)
                 return true;
 
             stub = stub->next();
         } while (stub);
@@ -1470,39 +1462,31 @@ class ICTypeMonitor_Fallback : public IC
 
         Compiler(JSContext *cx, uint32_t argumentIndex)
           : ICStubCompiler(cx, ICStub::TypeMonitor_Fallback),
             mainFallbackStub_(nullptr),
             argumentIndex_(argumentIndex)
         { }
 
         ICTypeMonitor_Fallback *getStub(ICStubSpace *space) {
-            return ICTypeMonitor_Fallback::New(space, getStubCode(), mainFallbackStub_,
-                                               argumentIndex_);
+            return ICStub::New<ICTypeMonitor_Fallback>(space, getStubCode(), mainFallbackStub_,
+                                                       argumentIndex_);
         }
     };
 };
 
 class ICTypeMonitor_PrimitiveSet : public TypeCheckPrimitiveSetStub
 {
     friend class ICStubSpace;
 
     ICTypeMonitor_PrimitiveSet(JitCode *stubCode, uint16_t flags)
         : TypeCheckPrimitiveSetStub(TypeMonitor_PrimitiveSet, stubCode, flags)
     {}
 
   public:
-    static inline ICTypeMonitor_PrimitiveSet *New(ICStubSpace *space, JitCode *code,
-                                                  uint16_t flags)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeMonitor_PrimitiveSet>(code, flags);
-    }
-
     class Compiler : public TypeCheckPrimitiveSetStub::Compiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ICTypeMonitor_PrimitiveSet *existingStub, JSValueType type)
           : TypeCheckPrimitiveSetStub::Compiler(cx, TypeMonitor_PrimitiveSet, existingStub, type)
         {}
@@ -1512,38 +1496,30 @@ class ICTypeMonitor_PrimitiveSet : publi
                 this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
             if (!stub)
                 return nullptr;
             return stub->toMonitorStub();
         }
 
         ICTypeMonitor_PrimitiveSet *getStub(ICStubSpace *space) {
             MOZ_ASSERT(!existingStub_);
-            return ICTypeMonitor_PrimitiveSet::New(space, getStubCode(), flags_);
+            return ICStub::New<ICTypeMonitor_PrimitiveSet>(space, getStubCode(), flags_);
         }
     };
 };
 
 class ICTypeMonitor_SingleObject : public ICStub
 {
     friend class ICStubSpace;
 
     HeapPtrObject obj_;
 
     ICTypeMonitor_SingleObject(JitCode *stubCode, HandleObject obj);
 
   public:
-    static inline ICTypeMonitor_SingleObject *New(
-            ICStubSpace *space, JitCode *code, HandleObject obj)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeMonitor_SingleObject>(code, obj);
-    }
-
     HeapPtrObject &object() {
         return obj_;
     }
 
     static size_t offsetOfObject() {
         return offsetof(ICTypeMonitor_SingleObject, obj_);
     }
 
@@ -1554,38 +1530,30 @@ class ICTypeMonitor_SingleObject : publi
 
       public:
         Compiler(JSContext *cx, HandleObject obj)
           : ICStubCompiler(cx, TypeMonitor_SingleObject),
             obj_(obj)
         { }
 
         ICTypeMonitor_SingleObject *getStub(ICStubSpace *space) {
-            return ICTypeMonitor_SingleObject::New(space, getStubCode(), obj_);
+            return ICStub::New<ICTypeMonitor_SingleObject>(space, getStubCode(), obj_);
         }
     };
 };
 
 class ICTypeMonitor_ObjectGroup : public ICStub
 {
     friend class ICStubSpace;
 
     HeapPtrObjectGroup group_;
 
     ICTypeMonitor_ObjectGroup(JitCode *stubCode, HandleObjectGroup group);
 
   public:
-    static inline ICTypeMonitor_ObjectGroup *New(
-            ICStubSpace *space, JitCode *code, HandleObjectGroup group)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeMonitor_ObjectGroup>(code, group);
-    }
-
     HeapPtrObjectGroup &group() {
         return group_;
     }
 
     static size_t offsetOfGroup() {
         return offsetof(ICTypeMonitor_ObjectGroup, group_);
     }
 
@@ -1596,17 +1564,17 @@ class ICTypeMonitor_ObjectGroup : public
 
       public:
         Compiler(JSContext *cx, HandleObjectGroup group)
           : ICStubCompiler(cx, TypeMonitor_ObjectGroup),
             group_(group)
         { }
 
         ICTypeMonitor_ObjectGroup *getStub(ICStubSpace *space) {
-            return ICTypeMonitor_ObjectGroup::New(space, getStubCode(), group_);
+            return ICStub::New<ICTypeMonitor_ObjectGroup>(space, getStubCode(), group_);
         }
     };
 };
 
 // TypeUpdate
 
 extern const VMFunction DoTypeUpdateFallbackInfo;
 
@@ -1616,55 +1584,41 @@ class ICTypeUpdate_Fallback : public ICS
 {
     friend class ICStubSpace;
 
     explicit ICTypeUpdate_Fallback(JitCode *stubCode)
       : ICStub(ICStub::TypeUpdate_Fallback, stubCode)
     {}
 
   public:
-    static inline ICTypeUpdate_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeUpdate_Fallback>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::TypeUpdate_Fallback)
         { }
 
         ICTypeUpdate_Fallback *getStub(ICStubSpace *space) {
-            return ICTypeUpdate_Fallback::New(space, getStubCode());
+            return ICStub::New<ICTypeUpdate_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICTypeUpdate_PrimitiveSet : public TypeCheckPrimitiveSetStub
 {
     friend class ICStubSpace;
 
     ICTypeUpdate_PrimitiveSet(JitCode *stubCode, uint16_t flags)
         : TypeCheckPrimitiveSetStub(TypeUpdate_PrimitiveSet, stubCode, flags)
     {}
 
   public:
-    static inline ICTypeUpdate_PrimitiveSet *New(ICStubSpace *space, JitCode *code,
-                                                 uint16_t flags)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeUpdate_PrimitiveSet>(code, flags);
-    }
-
     class Compiler : public TypeCheckPrimitiveSetStub::Compiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ICTypeUpdate_PrimitiveSet *existingStub, JSValueType type)
           : TypeCheckPrimitiveSetStub::Compiler(cx, TypeUpdate_PrimitiveSet, existingStub, type)
         {}
@@ -1674,39 +1628,31 @@ class ICTypeUpdate_PrimitiveSet : public
                 this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
             if (!stub)
                 return nullptr;
             return stub->toUpdateStub();
         }
 
         ICTypeUpdate_PrimitiveSet *getStub(ICStubSpace *space) {
             MOZ_ASSERT(!existingStub_);
-            return ICTypeUpdate_PrimitiveSet::New(space, getStubCode(), flags_);
+            return ICStub::New<ICTypeUpdate_PrimitiveSet>(space, getStubCode(), flags_);
         }
     };
 };
 
 // Type update stub to handle a singleton object.
 class ICTypeUpdate_SingleObject : public ICStub
 {
     friend class ICStubSpace;
 
     HeapPtrObject obj_;
 
     ICTypeUpdate_SingleObject(JitCode *stubCode, HandleObject obj);
 
   public:
-    static inline ICTypeUpdate_SingleObject *New(ICStubSpace *space, JitCode *code,
-                                                 HandleObject obj)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeUpdate_SingleObject>(code, obj);
-    }
-
     HeapPtrObject &object() {
         return obj_;
     }
 
     static size_t offsetOfObject() {
         return offsetof(ICTypeUpdate_SingleObject, obj_);
     }
 
@@ -1717,39 +1663,31 @@ class ICTypeUpdate_SingleObject : public
 
       public:
         Compiler(JSContext *cx, HandleObject obj)
           : ICStubCompiler(cx, TypeUpdate_SingleObject),
             obj_(obj)
         { }
 
         ICTypeUpdate_SingleObject *getStub(ICStubSpace *space) {
-            return ICTypeUpdate_SingleObject::New(space, getStubCode(), obj_);
+            return ICStub::New<ICTypeUpdate_SingleObject>(space, getStubCode(), obj_);
         }
     };
 };
 
 // Type update stub to handle a single ObjectGroup.
 class ICTypeUpdate_ObjectGroup : public ICStub
 {
     friend class ICStubSpace;
 
     HeapPtrObjectGroup group_;
 
     ICTypeUpdate_ObjectGroup(JitCode *stubCode, HandleObjectGroup group);
 
   public:
-    static inline ICTypeUpdate_ObjectGroup *New(ICStubSpace *space, JitCode *code,
-                                                HandleObjectGroup group)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeUpdate_ObjectGroup>(code, group);
-    }
-
     HeapPtrObjectGroup &group() {
         return group_;
     }
 
     static size_t offsetOfGroup() {
         return offsetof(ICTypeUpdate_ObjectGroup, group_);
     }
 
@@ -1760,83 +1698,70 @@ class ICTypeUpdate_ObjectGroup : public 
 
       public:
         Compiler(JSContext *cx, HandleObjectGroup group)
           : ICStubCompiler(cx, TypeUpdate_ObjectGroup),
             group_(group)
         { }
 
         ICTypeUpdate_ObjectGroup *getStub(ICStubSpace *space) {
-            return ICTypeUpdate_ObjectGroup::New(space, getStubCode(), group_);
+            return ICStub::New<ICTypeUpdate_ObjectGroup>(space, getStubCode(), group_);
         }
     };
 };
 
 // This
 //      JSOP_THIS
 
 class ICThis_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICThis_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::This_Fallback, stubCode) {}
 
   public:
-    static inline ICThis_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICThis_Fallback>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::This_Fallback) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICThis_Fallback::New(space, getStubCode());
+            return ICStub::New<ICThis_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICNewArray_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     HeapPtrArrayObject templateObject_;
 
     ICNewArray_Fallback(JitCode *stubCode, ArrayObject *templateObject)
       : ICFallbackStub(ICStub::NewArray_Fallback, stubCode), templateObject_(templateObject)
     {}
 
   public:
-    static inline ICNewArray_Fallback *New(ICStubSpace *space, JitCode *code,
-                                           ArrayObject *templateObject) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICNewArray_Fallback>(code, templateObject);
-    }
-
     class Compiler : public ICStubCompiler {
         RootedArrayObject templateObject;
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ArrayObject *templateObject)
           : ICStubCompiler(cx, ICStub::NewArray_Fallback),
             templateObject(cx, templateObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICNewArray_Fallback::New(space, getStubCode(), templateObject);
+            return ICStub::New<ICNewArray_Fallback>(space, getStubCode(), templateObject);
         }
     };
 
     HeapPtrArrayObject &templateObject() {
         return templateObject_;
     }
 };
 
@@ -1846,35 +1771,28 @@ class ICNewObject_Fallback : public ICFa
 
     HeapPtrPlainObject templateObject_;
 
     ICNewObject_Fallback(JitCode *stubCode, PlainObject *templateObject)
       : ICFallbackStub(ICStub::NewObject_Fallback, stubCode), templateObject_(templateObject)
     {}
 
   public:
-    static inline ICNewObject_Fallback *New(ICStubSpace *space, JitCode *code,
-                                            PlainObject *templateObject) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICNewObject_Fallback>(code, templateObject);
-    }
-
     class Compiler : public ICStubCompiler {
         RootedPlainObject templateObject;
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, PlainObject *templateObject)
           : ICStubCompiler(cx, ICStub::NewObject_Fallback),
             templateObject(cx, templateObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICNewObject_Fallback::New(space, getStubCode(), templateObject);
+            return ICStub::New<ICNewObject_Fallback>(space, getStubCode(), templateObject);
         }
     };
 
     HeapPtrPlainObject &templateObject() {
         return templateObject_;
     }
 };
 
@@ -1887,22 +1805,16 @@ class ICCompare_Fallback : public ICFall
     friend class ICStubSpace;
 
     explicit ICCompare_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::Compare_Fallback, stubCode) {}
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICCompare_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Fallback>(code);
-    }
-
     static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
     void noteUnoptimizableAccess() {
         extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
     bool hadUnoptimizableAccess() const {
         return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
 
@@ -1911,97 +1823,79 @@ class ICCompare_Fallback : public ICFall
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::Compare_Fallback) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Fallback::New(space, getStubCode());
+            return ICStub::New<ICCompare_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_Int32(JitCode *stubCode)
       : ICStub(ICStub::Compare_Int32, stubCode) {}
 
   public:
-    static inline ICCompare_Int32 *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Int32>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Int32, op) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Int32::New(space, getStubCode());
+            return ICStub::New<ICCompare_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Double : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_Double(JitCode *stubCode)
       : ICStub(ICStub::Compare_Double, stubCode)
     {}
 
   public:
-    static inline ICCompare_Double *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Double>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Double, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Double::New(space, getStubCode());
+            return ICStub::New<ICCompare_Double>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_NumberWithUndefined : public ICStub
 {
     friend class ICStubSpace;
 
     ICCompare_NumberWithUndefined(JitCode *stubCode, bool lhsIsUndefined)
       : ICStub(ICStub::Compare_NumberWithUndefined, stubCode)
     {
         extra_ = lhsIsUndefined;
     }
 
   public:
-    static inline ICCompare_NumberWithUndefined *New(ICStubSpace *space, JitCode *code, bool lhsIsUndefined) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_NumberWithUndefined>(code, lhsIsUndefined);
-    }
-
     bool lhsIsUndefined() {
         return extra_;
     }
 
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
@@ -2015,126 +1909,102 @@ class ICCompare_NumberWithUndefined : pu
 
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind)
                  | (static_cast<int32_t>(op) << 16)
                  | (static_cast<int32_t>(lhsIsUndefined) << 24);
         }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_NumberWithUndefined::New(space, getStubCode(), lhsIsUndefined);
+            return ICStub::New<ICCompare_NumberWithUndefined>(space, getStubCode(), lhsIsUndefined);
         }
     };
 };
 
 class ICCompare_String : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_String(JitCode *stubCode)
       : ICStub(ICStub::Compare_String, stubCode)
     {}
 
   public:
-    static inline ICCompare_String *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_String>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_String, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_String::New(space, getStubCode());
+            return ICStub::New<ICCompare_String>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Boolean : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_Boolean(JitCode *stubCode)
       : ICStub(ICStub::Compare_Boolean, stubCode)
     {}
 
   public:
-    static inline ICCompare_Boolean *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Boolean>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Boolean, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Boolean::New(space, getStubCode());
+            return ICStub::New<ICCompare_Boolean>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Object : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_Object(JitCode *stubCode)
       : ICStub(ICStub::Compare_Object, stubCode)
     {}
 
   public:
-    static inline ICCompare_Object *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Object>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Object, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Object::New(space, getStubCode());
+            return ICStub::New<ICCompare_Object>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_ObjectWithUndefined : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICCompare_ObjectWithUndefined(JitCode *stubCode)
       : ICStub(ICStub::Compare_ObjectWithUndefined, stubCode)
     {}
 
   public:
-    static inline ICCompare_ObjectWithUndefined *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_ObjectWithUndefined>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
         bool lhsIsUndefined;
         bool compareWithNull;
 
       public:
@@ -2147,40 +2017,32 @@ class ICCompare_ObjectWithUndefined : pu
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind)
                  | (static_cast<int32_t>(op) << 16)
                  | (static_cast<int32_t>(lhsIsUndefined) << 24)
                  | (static_cast<int32_t>(compareWithNull) << 25);
         }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_ObjectWithUndefined::New(space, getStubCode());
+            return ICStub::New<ICCompare_ObjectWithUndefined>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Int32WithBoolean : public ICStub
 {
     friend class ICStubSpace;
 
     ICCompare_Int32WithBoolean(JitCode *stubCode, bool lhsIsInt32)
       : ICStub(ICStub::Compare_Int32WithBoolean, stubCode)
     {
         extra_ = lhsIsInt32;
     }
 
   public:
-    static inline ICCompare_Int32WithBoolean *New(ICStubSpace *space, JitCode *code,
-                                                  bool lhsIsInt32)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCompare_Int32WithBoolean>(code, lhsIsInt32);
-    }
-
     bool lhsIsInt32() const {
         return extra_;
     }
 
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         JSOp op_;
@@ -2195,17 +2057,17 @@ class ICCompare_Int32WithBoolean : publi
       public:
         Compiler(JSContext *cx, JSOp op, bool lhsIsInt32)
           : ICStubCompiler(cx, ICStub::Compare_Int32WithBoolean),
             op_(op),
             lhsIsInt32_(lhsIsInt32)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCompare_Int32WithBoolean::New(space, getStubCode(), lhsIsInt32_);
+            return ICStub::New<ICCompare_Int32WithBoolean>(space, getStubCode(), lhsIsInt32_);
         }
     };
 };
 
 // ToBool
 //      JSOP_IFNE
 
 class ICToBool_Fallback : public ICFallbackStub
@@ -2213,210 +2075,168 @@ class ICToBool_Fallback : public ICFallb
     friend class ICStubSpace;
 
     explicit ICToBool_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::ToBool_Fallback, stubCode) {}
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICToBool_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_Fallback>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_Fallback) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_Fallback::New(space, getStubCode());
+            return ICStub::New<ICToBool_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICToBool_Int32(JitCode *stubCode)
       : ICStub(ICStub::ToBool_Int32, stubCode) {}
 
   public:
-    static inline ICToBool_Int32 *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_Int32>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_Int32) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_Int32::New(space, getStubCode());
+            return ICStub::New<ICToBool_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_String : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICToBool_String(JitCode *stubCode)
       : ICStub(ICStub::ToBool_String, stubCode) {}
 
   public:
-    static inline ICToBool_String *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_String>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_String) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_String::New(space, getStubCode());
+            return ICStub::New<ICToBool_String>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_NullUndefined : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICToBool_NullUndefined(JitCode *stubCode)
       : ICStub(ICStub::ToBool_NullUndefined, stubCode) {}
 
   public:
-    static inline ICToBool_NullUndefined *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_NullUndefined>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_NullUndefined) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_NullUndefined::New(space, getStubCode());
+            return ICStub::New<ICToBool_NullUndefined>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Double : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICToBool_Double(JitCode *stubCode)
       : ICStub(ICStub::ToBool_Double, stubCode) {}
 
   public:
-    static inline ICToBool_Double *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_Double>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_Double) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_Double::New(space, getStubCode());
+            return ICStub::New<ICToBool_Double>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Object : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICToBool_Object(JitCode *stubCode)
       : ICStub(ICStub::ToBool_Object, stubCode) {}
 
   public:
-    static inline ICToBool_Object *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToBool_Object>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToBool_Object) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToBool_Object::New(space, getStubCode());
+            return ICStub::New<ICToBool_Object>(space, getStubCode());
         }
     };
 };
 
 // ToNumber
 //     JSOP_POS
 
 class ICToNumber_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICToNumber_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::ToNumber_Fallback, stubCode) {}
 
   public:
-    static inline ICToNumber_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICToNumber_Fallback>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::ToNumber_Fallback) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICToNumber_Fallback::New(space, getStubCode());
+            return ICStub::New<ICToNumber_Fallback>(space, getStubCode());
         }
     };
 };
 
 // BinaryArith
 //      JSOP_ADD
 //      JSOP_BITAND, JSOP_BITXOR, JSOP_BITOR
 //      JSOP_LSH, JSOP_RSH, JSOP_URSH
@@ -2432,22 +2252,16 @@ class ICBinaryArith_Fallback : public IC
     }
 
     static const uint16_t SAW_DOUBLE_RESULT_BIT = 0x1;
     static const uint16_t UNOPTIMIZABLE_OPERANDS_BIT = 0x2;
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICBinaryArith_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_Fallback>(code);
-    }
-
     bool sawDoubleResult() const {
         return extra_ & SAW_DOUBLE_RESULT_BIT;
     }
     void setSawDoubleResult() {
         extra_ |= SAW_DOUBLE_RESULT_BIT;
     }
     bool hadUnoptimizableOperands() const {
         return extra_ & UNOPTIMIZABLE_OPERANDS_BIT;
@@ -2461,37 +2275,32 @@ class ICBinaryArith_Fallback : public IC
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::BinaryArith_Fallback) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_Fallback::New(space, getStubCode());
+            return ICStub::New<ICBinaryArith_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
     ICBinaryArith_Int32(JitCode *stubCode, bool allowDouble)
       : ICStub(BinaryArith_Int32, stubCode)
     {
         extra_ = allowDouble;
     }
 
   public:
-    static inline ICBinaryArith_Int32 *New(ICStubSpace *space, JitCode *code, bool allowDouble) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_Int32>(code, allowDouble);
-    }
     bool allowDouble() const {
         return extra_;
     }
 
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         JSOp op_;
@@ -2506,69 +2315,56 @@ class ICBinaryArith_Int32 : public ICStu
         }
 
       public:
         Compiler(JSContext *cx, JSOp op, bool allowDouble)
           : ICStubCompiler(cx, ICStub::BinaryArith_Int32),
             op_(op), allowDouble_(allowDouble) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_Int32::New(space, getStubCode(), allowDouble_);
+            return ICStub::New<ICBinaryArith_Int32>(space, getStubCode(), allowDouble_);
         }
     };
 };
 
 class ICBinaryArith_StringConcat : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICBinaryArith_StringConcat(JitCode *stubCode)
       : ICStub(BinaryArith_StringConcat, stubCode)
     {}
 
   public:
-    static inline ICBinaryArith_StringConcat *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_StringConcat>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::BinaryArith_StringConcat)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_StringConcat::New(space, getStubCode());
+            return ICStub::New<ICBinaryArith_StringConcat>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_StringObjectConcat : public ICStub
 {
     friend class ICStubSpace;
 
     ICBinaryArith_StringObjectConcat(JitCode *stubCode, bool lhsIsString)
       : ICStub(BinaryArith_StringObjectConcat, stubCode)
     {
         extra_ = lhsIsString;
     }
 
   public:
-    static inline ICBinaryArith_StringObjectConcat *New(ICStubSpace *space, JitCode *code,
-                                                        bool lhsIsString) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_StringObjectConcat>(code, lhsIsString);
-    }
-
     bool lhsIsString() const {
         return extra_;
     }
 
     class Compiler : public ICStubCompiler {
       protected:
         bool lhsIsString_;
         bool generateStubCode(MacroAssembler &masm);
@@ -2579,47 +2375,41 @@ class ICBinaryArith_StringObjectConcat :
 
       public:
         Compiler(JSContext *cx, bool lhsIsString)
           : ICStubCompiler(cx, ICStub::BinaryArith_StringObjectConcat),
             lhsIsString_(lhsIsString)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_StringObjectConcat::New(space, getStubCode(), lhsIsString_);
+            return ICStub::New<ICBinaryArith_StringObjectConcat>(space, getStubCode(), lhsIsString_);
         }
     };
 };
 
 class ICBinaryArith_Double : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICBinaryArith_Double(JitCode *stubCode)
       : ICStub(BinaryArith_Double, stubCode)
     {}
 
   public:
-    static inline ICBinaryArith_Double *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_Double>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::BinaryArith_Double, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_Double::New(space, getStubCode());
+            return ICStub::New<ICBinaryArith_Double>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_BooleanWithInt32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2630,23 +2420,16 @@ class ICBinaryArith_BooleanWithInt32 : p
         extra_ = 0;
         if (lhsIsBool)
             extra_ |= 1;
         if (rhsIsBool)
             extra_ |= 2;
     }
 
   public:
-    static inline ICBinaryArith_BooleanWithInt32 *New(ICStubSpace *space, JitCode *code,
-                                                      bool lhsIsBool, bool rhsIsBool) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_BooleanWithInt32>(code, lhsIsBool, rhsIsBool);
-    }
-
     bool lhsIsBoolean() const {
         return extra_ & 1;
     }
 
     bool rhsIsBoolean() const {
         return extra_ & 2;
     }
 
@@ -2669,40 +2452,33 @@ class ICBinaryArith_BooleanWithInt32 : p
             op_(op), lhsIsBool_(lhsIsBool), rhsIsBool_(rhsIsBool)
         {
             MOZ_ASSERT(op_ == JSOP_ADD || op_ == JSOP_SUB || op_ == JSOP_BITOR ||
                        op_ == JSOP_BITAND || op_ == JSOP_BITXOR);
             MOZ_ASSERT(lhsIsBool_ || rhsIsBool_);
         }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_BooleanWithInt32::New(space, getStubCode(),
-                                                       lhsIsBool_, rhsIsBool_);
+            return ICStub::New<ICBinaryArith_BooleanWithInt32>(space, getStubCode(),
+                                                               lhsIsBool_, rhsIsBool_);
         }
     };
 };
 
 class ICBinaryArith_DoubleWithInt32 : public ICStub
 {
     friend class ICStubSpace;
 
     ICBinaryArith_DoubleWithInt32(JitCode *stubCode, bool lhsIsDouble)
       : ICStub(BinaryArith_DoubleWithInt32, stubCode)
     {
         extra_ = lhsIsDouble;
     }
 
   public:
-    static inline ICBinaryArith_DoubleWithInt32 *New(ICStubSpace *space, JitCode *code,
-                                                     bool lhsIsDouble) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBinaryArith_DoubleWithInt32>(code, lhsIsDouble);
-    }
-
     bool lhsIsDouble() const {
         return extra_;
     }
 
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool lhsIsDouble_;
         bool generateStubCode(MacroAssembler &masm);
@@ -2714,17 +2490,17 @@ class ICBinaryArith_DoubleWithInt32 : pu
 
       public:
         Compiler(JSContext *cx, JSOp op, bool lhsIsDouble)
           : ICMultiStubCompiler(cx, ICStub::BinaryArith_DoubleWithInt32, op),
             lhsIsDouble_(lhsIsDouble)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBinaryArith_DoubleWithInt32::New(space, getStubCode(), lhsIsDouble_);
+            return ICStub::New<ICBinaryArith_DoubleWithInt32>(space, getStubCode(), lhsIsDouble_);
         }
     };
 };
 
 // UnaryArith
 //     JSOP_BITNOT
 //     JSOP_NEG
 
@@ -2736,22 +2512,16 @@ class ICUnaryArith_Fallback : public ICF
       : ICFallbackStub(UnaryArith_Fallback, stubCode)
     {
         extra_ = 0;
     }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICUnaryArith_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICUnaryArith_Fallback>(code);
-    }
-
     bool sawDoubleResult() {
         return extra_;
     }
     void setSawDoubleResult() {
         extra_ = 1;
     }
 
     // Compiler for this stub kind.
@@ -2760,77 +2530,65 @@ class ICUnaryArith_Fallback : public ICF
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::UnaryArith_Fallback)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICUnaryArith_Fallback::New(space, getStubCode());
+            return ICStub::New<ICUnaryArith_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICUnaryArith_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICUnaryArith_Int32(JitCode *stubCode)
       : ICStub(UnaryArith_Int32, stubCode)
     {}
 
   public:
-    static inline ICUnaryArith_Int32 *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICUnaryArith_Int32>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICUnaryArith_Int32::New(space, getStubCode());
+            return ICStub::New<ICUnaryArith_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICUnaryArith_Double : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICUnaryArith_Double(JitCode *stubCode)
       : ICStub(UnaryArith_Double, stubCode)
     {}
 
   public:
-    static inline ICUnaryArith_Double *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICUnaryArith_Double>(code);
-    }
-
     class Compiler : public ICMultiStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICUnaryArith_Double::New(space, getStubCode());
+            return ICStub::New<ICUnaryArith_Double>(space, getStubCode());
         }
     };
 };
 
 // GetElem
 //      JSOP_GETELEM
 
 class ICGetElem_Fallback : public ICMonitoredFallbackStub
@@ -2842,22 +2600,16 @@ class ICGetElem_Fallback : public ICMoni
     { }
 
     static const uint16_t EXTRA_NON_NATIVE = 0x1;
     static const uint16_t EXTRA_NEGATIVE_INDEX = 0x2;
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 16;
 
-    static inline ICGetElem_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_Fallback>(code);
-    }
-
     void noteNonNativeAccess() {
         extra_ |= EXTRA_NON_NATIVE;
     }
     bool hasNonNativeAccess() const {
         return extra_ & EXTRA_NON_NATIVE;
     }
 
     void noteNegativeIndex() {
@@ -2873,17 +2625,17 @@ class ICGetElem_Fallback : public ICMoni
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetElem_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            ICGetElem_Fallback *stub = ICGetElem_Fallback::New(space, getStubCode());
+            ICGetElem_Fallback *stub = ICStub::New<ICGetElem_Fallback>(space, getStubCode());
             if (!stub)
                 return nullptr;
             if (!stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
@@ -2985,56 +2737,30 @@ class ICGetElem_NativeSlot : public ICGe
 {
     friend class ICStubSpace;
     ICGetElem_NativeSlot(JitCode *stubCode, ICStub *firstMonitorStub,
                          HandleShape shape, HandlePropertyName name,
                          AccessType acctype, bool needsAtomize, uint32_t offset)
       : ICGetElemNativeSlotStub(ICStub::GetElem_NativeSlot, stubCode, firstMonitorStub, shape,
                                 name, acctype, needsAtomize, offset)
     {}
-
-  public:
-    static inline ICGetElem_NativeSlot *New(ICStubSpace *space, JitCode *code,
-                                            ICStub *firstMonitorStub,
-                                            HandleShape shape, HandlePropertyName name,
-                                            AccessType acctype, bool needsAtomize, uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_NativeSlot>(code, firstMonitorStub, shape, name,
-                                                     acctype, needsAtomize, offset);
-    }
 };
 
 class ICGetElem_NativePrototypeSlot : public ICGetElemNativeSlotStub
 {
     friend class ICStubSpace;
     HeapPtrObject holder_;
     HeapPtrShape holderShape_;
 
     ICGetElem_NativePrototypeSlot(JitCode *stubCode, ICStub *firstMonitorStub,
                                   HandleShape shape, HandlePropertyName name,
                                   AccessType acctype, bool needsAtomize, uint32_t offset,
                                   HandleObject holder, HandleShape holderShape);
 
   public:
-    static inline ICGetElem_NativePrototypeSlot *New(ICStubSpace *space, JitCode *code,
-                                                     ICStub *firstMonitorStub,
-                                                     HandleShape shape, HandlePropertyName name,
-                                                     AccessType acctype, bool needsAtomize,
-                                                     uint32_t offset, HandleObject holder,
-                                                     HandleShape holderShape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_NativePrototypeSlot>(
-                    code, firstMonitorStub, shape, name, acctype, needsAtomize, offset, holder,
-                    holderShape);
-    }
-
     HeapPtrObject &holder() {
         return holder_;
     }
     static size_t offsetOfHolder() {
         return offsetof(ICGetElem_NativePrototypeSlot, holder_);
     }
 
     HeapPtrShape &holderShape() {
@@ -3085,29 +2811,16 @@ class ICGetElem_NativePrototypeCallNativ
                                         HandleObject holder, HandleShape holderShape)
       : ICGetElemNativePrototypeCallStub(GetElem_NativePrototypeCallNative,
                                          stubCode, firstMonitorStub, shape, name,
                                          acctype, needsAtomize, getter, pcOffset, holder,
                                          holderShape)
     {}
 
   public:
-    static inline ICGetElem_NativePrototypeCallNative *New(
-                    ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                    HandleShape shape, HandlePropertyName name, AccessType acctype,
-                    bool needsAtomize, HandleFunction getter, uint32_t pcOffset,
-                    HandleObject holder, HandleShape holderShape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_NativePrototypeCallNative>(
-                        code, firstMonitorStub, shape, name, acctype, needsAtomize, getter,
-                        pcOffset, holder, holderShape);
-    }
-
     static ICGetElem_NativePrototypeCallNative *Clone(JSContext *cx, ICStubSpace *space,
                                                       ICStub *firstMonitorStub,
                                                       ICGetElem_NativePrototypeCallNative &other);
 };
 
 class ICGetElem_NativePrototypeCallScripted : public ICGetElemNativePrototypeCallStub
 {
     friend class ICStubSpace;
@@ -3119,29 +2832,16 @@ class ICGetElem_NativePrototypeCallScrip
                                           HandleObject holder, HandleShape holderShape)
       : ICGetElemNativePrototypeCallStub(GetElem_NativePrototypeCallScripted,
                                          stubCode, firstMonitorStub, shape, name,
                                          acctype, needsAtomize, getter, pcOffset, holder,
                                          holderShape)
     {}
 
   public:
-    static inline ICGetElem_NativePrototypeCallScripted *New(
-                    ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                    HandleShape shape, HandlePropertyName name, AccessType acctype,
-                    bool needsAtomize, HandleFunction getter, uint32_t pcOffset,
-                    HandleObject holder, HandleShape holderShape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_NativePrototypeCallScripted>(
-                        code, firstMonitorStub, shape, name, acctype, needsAtomize, getter,
-                        pcOffset, holder, holderShape);
-    }
-
     static ICGetElem_NativePrototypeCallScripted *
     Clone(JSContext *cx, ICStubSpace *space,
           ICStub *firstMonitorStub,
           ICGetElem_NativePrototypeCallScripted &other);
 };
 
 // Compiler for GetElem_NativeSlot and GetElem_NativePrototypeSlot stubs.
 class ICGetElemNativeCompiler : public ICStubCompiler
@@ -3208,92 +2908,78 @@ class ICGetElemNativeCompiler : public I
         getter_(getter),
         pcOffset_(pcOffset)
     {}
 
     ICStub *getStub(ICStubSpace *space) {
         RootedShape shape(cx, obj_->lastProperty());
         if (kind == ICStub::GetElem_NativeSlot) {
             MOZ_ASSERT(obj_ == holder_);
-            return ICGetElem_NativeSlot::New(
+            return ICStub::New<ICGetElem_NativeSlot>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     offset_);
         }
 
         MOZ_ASSERT(obj_ != holder_);
         RootedShape holderShape(cx, holder_->lastProperty());
         if (kind == ICStub::GetElem_NativePrototypeSlot) {
-            return ICGetElem_NativePrototypeSlot::New(
+            return ICStub::New<ICGetElem_NativePrototypeSlot>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     offset_, holder_, holderShape);
         }
 
         if (kind == ICStub::GetElem_NativePrototypeCallNative) {
-            return ICGetElem_NativePrototypeCallNative::New(
+            return ICStub::New<ICGetElem_NativePrototypeCallNative>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     getter_, pcOffset_, holder_, holderShape);
         }
 
         MOZ_ASSERT(kind == ICStub::GetElem_NativePrototypeCallScripted);
         if (kind == ICStub::GetElem_NativePrototypeCallScripted) {
-            return ICGetElem_NativePrototypeCallScripted::New(
+            return ICStub::New<ICGetElem_NativePrototypeCallScripted>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     getter_, pcOffset_, holder_, holderShape);
         }
 
         MOZ_CRASH("Invalid kind.");
     }
 };
 
 class ICGetElem_String : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICGetElem_String(JitCode *stubCode)
       : ICStub(ICStub::GetElem_String, stubCode) {}
 
   public:
-    static inline ICGetElem_String *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_String>(code);
-    }
-
     // Compiler for this stub kind.
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetElem_String) {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetElem_String::New(space, getStubCode());
+            return ICStub::New<ICGetElem_String>(space, getStubCode());
         }
     };
 };
 
 class ICGetElem_Dense : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
     HeapPtrShape shape_;
 
     ICGetElem_Dense(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape);
 
   public:
-    static inline ICGetElem_Dense *New(ICStubSpace *space, JitCode *code,
-                                       ICStub *firstMonitorStub, HandleShape shape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_Dense>(code, firstMonitorStub, shape);
-    }
-
     static ICGetElem_Dense *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                   ICGetElem_Dense &other);
 
     static size_t offsetOfShape() {
         return offsetof(ICGetElem_Dense, shape_);
     }
 
     HeapPtrShape &shape() {
@@ -3320,17 +3006,17 @@ class ICGetElem_Dense : public ICMonitor
         Compiler(JSContext *cx, ICStub *firstMonitorStub, Shape *shape, bool isCallElem)
           : ICStubCompiler(cx, ICStub::GetElem_Dense),
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             isCallElem_(isCallElem)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetElem_Dense::New(space, getStubCode(), firstMonitorStub_, shape_);
+            return ICStub::New<ICGetElem_Dense>(space, getStubCode(), firstMonitorStub_, shape_);
         }
     };
 };
 
 // Enum for stubs handling a combination of typed arrays and typed objects.
 enum TypedThingLayout {
     Layout_TypedArray,
     Layout_OutlineTypedObject,
@@ -3355,24 +3041,16 @@ class ICGetElem_TypedArray : public ICSt
     friend class ICStubSpace;
 
   protected: // Protected to silence Clang warning.
     HeapPtrShape shape_;
 
     ICGetElem_TypedArray(JitCode *stubCode, HandleShape shape, Scalar::Type type);
 
   public:
-    static inline ICGetElem_TypedArray *New(ICStubSpace *space, JitCode *code,
-                                            HandleShape shape, Scalar::Type type)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_TypedArray>(code, shape, type);
-    }
-
     static size_t offsetOfShape() {
         return offsetof(ICGetElem_TypedArray, shape_);
     }
 
     HeapPtrShape &shape() {
         return shape_;
     }
 
@@ -3394,17 +3072,17 @@ class ICGetElem_TypedArray : public ICSt
         Compiler(JSContext *cx, Shape *shape, Scalar::Type type)
           : ICStubCompiler(cx, ICStub::GetElem_TypedArray),
             shape_(cx, shape),
             type_(type),
             layout_(GetTypedThingLayout(shape->getObjectClass()))
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetElem_TypedArray::New(space, getStubCode(), shape_, type_);
+            return ICStub::New<ICGetElem_TypedArray>(space, getStubCode(), shape_, type_);
         }
     };
 };
 
 class ICGetElem_Arguments : public ICMonitoredStub
 {
     friend class ICStubSpace;
   public:
@@ -3413,24 +3091,16 @@ class ICGetElem_Arguments : public ICMon
   private:
     ICGetElem_Arguments(JitCode *stubCode, ICStub *firstMonitorStub, Which which)
       : ICMonitoredStub(ICStub::GetElem_Arguments, stubCode, firstMonitorStub)
     {
         extra_ = static_cast<uint16_t>(which);
     }
 
   public:
-    static inline ICGetElem_Arguments *New(ICStubSpace *space, JitCode *code,
-                                           ICStub *firstMonitorStub, Which which)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetElem_Arguments>(code, firstMonitorStub, which);
-    }
-
     static ICGetElem_Arguments *Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                                       ICGetElem_Arguments &other);
 
     Which which() const {
         return static_cast<Which>(extra_);
     }
 
     class Compiler : public ICStubCompiler {
@@ -3455,17 +3125,17 @@ class ICGetElem_Arguments : public ICMon
         Compiler(JSContext *cx, ICStub *firstMonitorStub, Which which, bool isCallElem)
           : ICStubCompiler(cx, ICStub::GetElem_Arguments),
             firstMonitorStub_(firstMonitorStub),
             which_(which),
             isCallElem_(isCallElem)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetElem_Arguments::New(space, getStubCode(), firstMonitorStub_, which_);
+            return ICStub::New<ICGetElem_Arguments>(space, getStubCode(), firstMonitorStub_, which_);
         }
     };
 };
 
 // SetElem
 //      JSOP_SETELEM
 //      JSOP_INITELEM
 
@@ -3475,22 +3145,16 @@ class ICSetElem_Fallback : public ICFall
 
     explicit ICSetElem_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::SetElem_Fallback, stubCode)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICSetElem_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetElem_Fallback>(code);
-    }
-
     void noteArrayWriteHole() {
         extra_ = 1;
     }
     bool hasArrayWriteHole() const {
         return extra_;
     }
 
     // Compiler for this stub kind.
@@ -3499,38 +3163,31 @@ class ICSetElem_Fallback : public ICFall
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::SetElem_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICSetElem_Fallback::New(space, getStubCode());
+            return ICStub::New<ICSetElem_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICSetElem_Dense : public ICUpdatedStub
 {
     friend class ICStubSpace;
 
     HeapPtrShape shape_;
     HeapPtrObjectGroup group_;
 
     ICSetElem_Dense(JitCode *stubCode, HandleShape shape, HandleObjectGroup group);
 
   public:
-    static inline ICSetElem_Dense *New(ICStubSpace *space, JitCode *code, HandleShape shape,
-                                       HandleObjectGroup group) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetElem_Dense>(code, shape, group);
-    }
-
     static size_t offsetOfShape() {
         return offsetof(ICSetElem_Dense, shape_);
     }
     static size_t offsetOfGroup() {
         return offsetof(ICSetElem_Dense, group_);
     }
 
     HeapPtrShape &shape() {
@@ -3553,17 +3210,17 @@ class ICSetElem_Dense : public ICUpdated
       public:
         Compiler(JSContext *cx, Shape *shape, HandleObjectGroup group)
           : ICStubCompiler(cx, ICStub::SetElem_Dense),
             shape_(cx, shape),
             group_(group)
         {}
 
         ICUpdatedStub *getStub(ICStubSpace *space) {
-            ICSetElem_Dense *stub = ICSetElem_Dense::New(space, getStubCode(), shape_, group_);
+            ICSetElem_Dense *stub = ICStub::New<ICSetElem_Dense>(space, getStubCode(), shape_, group_);
             if (!stub || !stub->initUpdatingChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 template <size_t ProtoChainDepth> class ICSetElem_DenseAddImpl;
@@ -3618,25 +3275,16 @@ class ICSetElem_DenseAddImpl : public IC
       : ICSetElem_DenseAdd(stubCode, group, ProtoChainDepth)
     {
         MOZ_ASSERT(shapes->length() == NumShapes);
         for (size_t i = 0; i < NumShapes; i++)
             shapes_[i].init((*shapes)[i]);
     }
 
   public:
-    static inline ICSetElem_DenseAddImpl *New(ICStubSpace *space, JitCode *code,
-                                              ObjectGroup *group,
-                                              const AutoShapeVector *shapes)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetElem_DenseAddImpl<ProtoChainDepth> >(code, group, shapes);
-    }
-
     void traceShapes(JSTracer *trc) {
         for (size_t i = 0; i < NumShapes; i++)
             MarkShape(trc, &shapes_[i], "baseline-setelem-denseadd-stub-shape");
     }
     Shape *shape(size_t i) const {
         MOZ_ASSERT(i < NumShapes);
         return shapes_[i];
     }
@@ -3676,25 +3324,16 @@ class ICSetElem_TypedArray : public ICSt
 
   protected: // Protected to silence Clang warning.
     HeapPtrShape shape_;
 
     ICSetElem_TypedArray(JitCode *stubCode, HandleShape shape, Scalar::Type type,
                          bool expectOutOfBounds);
 
   public:
-    static inline ICSetElem_TypedArray *New(ICStubSpace *space, JitCode *code,
-                                            HandleShape shape, Scalar::Type type,
-                                            bool expectOutOfBounds)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetElem_TypedArray>(code, shape, type, expectOutOfBounds);
-    }
-
     Scalar::Type type() const {
         return (Scalar::Type) (extra_ & 0xff);
     }
 
     bool expectOutOfBounds() const {
         return (extra_ >> 8) & 1;
     }
 
@@ -3727,50 +3366,44 @@ class ICSetElem_TypedArray : public ICSt
           : ICStubCompiler(cx, ICStub::SetElem_TypedArray),
             shape_(cx, shape),
             type_(type),
             layout_(GetTypedThingLayout(shape->getObjectClass())),
             expectOutOfBounds_(expectOutOfBounds)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICSetElem_TypedArray::New(space, getStubCode(), shape_, type_,
-                                             expectOutOfBounds_);
+            return ICStub::New<ICSetElem_TypedArray>(space, getStubCode(), shape_, type_,
+                                                     expectOutOfBounds_);
         }
     };
 };
 
 // In
 //      JSOP_IN
 class ICIn_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICIn_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::In_Fallback, stubCode)
     { }
 
   public:
-    static inline ICIn_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICIn_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::In_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICIn_Fallback::New(space, getStubCode());
+            return ICStub::New<ICIn_Fallback>(space, getStubCode());
         }
     };
 };
 
 // GetName
 //      JSOP_GETNAME
 //      JSOP_GETGNAME
 class ICGetName_Fallback : public ICMonitoredFallbackStub
@@ -3778,23 +3411,16 @@ class ICGetName_Fallback : public ICMoni
     friend class ICStubSpace;
 
     explicit ICGetName_Fallback(JitCode *stubCode)
       : ICMonitoredFallbackStub(ICStub::GetName_Fallback, stubCode)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
-
-    static inline ICGetName_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetName_Fallback>(code);
-    }
-
     static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
 
     void noteUnoptimizableAccess() {
         extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
     bool hadUnoptimizableAccess() const {
         return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
@@ -3804,17 +3430,17 @@ class ICGetName_Fallback : public ICMoni
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetName_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            ICGetName_Fallback *stub = ICGetName_Fallback::New(space, getStubCode());
+            ICGetName_Fallback *stub = ICStub::New<ICGetName_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Optimized GETGNAME/CALLGNAME stub.
@@ -3824,24 +3450,16 @@ class ICGetName_Global : public ICMonito
 
   protected: // Protected to silence Clang warning.
     HeapPtrShape shape_;
     uint32_t slot_;
 
     ICGetName_Global(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape, uint32_t slot);
 
   public:
-    static inline ICGetName_Global *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                                        HandleShape shape, uint32_t slot)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetName_Global>(code, firstMonitorStub, shape, slot);
-    }
-
     HeapPtrShape &shape() {
         return shape_;
     }
     static size_t offsetOfShape() {
         return offsetof(ICGetName_Global, shape_);
     }
     static size_t offsetOfSlot() {
         return offsetof(ICGetName_Global, slot_);
@@ -3859,17 +3477,18 @@ class ICGetName_Global : public ICMonito
         Compiler(JSContext *cx, ICStub *firstMonitorStub, Shape *shape, uint32_t slot)
           : ICStubCompiler(cx, ICStub::GetName_Global),
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             slot_(slot)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetName_Global::New(space, getStubCode(), firstMonitorStub_, shape_, slot_);
+            return ICStub::New<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, shape_,
+                                                 slot_);
         }
     };
 };
 
 // Optimized GETNAME/CALLNAME stub, making a variable number of hops to get an
 // 'own' property off some scope object. Unlike GETPROP on an object's
 // prototype, there is no teleporting optimization to take advantage of and
 // shape checks are required all along the scope chain.
@@ -3886,24 +3505,16 @@ class ICGetName_Scope : public ICMonitor
     ICGetName_Scope(JitCode *stubCode, ICStub *firstMonitorStub,
                     AutoShapeVector *shapes, uint32_t offset);
 
     static Kind GetStubKind() {
         return (Kind) (GetName_Scope0 + NumHops);
     }
 
   public:
-    static inline ICGetName_Scope *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                                       AutoShapeVector *shapes, uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetName_Scope<NumHops> >(code, firstMonitorStub, shapes, offset);
-    }
-
     void traceScopes(JSTracer *trc) {
         for (size_t i = 0; i < NumHops + 1; i++)
             MarkShape(trc, &shapes_[i], "baseline-scope-stub-shape");
     }
 
     static size_t offsetOfShape(size_t index) {
         MOZ_ASSERT(index <= NumHops);
         return offsetof(ICGetName_Scope, shapes_) + (index * sizeof(HeapPtrShape));
@@ -3933,81 +3544,70 @@ class ICGetName_Scope : public ICMonitor
             firstMonitorStub_(firstMonitorStub),
             shapes_(shapes),
             isFixedSlot_(isFixedSlot),
             offset_(offset)
         {
         }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetName_Scope::New(space, getStubCode(), firstMonitorStub_, shapes_, offset_);
+            return ICStub::New<ICGetName_Scope>(space, getStubCode(), firstMonitorStub_, shapes_, offset_);
         }
     };
 };
 
 // BindName
 //      JSOP_BINDNAME
 class ICBindName_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICBindName_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::BindName_Fallback, stubCode)
     { }
 
   public:
-    static inline ICBindName_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICBindName_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::BindName_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICBindName_Fallback::New(space, getStubCode());
+            return ICStub::New<ICBindName_Fallback>(space, getStubCode());
         }
     };
 };
 
 // GetIntrinsic
 //      JSOP_GETINTRINSIC
 class ICGetIntrinsic_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICGetIntrinsic_Fallback(JitCode *stubCode)
       : ICMonitoredFallbackStub(ICStub::GetIntrinsic_Fallback, stubCode)
     { }
 
   public:
-    static inline ICGetIntrinsic_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetIntrinsic_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetIntrinsic_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            ICGetIntrinsic_Fallback *stub = ICGetIntrinsic_Fallback::New(space, getStubCode());
+            ICGetIntrinsic_Fallback *stub =
+                ICStub::New<ICGetIntrinsic_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Stub that loads the constant result of a GETINTRINSIC operation.
@@ -4016,24 +3616,16 @@ class ICGetIntrinsic_Constant : public I
     friend class ICStubSpace;
 
     HeapValue value_;
 
     ICGetIntrinsic_Constant(JitCode *stubCode, HandleValue value);
     ~ICGetIntrinsic_Constant();
 
   public:
-    static inline ICGetIntrinsic_Constant *New(ICStubSpace *space, JitCode *code,
-                                               HandleValue value)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetIntrinsic_Constant>(code, value);
-    }
-
     HeapValue &value() {
         return value_;
     }
     static size_t offsetOfValue() {
         return offsetof(ICGetIntrinsic_Constant, value_);
     }
 
     class Compiler : public ICStubCompiler {
@@ -4043,38 +3635,31 @@ class ICGetIntrinsic_Constant : public I
 
       public:
         Compiler(JSContext *cx, HandleValue value)
           : ICStubCompiler(cx, ICStub::GetIntrinsic_Constant),
             value_(value)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetIntrinsic_Constant::New(space, getStubCode(), value_);
+            return ICStub::New<ICGetIntrinsic_Constant>(space, getStubCode(), value_);
         }
     };
 };
 
 class ICGetProp_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICGetProp_Fallback(JitCode *stubCode)
       : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 16;
-
-    static inline ICGetProp_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_Fallback>(code);
-    }
-
     static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
     static const size_t ACCESSED_GETTER_BIT = 1;
 
     void noteUnoptimizableAccess() {
         extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
     bool hadUnoptimizableAccess() const {
         return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
@@ -4094,17 +3679,17 @@ class ICGetProp_Fallback : public ICMoni
         bool postGenerateStubCode(MacroAssembler &masm, Handle<JitCode *> code);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetProp_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            ICGetProp_Fallback *stub = ICGetProp_Fallback::New(space, getStubCode());
+            ICGetProp_Fallback *stub = ICStub::New<ICGetProp_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Stub for sites, which are too polymorphic (i.e. MAX_OPTIMIZED_STUBS was reached)
@@ -4112,68 +3697,55 @@ class ICGetProp_Generic : public ICMonit
 {
     friend class ICStubSpace;
 
   protected:
     explicit ICGetProp_Generic(JitCode *stubCode, ICStub *firstMonitorStub)
       : ICMonitoredStub(ICStub::GetProp_Generic, stubCode, firstMonitorStub) {}
 
   public:
-    static inline ICGetProp_Generic *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub)
-    {
-        if(!code)
-            return nullptr;
-        return space->allocate<ICGetProp_Generic>(code, firstMonitorStub);
-    }
-
     static ICGetProp_Generic *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                     ICGetProp_Generic &other);
 
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
         ICStub *firstMonitorStub_;
       public:
         explicit Compiler(JSContext *cx, ICStub *firstMonitorStub)
           : ICStubCompiler(cx, ICStub::GetProp_Generic),
             firstMonitorStub_(firstMonitorStub)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_Generic::New(space, getStubCode(), firstMonitorStub_);
+            return ICStub::New<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
         }
     };
 };
 
 // Stub for accessing a dense array's length.
 class ICGetProp_ArrayLength : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICGetProp_ArrayLength(JitCode *stubCode)
       : ICStub(GetProp_ArrayLength, stubCode)
     {}
 
   public:
-    static inline ICGetProp_ArrayLength *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_ArrayLength>(code);
-    }
-
     class Compiler : public ICStubCompiler {
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetProp_ArrayLength)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_ArrayLength::New(space, getStubCode());
+            return ICStub::New<ICGetProp_ArrayLength>(space, getStubCode());
         }
     };
 };
 
 // Stub for accessing a property on a primitive's prototype.
 class ICGetProp_Primitive : public ICMonitoredStub
 {
     friend class ICStubSpace;
@@ -4184,24 +3756,16 @@ class ICGetProp_Primitive : public ICMon
 
     // Fixed or dynamic slot offset.
     uint32_t offset_;
 
     ICGetProp_Primitive(JitCode *stubCode, ICStub *firstMonitorStub,
                         HandleShape protoShape, uint32_t offset);
 
   public:
-    static inline ICGetProp_Primitive *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                                           HandleShape protoShape, uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_Primitive>(code, firstMonitorStub, protoShape, offset);
-    }
-
     HeapPtrShape &protoShape() {
         return protoShape_;
     }
     static size_t offsetOfProtoShape() {
         return offsetof(ICGetProp_Primitive, protoShape_);
     }
 
     static size_t offsetOfOffset() {
@@ -4233,48 +3797,42 @@ class ICGetProp_Primitive : public ICMon
             primitiveType_(primitiveType),
             prototype_(cx, prototype),
             isFixedSlot_(isFixedSlot),
             offset_(offset)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape protoShape(cx, prototype_->lastProperty());
-            return ICGetProp_Primitive::New(space, getStubCode(), firstMonitorStub_,
-                                            protoShape, offset_);
+            return ICStub::New<ICGetProp_Primitive>(space, getStubCode(), firstMonitorStub_,
+                                                    protoShape, offset_);
         }
     };
 };
 
 // Stub for accessing a string's length.
 class ICGetProp_StringLength : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICGetProp_StringLength(JitCode *stubCode)
       : ICStub(GetProp_StringLength, stubCode)
     {}
 
   public:
-    static inline ICGetProp_StringLength *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_StringLength>(code);
-    }
-
     class Compiler : public ICStubCompiler {
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetProp_StringLength)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_StringLength::New(space, getStubCode());
+            return ICStub::New<ICGetProp_StringLength>(space, getStubCode());
         }
     };
 };
 
 // Base class for native GetProp stubs.
 class ICGetPropNativeStub : public ICMonitoredStub
 {
     // Fixed or dynamic slot offset.
@@ -4309,25 +3867,16 @@ class ICGetProp_Native : public ICGetPro
 
     ICGetProp_Native(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                      uint32_t offset)
       : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, offset),
         shape_(shape)
     {}
 
   public:
-    static inline ICGetProp_Native *New(ICStubSpace *space, JitCode *code,
-                                        ICStub *firstMonitorStub, HandleShape shape,
-                                        uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_Native>(code, firstMonitorStub, shape, offset);
-    }
-
     HeapPtrShape &shape() {
         return shape_;
     }
     static size_t offsetOfShape() {
         return offsetof(ICGetProp_Native, shape_);
     }
 
     static ICGetProp_Native *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
@@ -4348,27 +3897,16 @@ class ICGetProp_NativePrototype : public
     // Holder and its shape.
     HeapPtrObject holder_;
     HeapPtrShape holderShape_;
 
     ICGetProp_NativePrototype(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                               uint32_t offset, HandleObject holder, HandleShape holderShape);
 
   public:
-    static inline ICGetProp_NativePrototype *New(ICStubSpace *space, JitCode *code,
-                                                 ICStub *firstMonitorStub, HandleShape shape,
-                                                 uint32_t offset, HandleObject holder,
-                                                 HandleShape holderShape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_NativePrototype>(code, firstMonitorStub, shape, offset,
-                                                          holder, holderShape);
-    }
-
     static ICGetProp_NativePrototype *Clone(JSContext *cx, ICStubSpace *space,
                                             ICStub *firstMonitorStub,
                                             ICGetProp_NativePrototype &other);
 
   public:
     HeapPtrShape &shape() {
         return shape_;
     }
@@ -4404,28 +3942,16 @@ class ICGetProp_UnboxedPrototype : publi
     HeapPtrObject holder_;
     HeapPtrShape holderShape_;
 
     ICGetProp_UnboxedPrototype(JitCode *stubCode, ICStub *firstMonitorStub,
                                HandleObjectGroup group,
                                uint32_t offset, HandleObject holder, HandleShape holderShape);
 
   public:
-    static inline ICGetProp_UnboxedPrototype *New(ICStubSpace *space, JitCode *code,
-                                                  ICStub *firstMonitorStub,
-                                                  HandleObjectGroup group,
-                                                  uint32_t offset, HandleObject holder,
-                                                  HandleShape holderShape)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_UnboxedPrototype>(code, firstMonitorStub, group, offset,
-                                                           holder, holderShape);
-    }
-
     static ICGetProp_UnboxedPrototype *Clone(JSContext *cx, ICStubSpace *space,
                                              ICStub *firstMonitorStub,
                                              ICGetProp_UnboxedPrototype &other);
 
   public:
     HeapPtrObjectGroup &group() {
         return group_;
     }
@@ -4501,26 +4027,16 @@ class ICGetProp_NativeDoesNotExist : pub
   public:
     static const size_t MAX_PROTO_CHAIN_DEPTH = 8;
 
   protected:
     ICGetProp_NativeDoesNotExist(JitCode *stubCode, ICStub *firstMonitorStub,
                                  size_t protoChainDepth);
 
   public:
-    static inline ICGetProp_NativeDoesNotExist *New(ICStubSpace *space, JitCode *code,
-                                                    ICStub *firstMonitorStub,
-                                                    size_t protoChainDepth)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_NativeDoesNotExist>(code, firstMonitorStub,
-                                                             protoChainDepth);
-    }
-
     size_t protoChainDepth() const {
         MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH);
         return extra_;
     }
 
     template <size_t ProtoChainDepth>
     ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth> *toImpl() {
         MOZ_ASSERT(ProtoChainDepth == protoChainDepth());
@@ -4540,26 +4056,16 @@ class ICGetProp_NativeDoesNotExistImpl :
 
   private:
     mozilla::Array<HeapPtrShape, NumShapes> shapes_;
 
     ICGetProp_NativeDoesNotExistImpl(JitCode *stubCode, ICStub *firstMonitorStub,
                                      const AutoShapeVector *shapes);
 
   public:
-    static inline ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth> *New(
-        ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-        const AutoShapeVector *shapes)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>>(
-                    code, firstMonitorStub, shapes);
-    }
-
     void traceShapes(JSTracer *trc) {
         for (size_t i = 0; i < NumShapes; i++)
             MarkShape(trc, &shapes_[i], "baseline-getpropnativedoesnotexist-stub-shape");
     }
 
     static size_t offsetOfShape(size_t idx) {
         return offsetof(ICGetProp_NativeDoesNotExistImpl, shapes_) + (idx * sizeof(HeapPtrShape));
     }
@@ -4579,18 +4085,18 @@ class ICGetPropNativeDoesNotExistCompile
     bool generateStubCode(MacroAssembler &masm);
 
   public:
     ICGetPropNativeDoesNotExistCompiler(JSContext *cx, ICStub *firstMonitorStub,
                                         HandleObject obj, size_t protoChainDepth);
 
     template <size_t ProtoChainDepth>
     ICStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes) {
-        return ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>::New(space, getStubCode(),
-                                                                      firstMonitorStub_, shapes);
+        return ICStub::New<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>>(space, getStubCode(),
+                                                                              firstMonitorStub_, shapes);
     }
 
     ICStub *getStub(ICStubSpace *space);
 };
 
 class ICGetProp_Unboxed : public ICMonitoredStub
 {
     friend class ICStubSpace;
@@ -4602,25 +4108,16 @@ class ICGetProp_Unboxed : public ICMonit
                       uint32_t fieldOffset)
       : ICMonitoredStub(ICStub::GetProp_Unboxed, stubCode, firstMonitorStub),
         group_(group), fieldOffset_(fieldOffset)
     {
         (void) fieldOffset_; // Silence clang warning
     }
 
   public:
-    static inline ICGetProp_Unboxed *New(ICStubSpace *space, JitCode *code,
-                                         ICStub *firstMonitorStub, HandleObjectGroup group,
-                                         uint32_t fieldOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_Unboxed>(code, firstMonitorStub, group, fieldOffset);
-    }
-
     HeapPtrObjectGroup &group() {
         return group_;
     }
 
     static size_t offsetOfGroup() {
         return offsetof(ICGetProp_Unboxed, group_);
     }
     static size_t offsetOfFieldOffset() {
@@ -4646,18 +4143,18 @@ class ICGetProp_Unboxed : public ICMonit
           : ICStubCompiler(cx, ICStub::GetProp_Unboxed),
             firstMonitorStub_(firstMonitorStub),
             group_(cx, group),
             fieldOffset_(fieldOffset),
             fieldType_(fieldType)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_Unboxed::New(space, getStubCode(), firstMonitorStub_,
-                                          group_, fieldOffset_);
+            return ICStub::New<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_,
+                                                  group_, fieldOffset_);
         }
     };
 };
 
 static uint32_t
 SimpleTypeDescrKey(SimpleTypeDescr *descr)
 {
     if (descr->is<ScalarTypeDescr>())
@@ -4676,25 +4173,16 @@ class ICGetProp_TypedObject : public ICM
                           uint32_t fieldOffset)
       : ICMonitoredStub(ICStub::GetProp_TypedObject, stubCode, firstMonitorStub),
         shape_(shape), fieldOffset_(fieldOffset)
     {
         (void) fieldOffset_; // Silence clang warning
     }
 
   public:
-    static inline ICGetProp_TypedObject *New(ICStubSpace *space, JitCode *code,
-                                             ICStub *firstMonitorStub, HandleShape shape,
-                                             uint32_t fieldOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_TypedObject>(code, firstMonitorStub, shape, fieldOffset);
-    }
-
     HeapPtrShape &shape() {
         return shape_;
     }
 
     static size_t offsetOfShape() {
         return offsetof(ICGetProp_TypedObject, shape_);
     }
     static size_t offsetOfFieldOffset() {
@@ -4724,18 +4212,18 @@ class ICGetProp_TypedObject : public ICM
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             fieldOffset_(fieldOffset),
             layout_(GetTypedThingLayout(shape->getObjectClass())),
             fieldDescr_(cx, fieldDescr)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_TypedObject::New(space, getStubCode(), firstMonitorStub_,
-                                              shape_, fieldOffset_);
+            return ICStub::New<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_,
+                                                      shape_, fieldOffset_);
         }
     };
 };
 
 class ICGetPropCallGetter : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
@@ -4862,28 +4350,16 @@ class ICGetProp_CallScripted : public IC
     ICGetProp_CallScripted(JitCode *stubCode, ICStub *firstMonitorStub,
                            HandleShape receiverShape, HandleObject holder, HandleShape holderShape,
                            HandleFunction getter, uint32_t pcOffset)
       : ICGetPropCallPrototypeGetter(GetProp_CallScripted, stubCode, firstMonitorStub,
                                      receiverShape, holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static inline ICGetProp_CallScripted *New(
-                ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                HandleShape receiverShape, HandleObject holder, HandleShape holderShape,
-                HandleFunction getter, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_CallScripted>(code, firstMonitorStub,
-                                                       receiverShape, holder, holderShape, getter,
-                                                       pcOffset);
-    }
-
     static ICGetProp_CallScripted *Clone(JSContext *cx, ICStubSpace *space,
                                          ICStub *firstMonitorStub, ICGetProp_CallScripted &other);
 
     class Compiler : public ICGetPropCallPrototypeGetter::Compiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
@@ -4892,18 +4368,19 @@ class ICGetProp_CallScripted : public IC
           : ICGetPropCallPrototypeGetter::Compiler(cx, ICStub::GetProp_CallScripted,
                                                    firstMonitorStub, obj, holder,
                                                    getter, pcOffset, /* outerClass = */ nullptr)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape receiverShape(cx, receiver_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
-            return ICGetProp_CallScripted::New(space, getStubCode(), firstMonitorStub_, receiverShape,
-                                               holder_, holderShape, getter_, pcOffset_);
+            return ICStub::New<ICGetProp_CallScripted>(space, getStubCode(), firstMonitorStub_,
+                                                       receiverShape, holder_, holderShape, getter_,
+                                                       pcOffset_);
         }
     };
 };
 
 // Stub for calling an own native getter on a native object.
 class ICGetProp_CallNative : public ICGetPropCallGetter
 {
     friend class ICStubSpace;
@@ -4912,27 +4389,16 @@ class ICGetProp_CallNative : public ICGe
 
     ICGetProp_CallNative(JitCode *stubCode, ICStub *firstMonitorStub, HandleObject obj,
                             HandleShape shape, HandleFunction getter, uint32_t pcOffset)
       : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub, obj, shape,
                             getter, pcOffset)
     { }
 
   public:
-    static inline ICGetProp_CallNative *New(ICStubSpace *space, JitCode *code,
-                                            ICStub *firstMonitorStub, HandleObject obj,
-                                            HandleShape shape, HandleFunction getter,
-                                            uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_CallNative>(code, firstMonitorStub, obj, shape,
-                                                     getter, pcOffset);
-    }
-
     static ICGetProp_CallNative *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                        ICGetProp_CallNative &other);
 
     class Compiler : public ICGetPropCallGetter::Compiler
     {
         bool inputDefinitelyObject_;
       protected:
         bool generateStubCode(MacroAssembler &masm);
@@ -4948,18 +4414,18 @@ class ICGetProp_CallNative : public ICGe
                  bool inputDefinitelyObject = false)
           : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallNative, firstMonitorStub,
                                           obj, getter, pcOffset, outerClass),
             inputDefinitelyObject_(inputDefinitelyObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape shape(cx, holder_->lastProperty());
-            return ICGetProp_CallNative::New(space, getStubCode(), firstMonitorStub_, holder_,
-                                             shape, getter_, pcOffset_);
+            return ICStub::New<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
+                                                     holder_, shape, getter_, pcOffset_);
         }
     };
 };
 
 // Stub for calling an native getter on a native object when the getter is kept on the proto-chain.
 class ICGetProp_CallNativePrototype : public ICGetPropCallPrototypeGetter
 {
     friend class ICStubSpace;
@@ -4968,28 +4434,16 @@ class ICGetProp_CallNativePrototype : pu
     ICGetProp_CallNativePrototype(JitCode *stubCode, ICStub *firstMonitorStub,
                          HandleShape receiverShape, HandleObject holder, HandleShape holderShape,
                          HandleFunction getter, uint32_t pcOffset)
       : ICGetPropCallPrototypeGetter(GetProp_CallNativePrototype, stubCode, firstMonitorStub,
                                      receiverShape, holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static inline ICGetProp_CallNativePrototype *New(
-                ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                HandleShape receiverShape, HandleObject holder, HandleShape holderShape,
-                HandleFunction getter, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_CallNativePrototype>(code, firstMonitorStub,
-                                                              receiverShape, holder, holderShape,
-                                                              getter, pcOffset);
-    }
-
     static ICGetProp_CallNativePrototype *Clone(JSContext *cx, ICStubSpace *space,
                                                 ICStub *firstMonitorStub,
                                                 ICGetProp_CallNativePrototype &other);
 
     class Compiler : public ICGetPropCallPrototypeGetter::Compiler {
         bool inputDefinitelyObject_;
       protected:
         bool generateStubCode(MacroAssembler &masm);
@@ -5007,18 +4461,19 @@ class ICGetProp_CallNativePrototype : pu
                                                    firstMonitorStub, obj, holder,
                                                    getter, pcOffset, outerClass),
             inputDefinitelyObject_(inputDefinitelyObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape receiverShape(cx, receiver_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
-            return ICGetProp_CallNativePrototype::New(space, getStubCode(), firstMonitorStub_, receiverShape,
-                                                      holder_, holderShape, getter_, pcOffset_);
+            return ICStub::New<ICGetProp_CallNativePrototype>(space, getStubCode(), firstMonitorStub_,
+                                                              receiverShape, holder_, holderShape,
+                                                              getter_, pcOffset_);
         }
     };
 };
 
 class ICGetPropCallDOMProxyNativeStub : public ICGetPropCallGetter
 {
   friend class ICStubSpace;
   protected:
@@ -5063,29 +4518,16 @@ class ICGetProp_CallDOMProxyNative : pub
                                  HandleObject holder, HandleShape holderShape,
                                  HandleFunction getter, uint32_t pcOffset)
       : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyNative, stubCode,
                                         firstMonitorStub, shape, proxyHandler, expandoShape,
                                         holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static inline ICGetProp_CallDOMProxyNative *New(
-            ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-            HandleShape shape, const BaseProxyHandler *proxyHandler,
-            HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
-            HandleFunction getter, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_CallDOMProxyNative>(code, firstMonitorStub, shape,
-                                                   proxyHandler, expandoShape, holder,
-                                                   holderShape, getter, pcOffset);
-    }
-
     static ICGetProp_CallDOMProxyNative *Clone(JSContext *cx, ICStubSpace *space,
                                                ICStub *firstMonitorStub,
                                                ICGetProp_CallDOMProxyNative &other);
 };
 
 class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyNativeStub
 {
   protected:
@@ -5102,31 +4544,16 @@ class ICGetProp_CallDOMProxyWithGenerati
       : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative,
                                         stubCode, firstMonitorStub, shape, proxyHandler,
                                         expandoShape, holder, holderShape, getter, pcOffset),
         expandoAndGeneration_(expandoAndGeneration),
         generation_(generation)
     {
     }
 
-    static inline ICGetProp_CallDOMProxyWithGenerationNative *New(
-            ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-            HandleShape shape, const BaseProxyHandler *proxyHandler,
-            ExpandoAndGeneration *expandoAndGeneration, uint32_t generation,
-            HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
-            HandleFunction getter, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_CallDOMProxyWithGenerationNative>(code, firstMonitorStub,
-                                                   shape, proxyHandler, expandoAndGeneration,
-                                                   generation, expandoShape, holder, holderShape,
-                                                   getter, pcOffset);
-    }
-
     static ICGetProp_CallDOMProxyWithGenerationNative *
     Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
           ICGetProp_CallDOMProxyWithGenerationNative &other);
 
     void *expandoAndGeneration() const {
         return expandoAndGeneration_;
     }
     uint32_t generation() const {
@@ -5174,27 +4601,16 @@ class ICGetProp_DOMProxyShadowed : publi
     HeapPtrPropertyName name_;
     uint32_t pcOffset_;
 
     ICGetProp_DOMProxyShadowed(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                                const BaseProxyHandler *proxyHandler, HandlePropertyName name,
                                uint32_t pcOffset);
 
   public:
-    static inline ICGetProp_DOMProxyShadowed *New(ICStubSpace *space, JitCode *code,
-                                                  ICStub *firstMonitorStub, HandleShape shape,
-                                                  const BaseProxyHandler *proxyHandler,
-                                                  HandlePropertyName name, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_DOMProxyShadowed>(code, firstMonitorStub, shape,
-                                                           proxyHandler, name, pcOffset);
-    }
-
     static ICGetProp_DOMProxyShadowed *Clone(JSContext *cx, ICStubSpace *space,
                                              ICStub *firstMonitorStub,
                                              ICGetProp_DOMProxyShadowed &other);
 
     HeapPtrShape &shape() {
         return shape_;
     }
     HeapPtrPropertyName &name() {
@@ -5243,23 +4659,16 @@ class ICGetProp_ArgumentsLength : public
     enum Which { Normal, Strict, Magic };
 
   protected:
     explicit ICGetProp_ArgumentsLength(JitCode *stubCode)
       : ICStub(ICStub::GetProp_ArgumentsLength, stubCode)
     { }
 
   public:
-    static inline ICGetProp_ArgumentsLength *New(ICStubSpace *space, JitCode *code)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_ArgumentsLength>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         Which which_;
 
         bool generateStubCode(MacroAssembler &masm);
 
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind) | (static_cast<int32_t>(which_) << 16);
@@ -5267,50 +4676,42 @@ class ICGetProp_ArgumentsLength : public
 
       public:
         Compiler(JSContext *cx, Which which)
           : ICStubCompiler(cx, ICStub::GetProp_ArgumentsLength),
             which_(which)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_ArgumentsLength::New(space, getStubCode());
+            return ICStub::New<ICGetProp_ArgumentsLength>(space, getStubCode());
         }
     };
 };
 
 class ICGetProp_ArgumentsCallee : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
   protected:
     ICGetProp_ArgumentsCallee(JitCode *stubCode, ICStub *firstMonitorStub);
 
   public:
-    static inline ICGetProp_ArgumentsCallee *New(ICStubSpace *space, JitCode *code,
-                                                 ICStub *firstMonitorStub)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICGetProp_ArgumentsCallee>(code, firstMonitorStub);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         ICStub *firstMonitorStub_;
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub)
           : ICStubCompiler(cx, ICStub::GetProp_ArgumentsCallee),
             firstMonitorStub_(firstMonitorStub)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetProp_ArgumentsCallee::New(space, getStubCode(), firstMonitorStub_);
+            return ICStub::New<ICGetProp_ArgumentsCallee>(space, getStubCode(), firstMonitorStub_);
         }
     };
 };
 
 // SetProp
 //     JSOP_SETPROP
 //     JSOP_SETNAME
 //     JSOP_SETGNAME
@@ -5322,22 +4723,16 @@ class ICSetProp_Fallback : public ICFall
 
     explicit ICSetProp_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::SetProp_Fallback, stubCode)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICSetProp_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_Fallback>(code);
-    }
-
     static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
     void noteUnoptimizableAccess() {
         extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
     bool hadUnoptimizableAccess() const {
         return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
     }
 
@@ -5348,17 +4743,17 @@ class ICSetProp_Fallback : public ICFall
         bool postGenerateStubCode(MacroAssembler &masm, Handle<JitCode *> code);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::SetProp_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICSetProp_Fallback::New(space, getStubCode());
+            return ICStub::New<ICSetProp_Fallback>(space, getStubCode());
         }
     };
 };
 
 // Optimized SETPROP/SETGNAME/SETNAME stub.
 class ICSetProp_Native : public ICUpdatedStub
 {
     friend class ICStubSpace;
@@ -5366,23 +4761,16 @@ class ICSetProp_Native : public ICUpdate
   protected: // Protected to silence Clang warning.
     HeapPtrObjectGroup group_;
     HeapPtrShape shape_;
     uint32_t offset_;
 
     ICSetProp_Native(JitCode *stubCode, HandleObjectGroup group, HandleShape shape, uint32_t offset);
 
   public:
-    static inline ICSetProp_Native *New(ICStubSpace *space, JitCode *code, HandleObjectGroup group,
-                                        HandleShape shape, uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_Native>(code, group, shape, offset);
-    }
     HeapPtrObjectGroup &group() {
         return group_;
     }
     HeapPtrShape &shape() {
         return shape_;
     }
     void notePreliminaryObject() {
         extra_ = 1;
@@ -5483,27 +4871,16 @@ class ICSetProp_NativeAddImpl : public I
     static const size_t NumShapes = ProtoChainDepth + 1;
     mozilla::Array<HeapPtrShape, NumShapes> shapes_;
 
     ICSetProp_NativeAddImpl(JitCode *stubCode, HandleObjectGroup group,
                             const AutoShapeVector *shapes,
                             HandleShape newShape, HandleObjectGroup newGroup, uint32_t offset);
 
   public:
-    static inline ICSetProp_NativeAddImpl *New(
-            ICStubSpace *space, JitCode *code, HandleObjectGroup group,
-            const AutoShapeVector *shapes, HandleShape newShape,
-            HandleObjectGroup newGroup, uint32_t offset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_NativeAddImpl<ProtoChainDepth> >(
-                            code, group, shapes, newShape, newGroup, offset);
-    }
-
     void traceShapes(JSTracer *trc) {
         for (size_t i = 0; i < NumShapes; i++)
             MarkShape(trc, &shapes_[i], "baseline-setpropnativeadd-stub-shape");
     }
 
     static size_t offsetOfShape(size_t idx) {
         return offsetof(ICSetProp_NativeAddImpl, shapes_) + (idx * sizeof(HeapPtrShape));
     }
@@ -5541,17 +4918,17 @@ class ICSetPropNativeAddCompiler : publi
         // Only specify newGroup when the object's group changes due to the
         // object becoming fully initialized per the acquired properties
         // analysis.
         if (newGroup == oldGroup_)
             newGroup = nullptr;
 
         RootedShape newShape(cx, obj_->lastProperty());
 
-        return ICSetProp_NativeAddImpl<ProtoChainDepth>::New(
+        return ICStub::New<ICSetProp_NativeAddImpl<ProtoChainDepth>>(
                     space, getStubCode(), oldGroup_, shapes, newShape, newGroup, offset_);
     }
 
     ICUpdatedStub *getStub(ICStubSpace *space);
 };
 
 class ICSetProp_Unboxed : public ICUpdatedStub
 {
@@ -5564,24 +4941,16 @@ class ICSetProp_Unboxed : public ICUpdat
       : ICUpdatedStub(ICStub::SetProp_Unboxed, stubCode),
         group_(group),
         fieldOffset_(fieldOffset)
     {
         (void) fieldOffset_; // Silence clang warning
     }
 
   public:
-    static inline ICSetProp_Unboxed *New(ICStubSpace *space, JitCode *code,
-                                         HandleObjectGroup group, uint32_t fieldOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_Unboxed>(code, group, fieldOffset);
-    }
-
     HeapPtrObjectGroup &group() {
         return group_;
     }
 
     static size_t offsetOfGroup() {
         return offsetof(ICSetProp_Unboxed, group_);
     }
     static size_t offsetOfFieldOffset() {
@@ -5606,18 +4975,18 @@ class ICSetProp_Unboxed : public ICUpdat
                  JSValueType fieldType)
           : ICStubCompiler(cx, ICStub::SetProp_Unboxed),
             group_(cx, group),
             fieldOffset_(fieldOffset),
             fieldType_(fieldType)
         {}
 
         ICUpdatedStub *getStub(ICStubSpace *space) {
-            ICUpdatedStub *stub = ICSetProp_Unboxed::New(space, getStubCode(),
-                                                         group_, fieldOffset_);
+            ICUpdatedStub *stub = ICStub::New<ICSetProp_Unboxed>(space, getStubCode(),
+                                                                 group_, fieldOffset_);
             if (!stub || !stub->initUpdatingChain(cx, space))
                 return nullptr;
             return stub;
         }
 
         bool needsUpdateStubs() {
             return fieldType_ == JSVAL_TYPE_OBJECT;
         }
@@ -5640,26 +5009,16 @@ class ICSetProp_TypedObject : public ICU
         group_(group),
         fieldOffset_(fieldOffset),
         isObjectReference_(isObjectReference)
     {
         (void) fieldOffset_; // Silence clang warning
     }
 
   public:
-    static inline ICSetProp_TypedObject *New(ICStubSpace *space, JitCode *code,
-                                             HandleShape shape, HandleObjectGroup group,
-                                             uint32_t fieldOffset, bool isObjectReference)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_TypedObject>(code, shape, group,
-                                                      fieldOffset, isObjectReference);
-    }
-
     HeapPtrShape &shape() {
         return shape_;
     }
     HeapPtrObjectGroup &group() {
         return group_;
     }
     bool isObjectReference() {
         return isObjectReference_;
@@ -5701,18 +5060,19 @@ class ICSetProp_TypedObject : public ICU
             layout_(GetTypedThingLayout(shape->getObjectClass())),
             fieldDescr_(cx, fieldDescr)
         {}
 
         ICUpdatedStub *getStub(ICStubSpace *space) {
             bool isObjectReference =
                 fieldDescr_->is<ReferenceTypeDescr>() &&
                 fieldDescr_->as<ReferenceTypeDescr>().type() == ReferenceTypeDescr::TYPE_OBJECT;
-            ICUpdatedStub *stub = ICSetProp_TypedObject::New(space, getStubCode(), shape_, group_,
-                                                             fieldOffset_, isObjectReference);
+            ICUpdatedStub *stub = ICStub::New<ICSetProp_TypedObject>(space, getStubCode(), shape_,
+                                                                     group_, fieldOffset_,
+                                                                     isObjectReference);
             if (!stub || !stub->initUpdatingChain(cx, space))
                 return nullptr;
             return stub;
         }
 
         bool needsUpdateStubs() {
             return fieldDescr_->is<ReferenceTypeDescr>() &&
                    fieldDescr_->as<ReferenceTypeDescr>().type() != ReferenceTypeDescr::TYPE_STRING;
@@ -5801,27 +5161,16 @@ class ICSetProp_CallScripted : public IC
   protected:
     ICSetProp_CallScripted(JitCode *stubCode, HandleShape shape, HandleObject holder,
                            HandleShape holderShape, HandleFunction setter, uint32_t pcOffset)
       : ICSetPropCallSetter(SetProp_CallScripted, stubCode, shape, holder, holderShape,
                             setter, pcOffset)
     {}
 
   public:
-    static inline ICSetProp_CallScripted *New(ICStubSpace *space, JitCode *code,
-                                              HandleShape shape, HandleObject holder,
-                                              HandleShape holderShape, HandleFunction setter,
-                                              uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_CallScripted>(code, shape, holder, holderShape, setter,
-                                                       pcOffset);
-    }
-
     static ICSetProp_CallScripted *Clone(JSContext *cx, ICStubSpace *space, ICStub *,
                                          ICSetProp_CallScripted &other);
 
     class Compiler : public ICSetPropCallSetter::Compiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
@@ -5829,18 +5178,18 @@ class ICSetProp_CallScripted : public IC
                  uint32_t pcOffset)
           : ICSetPropCallSetter::Compiler(cx, ICStub::SetProp_CallScripted,
                                           obj, holder, setter, pcOffset)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape shape(cx, obj_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
-            return ICSetProp_CallScripted::New(space, getStubCode(), shape, holder_, holderShape,
-                                               setter_, pcOffset_);
+            return ICStub::New<ICSetProp_CallScripted>(space, getStubCode(), shape, holder_,
+                                                       holderShape, setter_, pcOffset_);
         }
     };
 };
 
 // Stub for calling a native setter on a native object.
 class ICSetProp_CallNative : public ICSetPropCallSetter
 {
     friend class ICStubSpace;
@@ -5848,27 +5197,16 @@ class ICSetProp_CallNative : public ICSe
   protected:
     ICSetProp_CallNative(JitCode *stubCode, HandleShape shape, HandleObject holder,
                            HandleShape holderShape, HandleFunction setter, uint32_t pcOffset)
       : ICSetPropCallSetter(SetProp_CallNative, stubCode, shape, holder, holderShape,
                             setter, pcOffset)
     {}
 
   public:
-    static inline ICSetProp_CallNative *New(ICStubSpace *space, JitCode *code,
-                                            HandleShape shape, HandleObject holder,
-                                            HandleShape holderShape, HandleFunction setter,
-                                            uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICSetProp_CallNative>(code, shape, holder, holderShape, setter,
-                                                     pcOffset);
-    }
-
     static ICSetProp_CallNative *Clone(JSContext *cx, ICStubSpace *space, ICStub *,
                                        ICSetProp_CallNative &other);
 
     class Compiler : public ICSetPropCallSetter::Compiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
@@ -5876,18 +5214,18 @@ class ICSetProp_CallNative : public ICSe
                  uint32_t pcOffset)
           : ICSetPropCallSetter::Compiler(cx, ICStub::SetProp_CallNative,
                                           obj, holder, setter, pcOffset)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape shape(cx, obj_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
-            return ICSetProp_CallNative::New(space, getStubCode(), shape, holder_, holderShape,
-                                               setter_, pcOffset_);
+            return ICStub::New<ICSetProp_CallNative>(space, getStubCode(), shape, holder_,
+                                                     holderShape, setter_, pcOffset_);
         }
     };
 };
 
 // Call
 //      JSOP_CALL
 //      JSOP_FUNAPPLY
 //      JSOP_FUNCALL
@@ -5935,24 +5273,16 @@ class ICCall_Fallback : public ICMonitor
       : ICMonitoredFallbackStub(ICStub::Call_Fallback, stubCode)
     {
         extra_ = 0;
         if (isConstructing)
             extra_ |= CONSTRUCTING_FLAG;
     }
 
   public:
-
-    static inline ICCall_Fallback *New(ICStubSpace *space, JitCode *code, bool isConstructing)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_Fallback>(code, isConstructing);
-    }
-
     bool isConstructing() const {
         return extra_ & CONSTRUCTING_FLAG;
     }
 
     void noteUnoptimizableCall() {
         extra_ |= UNOPTIMIZABLE_CALL_FLAG;
     }
     bool hadUnoptimizableCall() const {
@@ -5990,17 +5320,17 @@ class ICCall_Fallback : public ICMonitor
       public:
         Compiler(JSContext *cx, bool isConstructing, bool isSpread)
           : ICCallStubCompiler(cx, ICStub::Call_Fallback),
             isConstructing_(isConstructing),
             isSpread_(isSpread)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            ICCall_Fallback *stub = ICCall_Fallback::New(space, getStubCode(), isConstructing_);
+            ICCall_Fallback *stub = ICStub::New<ICCall_Fallback>(space, getStubCode(), isConstructing_);
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 class ICCall_Scripted : public ICMonitoredStub
@@ -6017,27 +5347,16 @@ class ICCall_Scripted : public ICMonitor
     HeapPtrObject templateObject_;
     uint32_t pcOffset_;
 
     ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub,
                     HandleFunction callee, HandleObject templateObject,
                     uint32_t pcOffset);
 
   public:
-    static inline ICCall_Scripted *New(
-            ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-            HandleFunction callee, HandleObject templateObject,
-            uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_Scripted>(code, firstMonitorStub,
-                                                callee, templateObject, pcOffset);
-    }
-
     static ICCall_Scripted *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                   ICCall_Scripted &other);
 
     HeapPtrFunction &callee() {
         return callee_;
     }
     HeapPtrObject &templateObject() {
         return templateObject_;
@@ -6059,24 +5378,16 @@ class ICCall_AnyScripted : public ICMoni
     uint32_t pcOffset_;
 
     ICCall_AnyScripted(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
       : ICMonitoredStub(ICStub::Call_AnyScripted, stubCode, firstMonitorStub),
         pcOffset_(pcOffset)
     { }
 
   public:
-    static inline ICCall_AnyScripted *New(ICStubSpace *space, JitCode *code,
-                                          ICStub *firstMonitorStub, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_AnyScripted>(code, firstMonitorStub, pcOffset);
-    }
-
     static ICCall_AnyScripted *Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                                      ICCall_AnyScripted &other);
 
     static size_t offsetOfPCOffset() {
         return offsetof(ICCall_AnyScripted, pcOffset_);
     }
 };
 
@@ -6117,21 +5428,21 @@ class ICCallScriptedCompiler : public IC
         isSpread_(isSpread),
         callee_(cx, nullptr),
         templateObject_(cx, nullptr),
         pcOffset_(pcOffset)
     { }
 
     ICStub *getStub(ICStubSpace *space) {
         if (callee_) {
-            return ICCall_Scripted::New(space, getStubCode(), firstMonitorStub_,
-                                        callee_, templateObject_,
-                                        pcOffset_);
+            return ICStub::New<ICCall_Scripted>(space, getStubCode(), firstMonitorStub_,
+                                                callee_, templateObject_,
+                                                pcOffset_);
         }
-        return ICCall_AnyScripted::New(space, getStubCode(), firstMonitorStub_, pcOffset_);
+        return ICStub::New<ICCall_AnyScripted>(space, getStubCode(), firstMonitorStub_, pcOffset_);
     }
 };
 
 class ICCall_Native : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
   protected:
@@ -6143,26 +5454,16 @@ class ICCall_Native : public ICMonitored
     void *native_;
 #endif
 
     ICCall_Native(JitCode *stubCode, ICStub *firstMonitorStub,
                   HandleFunction callee, HandleObject templateObject,
                   uint32_t pcOffset);
 
   public:
-    static inline ICCall_Native *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
-                                     HandleFunction callee, HandleObject templateObject,
-                                     uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_Native>(code, firstMonitorStub,
-                                              callee, templateObject, pcOffset);
-    }
-
     static ICCall_Native *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                 ICCall_Native &other);
 
     HeapPtrFunction &callee() {
         return callee_;
     }
     HeapPtrObject &templateObject() {
         return templateObject_;
@@ -6206,18 +5507,18 @@ class ICCall_Native : public ICMonitored
             isConstructing_(isConstructing),
             isSpread_(isSpread),
             callee_(cx, callee),
             templateObject_(cx, templateObject),
             pcOffset_(pcOffset)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_Native::New(space, getStubCode(), firstMonitorStub_,
-                                      callee_, templateObject_, pcOffset_);
+            return ICStub::New<ICCall_Native>(space, getStubCode(), firstMonitorStub_,
+                                              callee_, templateObject_, pcOffset_);
         }
     };
 };
 
 class ICCall_ClassHook : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
@@ -6227,28 +5528,16 @@ class ICCall_ClassHook : public ICMonito
     HeapPtrObject templateObject_;
     uint32_t pcOffset_;
 
     ICCall_ClassHook(JitCode *stubCode, ICStub *firstMonitorStub,
                      const Class *clasp, Native native, HandleObject templateObject,
                      uint32_t pcOffset);
 
   public:
-    static inline ICCall_ClassHook *New(ICStubSpace *space,
-                                        JitCode *code, ICStub *firstMonitorStub,
-                                        const Class *clasp, Native native,
-                                        HandleObject templateObject,
-                                        uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_ClassHook>(code, firstMonitorStub,
-                                                 clasp, native, templateObject, pcOffset);
-    }
-
     static ICCall_ClassHook *Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                                    ICCall_ClassHook &other);
 
     const Class *clasp() {
         return clasp_;
     }
     void *native() {
         return native_;
@@ -6292,18 +5581,18 @@ class ICCall_ClassHook : public ICMonito
             isConstructing_(isConstructing),
             clasp_(clasp),
             native_(native),
             templateObject_(cx, templateObject),
             pcOffset_(pcOffset)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_ClassHook::New(space, getStubCode(), firstMonitorStub_,
-                                         clasp_, native_, templateObject_, pcOffset_);
+            return ICStub::New<ICCall_ClassHook>(space, getStubCode(), firstMonitorStub_,
+                                                 clasp_, native_, templateObject_, pcOffset_);
         }
     };
 };
 
 class ICCall_ScriptedApplyArray : public ICMonitoredStub
 {
     friend class ICStubSpace;
   public:
@@ -6316,24 +5605,16 @@ class ICCall_ScriptedApplyArray : public
     uint32_t pcOffset_;
 
     ICCall_ScriptedApplyArray(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
       : ICMonitoredStub(ICStub::Call_ScriptedApplyArray, stubCode, firstMonitorStub),
         pcOffset_(pcOffset)
     {}
 
   public:
-    static inline ICCall_ScriptedApplyArray *New(ICStubSpace *space, JitCode *code,
-                                                 ICStub *firstMonitorStub, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_ScriptedApplyArray>(code, firstMonitorStub, pcOffset);
-    }
-
     static ICCall_ScriptedApplyArray *Clone(JSContext *, ICStubSpace *space,
                                             ICStub *firstMonitorStub,
                                             ICCall_ScriptedApplyArray &other);
 
     static size_t offsetOfPCOffset() {
         return offsetof(ICCall_ScriptedApplyArray, pcOffset_);
     }
 
@@ -6351,18 +5632,18 @@ class ICCall_ScriptedApplyArray : public
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, uint32_t pcOffset)
           : ICCallStubCompiler(cx, ICStub::Call_ScriptedApplyArray),
             firstMonitorStub_(firstMonitorStub),
             pcOffset_(pcOffset)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_ScriptedApplyArray::New(space, getStubCode(), firstMonitorStub_,
-                                                      pcOffset_);
+            return ICStub::New<ICCall_ScriptedApplyArray>(space, getStubCode(), firstMonitorStub_,
+                                                          pcOffset_);
         }
     };
 };
 
 class ICCall_ScriptedApplyArguments : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
@@ -6370,24 +5651,16 @@ class ICCall_ScriptedApplyArguments : pu
     uint32_t pcOffset_;
 
     ICCall_ScriptedApplyArguments(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
       : ICMonitoredStub(ICStub::Call_ScriptedApplyArguments, stubCode, firstMonitorStub),
         pcOffset_(pcOffset)
     {}
 
   public:
-    static inline ICCall_ScriptedApplyArguments *New(ICStubSpace *space, JitCode *code,
-                                                     ICStub *firstMonitorStub, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_ScriptedApplyArguments>(code, firstMonitorStub, pcOffset);
-    }
-
     static ICCall_ScriptedApplyArguments *Clone(JSContext *, ICStubSpace *space,
                                                 ICStub *firstMonitorStub,
                                                 ICCall_ScriptedApplyArguments &other);
 
     static size_t offsetOfPCOffset() {
         return offsetof(ICCall_ScriptedApplyArguments, pcOffset_);
     }
 
@@ -6405,18 +5678,18 @@ class ICCall_ScriptedApplyArguments : pu
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, uint32_t pcOffset)
           : ICCallStubCompiler(cx, ICStub::Call_ScriptedApplyArguments),
             firstMonitorStub_(firstMonitorStub),
             pcOffset_(pcOffset)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_ScriptedApplyArguments::New(space, getStubCode(), firstMonitorStub_,
-                                                      pcOffset_);
+            return ICStub::New<ICCall_ScriptedApplyArguments>(space, getStubCode(), firstMonitorStub_,
+                                                              pcOffset_);
         }
     };
 };
 
 // Handles calls of the form |fun.call(...)| where fun is a scripted function.
 class ICCall_ScriptedFunCall : public ICMonitoredStub
 {
     friend class ICStubSpace;
@@ -6425,24 +5698,16 @@ class ICCall_ScriptedFunCall : public IC
     uint32_t pcOffset_;
 
     ICCall_ScriptedFunCall(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
       : ICMonitoredStub(ICStub::Call_ScriptedFunCall, stubCode, firstMonitorStub),
         pcOffset_(pcOffset)
     {}
 
   public:
-    static inline ICCall_ScriptedFunCall *New(ICStubSpace *space, JitCode *code,
-                                              ICStub *firstMonitorStub, uint32_t pcOffset)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_ScriptedFunCall>(code, firstMonitorStub, pcOffset);
-    }
-
     static ICCall_ScriptedFunCall *Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
                                          ICCall_ScriptedFunCall &other);
 
     static size_t offsetOfPCOffset() {
         return offsetof(ICCall_ScriptedFunCall, pcOffset_);
     }
 
     // Compiler for this stub kind.
@@ -6459,18 +5724,18 @@ class ICCall_ScriptedFunCall : public IC
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, uint32_t pcOffset)
           : ICCallStubCompiler(cx, ICStub::Call_ScriptedFunCall),
             firstMonitorStub_(firstMonitorStub),
             pcOffset_(pcOffset)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_ScriptedFunCall::New(space, getStubCode(), firstMonitorStub_,
-                                               pcOffset_);
+            return ICStub::New<ICCall_ScriptedFunCall>(space, getStubCode(), firstMonitorStub_,
+                                                       pcOffset_);
         }
     };
 };
 
 class ICCall_StringSplit : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
@@ -6483,26 +5748,16 @@ class ICCall_StringSplit : public ICMoni
     ICCall_StringSplit(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
                        HandleString argString, HandleArrayObject templateObject)
       : ICMonitoredStub(ICStub::Call_StringSplit, stubCode, firstMonitorStub),
         pcOffset_(pcOffset), expectedThis_(thisString), expectedArg_(argString),
         templateObject_(templateObject)
     { }
 
   public:
-    static inline ICCall_StringSplit *New(ICStubSpace *space, JitCode *code,
-                                          ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
-                                          HandleString argString, HandleArrayObject templateObject)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_StringSplit>(code, firstMonitorStub, pcOffset, thisString,
-                                                   argString, templateObject);
-    }
-
     static size_t offsetOfExpectedThis() {
         return offsetof(ICCall_StringSplit, expectedThis_);
     }
 
     static size_t offsetOfExpectedArg() {
         return offsetof(ICCall_StringSplit, expectedArg_);
     }
 
@@ -6543,49 +5798,43 @@ class ICCall_StringSplit : public ICMoni
             firstMonitorStub_(firstMonitorStub),
             pcOffset_(pcOffset),
             expectedThis_(cx, thisString),
             expectedArg_(cx, argString),
             templateObject_(cx, &templateObject.toObject().as<ArrayObject>())
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_StringSplit::New(space, getStubCode(), firstMonitorStub_,
-                                           pcOffset_, expectedThis_, expectedArg_,
-                                           templateObject_);
+            return ICStub::New<ICCall_StringSplit>(space, getStubCode(), firstMonitorStub_,
+                                                   pcOffset_, expectedThis_, expectedArg_,
+                                                   templateObject_);
         }
    };
 };
 
 class ICCall_IsSuspendedStarGenerator : public ICStub
 {
     friend class ICStubSpace;
 
   protected:
     explicit ICCall_IsSuspendedStarGenerator(JitCode *stubCode)
       : ICStub(ICStub::Call_IsSuspendedStarGenerator, stubCode)
     {}
 
   public:
-    static inline ICCall_IsSuspendedStarGenerator *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICCall_IsSuspendedStarGenerator>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::Call_IsSuspendedStarGenerator)
         {}
         ICStub *getStub(ICStubSpace *space) {
-            return ICCall_IsSuspendedStarGenerator::New(space, getStubCode());
+            return ICStub::New<ICCall_IsSuspendedStarGenerator>(space, getStubCode());
         }
    };
 };
 
 // Stub for performing a TableSwitch, updating the IC's return address to jump
 // to whatever point the switch is branching to.
 class ICTableSwitch : public ICStub
 {
@@ -6599,23 +5848,16 @@ class ICTableSwitch : public ICStub
 
     ICTableSwitch(JitCode *stubCode, void **table,
                   int32_t min, int32_t length, void *defaultTarget)
       : ICStub(TableSwitch, stubCode), table_(table),
         min_(min), length_(length), defaultTarget_(defaultTarget)
     {}
 
   public:
-    static inline ICTableSwitch *New(ICStubSpace *space, JitCode *code, void **table,
-                                     int32_t min, int32_t length, void *defaultTarget) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTableSwitch>(code, table, min, length, defaultTarget);
-    }
-
     void fixupJumpTable(JSScript *script, BaselineScript *baseline);
 
     class Compiler : public ICStubCompiler {
         bool generateStubCode(MacroAssembler &masm);
 
         jsbytecode *pc_;
 
       public:
@@ -6632,53 +5874,41 @@ class ICIteratorNew_Fallback : public IC
 {
     friend class ICStubSpace;
 
     explicit ICIteratorNew_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::IteratorNew_Fallback, stubCode)
     { }
 
   public:
-    static inline ICIteratorNew_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICIteratorNew_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::IteratorNew_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICIteratorNew_Fallback::New(space, getStubCode());
+            return ICStub::New<ICIteratorNew_Fallback>(space, getStubCode());
         }
     };
 };
 
 // IC for testing if there are more values in an iterator.
 class ICIteratorMore_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICIteratorMore_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::IteratorMore_Fallback, stubCode)
     { }
 
   public:
-    static inline ICIteratorMore_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICIteratorMore_Fallback>(code);
-    }
-
     void setHasNonStringResult() {
         extra_ = 1;
     }
     bool hasNonStringResult() const {
         MOZ_ASSERT(extra_ <= 1);
         return extra_;
     }
 
@@ -6687,79 +5917,67 @@ class ICIteratorMore_Fallback : public I
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::IteratorMore_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICIteratorMore_Fallback::New(space, getStubCode());
+            return ICStub::New<ICIteratorMore_Fallback>(space, getStubCode());
         }
     };
 };
 
 // IC for testing if there are more values in a native iterator.
 class ICIteratorMore_Native : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICIteratorMore_Native(JitCode *stubCode)
       : ICStub(ICStub::IteratorMore_Native, stubCode)
     { }
 
   public:
-    static inline ICIteratorMore_Native *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICIteratorMore_Native>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::IteratorMore_Native)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICIteratorMore_Native::New(space, getStubCode());
+            return ICStub::New<ICIteratorMore_Native>(space, getStubCode());
         }
     };
 };
 
 // IC for closing an iterator.
 class ICIteratorClose_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICIteratorClose_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::IteratorClose_Fallback, stubCode)
     { }
 
   public:
-    static inline ICIteratorClose_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICIteratorClose_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::IteratorClose_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICIteratorClose_Fallback::New(space, getStubCode());
+            return ICStub::New<ICIteratorClose_Fallback>(space, getStubCode());
         }
     };
 };
 
 // InstanceOf
 //      JSOP_INSTANCEOF
 class ICInstanceOf_Fallback : public ICFallbackStub
 {
@@ -6769,22 +5987,16 @@ class ICInstanceOf_Fallback : public ICF
       : ICFallbackStub(ICStub::InstanceOf_Fallback, stubCode)
     { }
 
     static const uint16_t UNOPTIMIZABLE_ACCESS_BIT = 0x1;
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 4;
 
-    static inline ICInstanceOf_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICInstanceOf_Fallback>(code);
-    }
-
     void noteUnoptimizableAccess() {
         extra_ |= UNOPTIMIZABLE_ACCESS_BIT;
     }
     bool hadUnoptimizableAccess() const {
         return extra_ & UNOPTIMIZABLE_ACCESS_BIT;
     }
 
     class Compiler : public ICStubCompiler {
@@ -6792,40 +6004,32 @@ class ICInstanceOf_Fallback : public ICF
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::InstanceOf_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICInstanceOf_Fallback::New(space, getStubCode());
+            return ICStub::New<ICInstanceOf_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICInstanceOf_Function : public ICStub
 {
     friend class ICStubSpace;
 
     HeapPtrShape shape_;
     HeapPtrObject prototypeObj_;
     uint32_t slot_;
 
     ICInstanceOf_Function(JitCode *stubCode, Shape *shape, JSObject *prototypeObj, uint32_t slot);
 
   public:
-    static inline ICInstanceOf_Function *New(ICStubSpace *space, JitCode *code, Shape *shape,
-                                             JSObject *prototypeObj, uint32_t slot)
-    {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICInstanceOf_Function>(code, shape, prototypeObj, slot);
-    }
-
     HeapPtrShape &shape() {
         return shape_;
     }
     HeapPtrObject &prototypeObject() {
         return prototypeObj_;
     }
     uint32_t slot() const {
         return slot_;
@@ -6852,72 +6056,60 @@ class ICInstanceOf_Function : public ICS
         Compiler(JSContext *cx, Shape *shape, JSObject *prototypeObj, uint32_t slot)
           : ICStubCompiler(cx, ICStub::InstanceOf_Function),
             shape_(cx, shape),
             prototypeObj_(cx, prototypeObj),
             slot_(slot)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICInstanceOf_Function::New(space, getStubCode(), shape_, prototypeObj_, slot_);
+            return ICStub::New<ICInstanceOf_Function>(space, getStubCode(), shape_, prototypeObj_, slot_);
         }
     };
 };
 
 // TypeOf
 //      JSOP_TYPEOF
 //      JSOP_TYPEOFEXPR
 class ICTypeOf_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICTypeOf_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::TypeOf_Fallback, stubCode)
     { }
 
   public:
-    static inline ICTypeOf_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeOf_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::TypeOf_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICTypeOf_Fallback::New(space, getStubCode());
+            return ICStub::New<ICTypeOf_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICTypeOf_Typed : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     ICTypeOf_Typed(JitCode *stubCode, JSType type)
       : ICFallbackStub(ICStub::TypeOf_Typed, stubCode)
     {
         extra_ = uint16_t(type);
         MOZ_ASSERT(JSType(extra_) == type);
     }
 
   public:
-    static inline ICTypeOf_Typed *New(ICStubSpace *space, JitCode *code, JSType type) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICTypeOf_Typed>(code, type);
-    }
-
     JSType type() const {
         return JSType(extra_);
     }
 
     class Compiler : public ICStubCompiler {
       protected:
         JSType type_;
         RootedString typeString_;
@@ -6930,17 +6122,17 @@ class ICTypeOf_Typed : public ICFallback
       public:
         Compiler(JSContext *cx, JSType type, HandleString string)
           : ICStubCompiler(cx, ICStub::TypeOf_Typed),
             type_(type),
             typeString_(cx, string)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICTypeOf_Typed::New(space, getStubCode(), type_);
+            return ICStub::New<ICTypeOf_Typed>(space, getStubCode(), type_);
         }
     };
 };
 
 class ICRest_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
@@ -6948,73 +6140,60 @@ class ICRest_Fallback : public ICFallbac
 
     ICRest_Fallback(JitCode *stubCode, ArrayObject *templateObject)
       : ICFallbackStub(ICStub::Rest_Fallback, stubCode), templateObject_(templateObject)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICRest_Fallback *New(ICStubSpace *space, JitCode *code,
-                                       ArrayObject *templateObject) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICRest_Fallback>(code, templateObject);
-    }
-
     HeapPtrArrayObject &templateObject() {
         return templateObject_;
     }
 
     class Compiler : public ICStubCompiler {
       protected:
         RootedArrayObject templateObject;
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ArrayObject *templateObject)
           : ICStubCompiler(cx, ICStub::Rest_Fallback),
             templateObject(cx, templateObject)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICRest_Fallback::New(space, getStubCode(), templateObject);
+            return ICStub::New<ICRest_Fallback>(space, getStubCode(), templateObject);
         }
     };
 };
 
 // Stub for JSOP_RETSUB ("returning" from a |finally| block).
 class ICRetSub_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICRetSub_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::RetSub_Fallback, stubCode)
     { }
 
   public:
     static const uint32_t MAX_OPTIMIZED_STUBS = 8;
 
-    static inline ICRetSub_Fallback *New(ICStubSpace *space, JitCode *code) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICRetSub_Fallback>(code);
-    }
-
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::RetSub_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICRetSub_Fallback::New(space, getStubCode());
+            return ICStub::New<ICRetSub_Fallback>(space, getStubCode());
         }
     };
 };
 
 // Optimized JSOP_RETSUB stub. Every stub maps a single pc offset to its
 // native code address.
 class ICRetSub_Resume : public ICStub
 {
@@ -7026,23 +6205,16 @@ class ICRetSub_Resume : public ICStub
 
     ICRetSub_Resume(JitCode *stubCode, uint32_t pcOffset, uint8_t *addr)
       : ICStub(ICStub::RetSub_Resume, stubCode),
         pcOffset_(pcOffset),
         addr_(addr)
     { }
 
   public:
-    static ICRetSub_Resume *New(ICStubSpace *space, JitCode *code, uint32_t pcOffset,
-                                uint8_t *addr) {
-        if (!code)
-            return nullptr;
-        return space->allocate<ICRetSub_Resume>(code, pcOffset, addr);
-    }
-
     static size_t offsetOfPCOffset() {
         return offsetof(ICRetSub_Resume, pcOffset_);
     }
     static size_t offsetOfAddr() {
         return offsetof(ICRetSub_Resume, addr_);
     }
 
     class Compiler : public ICStubCompiler {
@@ -7054,17 +6226,17 @@ class ICRetSub_Resume : public ICStub
       public:
         Compiler(JSContext *cx, uint32_t pcOffset, uint8_t *addr)
           : ICStubCompiler(cx, ICStub::RetSub_Resume),
             pcOffset_(pcOffset),
             addr_(addr)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICRetSub_Resume::New(space, getStubCode(), pcOffset_, addr_);
+            return ICStub::New<ICRetSub_Resume>(space, getStubCode(), pcOffset_, addr_);
         }
     };
 };
 
 inline bool
 IsCacheableDOMProxy(JSObject *obj)
 {
     if (!obj->is<ProxyObject>())
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -26,16 +26,17 @@
 
 using namespace js;
 using namespace js::jit;
 
 using JS::ToInt32;
 
 using mozilla::NumbersAreIdentical;
 using mozilla::IsFloat32Representable;
+using mozilla::IsNaN;
 using mozilla::Maybe;
 using mozilla::DebugOnly;
 
 #ifdef DEBUG
 size_t MUse::index() const
 {
     return consumer()->indexOf(this);
 }
@@ -624,17 +625,17 @@ MConstant::New(TempAllocator &alloc, con
 {
     return new(alloc) MConstant(v, constraints);
 }
 
 MConstant *
 MConstant::NewTypedValue(TempAllocator &alloc, const Value &v, MIRType type, CompilerConstraintList *constraints)
 {
     MOZ_ASSERT(!IsSimdType(type));
-    MOZ_ASSERT_IF(type == MIRType_Float32, v.toDouble() == double(float(v.toDouble())));
+    MOZ_ASSERT_IF(type == MIRType_Float32, IsNaN(v.toDouble()) || v.toDouble() == double(float(v.toDouble())));
     MConstant *constant = new(alloc) MConstant(v, constraints);
     constant->setResultType(type);
     return constant;
 }
 
 MConstant *
 MConstant::NewAsmJS(TempAllocator &alloc, const Value &v, MIRType type)
 {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4223,17 +4223,16 @@ class MAssertRange
     // range_ member or the range() accessor. Since MAssertRange doesn't return
     // a value, it doesn't use those.
     const Range *assertedRange_;
 
     MAssertRange(MDefinition *ins, const Range *assertedRange)
       : MUnaryInstruction(ins), assertedRange_(assertedRange)
     {
         setGuard();
-        setMovable();
         setResultType(MIRType_None);
     }
 
   public:
     INSTRUCTION_HEADER(AssertRange)
 
     static MAssertRange *New(TempAllocator &alloc, MDefinition *ins, const Range *assertedRange) {
         return new(alloc) MAssertRange(ins, assertedRange);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1342,20 +1342,20 @@ JSFunction::initBoundFunction(JSContext 
     /*
      * Convert to a dictionary to set the BOUND_FUNCTION flag and increase
      * the slot span to cover the arguments and additional slots for the 'this'
      * value and arguments count.
      */
     if (!self->toDictionaryMode(cx))
         return false;
 
-    if (!self->setFlag(cx, BaseShape::BOUND_FUNCTION))
+    if (!self->JSObject::setFlags(cx, BaseShape::BOUND_FUNCTION))
         return false;
 
-    if (!NativeObject::setSlotSpan(cx, self, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
+    if (!self->setSlotSpan(cx, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
         return false;
 
     self->setSlot(JSSLOT_BOUND_FUNCTION_TARGET, ObjectValue(*target));
     self->setSlot(JSSLOT_BOUND_FUNCTION_THIS, thisArg);
     self->setSlot(JSSLOT_BOUND_FUNCTION_ARGS_COUNT, PrivateUint32Value(argslen));
 
     self->initSlotRange(BOUND_FUNCTION_RESERVED_SLOTS, args, argslen);
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -5458,16 +5458,20 @@ GCRuntime::compactPhase(bool lastGC)
     protectRelocatedArenas(relocatedList);
     MOZ_ASSERT(!relocatedArenasToRelease);
     if (!lastGC)
         relocatedArenasToRelease = relocatedList;
     else
         releaseRelocatedArenas(relocatedList);
 #endif
 
+    // Ensure execess chunks are returns to the system and free arenas
+    // decommitted.
+    shrinkBuffers();
+
 #ifdef DEBUG
     CheckHashTablesAfterMovingGC(rt);
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         if (CanRelocateZone(rt, zone)) {
             MOZ_ASSERT(!zone->isPreservingCode());
             zone->arenas.checkEmptyFreeLists();
 
             // Check that we did as much compaction as we should have. There
@@ -6298,25 +6302,25 @@ js::PrepareForDebugGC(JSRuntime *rt)
 {
     if (!ZonesSelected(rt))
         JS::PrepareForFullGC(rt);
 }
 
 JS_PUBLIC_API(void)
 JS::ShrinkGCBuffers(JSRuntime *rt)
 {
+    MOZ_ASSERT(!rt->isHeapBusy());
     rt->gc.shrinkBuffers();
 }
 
 void
 GCRuntime::shrinkBuffers()
 {
     AutoLockHelperThreadState helperLock;
     AutoLockGC lock(rt);
-    MOZ_ASSERT(!rt->isHeapBusy());
 
     if (CanUseExtraThreads())
         helperState.startBackgroundShrink(lock);
     else
         expireChunksAndArenas(true, lock);
 }
 
 void
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1033,17 +1033,17 @@ js::SetIntegrityLevel(JSContext *cx, Han
                 MarkTypePropertyNonWritable(cx, nobj, child->propid);
 
             last = cx->compartment()->propertyTree.getChild(cx, last, *child);
             if (!last)
                 return false;
         }
 
         MOZ_ASSERT(nobj->lastProperty()->slotSpan() == last->slotSpan());
-        JS_ALWAYS_TRUE(NativeObject::setLastProperty(cx, nobj, last));
+        JS_ALWAYS_TRUE(nobj->setLastProperty(cx, last));
     } else {
         RootedId id(cx);
         Rooted<PropertyDescriptor> desc(cx);
 
         const unsigned AllowConfigure = JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY |
                                         JSPROP_IGNORE_VALUE;
         const unsigned AllowConfigureAndWritable = AllowConfigure & ~JSPROP_IGNORE_READONLY;
 
@@ -1093,70 +1093,58 @@ js::SetIntegrityLevel(JSContext *cx, Han
         if (!obj->as<ArrayObject>().maybeCopyElementsForWrite(cx))
             return false;
         obj->as<ArrayObject>().getElementsHeader()->setNonwritableArrayLength();
     }
 
     return true;
 }
 
-/* ES6 rev 29 (6 Dec 2014) 7.3.14. */
+// ES6 draft rev33 (12 Feb 2015) 7.3.15
 bool
 js::TestIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level, bool *result)
 {
     // Steps 3-6. (Steps 1-2 are redundant assertions.)
     bool status;
     if (!IsExtensible(cx, obj, &status))
         return false;
     if (status) {
         *result = false;
         return true;
     }
 
-    if (IsAnyTypedArray(obj)) {
-        if (level == IntegrityLevel::Sealed) {
-            // Typed arrays are considered sealed (bug 1120503).
-            *result = true;
-        } else {
-            // Typed arrays cannot be frozen, but an empty typed array is
-            // considered frozen (bug 1120503).
-            *result = (AnyTypedArrayLength(obj) == 0);
-        }
-        return true;
-    }
-
     // Steps 7-8.
     AutoIdVector props(cx);
     if (!GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY | JSITER_SYMBOLS, &props))
         return false;
 
-    // Step 11.
+    // Step 9.
     RootedId id(cx);
     Rooted<PropertyDescriptor> desc(cx);
     for (size_t i = 0, len = props.length(); i < len; i++) {
         id = props[i];
 
-        // Steps 11.a-b.
+        // Steps 9.a-b.
         if (!GetOwnPropertyDescriptor(cx, obj, id, &desc))
             return false;
 
-        // Step 11.c.
+        // Step 9.c.
         if (!desc.object())
             continue;
 
-        // Steps 11.c.i-ii.
+        // Steps 9.c.i-ii.
         if (!desc.isPermanent() ||
             (level == IntegrityLevel::Frozen && desc.isDataDescriptor() && desc.isWritable()))
         {
             *result = false;
             return true;
         }
     }
 
-    // Step 12.
+    // Step 10.
     *result = true;
     return true;
 }
 
 
 /* * */
 
 /*
@@ -1852,17 +1840,17 @@ js::DeepCloneObjectLiteral(JSContext *cx
         clone->setDenseInitializedLength(i + 1);
         clone->initDenseElement(i, v);
     }
 
     MOZ_ASSERT(obj->compartment() == clone->compartment());
     MOZ_ASSERT(!obj->hasPrivate());
     RootedShape shape(cx, obj->lastProperty());
     size_t span = shape->slotSpan();
-    clone->setLastProperty(cx, clone, shape);
+    clone->setLastProperty(cx, shape);
     for (size_t i = 0; i < span; i++) {
         v = obj->getSlot(i);
         if (v.isObject()) {
             deepObj = &v.toObject().as<NativeObject>();
             deepObj = js::DeepCloneObjectLiteral(cx, deepObj, newKind);
             if (!deepObj)
                 return nullptr;
             v.setObject(*deepObj);
@@ -2144,17 +2132,17 @@ js::CloneObjectLiteral(JSContext *cx, Ha
 
         RootedPlainObject res(cx, NewObjectWithGroup<PlainObject>(cx, group, parent, kind,
                                                                   MaybeSingletonObject));
         if (!res)
             return nullptr;
 
         RootedShape newShape(cx, ReshapeForParentAndAllocKind(cx, srcObj->lastProperty(),
                                                               TaggedProto(proto), parent, kind));
-        if (!newShape || !NativeObject::setLastProperty(cx, res, newShape))
+        if (!newShape || !res->setLastProperty(cx, newShape))
             return nullptr;
 
         return res;
     }
 
     RootedArrayObject srcArray(cx, &srcObj->as<ArrayObject>());
     MOZ_ASSERT(srcArray->denseElementsAreCopyOnWrite());
     MOZ_ASSERT(srcArray->getElementsHeader()->ownerObject() == srcObj);
@@ -3146,17 +3134,17 @@ js::PreventExtensions(JSContext *cx, Han
      * initialized length and capacity of the object to zero and ensure that no
      * new dense elements can be added without calling growElements(), which
      * checks isExtensible().
      */
     if (obj->isNative() && !NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
         return false;
 
     *succeeded = true;
-    return obj->setFlag(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE);
+    return obj->setFlags(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE);
 }
 
 bool
 js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
                              MutableHandle<PropertyDescriptor> desc)
 {
     if (GetOwnPropertyOp op = obj->getOps()->getOwnPropertyDescriptor)
         return op(cx, obj, id, desc);
@@ -3241,17 +3229,17 @@ bool
 js::SetImmutablePrototype(ExclusiveContext *cx, HandleObject obj, bool *succeeded)
 {
     if (obj->hasLazyPrototype()) {
         if (!cx->shouldBeJSContext())
             return false;
         return Proxy::setImmutablePrototype(cx->asJSContext(), obj, succeeded);
     }
 
-    if (!obj->setFlag(cx, BaseShape::IMMUTABLE_PROTOTYPE))
+    if (!obj->setFlags(cx, BaseShape::IMMUTABLE_PROTOTYPE))
         return false;
     *succeeded = true;
     return true;
 }
 
 bool
 js::GetPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
                           MutableHandle<PropertyDescriptor> desc)
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -184,89 +184,87 @@ class JSObject : public js::gc::Cell
 
     // Set the initial slots and elements of an object. These pointers are only
     // valid for native objects, but during initialization are set for all
     // objects. For non-native objects, these must not be dynamically allocated
     // pointers which leak when the non-native object finishes initialization.
     inline void setInitialSlotsMaybeNonNative(js::HeapSlot *slots);
     inline void setInitialElementsMaybeNonNative(js::HeapSlot *elements);
 
-  protected:
     enum GenerateShape {
         GENERATE_NONE,
         GENERATE_SHAPE
     };
 
-    bool setFlag(js::ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag,
-                 GenerateShape generateShape = GENERATE_NONE);
+    bool setFlags(js::ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flags,
+                  GenerateShape generateShape = GENERATE_NONE);
 
-  public:
     /*
      * An object is a delegate if it is on another object's prototype or scope
      * chain, and therefore the delegate might be asked implicitly to get or
      * set a property on behalf of another object. Delegates may be accessed
      * directly too, as may any object, but only those objects linked after the
      * head of any prototype or scope chain are flagged as delegates. This
      * definition helps to optimize shape-based property cache invalidation
      * (see Purge{Scope,Proto}Chain in jsobj.cpp).
      */
     bool isDelegate() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::DELEGATE);
     }
 
     bool setDelegate(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
+        return setFlags(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
     }
 
     bool isBoundFunction() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::BOUND_FUNCTION);
     }
 
     inline bool hasSpecialEquality() const;
 
     bool watched() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::WATCHED);
     }
     bool setWatched(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
+        return setFlags(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
     }
 
     /* See InterpreterFrame::varObj. */
     inline bool isQualifiedVarObj();
     bool setQualifiedVarObj(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::QUALIFIED_VAROBJ);
+        return setFlags(cx, js::BaseShape::QUALIFIED_VAROBJ);
     }
 
     inline bool isUnqualifiedVarObj();
     bool setUnqualifiedVarObj(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::UNQUALIFIED_VAROBJ);
+        return setFlags(cx, js::BaseShape::UNQUALIFIED_VAROBJ);
     }
 
     /*
      * Objects with an uncacheable proto can have their prototype mutated
      * without inducing a shape change on the object. Property cache entries
      * and JIT inline caches should not be filled for lookups across prototype
      * lookups on the object.
      */
     bool hasUncacheableProto() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::UNCACHEABLE_PROTO);
     }
     bool setUncacheableProto(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
+        return setFlags(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
     }
 
     /*
      * Whether SETLELEM was used to access this object. See also the comment near
      * PropertyTree::MAX_HEIGHT.
      */
     bool hadElementsAccess() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::HAD_ELEMENTS_ACCESS);
     }
     bool setHadElementsAccess(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::HAD_ELEMENTS_ACCESS);
+        return setFlags(cx, js::BaseShape::HAD_ELEMENTS_ACCESS);
     }
 
     /*
      * Whether there may be indexed properties on this object, excluding any in
      * the object's elements.
      */
     bool isIndexed() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::INDEXED);
@@ -392,34 +390,34 @@ class JSObject : public js::gc::Cell
      * Mark an object that has been iterated over and is a singleton. We need
      * to recover this information in the object's type information after it
      * is purged on GC.
      */
     bool isIteratedSingleton() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::ITERATED_SINGLETON);
     }
     bool setIteratedSingleton(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
+        return setFlags(cx, js::BaseShape::ITERATED_SINGLETON);
     }
 
     /*
      * Mark an object as requiring its default 'new' type to have unknown
      * properties.
      */
     bool isNewGroupUnknown() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::NEW_GROUP_UNKNOWN);
     }
     static bool setNewGroupUnknown(JSContext *cx, const js::Class *clasp, JS::HandleObject obj);
 
     // Mark an object as having its 'new' script information cleared.
     bool wasNewScriptCleared() const {
         return lastProperty()->hasObjectFlag(js::BaseShape::NEW_SCRIPT_CLEARED);
     }
     bool setNewScriptCleared(js::ExclusiveContext *cx) {
-        return setFlag(cx, js::BaseShape::NEW_SCRIPT_CLEARED);
+        return setFlags(cx, js::BaseShape::NEW_SCRIPT_CLEARED);
     }
 
     /* Set a new prototype for an object with a singleton type. */
     bool splicePrototype(JSContext *cx, const js::Class *clasp, js::Handle<js::TaggedProto> proto);
 
     /*
      * For bootstrapping, whether to splice a prototype for Function.prototype
      * or the global object.
--- a/js/src/tests/ecma_6/Class/compPropNames.js
+++ b/js/src/tests/ecma_6/Class/compPropNames.js
@@ -90,22 +90,20 @@ assertEq(a.x, 0);
 a = {["x"]: 1, ["x"]: 2};
 assertEq(a.x, 2);
 a = {x: 1, ["x"]: 2};
 assertEq(a.x, 2);
 a = {["x"]: 1, x: 2};
 assertEq(a.x, 2);
 
 // Symbols
-if (typeof Symbol === "function") {
-    var unique_sym = Symbol("1"), registered_sym = Symbol.for("2");
-    a = { [unique_sym] : 2, [registered_sym] : 3 };
-    assertEq(a[unique_sym], 2);
-    assertEq(a[registered_sym], 3);
-}
+var unique_sym = Symbol("1"), registered_sym = Symbol.for("2");
+a = { [unique_sym] : 2, [registered_sym] : 3 };
+assertEq(a[unique_sym], 2);
+assertEq(a[registered_sym], 3);
 
 // Same expression can be run several times to build objects with different property names.
 a = [];
 for (var i = 0; i < 3; i++) {
     a[i] = {["foo" + i]: i};
 }
 assertEq(a[0].foo0, 0);
 assertEq(a[1].foo1, 1);
@@ -210,23 +208,21 @@ syntaxError('a = {get@ [f1](){}, set [f1
 syntaxError('a = {get [f1](){}, set@ [f1](a){}}'); // unexpected symbol after set
 
 expr = "hey";
 a = {get [expr]() { return 3; }, set[expr](v) { throw 2; }};
 assertEq(a.hey, 3);
 assertThrowsValue(() => { a.hey = 5; }, 2);
 
 // Symbols with duplicate get and set.
-if (typeof Symbol === "function") {
-    expr = Symbol("hey");
-    a = {get [expr]() { return 3; }, set[expr](v) { throw 2; },
-         set [expr] (w) { throw 4; }, get[expr](){return 5; }};
-    assertEq(a[expr], 5);
-    assertThrowsValue(() => { a[expr] = 7; }, 4);
-}
+expr = Symbol("hey");
+a = {get [expr]() { return 3; }, set[expr](v) { throw 2; },
+     set [expr] (w) { throw 4; }, get[expr](){return 5; }};
+assertEq(a[expr], 5);
+assertThrowsValue(() => { a[expr] = 7; }, 4);
 
 // expressions with side effects are called in the right order
 log = "";
 obj = {
     "a": log += 'a',
     get [log += 'b']() {},
     [log += 'c']: log += 'd',
     set [log += 'e'](a) {}
--- a/js/src/tests/ecma_6/Class/methDefn.js
+++ b/js/src/tests/ecma_6/Class/methDefn.js
@@ -97,22 +97,20 @@ var a = {
 };
 assertEq(a.foo0(), 0);
 assertEq(a.foo1(), 1);
 assertEq(a.foo2(), 2);
 assertEq(a.foo3(), 3);
 assertEq(a.foo4(), 4);
 
 // Symbols.
-if (typeof Symbol === "function") {
-    var unique_sym = Symbol("1"), registered_sym = Symbol.for("2");
-    a = { [unique_sym](){return 2;}, [registered_sym](){return 3;} };
-    assertEq(a[unique_sym](), 2);
-    assertEq(a[registered_sym](), 3);
-}
+var unique_sym = Symbol("1"), registered_sym = Symbol.for("2");
+a = { [unique_sym](){return 2;}, [registered_sym](){return 3;} };
+assertEq(a[unique_sym](), 2);
+assertEq(a[registered_sym](), 3);
 
 // Method characteristics.
 a = { b(){ return 4;} };
 b = Object.getOwnPropertyDescriptor(a, "b");
 assertEq(b.configurable, true);
 assertEq(b.enumerable, true);
 assertEq(b.writable, true);
 assertEq(b.value(), 4);
--- a/js/src/tests/ecma_6/Map/symbols.js
+++ b/js/src/tests/ecma_6/Map/symbols.js
@@ -1,35 +1,33 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    var m = new Map;
+var m = new Map;
 
-    // Symbols can be Map keys.
-    var sym = Symbol();
-    m.set(sym, "zero");
-    assertEq(m.has(sym), true);
-    assertEq(m.get(sym), "zero");
-    assertEq(m.has(Symbol()), false);
-    assertEq(m.get(Symbol()), undefined);
-    assertEq([...m][0][0], sym);
-    m.set(sym, "replaced");
-    assertEq(m.get(sym), "replaced");
-    m.delete(sym);
-    assertEq(m.has(sym), false);
-    assertEq(m.size, 0);
+// Symbols can be Map keys.
+var sym = Symbol();
+m.set(sym, "zero");
+assertEq(m.has(sym), true);
+assertEq(m.get(sym), "zero");
+assertEq(m.has(Symbol()), false);
+assertEq(m.get(Symbol()), undefined);
+assertEq([...m][0][0], sym);
+m.set(sym, "replaced");
+assertEq(m.get(sym), "replaced");
+m.delete(sym);
+assertEq(m.has(sym), false);
+assertEq(m.size, 0);
 
-    // Symbols returned by Symbol.for() can be Map keys.
-    for (var word of "that that is is that that is not is not is that not it".split(' ')) {
-        sym = Symbol.for(word);
-        m.set(sym, (m.get(sym) || 0) + 1);
-    }
-    assertDeepEq([...m], [
-        [Symbol.for("that"), 5],
-        [Symbol.for("is"), 5],
-        [Symbol.for("not"), 3],
-        [Symbol.for("it"), 1]
-    ]);
+// Symbols returned by Symbol.for() can be Map keys.
+for (var word of "that that is is that that is not is not is that not it".split(' ')) {
+    sym = Symbol.for(word);
+    m.set(sym, (m.get(sym) || 0) + 1);
 }
+assertDeepEq([...m], [
+    [Symbol.for("that"), 5],
+    [Symbol.for("is"), 5],
+    [Symbol.for("not"), 3],
+    [Symbol.for("it"), 1]
+]);
 
 if (typeof reportCompare === "function")
   reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Object/assign.js
+++ b/js/src/tests/ecma_6/Object/assign.js
@@ -31,18 +31,17 @@ function basicSymbols() {
     var a = {};
     var b = { bProp : 7 };
     var aSymbol = Symbol("aSymbol");
     b[aSymbol] = 22;
     Object.assign(a, b);
     assertEq(a.bProp, 7);
     assertEq(a[aSymbol], 22);
 }
-if (typeof Symbol === "function")
-    basicSymbols();
+basicSymbols();
 
 // Calls ToObject() for target, skips null/undefined sources, uses
 // ToObject(source) otherwise.
 function testToObject() {
     assertThrowsInstanceOf(() => Object.assign(null, null), TypeError);
     assertThrowsInstanceOf(() => Object.assign(), TypeError);
     assertThrowsInstanceOf(() => Object.assign(null, {}), TypeError);
     assertEq(Object.assign({}, null) instanceof Object, true);
--- a/js/src/tests/ecma_6/Object/getOwnPropertySymbols-proxy.js
+++ b/js/src/tests/ecma_6/Object/getOwnPropertySymbols-proxy.js
@@ -1,30 +1,28 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
+// getOwnPropertySymbols(proxy) calls the getOwnPropertyNames hook (only).
+
+var symbols = [Symbol(), Symbol("moon"), Symbol.for("sun"), Symbol.iterator];
+var hits = 0;
+
 function HandlerProxy() {
     return new Proxy({}, {
         get: function (t, key) {
             if (key !== "ownKeys")
                 throw new Error("tried to access handler[" + uneval(key) + "]");
             hits++;
             return t => symbols;
         }
     });
 }
 
 function OwnKeysProxy() {
     return new Proxy({}, new HandlerProxy);
 }
 
-if (typeof Symbol === "function") {
-    // getOwnPropertySymbols(proxy) calls the getOwnPropertyNames hook (only).
-
-    var symbols = [Symbol(), Symbol("moon"), Symbol.for("sun"), Symbol.iterator];
-    var hits = 0;
-
-    assertDeepEq(Object.getOwnPropertySymbols(new OwnKeysProxy), symbols);
-    assertEq(hits, 1);
-}
+assertDeepEq(Object.getOwnPropertySymbols(new OwnKeysProxy), symbols);
+assertEq(hits, 1);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Object/getOwnPropertySymbols.js
+++ b/js/src/tests/ecma_6/Object/getOwnPropertySymbols.js
@@ -1,48 +1,46 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    assertDeepEq(Object.getOwnPropertySymbols({}), []);
+assertDeepEq(Object.getOwnPropertySymbols({}), []);
 
-    // String keys are ignored.
-    assertEq(Object.getOwnPropertySymbols({a: 1, b: 2}).length, 0);
-    assertEq(Object.getOwnPropertySymbols([0, 1, 2, 3]).length, 0);
+// String keys are ignored.
+assertEq(Object.getOwnPropertySymbols({a: 1, b: 2}).length, 0);
+assertEq(Object.getOwnPropertySymbols([0, 1, 2, 3]).length, 0);
 
-    // Symbol keys are observed.
-    var iterable = {};
-    Object.defineProperty(iterable, Symbol.iterator, {
-        value: () => [][Symbol.iterator]()
-    });
-    assertDeepEq(Object.getOwnPropertySymbols(iterable), [Symbol.iterator]);
-    assertDeepEq(Object.getOwnPropertySymbols(new Proxy(iterable, {})), [Symbol.iterator]);
+// Symbol keys are observed.
+var iterable = {};
+Object.defineProperty(iterable, Symbol.iterator, {
+    value: () => [][Symbol.iterator]()
+});
+assertDeepEq(Object.getOwnPropertySymbols(iterable), [Symbol.iterator]);
+assertDeepEq(Object.getOwnPropertySymbols(new Proxy(iterable, {})), [Symbol.iterator]);
 
-    // Test on an object with a thousand own properties.
-    var obj = {};
-    for (var i = 0; i < 1000; i++) {
-        obj[Symbol.for("x" + i)] = 1;
-    }
-    assertEq(Object.getOwnPropertyNames(obj).length, 0);
-    var symbols = Object.getOwnPropertySymbols(obj);
-    assertEq(symbols.length, 1000);
-    assertEq(symbols.indexOf(Symbol.for("x0")) !== -1, true);
-    assertEq(symbols.indexOf(Symbol.for("x241")) !== -1, true);
-    assertEq(symbols.indexOf(Symbol.for("x999")) !== -1, true);
-    assertEq(Object.getOwnPropertySymbols(new Proxy(obj, {})).length, 1000);
+// Test on an object with a thousand own properties.
+var obj = {};
+for (var i = 0; i < 1000; i++) {
+    obj[Symbol.for("x" + i)] = 1;
+}
+assertEq(Object.getOwnPropertyNames(obj).length, 0);
+var symbols = Object.getOwnPropertySymbols(obj);
+assertEq(symbols.length, 1000);
+assertEq(symbols.indexOf(Symbol.for("x0")) !== -1, true);
+assertEq(symbols.indexOf(Symbol.for("x241")) !== -1, true);
+assertEq(symbols.indexOf(Symbol.for("x999")) !== -1, true);
+assertEq(Object.getOwnPropertySymbols(new Proxy(obj, {})).length, 1000);
 
-    // The prototype chain is not consulted.
-    assertEq(Object.getOwnPropertySymbols(Object.create(obj)).length, 0);
-    assertEq(Object.getOwnPropertySymbols(new Proxy(Object.create(obj), {})).length, 0);
+// The prototype chain is not consulted.
+assertEq(Object.getOwnPropertySymbols(Object.create(obj)).length, 0);
+assertEq(Object.getOwnPropertySymbols(new Proxy(Object.create(obj), {})).length, 0);
 
-    // Primitives are coerced to objects; but there are never any symbol-keyed
-    // properties on the resulting wrapper objects.
-    assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(), TypeError);
-    assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(undefined), TypeError);
-    assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(null), TypeError);
-    for (var primitive of [true, 1, 3.14, "hello", Symbol()])
-        assertEq(Object.getOwnPropertySymbols(primitive).length, 0);
+// Primitives are coerced to objects; but there are never any symbol-keyed
+// properties on the resulting wrapper objects.
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(undefined), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(null), TypeError);
+for (var primitive of [true, 1, 3.14, "hello", Symbol()])
+    assertEq(Object.getOwnPropertySymbols(primitive).length, 0);
 
-    assertEq(Object.getOwnPropertySymbols.length, 1);
-}
+assertEq(Object.getOwnPropertySymbols.length, 1);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Set/symbols.js
+++ b/js/src/tests/ecma_6/Set/symbols.js
@@ -1,29 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    var s = new Set;
+var s = new Set;
 
-    // Symbols can be stored in Sets.
-    var sym = Symbol();
-    s.add(sym);
-    assertEq(s.has(sym), true);
-    assertEq(s.has(Symbol()), false);
-    assertEq([...s][0], sym);
-    s.add(sym);
-    assertEq(s.has(sym), true);
-    assertEq(s.size, 1);
-    s.delete(sym);
-    assertEq(s.has(sym), false);
-    assertEq(s.size, 0);
+// Symbols can be stored in Sets.
+var sym = Symbol();
+s.add(sym);
+assertEq(s.has(sym), true);
+assertEq(s.has(Symbol()), false);
+assertEq([...s][0], sym);
+s.add(sym);
+assertEq(s.has(sym), true);
+assertEq(s.size, 1);
+s.delete(sym);
+assertEq(s.has(sym), false);
+assertEq(s.size, 0);
 
-    // Symbols returned by Symbol.for() can be in Sets.
-    var str = "how much wood would a woodchuck chuck if a woodchuck could chuck wood";
-    var s2  = "how much wood would a woodchuck chuck if could";
-    var arr = [for (word of str.split(" ")) Symbol.for(word)];
-    s = new Set(arr);
-    assertDeepEq([...s], [for (word of s2.split(" ")) Symbol.for(word)]);
-}
+// Symbols returned by Symbol.for() can be in Sets.
+var str = "how much wood would a woodchuck chuck if a woodchuck could chuck wood";
+var s2  = "how much wood would a woodchuck chuck if could";
+var arr = [for (word of str.split(" ")) Symbol.for(word)];
+s = new Set(arr);
+assertDeepEq([...s], [for (word of s2.split(" ")) Symbol.for(word)]);
 
 if (typeof reportCompare === "function")
   reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generateddata-part0.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - part0';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  load('ecma_6/String/normalize-generateddata-input.js');
+
+  for (var test0 of tests_part0) {
+    runNormalizeTest(test0);
+  }
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generateddata-part1-not-listed.js
@@ -0,0 +1,38 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - not listed in part1';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  load('ecma_6/String/normalize-generateddata-input.js');
+
+  var part1 = new Set();
+  for (var test1 of tests_part1) {
+    part1.add(test1.source[0]);
+  }
+
+  /* not listed in Part 1 */
+  for (var x = 0; x <= 0x2FFFF; x++) {
+    if (part1.has(x)) {
+      continue;
+    }
+    var xstr = x.toString(16);
+    var c = String.fromCodePoint(x);
+    assertEq(c.normalize(), c, "NFC of " + xstr);
+    assertEq(c.normalize(undefined), c, "NFC of " + xstr);
+    assertEq(c.normalize("NFC"), c, "NFC of " + xstr);
+    assertEq(c.normalize("NFD"), c, "NFD of " + xstr);
+    assertEq(c.normalize("NFKC"), c, "NFKC of " + xstr);
+    assertEq(c.normalize("NFKD"), c, "NFKD of " + xstr);
+  }
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generateddata-part1.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - part1';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  load('ecma_6/String/normalize-generateddata-input.js');
+
+  for (var test1 of tests_part1) {
+    runNormalizeTest(test1);
+  }
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generateddata-part2.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - part2';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  load('ecma_6/String/normalize-generateddata-input.js');
+
+  for (var test2 of tests_part2) {
+    runNormalizeTest(test2);
+  }
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generateddata-part3.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - part3';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  load('ecma_6/String/normalize-generateddata-input.js');
+
+  for (var test3 of tests_part3) {
+    runNormalizeTest(test3);
+  }
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/String/normalize-generateddata.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// |reftest| skip-if(!xulRuntime.shell||!("normalize"in(String.prototype))) -- uses shell load() function, String.prototype.normalize is not enabled in all builds
-var BUGNUMBER = 918987;
-var summary = 'String.prototype.normalize';
-
-print(BUGNUMBER + ": " + summary);
-
-/**************
- * BEGIN TEST *
- **************/
-
-load('ecma_6/String/normalize-generateddata-input.js');
-
-function codePointsToString(points) {
-  return points.map(x => String.fromCodePoint(x)).join("");
-}
-function stringify(points) {
-  return points.map(x => x.toString(16)).join();
-}
-
-function runTest(test) {
-  var source = codePointsToString(test.source);
-  var NFC = codePointsToString(test.NFC);
-  var NFD = codePointsToString(test.NFD);
-  var NFKC = codePointsToString(test.NFKC);
-  var NFKD = codePointsToString(test.NFKD);
-  var sourceStr = stringify(test.source);
-  var nfcStr = stringify(test.NFC);
-  var nfdStr = stringify(test.NFD);
-  var nfkcStr = stringify(test.NFKC);
-  var nfkdStr = stringify(test.NFKD);
-
-  /* NFC */
-  assertEq(source.normalize(), NFC, "NFC of " + sourceStr);
-  assertEq(NFC.normalize(), NFC, "NFC of " + nfcStr);
-  assertEq(NFD.normalize(), NFC, "NFC of " + nfdStr);
-  assertEq(NFKC.normalize(), NFKC, "NFC of " + nfkcStr);
-  assertEq(NFKD.normalize(), NFKC, "NFC of " + nfkdStr);
-
-  assertEq(source.normalize(undefined), NFC, "NFC of " + sourceStr);
-  assertEq(NFC.normalize(undefined), NFC, "NFC of " + nfcStr);
-  assertEq(NFD.normalize(undefined), NFC, "NFC of " + nfdStr);
-  assertEq(NFKC.normalize(undefined), NFKC, "NFC of " + nfkcStr);
-  assertEq(NFKD.normalize(undefined), NFKC, "NFC of " + nfkdStr);
-
-  assertEq(source.normalize("NFC"), NFC, "NFC of " + sourceStr);
-  assertEq(NFC.normalize("NFC"), NFC, "NFC of " + nfcStr);
-  assertEq(NFD.normalize("NFC"), NFC, "NFC of " + nfdStr);
-  assertEq(NFKC.normalize("NFC"), NFKC, "NFC of " + nfkcStr);
-  assertEq(NFKD.normalize("NFC"), NFKC, "NFC of " + nfkdStr);
-
-  /* NFD */
-  assertEq(source.normalize("NFD"), NFD, "NFD of " + sourceStr);
-  assertEq(NFC.normalize("NFD"), NFD, "NFD of " + nfcStr);
-  assertEq(NFD.normalize("NFD"), NFD, "NFD of " + nfdStr);
-  assertEq(NFKC.normalize("NFD"), NFKD, "NFD of " + nfkcStr);
-  assertEq(NFKD.normalize("NFD"), NFKD, "NFD of " + nfkdStr);
-
-  /* NFKC */
-  assertEq(source.normalize("NFKC"), NFKC, "NFKC of " + sourceStr);
-  assertEq(NFC.normalize("NFKC"), NFKC, "NFKC of " + nfcStr);
-  assertEq(NFD.normalize("NFKC"), NFKC, "NFKC of " + nfdStr);
-  assertEq(NFKC.normalize("NFKC"), NFKC, "NFKC of " + nfkcStr);
-  assertEq(NFKD.normalize("NFKC"), NFKC, "NFKC of " + nfkdStr);
-
-  /* NFKD */
-  assertEq(source.normalize("NFKD"), NFKD, "NFKD of " + sourceStr);
-  assertEq(NFC.normalize("NFKD"), NFKD, "NFKD of " + nfcStr);
-  assertEq(NFD.normalize("NFKD"), NFKD, "NFKD of " + nfdStr);
-  assertEq(NFKC.normalize("NFKD"), NFKD, "NFKD of " + nfkcStr);
-  assertEq(NFKD.normalize("NFKD"), NFKD, "NFKD of " + nfkdStr);
-}
-
-for (var test0 of tests_part0) {
-  runTest(test0);
-}
-var part1 = new Set();
-for (var test1 of tests_part1) {
-  part1.add(test1.source[0]);
-  runTest(test1);
-}
-for (var test2 of tests_part2) {
-  runTest(test2);
-}
-for (var test3 of tests_part3) {
-  runTest(test3);
-}
-
-/* not listed in Part 1 */
-for (var x = 0; x <= 0x2FFFF; x++) {
-  if (part1.has(x)) {
-    continue;
-  }
-  var xstr = x.toString(16);
-  var c = String.fromCodePoint(x);
-  assertEq(c.normalize(), c, "NFC of " + xstr);
-  assertEq(c.normalize(undefined), c, "NFC of " + xstr);
-  assertEq(c.normalize("NFC"), c, "NFC of " + xstr);
-  assertEq(c.normalize("NFD"), c, "NFD of " + xstr);
-  assertEq(c.normalize("NFKC"), c, "NFKC of " + xstr);
-  assertEq(c.normalize("NFKD"), c, "NFKD of " + xstr);
-}
-
-var myobj = {toString : (function () "a\u0301"), normalize : String.prototype.normalize};
-assertEq(myobj.normalize(), "\u00E1");
-
-assertThrowsInstanceOf(function() {
-                         "abc".normalize("NFE");
-                       }, RangeError,
-                       "String.prototype.normalize should raise RangeError on invalid form");
-
-assertEq("".normalize(), "");
-
-/* JSRope test */
-var a = "";
-var b = "";
-for (var i = 0; i < 100; i++) {
-  a += "\u0100";
-  b += "\u0041\u0304";
-}
-assertEq(a.normalize("NFD"), b);
-
-/******************************************************************************/
-
-if (typeof reportCompare === "function")
-  reportCompare(true, true);
-print("Tests complete");
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-generic.js
@@ -0,0 +1,20 @@
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - normalize no String object';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  var myobj = {
+    toString: () => "a\u0301",
+    normalize: String.prototype.normalize
+  };
+  assertEq(myobj.normalize(), "\u00E1");
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-parameter.js
@@ -0,0 +1,19 @@
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - passing wrong parameter';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  assertThrowsInstanceOf(() => "abc".normalize("NFE"), RangeError,
+                         "String.prototype.normalize should raise RangeError on invalid form");
+
+  assertEq("".normalize(), "");
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/normalize-rope.js
@@ -0,0 +1,23 @@
+var BUGNUMBER = 918987;
+var summary = 'String.prototype.normalize - normalize rope string';
+
+print(BUGNUMBER + ": " + summary);
+
+function test() {
+  /* JSRope test */
+  var a = "";
+  var b = "";
+  for (var i = 0; i < 100; i++) {
+    a += "\u0100";
+    b += "\u0041\u0304";
+  }
+  assertEq(a.normalize("NFD"), b);
+}
+
+if ("normalize" in String.prototype) {
+  // String.prototype.normalize is not enabled in all builds.
+  test();
+}
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
--- a/js/src/tests/ecma_6/String/shell.js
+++ b/js/src/tests/ecma_6/String/shell.js
@@ -0,0 +1,59 @@
+function runNormalizeTest(test) {
+  function codePointsToString(points) {
+    return points.map(x => String.fromCodePoint(x)).join("");
+  }
+  function stringify(points) {
+    return points.map(x => x.toString(16)).join();
+  }
+
+  var source = codePointsToString(test.source);
+  var NFC = codePointsToString(test.NFC);
+  var NFD = codePointsToString(test.NFD);
+  var NFKC = codePointsToString(test.NFKC);
+  var NFKD = codePointsToString(test.NFKD);
+  var sourceStr = stringify(test.source);
+  var nfcStr = stringify(test.NFC);
+  var nfdStr = stringify(test.NFD);
+  var nfkcStr = stringify(test.NFKC);
+  var nfkdStr = stringify(test.NFKD);
+
+  /* NFC */
+  assertEq(source.normalize(), NFC, "NFC of " + sourceStr);
+  assertEq(NFC.normalize(), NFC, "NFC of " + nfcStr);
+  assertEq(NFD.normalize(), NFC, "NFC of " + nfdStr);
+  assertEq(NFKC.normalize(), NFKC, "NFC of " + nfkcStr);
+  assertEq(NFKD.normalize(), NFKC, "NFC of " + nfkdStr);
+
+  assertEq(source.normalize(undefined), NFC, "NFC of " + sourceStr);
+  assertEq(NFC.normalize(undefined), NFC, "NFC of " + nfcStr);
+  assertEq(NFD.normalize(undefined), NFC, "NFC of " + nfdStr);
+  assertEq(NFKC.normalize(undefined), NFKC, "NFC of " + nfkcStr);
+  assertEq(NFKD.normalize(undefined), NFKC, "NFC of " + nfkdStr);
+
+  assertEq(source.normalize("NFC"), NFC, "NFC of " + sourceStr);
+  assertEq(NFC.normalize("NFC"), NFC, "NFC of " + nfcStr);
+  assertEq(NFD.normalize("NFC"), NFC, "NFC of " + nfdStr);
+  assertEq(NFKC.normalize("NFC"), NFKC, "NFC of " + nfkcStr);
+  assertEq(NFKD.normalize("NFC"), NFKC, "NFC of " + nfkdStr);
+
+  /* NFD */
+  assertEq(source.normalize("NFD"), NFD, "NFD of " + sourceStr);
+  assertEq(NFC.normalize("NFD"), NFD, "NFD of " + nfcStr);
+  assertEq(NFD.normalize("NFD"), NFD, "NFD of " + nfdStr);
+  assertEq(NFKC.normalize("NFD"), NFKD, "NFD of " + nfkcStr);
+  assertEq(NFKD.normalize("NFD"), NFKD, "NFD of " + nfkdStr);
+
+  /* NFKC */
+  assertEq(source.normalize("NFKC"), NFKC, "NFKC of " + sourceStr);
+  assertEq(NFC.normalize("NFKC"), NFKC, "NFKC of " + nfcStr);
+  assertEq(NFD.normalize("NFKC"), NFKC, "NFKC of " + nfdStr);
+  assertEq(NFKC.normalize("NFKC"), NFKC, "NFKC of " + nfkcStr);
+  assertEq(NFKD.normalize("NFKC"), NFKC, "NFKC of " + nfkdStr);
+
+  /* NFKD */
+  assertEq(source.normalize("NFKD"), NFKD, "NFKD of " + sourceStr);
+  assertEq(NFC.normalize("NFKD"), NFKD, "NFKD of " + nfcStr);
+  assertEq(NFD.normalize("NFKD"), NFKD, "NFKD of " + nfdStr);
+  assertEq(NFKC.normalize("NFKD"), NFKD, "NFKD of " + nfkcStr);
+  assertEq(NFKD.normalize("NFKD"), NFKD, "NFKD of " + nfkdStr);
+}
--- a/js/src/tests/ecma_6/Symbol/as-base-value.js
+++ b/js/src/tests/ecma_6/Symbol/as-base-value.js
@@ -1,91 +1,89 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // Like other primitives, symbols can be treated as objects, using object-like
-    // syntax: `symbol.prop` or `symbol[key]`.
-    //
-    // In ECMAScript spec jargon, this creates a Reference whose base value is a
-    // primitive Symbol value.
+// Like other primitives, symbols can be treated as objects, using object-like
+// syntax: `symbol.prop` or `symbol[key]`.
+//
+// In ECMAScript spec jargon, this creates a Reference whose base value is a
+// primitive Symbol value.
 
-    var symbols = [
-        Symbol(),
-        Symbol("ponies"),
-        Symbol.for("sym"),
-        Symbol.iterator
-    ];
+var symbols = [
+    Symbol(),
+    Symbol("ponies"),
+    Symbol.for("sym"),
+    Symbol.iterator
+];
 
-    // Test accessor property, used below.
-    var gets, sets;
-    Object.defineProperty(Symbol.prototype, "prop", {
-        get: function () {
-            "use strict";
-            gets++;
-            assertEq(typeof this, "object");
-            assertEq(this instanceof Symbol, true);
-            assertEq(this.valueOf(), sym);
-            return "got";
-        },
-        set: function (v) {
-            "use strict";
-            sets++;
-            assertEq(typeof this, "object");
-            assertEq(this instanceof Symbol, true);
-            assertEq(this.valueOf(), sym);
-            assertEq(v, "newvalue");
-        }
-    });
+// Test accessor property, used below.
+var gets, sets;
+Object.defineProperty(Symbol.prototype, "prop", {
+    get: function () {
+        "use strict";
+        gets++;
+        assertEq(typeof this, "object");
+        assertEq(this instanceof Symbol, true);
+        assertEq(this.valueOf(), sym);
+        return "got";
+    },
+    set: function (v) {
+        "use strict";
+        sets++;
+        assertEq(typeof this, "object");
+        assertEq(this instanceof Symbol, true);
+        assertEq(this.valueOf(), sym);
+        assertEq(v, "newvalue");
+    }
+});
 
-    for (var sym of symbols) {
-        assertEq(sym.constructor, Symbol);
+for (var sym of symbols) {
+    assertEq(sym.constructor, Symbol);
 
-        // method on Object.prototype
-        assertEq(sym.hasOwnProperty("constructor"), false);
-        assertEq(sym.toLocaleString(), sym.toString()); // once .toString() exists
+    // method on Object.prototype
+    assertEq(sym.hasOwnProperty("constructor"), false);
+    assertEq(sym.toLocaleString(), sym.toString()); // once .toString() exists
 
-        // custom method monkeypatched onto Symbol.prototype
-        Symbol.prototype.nonStrictMethod = function (arg) {
-            assertEq(arg, "ok");
-            assertEq(this instanceof Symbol, true);
-            assertEq(this.valueOf(), sym);
-            return 13;
-        };
-        assertEq(sym.nonStrictMethod("ok"), 13);
+    // custom method monkeypatched onto Symbol.prototype
+    Symbol.prototype.nonStrictMethod = function (arg) {
+        assertEq(arg, "ok");
+        assertEq(this instanceof Symbol, true);
+        assertEq(this.valueOf(), sym);
+        return 13;
+    };
+    assertEq(sym.nonStrictMethod("ok"), 13);
 
-        // the same, but strict mode
-        Symbol.prototype.strictMethod = function (arg) {
-            "use strict";
-            assertEq(arg, "ok2");
-            assertEq(this, sym);
-            return 14;
-        };
-        assertEq(sym.strictMethod("ok2"), 14);
+    // the same, but strict mode
+    Symbol.prototype.strictMethod = function (arg) {
+        "use strict";
+        assertEq(arg, "ok2");
+        assertEq(this, sym);
+        return 14;
+    };
+    assertEq(sym.strictMethod("ok2"), 14);
 
-        // getter/setter on Symbol.prototype
-        gets = 0;
-        sets = 0;
-        var propname = "prop";
+    // getter/setter on Symbol.prototype
+    gets = 0;
+    sets = 0;
+    var propname = "prop";
 
-        assertEq(sym.prop, "got");
-        assertEq(gets, 1);
-        assertEq(sym[propname], "got");
-        assertEq(gets, 2);
+    assertEq(sym.prop, "got");
+    assertEq(gets, 1);
+    assertEq(sym[propname], "got");
+    assertEq(gets, 2);
 
-        assertEq(sym.prop = "newvalue", "newvalue");
-        assertEq(sets, 1);
-        assertEq(sym[propname] = "newvalue", "newvalue");
-        assertEq(sets, 2);
+    assertEq(sym.prop = "newvalue", "newvalue");
+    assertEq(sets, 1);
+    assertEq(sym[propname] = "newvalue", "newvalue");
+    assertEq(sets, 2);
 
-        // non-existent property
-        assertEq(sym.noSuchProp, undefined);
-        var noSuchPropName = "nonesuch";
-        assertEq(sym[noSuchPropName], undefined);
+    // non-existent property
+    assertEq(sym.noSuchProp, undefined);
+    var noSuchPropName = "nonesuch";
+    assertEq(sym[noSuchPropName], undefined);
 
-        // non-existent method
-        assertThrowsInstanceOf(() => sym.noSuchProp(), TypeError);
-        assertThrowsInstanceOf(() => sym[noSuchPropName](), TypeError);
-    }
+    // non-existent method
+    assertThrowsInstanceOf(() => sym.noSuchProp(), TypeError);
+    assertThrowsInstanceOf(() => sym[noSuchPropName](), TypeError);
 }
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/comparisons.js
+++ b/js/src/tests/ecma_6/Symbol/comparisons.js
@@ -1,36 +1,34 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    var symbols = [
-        Symbol(),
-        Symbol("0"),
-        Symbol.for("snowman"),
-        Symbol.iterator
-    ];
+var symbols = [
+    Symbol(),
+    Symbol("0"),
+    Symbol.for("snowman"),
+    Symbol.iterator
+];
 
-    var values = [
-        undefined, null, 0, 3.14, -0, NaN, "", "alphabet", Symbol("0"),
-        {}, []
-    ];
+var values = [
+    undefined, null, 0, 3.14, -0, NaN, "", "alphabet", Symbol("0"),
+    {}, []
+];
 
-    for (var comparator of ["==", "!=", "===", "!=="]) {
-        var f = Function("a, b", "return a " + comparator + " b;");
-        var expected = (comparator[0] == '!');
-        for (var a of symbols) {
-            for (var b of values)
-                assertEq(f(a, b), expected);
-        }
+for (var comparator of ["==", "!=", "===", "!=="]) {
+    var f = Function("a, b", "return a " + comparator + " b;");
+    var expected = (comparator[0] == '!');
+    for (var a of symbols) {
+        for (var b of values)
+            assertEq(f(a, b), expected);
     }
+}
 
-    for (var comparator of ["<", "<=", ">", ">="]) {
-        var f = Function("a, b", "return a " + comparator + " b;");
-        for (var a of symbols) {
-            for (var b of values)
-                assertThrowsInstanceOf(() => f(a, b), TypeError);
-        }
+for (var comparator of ["<", "<=", ">", ">="]) {
+    var f = Function("a, b", "return a " + comparator + " b;");
+    for (var a of symbols) {
+        for (var b of values)
+            assertThrowsInstanceOf(() => f(a, b), TypeError);
     }
 }
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/constructor.js
+++ b/js/src/tests/ecma_6/Symbol/constructor.js
@@ -1,37 +1,35 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // Symbol(symbol) throws a TypeError.
-    var sym = Symbol();
-    assertThrowsInstanceOf(() => Symbol(sym), TypeError);
+// Symbol(symbol) throws a TypeError.
+var sym = Symbol();
+assertThrowsInstanceOf(() => Symbol(sym), TypeError);
 
-    // Symbol(undefined) is equivalent to Symbol().
-    assertEq(Symbol(undefined).toString(), "Symbol()");
+// Symbol(undefined) is equivalent to Symbol().
+assertEq(Symbol(undefined).toString(), "Symbol()");
 
-    // Otherwise, Symbol(v) means Symbol(ToString(v)).
-    assertEq(Symbol(7).toString(), "Symbol(7)");
-    assertEq(Symbol(true).toString(), "Symbol(true)");
-    assertEq(Symbol(null).toString(), "Symbol(null)");
-    assertEq(Symbol([1, 2]).toString(), "Symbol(1,2)");
-    var symobj = Object(sym);
-    assertThrowsInstanceOf(() => Symbol(symobj), TypeError);
+// Otherwise, Symbol(v) means Symbol(ToString(v)).
+assertEq(Symbol(7).toString(), "Symbol(7)");
+assertEq(Symbol(true).toString(), "Symbol(true)");
+assertEq(Symbol(null).toString(), "Symbol(null)");
+assertEq(Symbol([1, 2]).toString(), "Symbol(1,2)");
+var symobj = Object(sym);
+assertThrowsInstanceOf(() => Symbol(symobj), TypeError);
 
-    var hits = 0;
-    var obj = {
-        toString: function () {
-            hits++;
-            return "ponies";
-        }
-    };
-    assertEq(Symbol(obj).toString(), "Symbol(ponies)");
-    assertEq(hits, 1);
+var hits = 0;
+var obj = {
+    toString: function () {
+        hits++;
+        return "ponies";
+    }
+};
+assertEq(Symbol(obj).toString(), "Symbol(ponies)");
+assertEq(hits, 1);
 
-    assertEq(Object.getPrototypeOf(Symbol.prototype), Object.prototype);
+assertEq(Object.getPrototypeOf(Symbol.prototype), Object.prototype);
 
-    // Symbol.prototype is not itself a Symbol object.
-    assertThrowsInstanceOf(() => Symbol.prototype.valueOf(), TypeError);
-}
+// Symbol.prototype is not itself a Symbol object.
+assertThrowsInstanceOf(() => Symbol.prototype.valueOf(), TypeError);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/conversions.js
+++ b/js/src/tests/ecma_6/Symbol/conversions.js
@@ -1,68 +1,66 @@
 // Section numbers cite ES6 rev 24 (2014 April 27).
 
-if (typeof Symbol === "function") {
-    var symbols = [
-        Symbol(),
-        Symbol("one"),
-        Symbol.for("two"),
-        Symbol.iterator
-    ];
+var symbols = [
+    Symbol(),
+    Symbol("one"),
+    Symbol.for("two"),
+    Symbol.iterator
+];
+
+if (Symbol.toPrimitive in Symbol.prototype) {
+    // We should test that deleting Symbol.prototype[@@toPrimitive] changes the
+    // behavior of ToPrimitive on Symbol objects, but @@toPrimitive is not
+    // implemented yet.
+    throw new Error("Congratulations on implementing @@toPrimitive! Please update this test.");
+}
 
-    if (Symbol.toPrimitive in Symbol.prototype) {
-        // We should test that deleting Symbol.prototype[@@toPrimitive] changes the
-        // behavior of ToPrimitive on Symbol objects, but @@toPrimitive is not
-        // implemented yet.
-        throw new Error("Congratulations on implementing @@toPrimitive! Please update this test.");
-    }
-
-    for (var sym of symbols) {
-        // 7.1.1 ToPrimitive
-        var symobj = Object(sym);
-        assertThrowsInstanceOf(() => Number(symobj), TypeError);
-        assertThrowsInstanceOf(() => String(symobj), TypeError);
-        assertThrowsInstanceOf(() => symobj < 0, TypeError);
-        assertThrowsInstanceOf(() => 0 < symobj, TypeError);
-        assertThrowsInstanceOf(() => symobj + 1, TypeError);
-        assertThrowsInstanceOf(() => "" + symobj, TypeError);
-        assertEq(sym == symobj, true);
-        assertEq(sym === symobj, false);
-        assertEq(symobj == 0, false);
-        assertEq(0 != symobj, true);
+for (var sym of symbols) {
+    // 7.1.1 ToPrimitive
+    var symobj = Object(sym);
+    assertThrowsInstanceOf(() => Number(symobj), TypeError);
+    assertThrowsInstanceOf(() => String(symobj), TypeError);
+    assertThrowsInstanceOf(() => symobj < 0, TypeError);
+    assertThrowsInstanceOf(() => 0 < symobj, TypeError);
+    assertThrowsInstanceOf(() => symobj + 1, TypeError);
+    assertThrowsInstanceOf(() => "" + symobj, TypeError);
+    assertEq(sym == symobj, true);
+    assertEq(sym === symobj, false);
+    assertEq(symobj == 0, false);
+    assertEq(0 != symobj, true);
 
-        // 7.1.2 ToBoolean
-        assertEq(Boolean(sym), true);
-        assertEq(!sym, false);
-        assertEq(sym || 13, sym);
-        assertEq(sym && 13, 13);
+    // 7.1.2 ToBoolean
+    assertEq(Boolean(sym), true);
+    assertEq(!sym, false);
+    assertEq(sym || 13, sym);
+    assertEq(sym && 13, 13);
 
-        // 7.1.3 ToNumber
-        assertThrowsInstanceOf(() => +sym, TypeError);
-        assertThrowsInstanceOf(() => sym | 0, TypeError);
+    // 7.1.3 ToNumber
+    assertThrowsInstanceOf(() => +sym, TypeError);
+    assertThrowsInstanceOf(() => sym | 0, TypeError);
 
-        // 7.1.12 ToString
-        assertThrowsInstanceOf(() => "" + sym, TypeError);
-        assertThrowsInstanceOf(() => sym + "", TypeError);
-        assertThrowsInstanceOf(() => "" + [1, 2, Symbol()], TypeError);
-        assertThrowsInstanceOf(() => ["simple", "thimble", Symbol()].join(), TypeError);
+    // 7.1.12 ToString
+    assertThrowsInstanceOf(() => "" + sym, TypeError);
+    assertThrowsInstanceOf(() => sym + "", TypeError);
+    assertThrowsInstanceOf(() => "" + [1, 2, Symbol()], TypeError);
+    assertThrowsInstanceOf(() => ["simple", "thimble", Symbol()].join(), TypeError);
 
-        // 21.1.1.1 String()
-        assertEq(String(sym), sym.toString());
-        assertThrowsInstanceOf(() => String(Object(sym)), TypeError);
+    // 21.1.1.1 String()
+    assertEq(String(sym), sym.toString());
+    assertThrowsInstanceOf(() => String(Object(sym)), TypeError);
 
-        // 21.1.1.2 new String()
-        assertThrowsInstanceOf(() => new String(sym), TypeError);
+    // 21.1.1.2 new String()
+    assertThrowsInstanceOf(() => new String(sym), TypeError);
 
-        // 7.1.13 ToObject
-        var obj = Object(sym);
-        assertEq(typeof obj, "object");
-        assertEq(Object.prototype.toString.call(obj), "[object Symbol]");
-        assertEq(Object.getPrototypeOf(obj), Symbol.prototype);
-        assertEq(Object.getOwnPropertyNames(obj).length, 0);
-        assertEq(Object(sym) === Object(sym), false);  // new object each time
-        var f = function () { return this; };
-        assertEq(f.call(sym) === f.call(sym), false);  // new object each time
-    }
+    // 7.1.13 ToObject
+    var obj = Object(sym);
+    assertEq(typeof obj, "object");
+    assertEq(Object.prototype.toString.call(obj), "[object Symbol]");
+    assertEq(Object.getPrototypeOf(obj), Symbol.prototype);
+    assertEq(Object.getOwnPropertyNames(obj).length, 0);
+    assertEq(Object(sym) === Object(sym), false);  // new object each time
+    var f = function () { return this; };
+    assertEq(f.call(sym) === f.call(sym), false);  // new object each time
 }
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/enumeration-order.js
+++ b/js/src/tests/ecma_6/Symbol/enumeration-order.js
@@ -1,43 +1,40 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
+// Symbols follow all other property keys in the result list.
 var log;
 function LoggingProxy() {
     return new Proxy({}, {
         defineProperty: (t, key, desc) => {
             log.push(key);
             return true;
         }
     });
 }
 
+var keys = [
+    "before",
+    Symbol(),
+    "during",
+    Symbol.for("during"),
+    Symbol.iterator,
+    "after"
+];
+var descs = {};
+for (var k of keys)
+    descs[k] = {configurable: true, value: 0};
+
 function test(descsObj) {
     log = [];
     Object.defineProperties(LoggingProxy(), descs);
     assertEq(log.length, keys.length);
     assertDeepEq(log.map(k => typeof k), ["string", "string", "string", "symbol", "symbol", "symbol"]);
     for (var key of keys)
         assertEq(log.indexOf(key) !== -1, true);
 }
 
-if (typeof Symbol === "function") {
-    // ES6 draft rev 25 (2014 May 22), 9.1.12 "[[OwnPropertyKeys]] ()":
-
-    var keys = [
-        "before",
-        Symbol(),
-        "during",
-        Symbol.for("during"),
-        Symbol.iterator,
-        "after"
-    ];
-    var descs = {};
-    for (var k of keys)
-        descs[k] = {configurable: true, value: 0};
-
-    test(descs);
-    test(new Proxy(descs, {}));
-}
+test(descs);
+test(new Proxy(descs, {}));
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/enumeration.js
+++ b/js/src/tests/ecma_6/Symbol/enumeration.js
@@ -1,54 +1,52 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // for-in loops skip properties with symbol keys, even enumerable properties.
-    var obj = {};
-    obj[Symbol.for("moon")] = "sun";
-    obj[Symbol("asleep")] = "awake";
-    obj[Symbol.iterator] = "List";
-    for (var x in obj)
-        throw "FAIL: " + uneval(x);
+// for-in loops skip properties with symbol keys, even enumerable properties.
+var obj = {};
+obj[Symbol.for("moon")] = "sun";
+obj[Symbol("asleep")] = "awake";
+obj[Symbol.iterator] = "List";
+for (var x in obj)
+    throw "FAIL: " + uneval(x);
 
-    // This includes inherited properties.
-    var obj2 = Object.create(obj);
-    for (var x in obj2)
-        throw "FAIL: " + uneval(x);
+// This includes inherited properties.
+var obj2 = Object.create(obj);
+for (var x in obj2)
+    throw "FAIL: " + uneval(x);
 
-    // The same goes for proxies.
-    var p = new Proxy(obj, {});
-    for (var x in p)
-        throw "FAIL: " + uneval(x);
-    var p2 = new Proxy(obj2, {});
-    for (var x in p2)
-        throw "FAIL: " + uneval(x);
+// The same goes for proxies.
+var p = new Proxy(obj, {});
+for (var x in p)
+    throw "FAIL: " + uneval(x);
+var p2 = new Proxy(obj2, {});
+for (var x in p2)
+    throw "FAIL: " + uneval(x);
 
-    // Object.keys() and .getOwnPropertyNames() also skip symbols.
-    assertEq(Object.keys(obj).length, 0);
-    assertEq(Object.keys(p).length, 0);
-    assertEq(Object.keys(obj2).length, 0);
-    assertEq(Object.keys(p2).length, 0);
-    assertEq(Object.getOwnPropertyNames(obj).length, 0);
-    assertEq(Object.getOwnPropertyNames(p).length, 0);
-    assertEq(Object.getOwnPropertyNames(obj2).length, 0);
-    assertEq(Object.getOwnPropertyNames(p2).length, 0);
+// Object.keys() and .getOwnPropertyNames() also skip symbols.
+assertEq(Object.keys(obj).length, 0);
+assertEq(Object.keys(p).length, 0);
+assertEq(Object.keys(obj2).length, 0);
+assertEq(Object.keys(p2).length, 0);
+assertEq(Object.getOwnPropertyNames(obj).length, 0);
+assertEq(Object.getOwnPropertyNames(p).length, 0);
+assertEq(Object.getOwnPropertyNames(obj2).length, 0);
+assertEq(Object.getOwnPropertyNames(p2).length, 0);
 
-    // Test interaction of Object.keys(), proxies, and symbol property keys.
-    var log = [];
-    var h = {
-        ownKeys: (t) => {
-            log.push("ownKeys");
-            return ["a", "0", Symbol.for("moon"), Symbol("asleep"), Symbol.iterator];
-        },
-        getOwnPropertyDescriptor: (t, key) => {
-            log.push("gopd", key);
-            return {configurable: true, enumerable: true, value: 0, writable: true};
-        }
-    };
-    p = new Proxy({}, h);
-    assertDeepEq(Object.keys(p), ["a", "0"]);
-    assertDeepEq(log, ["ownKeys", "gopd", "a", "gopd", "0"]);
-}
+// Test interaction of Object.keys(), proxies, and symbol property keys.
+var log = [];
+var h = {
+    ownKeys: (t) => {
+        log.push("ownKeys");
+        return ["a", "0", Symbol.for("moon"), Symbol("asleep"), Symbol.iterator];
+    },
+    getOwnPropertyDescriptor: (t, key) => {
+        log.push("gopd", key);
+        return {configurable: true, enumerable: true, value: 0, writable: true};
+    }
+};
+p = new Proxy({}, h);
+assertDeepEq(Object.keys(p), ["a", "0"]);
+assertDeepEq(log, ["ownKeys", "gopd", "a", "gopd", "0"]);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/equality.js
+++ b/js/src/tests/ecma_6/Symbol/equality.js
@@ -1,32 +1,30 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // Symbol.for returns the same symbol whenever the same argument is passed.
-    assertEq(Symbol.for("q") === Symbol.for("q"), true);
+// Symbol.for returns the same symbol whenever the same argument is passed.
+assertEq(Symbol.for("q") === Symbol.for("q"), true);
 
-    // Several distinct Symbol values.
-    var symbols = [
-        Symbol(),
-        Symbol("Symbol.iterator"),
-        Symbol("Symbol.iterator"),  // distinct new symbol with the same description
-        Symbol.for("Symbol.iterator"),
-        Symbol.iterator
-    ];
+// Several distinct Symbol values.
+var symbols = [
+    Symbol(),
+    Symbol("Symbol.iterator"),
+    Symbol("Symbol.iterator"),  // distinct new symbol with the same description
+    Symbol.for("Symbol.iterator"),
+    Symbol.iterator
+];
 
-    // Distinct symbols are never equal to each other, even if they have the same
-    // description.
-    for (var i = 0; i < symbols.length; i++) {
-        for (var j = i; j < symbols.length; j++) {
-            var expected = (i === j);
-            assertEq(symbols[i] == symbols[j], expected);
-            assertEq(symbols[i] != symbols[j], !expected);
-            assertEq(symbols[i] === symbols[j], expected);
-            assertEq(symbols[i] !== symbols[j], !expected);
-            assertEq(Object.is(symbols[i], symbols[j]), expected);
-        }
+// Distinct symbols are never equal to each other, even if they have the same
+// description.
+for (var i = 0; i < symbols.length; i++) {
+    for (var j = i; j < symbols.length; j++) {
+        var expected = (i === j);
+        assertEq(symbols[i] == symbols[j], expected);
+        assertEq(symbols[i] != symbols[j], !expected);
+        assertEq(symbols[i] === symbols[j], expected);
+        assertEq(symbols[i] !== symbols[j], !expected);
+        assertEq(Object.is(symbols[i], symbols[j]), expected);
     }
 }
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/errors.js
+++ b/js/src/tests/ecma_6/Symbol/errors.js
@@ -1,19 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // Section numbers cite ES6 rev 24 (2014 April 27).
+// Section numbers cite ES6 rev 24 (2014 April 27).
 
-    var sym = Symbol();
+var sym = Symbol();
 
-    // 7.2.2 IsCallable
-    assertThrowsInstanceOf(() => sym(), TypeError);
-    assertThrowsInstanceOf(() => Function.prototype.call.call(sym), TypeError);
+// 7.2.2 IsCallable
+assertThrowsInstanceOf(() => sym(), TypeError);
+assertThrowsInstanceOf(() => Function.prototype.call.call(sym), TypeError);
 
-    // 7.2.5 IsConstructor
-    assertThrowsInstanceOf(() => new sym(), TypeError);
-    assertThrowsInstanceOf(() => new Symbol(), TypeError);
-}
+// 7.2.5 IsConstructor
+assertThrowsInstanceOf(() => new sym(), TypeError);
+assertThrowsInstanceOf(() => new Symbol(), TypeError);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/for-in-order.js
+++ b/js/src/tests/ecma_6/Symbol/for-in-order.js
@@ -1,35 +1,33 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // ES6 does not specify enumeration order, but implementations mostly retain
-    // property insertion order -- and must, for web compatibility. This test checks
-    // that symbol-keyed properties do not interfere with that order.
+// ES6 does not specify enumeration order, but implementations mostly retain
+// property insertion order -- and must, for web compatibility. This test checks
+// that symbol-keyed properties do not interfere with that order.
 
-    var obj = {};
-    obj[Symbol("moon")] = 0;
-    obj.x = 1;
-    obj[Symbol.for("y")] = 2
-    obj.y = 3;
-    obj[Symbol.iterator] = function* () { yield 4; };
-    obj.z = 5;
-    Object.prototype[Symbol.for("comet")] = 6;
+var obj = {};
+obj[Symbol("moon")] = 0;
+obj.x = 1;
+obj[Symbol.for("y")] = 2
+obj.y = 3;
+obj[Symbol.iterator] = function* () { yield 4; };
+obj.z = 5;
+Object.prototype[Symbol.for("comet")] = 6;
 
-    var keys = [];
-    for (var k in obj)
-        keys.push(k);
-    assertDeepEq(keys, ["x", "y", "z"]);
-    assertDeepEq(Object.keys(obj), ["x", "y", "z"]);
+var keys = [];
+for (var k in obj)
+    keys.push(k);
+assertDeepEq(keys, ["x", "y", "z"]);
+assertDeepEq(Object.keys(obj), ["x", "y", "z"]);
 
-    // Test with more properties.
-    for (var i = 0; i < 1000; i++)
-        obj[Symbol(i)] = i;
-    obj.w = 1000;
-    keys = []
-    for (var k in obj)
-        keys.push(k);
-    assertDeepEq(keys, ["x", "y", "z", "w"]);
-}
+// Test with more properties.
+for (var i = 0; i < 1000; i++)
+    obj[Symbol(i)] = i;
+obj.w = 1000;
+keys = []
+for (var k in obj)
+    keys.push(k);
+assertDeepEq(keys, ["x", "y", "z", "w"]);
 
 if (typeof reportCompare === "function")
     reportCompare(0, 0);
--- a/js/src/tests/ecma_6/Symbol/for.js
+++ b/js/src/tests/ecma_6/Symbol/for.js
@@ -1,33 +1,31 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
-if (typeof Symbol === "function") {
-    // Symbol.for called twice with the same argument returns the same symbol.
-    assertEq(Symbol.for("ponies"), Symbol.for("ponies"));
+// Symbol.for called twice with the same argument returns the same symbol.
+assertEq(Symbol.for("ponies&qu