Merge inbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 09 Jul 2015 18:01:25 -0700
changeset 252191 2c91d57441fd7623a1c55dfe21b6992a7029e9c3
parent 252190 7ec3e4b2a45f0a7f7c086e29daaf6078758322e4 (current diff)
parent 252139 545d66184121b9bdf806ec522c9b0ee242c851c3 (diff)
child 252192 d7ca6e1baa190e9087ae422b7f5107063cf72df2
child 252264 2b6306974926c1b39a8d8fd7d8b0f1418bc77e6b
child 252274 e73e0208e9a264d5ca680185e15281694855aeda
push id62083
push userkwierso@gmail.com
push dateFri, 10 Jul 2015 01:06:27 +0000
treeherdermozilla-inbound@d7ca6e1baa19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone42.0a1
first release with
nightly linux32
2c91d57441fd / 42.0a1 / 20150710030206 / files
nightly linux64
2c91d57441fd / 42.0a1 / 20150710030206 / files
nightly mac
2c91d57441fd / 42.0a1 / 20150710030206 / files
nightly win32
2c91d57441fd / 42.0a1 / 20150710030206 / files
nightly win64
2c91d57441fd / 42.0a1 / 20150710030206 / 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 central, a=merge
browser/base/content/browser.js
browser/base/content/test/general/browser.ini
build/unix/build-clang/tooltool.py
layout/reftests/css-gradients/aja-linear-1g.html
layout/reftests/css-gradients/aja-linear-2c.html
layout/reftests/css-gradients/aja-linear-2d.html
layout/reftests/css-gradients/aja-linear-6-ref.html
layout/reftests/css-gradients/aja-linear-6a.html
layout/reftests/css-gradients/aja-linear-6b.html
layout/reftests/css-gradients/linear-1b.html
layout/reftests/css-gradients/linear-diagonal-1b.html
layout/reftests/css-gradients/linear-diagonal-1c.html
layout/reftests/css-gradients/linear-diagonal-2b.html
layout/reftests/css-gradients/linear-diagonal-2c.html
layout/reftests/css-gradients/linear-diagonal-3b.html
layout/reftests/css-gradients/linear-diagonal-3c.html
layout/reftests/css-gradients/linear-diagonal-4b.html
layout/reftests/css-gradients/linear-diagonal-4c.html
layout/reftests/css-gradients/linear-diagonal-5-ref.html
layout/reftests/css-gradients/linear-diagonal-5a.html
layout/reftests/css-gradients/linear-diagonal-6-ref.html
layout/reftests/css-gradients/linear-diagonal-6a.html
layout/reftests/css-gradients/linear-diagonal-7-ref.html
layout/reftests/css-gradients/linear-diagonal-7a.html
layout/reftests/css-gradients/linear-diagonal-8-ref.html
layout/reftests/css-gradients/linear-diagonal-8a.html
layout/reftests/css-gradients/linear-diagonal-9-ref.html
layout/reftests/css-gradients/linear-diagonal-9a.html
layout/reftests/css-gradients/linear-keywords-1b.html
layout/reftests/css-gradients/linear-mix-ref.html
layout/reftests/css-gradients/linear-mix.html
layout/reftests/css-gradients/linear-percent-ref.html
layout/reftests/css-gradients/linear-percent.html
layout/reftests/css-gradients/linear-vertical-1e.html
layout/reftests/css-gradients/linear-zero-length-1-ref.html
layout/reftests/css-gradients/linear-zero-length-1a.html
layout/reftests/css-gradients/linear-zero-length-1b.html
layout/reftests/css-gradients/linear-zero-length-1c.html
layout/reftests/css-gradients/radial-1c.html
layout/reftests/css-gradients/radial-2e.html
layout/reftests/css-gradients/radial-2f.html
layout/reftests/css-gradients/radial-onestopposition-1c.html
layout/reftests/css-gradients/radial-shape-closest-corner-1c.html
layout/reftests/css-gradients/radial-shape-closest-side-1c.html
layout/reftests/css-gradients/radial-shape-farthest-corner-1c.html
layout/reftests/css-gradients/radial-shape-farthest-side-1c.html
layout/reftests/css-gradients/radial-zero-length-1g.html
layout/reftests/css-gradients/radial-zero-length-1h.html
layout/reftests/css-gradients/radial-zero-length-1i.html
layout/reftests/css-gradients/radial-zero-length-1j.html
layout/reftests/css-gradients/repeating-radial-1e.html
layout/reftests/css-gradients/repeating-radial-1f.html
layout/reftests/css-gradients/repeating-radial-onestopposition-1c.html
layout/reftests/css-gradients/twostops-1f.html
layout/reftests/css-gradients/twostops-1g.html
modules/libpref/init/all.js
security/manager/ssl/tests/mochitest/bugs/test_bug480619.html
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -874,47 +874,52 @@ function _loadURIWithFlags(browser, uri,
   if (!uri) {
     uri = "about:blank";
   }
   let flags = params.flags || 0;
   let referrer = params.referrerURI;
   let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy :
                         Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
   let charset = params.charset;
-  let postdata = params.postData;
+  let postData = params.postData;
 
   if (!(flags & browser.webNavigation.LOAD_FLAGS_FROM_EXTERNAL)) {
     browser.userTypedClear++;
   }
 
   let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
                                         : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
   let mustChangeProcess = gMultiProcessBrowser &&
                           !E10SUtils.canLoadURIInProcess(uri, process);
   try {
     if (!mustChangeProcess) {
       browser.webNavigation.loadURIWithOptions(uri, flags,
                                                referrer, referrerPolicy,
-                                               postdata, null, null);
+                                               postData, null, null);
     } else {
+      if (postData) {
+        postData = NetUtil.readInputStreamToString(postData, postData.available());
+      }
+
       LoadInOtherProcess(browser, {
         uri: uri,
         flags: flags,
         referrer: referrer ? referrer.spec : null,
         referrerPolicy: referrerPolicy,
+        postData: postData,
       });
     }
   } catch (e) {
     // If anything goes wrong just switch remoteness manually and load the URI.
     // We might lose history that way but at least the browser loaded a page.
     // This might be necessary if SessionStore wasn't initialized yet i.e.
     // when the homepage is a non-remote page.
     gBrowser.updateBrowserRemotenessByURL(browser, uri);
     browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
-                                             postdata, null, null);
+                                             postData, null, null);
   } finally {
     if (browser.userTypedClear) {
       browser.userTypedClear--;
     }
   }
 }
 
 // Starts a new load in the browser first switching the browser to the correct
--- a/browser/base/content/docs/sslerrorreport/dataformat.rst
+++ b/browser/base/content/docs/sslerrorreport/dataformat.rst
@@ -2,29 +2,37 @@
 
 ==============
 Payload Format
 ==============
 
 An example report::
 
   {
+    "hostname":"example.com",
+    "port":443,
     "timestamp":1413490449,
     "errorCode":-16384,
     "failedCertChain":[
       ],
     "userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0",
     "version":1,
     "build":"20141022164419",
     "product":"Firefox",
     "channel":"default"
   }
 
 Where the data represents the following:
 
+"hostname"
+  The name of the host the connection was being made to.
+
+"port"
+  The TCP port the connection was being made to.
+
 "timestamp"
   The (local) time at which the report was generated. Seconds since 1 Jan 1970,
   UTC.
 
 "errorCode"
   The error code. This is the error code from certificate verification. Here's a small list of the most commonly-encountered errors:
   https://wiki.mozilla.org/SecurityEngineering/x509Certs#Error_Codes_in_Firefox
   In theory many of the errors from sslerr.h, secerr.h, and pkixnss.h could be encountered. We're starting with just MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE, which means that key pinning failed (i.e. there wasn't an intersection between the keys in any computed trusted certificate chain and the expected list of keys for the domain the user is attempting to connect to).
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -343,16 +343,17 @@ skip-if = buildapp == 'mulet' || e10s # 
 skip-if = buildapp == 'mulet'
 [browser_private_no_prompt.js]
 skip-if = buildapp == 'mulet'
 [browser_PageMetaData_pushstate.js]
 [browser_relatedTabs.js]
 [browser_remoteTroubleshoot.js]
 support-files =
   test_remoteTroubleshoot.html
+[browser_remoteWebNavigation_postdata.js]
 [browser_removeTabsToTheEnd.js]
 [browser_removeUnsafeProtocolsFromURLBarPaste.js]
 [browser_restore_isAppTab.js]
 [browser_sanitize-passwordDisabledHosts.js]
 [browser_sanitize-sitepermissions.js]
 [browser_sanitize-timespans.js]
 skip-if = buildapp == 'mulet'
 [browser_sanitizeDialog.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_remoteWebNavigation_postdata.js
@@ -0,0 +1,50 @@
+/* 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/. */
+
+Cu.import("resource://gre/modules/BrowserUtils.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+function makeInputStream(aString) {
+  let stream = Cc["@mozilla.org/io/string-input-stream;1"]
+                 .createInstance(Ci.nsIStringInputStream);
+  stream.data = aString;
+  return stream; // XPConnect will QI this to nsIInputStream for us.
+}
+
+add_task(function* test_remoteWebNavigation_postdata() {
+  let obj = {};
+  Cu.import("resource://testing-common/httpd.js", obj);
+  Cu.import("resource://services-common/utils.js", obj);
+
+  let server = new obj.HttpServer();
+  server.start(-1);
+
+  let loadDeferred = Promise.defer();
+
+  server.registerPathHandler("/test", (request, response) => {
+    let body = obj.CommonUtils.readBytesFromInputStream(request.bodyInputStream);
+    is(body, "success", "request body is correct");
+    is(request.method, "POST", "request was a post");
+    response.write("Received from POST: " + body);
+    loadDeferred.resolve();
+  });
+
+  let i = server.identity;
+  let path = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort + "/test";
+
+  let postdata =
+    "Content-Length: 7\r\n" +
+    "Content-Type: application/x-www-form-urlencoded\r\n" +
+    "\r\n" +
+    "success";
+
+  openUILinkIn(path, "tab", null, makeInputStream(postdata));
+
+  yield loadDeferred.promise;
+  yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+
+  let serverStoppedDeferred = Promise.defer();
+  server.stop(function() { serverStoppedDeferred.resolve(); });
+  yield serverStoppedDeferred.promise;
+});
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -197,19 +197,21 @@ ContentRestoreInternal.prototype = {
       if (loadArguments) {
         // A load has been redirected to a new process so get history into the
         // same state it was before the load started then trigger the load.
         let referrer = loadArguments.referrer ?
                        Utils.makeURI(loadArguments.referrer) : null;
         let referrerPolicy = ('referrerPolicy' in loadArguments
             ? loadArguments.referrerPolicy
             : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
+        let postData = loadArguments.postData ?
+                       Utils.makeInputStream(loadArguments.postData) : null;
         webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
-                                         referrer, referrerPolicy, null, null,
-                                         null);
+                                         referrer, referrerPolicy, postData,
+                                         null, null);
       } else if (tabData.userTypedValue && tabData.userTypedClear) {
         // If the user typed a URL into the URL bar and hit enter right before
         // we crashed, we want to start loading that page again. A non-zero
         // userTypedClear value means that the load had started.
         // Load userTypedValue and fix up the URL if it's partial/broken.
         webNavigation.loadURI(tabData.userTypedValue,
                               Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
                               null, null, null);
--- a/browser/components/sessionstore/Utils.jsm
+++ b/browser/components/sessionstore/Utils.jsm
@@ -2,24 +2,33 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["Utils"];
 
 const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 this.Utils = Object.freeze({
   makeURI: function (url) {
     return Services.io.newURI(url, null, null);
   },
 
+  makeInputStream: function (aString) {
+    let stream = Cc["@mozilla.org/io/string-input-stream;1"].
+                 createInstance(Ci.nsISupportsCString);
+    stream.data = aString;
+    return stream; // XPConnect will QI this to nsIInputStream for us.
+  },
+
   /**
    * Returns true if the |url| passed in is part of the given root |domain|.
    * For example, if |url| is "www.mozilla.org", and we pass in |domain| as
    * "mozilla.org", this will return true. It would return false the other way
    * around.
    */
   hasRootDomain: function (url, domain) {
     let host;
--- a/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js
@@ -177,17 +177,17 @@ function test() {
         is(allSwatches[1].textContent, "rgba(33,180,226,1)");
         is(allSwatches[2].textContent, "rgba(31,170,217,.5)");
         is(allSwatches[3].textContent, "#F06");
         is(allSwatches[4].textContent, "red");
       }
     },
     {
       name: "background",
-      value: "-moz-radial-gradient(center 45deg, circle closest-side, orange 0%, red 100%)",
+      value: "radial-gradient(circle closest-side at center, orange 0%, red 100%)",
       test: fragment => {
         is(countAll(fragment), 4);
         let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS);
         is(allSwatches.length, 2);
         is(allSwatches[0].textContent, "orange");
         is(allSwatches[1].textContent, "red");
       }
     },
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -1,12 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+import datetime
 import glob
 import time
 import re
 import os
 import tempfile
 import shutil
 import subprocess
 import sys
@@ -132,18 +133,21 @@ class RemoteAutomation(Automation):
             print "Error deleting %s" % traces
             pass
 
     def checkForANRs(self):
         traces = "/data/anr/traces.txt"
         if self._devicemanager.fileExists(traces):
             try:
                 t = self._devicemanager.pullFile(traces)
-                print "Contents of %s:" % traces
-                print t
+                if t:
+                    stripped = t.strip()
+                    if len(stripped) > 0:
+                        print "Contents of %s:" % traces
+                        print t
                 # Once reported, delete traces
                 self.deleteANRs()
             except DMError:
                 print "Error pulling %s" % traces
             except IOError:
                 print "Error pulling %s" % traces
         else:
             print "%s not found" % traces
@@ -276,17 +280,16 @@ class RemoteAutomation(Automation):
             if (self.proc is None):
                 if cmd[0] == 'am':
                     self.proc = stdout
                 else:
                     raise Exception("unable to launch process")
             self.procName = cmd[0].split('/')[-1]
             if cmd[0] == 'am' and cmd[1] in RemoteAutomation._specialAmCommands:
                 self.procName = app
-                print "Robocop process name: "+self.procName
 
             # Setting timeout at 1 hour since on a remote device this takes much longer.
             # Temporarily increased to 75 minutes because no more chunks can be created.
             self.timeout = 4500
             # The benefit of the following sleep is unclear; it was formerly 15 seconds
             time.sleep(1)
 
             # Used to buffer log messages until we meet a line break
@@ -355,42 +358,44 @@ class RemoteAutomation(Automation):
         # While waiting, periodically retrieve the process output and print it.
         # If the process is still running after *timeout* seconds, return 1;
         # If the process is still running but no output is received in *noOutputTimeout*
         # seconds, return 2;
         # Else, once the process exits/goes to background, return 0.
         def wait(self, timeout = None, noOutputTimeout = None):
             timer = 0
             noOutputTimer = 0
-            interval = 20
-
+            interval = 10
             if timeout == None:
                 timeout = self.timeout
-
             status = 0
-            while (self.dm.getTopActivity() == self.procName):
-                # retrieve log updates every 60 seconds
-                if timer % 60 == 0:
+            top = self.procName
+            slowLog = False
+            while (top == self.procName):
+                # Get log updates on each interval, but if it is taking
+                # too long, only do it every 60 seconds
+                if (not slowLog) or (timer % 60 == 0):
+                    startRead = datetime.datetime.now()
                     messages = self.read_stdout()
+                    if (datetime.datetime.now() - startRead) > datetime.timedelta(seconds=5):
+                        slowLog = True
                     if messages:
                         noOutputTimer = 0
-
                 time.sleep(interval)
                 timer += interval
                 noOutputTimer += interval
                 if (timer > timeout):
                     status = 1
                     break
                 if (noOutputTimeout and noOutputTimer > noOutputTimeout):
                     status = 2
                     break
-
+                top = self.dm.getTopActivity()
             # Flush anything added to stdout during the sleep
             self.read_stdout()
-
             return status
 
         def kill(self, stagedShutdown = False):
             if stagedShutdown:
                 # Trigger an ANR report with "kill -3" (SIGQUIT)
                 self.dm.killProcess(self.procName, 3)
                 time.sleep(3)
                 # Trigger a breakpad dump with "kill -6" (SIGABRT)
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -3,19 +3,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 import os.path
 import shutil
 import subprocess
 import platform
-import sys
 import json
-import collections
 import argparse
 
 
 def check_run(args):
     r = subprocess.call(args)
     assert r == 0
 
 
@@ -60,33 +58,16 @@ def svn_co(url, directory, revision):
 
 
 def build_one_stage(env, stage_dir, llvm_source_dir, gcc_toolchain_dir):
     def f():
         build_one_stage_aux(stage_dir, llvm_source_dir, gcc_toolchain_dir)
     with_env(env, f)
 
 
-def build_tooltool_manifest(llvm_revision):
-    basedir = os.path.split(os.path.realpath(sys.argv[0]))[0]
-    tooltool = basedir + '/tooltool.py'
-    setup = basedir + '/setup.sh'
-    manifest = 'clang.manifest'
-    check_run(['python', tooltool, '-m', manifest, 'add',
-               setup, 'clang.tar.bz2'])
-    data = json.load(file(manifest), object_pairs_hook=collections.OrderedDict)
-    data = [{'clang_version': 'r%s' % llvm_revision}] + data
-    out = file(manifest, 'w')
-    json.dump(data, out, indent=0)
-    out.write('\n')
-
-    assert data[2]['filename'] == 'clang.tar.bz2'
-    os.rename('clang.tar.bz2', data[2]['digest'])
-
-
 def get_platform():
     p = platform.system()
     if p == "Darwin":
         return "macosx64"
     elif p == "Linux":
         if platform.processor() == "x86_64":
             return "linux64"
         else:
@@ -190,9 +171,8 @@ if __name__ == "__main__":
 
     stage2_dir = build_dir + '/stage2'
     build_one_stage(
         {"CC": stage1_inst_dir + "/bin/clang %s" % extra_cflags,
          "CXX": stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
         stage2_dir, llvm_source_dir, gcc_dir)
 
     build_tar_package("tar", "clang.tar.bz2", stage2_dir, "clang")
-    build_tooltool_manifest(llvm_revision)
deleted file mode 100644
--- a/build/unix/build-clang/tooltool.py
+++ /dev/null
@@ -1,561 +0,0 @@
-#!/usr/bin/env python
-
-#tooltool is a lookaside cache implemented in Python
-#Copyright (C) 2011 John H. Ford <john@johnford.info>
-#
-#This program is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public License
-#as published by the Free Software Foundation version 2
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, write to the Free Software
-#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-# An manifest file specifies files in that directory that are stored
-# elsewhere.  This file should only contain file in the directory
-# which the manifest file resides in and it should be called 'manifest.manifest'
-
-__version__ = '1'
-
-import json
-import os
-import optparse
-import logging
-import hashlib
-import urllib2
-import ConfigParser
-
-log = logging.getLogger(__name__)
-
-class FileRecordJSONEncoderException(Exception): pass
-class InvalidManifest(Exception): pass
-class ExceptionWithFilename(Exception):
-    def __init__(self, filename):
-        Exception.__init__(self)
-        self.filename = filename
-
-class DigestMismatchException(ExceptionWithFilename): pass
-class MissingFileException(ExceptionWithFilename): pass
-
-class FileRecord(object):
-    def __init__(self, filename, size, digest, algorithm):
-        object.__init__(self)
-        self.filename = filename
-        self.size = size
-        self.digest = digest
-        self.algorithm = algorithm
-        log.debug("creating %s 0x%x" % (self.__class__.__name__, id(self)))
-
-    def __eq__(self, other):
-        if self is other:
-            return True
-        if self.filename == other.filename and \
-            self.size == other.size and \
-            self.digest == other.digest and \
-            self.algorithm == other.algorithm:
-            return True
-        else:
-            return False
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def __str__(self):
-        return repr(self)
-
-    def __repr__(self):
-        return "%s.%s(filename='%s', size='%s', digest='%s', algorithm='%s')" % (__name__,
-                self.__class__.__name__,
-                self.filename, self.size, self.digest, self.algorithm)
-
-    def present(self):
-        # Doesn't check validity
-        return os.path.exists(self.filename)
-
-    def validate_size(self):
-        if self.present():
-            return self.size == os.path.getsize(self.filename)
-        else:
-            log.debug("trying to validate size on a missing file, %s", self.filename)
-            raise MissingFileException(filename=self.filename)
-
-    def validate_digest(self):
-        if self.present():
-            with open(self.filename, 'rb') as f:
-                return self.digest == digest_file(f, self.algorithm)
-        else:
-            log.debug("trying to validate digest on a missing file, %s', self.filename")
-            raise MissingFileException(filename=self.filename)
-
-    def validate(self):
-        if self.validate_size():
-            if self.validate_digest():
-                return True
-        return False
-
-    def describe(self):
-        if self.present() and self.validate():
-            return "'%s' is present and valid" % self.filename
-        elif self.present():
-            return "'%s' is present and invalid" % self.filename
-        else:
-            return "'%s' is absent" % self.filename
-
-
-def create_file_record(filename, algorithm):
-    fo = open(filename, 'rb')
-    stored_filename = os.path.split(filename)[1]
-    fr = FileRecord(stored_filename, os.path.getsize(filename), digest_file(fo, algorithm), algorithm)
-    fo.close()
-    return fr
-
-
-class FileRecordJSONEncoder(json.JSONEncoder):
-    def encode_file_record(self, obj):
-        if not issubclass(type(obj), FileRecord):
-            err = "FileRecordJSONEncoder is only for FileRecord and lists of FileRecords, not %s" % obj.__class__.__name__
-            log.warn(err)
-            raise FileRecordJSONEncoderException(err)
-        else:
-            return {'filename': obj.filename, 'size': obj.size, 'algorithm': obj.algorithm, 'digest': obj.digest}
-
-    def default(self, f):
-        if issubclass(type(f), list):
-            record_list = []
-            for i in f:
-                record_list.append(self.encode_file_record(i))
-            return record_list
-        else:
-            return self.encode_file_record(f)
-
-
-class FileRecordJSONDecoder(json.JSONDecoder):
-    """I help the json module materialize a FileRecord from
-    a JSON file.  I understand FileRecords and lists of
-    FileRecords.  I ignore things that I don't expect for now"""
-    # TODO: make this more explicit in what it's looking for
-    # and error out on unexpected things
-    def process_file_records(self, obj):
-        if isinstance(obj, list):
-            record_list = []
-            for i in obj:
-                record = self.process_file_records(i)
-                if issubclass(type(record), FileRecord):
-                    record_list.append(record)
-            return record_list
-        if isinstance(obj, dict) and \
-           len(obj.keys()) == 4 and \
-           obj.has_key('filename') and \
-           obj.has_key('size') and \
-           obj.has_key('algorithm') and \
-           obj.has_key('digest'):
-            rv = FileRecord(obj['filename'], obj['size'], obj['digest'], obj['algorithm'])
-            log.debug("materialized %s" % rv)
-            return rv
-        return obj
-
-    def decode(self, s):
-        decoded = json.JSONDecoder.decode(self, s)
-        rv = self.process_file_records(decoded)
-        return rv
-
-
-class Manifest(object):
-
-    valid_formats = ('json',)
-
-    def __init__(self, file_records=[]):
-        self.file_records = file_records
-
-    def __eq__(self, other):
-        if self is other:
-            return True
-        if len(self.file_records) != len(other.file_records):
-            log.debug('Manifests differ in number of files')
-            return False
-        #TODO: Lists in a different order should be equal
-        for record in range(0,len(self.file_records)):
-            if self.file_records[record] != other.file_records[record]:
-                log.debug('FileRecords differ, %s vs %s' % (self.file_records[record],
-                                                            other.file_records[record]))
-                return False
-        return True
-
-    def __deepcopy__(self, memo):
-        # This is required for a deep copy
-        return Manifest(self.file_records[:])
-
-    def __copy__(self):
-        return Manifest(self.file_records)
-
-    def copy(self):
-        return Manifest(self.file_records[:])
-
-    def present(self):
-        return all(i.present() for i in self.file_records)
-
-    def validate_sizes(self):
-        return all(i.validate_size() for i in self.file_records)
-
-    def validate_digests(self):
-        return all(i.validate_digest() for i in self.file_records)
-
-    def validate(self):
-        return all(i.validate() for i in self.file_records)
-
-    def sort(self):
-        #TODO: WRITE TESTS
-        self.file_records.sort(key=lambda x: x.size)
-
-    def load(self, data_file, fmt='json'):
-        assert fmt in self.valid_formats
-        if fmt == 'json':
-            try:
-                self.file_records.extend(json.load(data_file, cls=FileRecordJSONDecoder))
-                self.sort()
-            except ValueError:
-                raise InvalidManifest("trying to read invalid manifest file")
-
-    def loads(self, data_string, fmt='json'):
-        assert fmt in self.valid_formats
-        if fmt == 'json':
-            try:
-                self.file_records.extend(json.loads(data_string, cls=FileRecordJSONDecoder))
-                self.sort()
-            except ValueError:
-                raise InvalidManifest("trying to read invalid manifest file")
-
-    def dump(self, output_file, fmt='json'):
-        assert fmt in self.valid_formats
-        self.sort()
-        if fmt == 'json':
-            rv = json.dump(self.file_records, output_file, indent=0, cls=FileRecordJSONEncoder)
-            print >> output_file, ''
-            return rv
-
-    def dumps(self, fmt='json'):
-        assert fmt in self.valid_formats
-        self.sort()
-        if fmt == 'json':
-            return json.dumps(self.file_records, cls=FileRecordJSONEncoder)
-
-
-def digest_file(f, a):
-    """I take a file like object 'f' and return a hex-string containing
-    of the result of the algorithm 'a' applied to 'f'."""
-    h = hashlib.new(a)
-    chunk_size = 1024*10
-    data = f.read(chunk_size)
-    while data:
-        h.update(data)
-        data = f.read(chunk_size)
-    if hasattr(f, 'name'):
-        log.debug('hashed %s with %s to be %s', f.name, a, h.hexdigest())
-    else:
-        log.debug('hashed a file with %s to be %s', a, h.hexdigest())
-    return h.hexdigest()
-
-# TODO: write tests for this function
-def open_manifest(manifest_file):
-    """I know how to take a filename and load it into a Manifest object"""
-    if os.path.exists(manifest_file):
-        manifest = Manifest()
-        with open(manifest_file) as f:
-            manifest.load(f)
-            log.debug("loaded manifest from file '%s'" % manifest_file)
-        return manifest
-    else:
-        log.debug("tried to load absent file '%s' as manifest" % manifest_file)
-        raise InvalidManifest("manifest file '%s' does not exist" % manifest_file)
-
-# TODO: write tests for this function
-def list_manifest(manifest_file):
-    """I know how print all the files in a location"""
-    try:
-        manifest = open_manifest(manifest_file)
-    except InvalidManifest:
-        log.error("failed to load manifest file at '%s'" % manifest_file)
-        return False
-    for f in manifest.file_records:
-        print "%s\t%s\t%s" % ("P" if f.present() else "-",
-                              "V" if f.present() and f.validate() else "-",
-                              f.filename)
-    return True
-
-def validate_manifest(manifest_file):
-    """I validate that all files in a manifest are present and valid but
-    don't fetch or delete them if they aren't"""
-    try:
-        manifest = open_manifest(manifest_file)
-    except InvalidManifest:
-        log.error("failed to load manifest file at '%s'" % manifest_file)
-        return False
-    invalid_files = []
-    absent_files = []
-    for f in manifest.file_records:
-        if not f.present():
-            absent_files.append(f)
-        else:
-            if not f.validate():
-                invalid_files.append(f)
-    if len(invalid_files + absent_files) == 0:
-        return True
-    else:
-        return False
-
-# TODO: write tests for this function
-def add_files(manifest_file, algorithm, filenames):
-    # returns True if all files successfully added, False if not
-    # and doesn't catch library Exceptions.  If any files are already
-    # tracked in the manifest, return will be False because they weren't
-    # added
-    all_files_added = True
-    # Create a old_manifest object to add to
-    if os.path.exists(manifest_file):
-        old_manifest = open_manifest(manifest_file)
-    else:
-        old_manifest = Manifest()
-        log.debug("creating a new manifest file")
-    new_manifest = Manifest() # use a different manifest for the output
-    for filename in filenames:
-        log.debug("adding %s" % filename)
-        path, name = os.path.split(filename)
-        new_fr = create_file_record(filename, algorithm)
-        log.debug("appending a new file record to manifest file")
-        add = True
-        for fr in old_manifest.file_records:
-            log.debug("manifest file has '%s'" % "', ".join([x.filename for x in old_manifest.file_records]))
-            if new_fr == fr and new_fr.validate():
-                # TODO: Decide if this case should really cause a False return
-                log.info("file already in old_manifest file and matches")
-                add = False
-            elif new_fr == fr and not new_fr.validate():
-                log.error("file already in old_manifest file but is invalid")
-                add = False
-            if filename == fr.filename:
-                log.error("manifest already contains file named %s" % filename)
-                add = False
-        if add:
-            new_manifest.file_records.append(new_fr)
-            log.debug("added '%s' to manifest" % filename)
-        else:
-            all_files_added = False
-    with open(manifest_file, 'wb') as output:
-        new_manifest.dump(output, fmt='json')
-    return all_files_added
-
-
-# TODO: write tests for this function
-def fetch_file(base_url, file_record, overwrite=False, grabchunk=1024*4):
-    # A file which is requested to be fetched that exists locally will be hashed.
-    # If the hash matches the requested file's hash, nothing will be done and the
-    # function will return.  If the function is told to overwrite and there is a 
-    # digest mismatch, the exiting file will be overwritten
-    if file_record.present():
-        if file_record.validate():
-            log.info("existing '%s' is valid, not fetching" % file_record.filename)
-            return True
-        if overwrite:
-            log.info("overwriting '%s' as requested" % file_record.filename)
-        else:
-            # All of the following is for a useful error message
-            with open(file_record.filename, 'rb') as f:
-                d = digest_file(f, file_record.algorithm)
-            log.error("digest mismatch between manifest(%s...) and local file(%s...)" % \
-                    (file_record.digest[:8], d[:8]))
-            log.debug("full digests: manifest (%s) local file (%s)" % (file_record.digest, d))
-            # Let's bail!
-            return False
-
-    # Generate the URL for the file on the server side
-    url = "%s/%s/%s" % (base_url, file_record.algorithm, file_record.digest)
-
-    log.debug("fetching from '%s'" % url)
-
-    # TODO: This should be abstracted to make generic retreival protocol handling easy
-    # Well, the file doesn't exist locally.  Lets fetch it.
-    try:
-        f = urllib2.urlopen(url)
-        log.debug("opened %s for reading" % url)
-        with open(file_record.filename, 'wb') as out:
-            k = True
-            size = 0
-            while k:
-                # TODO: print statistics as file transfers happen both for info and to stop
-                # buildbot timeouts
-                indata = f.read(grabchunk)
-                out.write(indata)
-                size += len(indata)
-                if indata == '':
-                    k = False
-            if size != file_record.size:
-                log.error("transfer from %s to %s failed due to a difference of %d bytes" % (url,
-                            file_record.filename, file_record.size - size))
-                return False
-            log.info("fetched %s" % file_record.filename)
-    except (urllib2.URLError, urllib2.HTTPError) as e:
-        log.error("failed to fetch '%s': %s" % (file_record.filename, e),
-                  exc_info=True)
-        return False
-    except IOError:
-        log.error("failed to write to '%s'" % file_record.filename,
-                  exc_info=True)
-        return False
-    return True
-
-
-# TODO: write tests for this function
-def fetch_files(manifest_file, base_url, overwrite, filenames=[]):
-    # Lets load the manifest file
-    try:
-        manifest = open_manifest(manifest_file)
-    except InvalidManifest:
-        log.error("failed to load manifest file at '%s'" % manifest_file)
-        return False
-    # We want to track files that fail to be fetched as well as
-    # files that are fetched
-    failed_files = []
-
-    # Lets go through the manifest and fetch the files that we want
-    fetched_files = []
-    for f in manifest.file_records:
-        if f.filename in filenames or len(filenames) == 0:
-            log.debug("fetching %s" % f.filename)
-            if fetch_file(base_url, f, overwrite):
-                fetched_files.append(f)
-            else:
-                failed_files.append(f.filename)
-        else:
-            log.debug("skipping %s" % f.filename)
-
-    # Even if we get the file, lets ensure that it matches what the
-    # manifest specified
-    for localfile in fetched_files:
-        if not localfile.validate():
-            log.error("'%s'" % localfile.describe())
-
-    # If we failed to fetch or validate a file, we need to fail
-    if len(failed_files) > 0:
-        log.error("The following files failed: '%s'" % "', ".join(failed_files))
-        return False
-    return True
-
-
-# TODO: write tests for this function
-def process_command(options, args):
-    """ I know how to take a list of program arguments and
-    start doing the right thing with them"""
-    cmd = args[0]
-    cmd_args = args[1:]
-    log.debug("processing '%s' command with args '%s'" % (cmd, '", "'.join(cmd_args)))
-    log.debug("using options: %s" % options)
-    if cmd == 'list':
-        return list_manifest(options['manifest'])
-    if cmd == 'validate':
-        return validate_manifest(options['manifest'])
-    elif cmd == 'add':
-        return add_files(options['manifest'], options['algorithm'], cmd_args)
-    elif cmd == 'fetch':
-        if not options.has_key('base_url') or options.get('base_url') is None:
-            log.critical('fetch command requires url option')
-            return False
-        return fetch_files(options['manifest'], options['base_url'], options['overwrite'], cmd_args)
-    else:
-        log.critical('command "%s" is not implemented' % cmd)
-        return False
-
-# fetching api:
-#   http://hostname/algorithm/hash
-#   example: http://people.mozilla.org/sha1/1234567890abcedf
-# This will make it possible to have the server allow clients to
-# use different algorithms than what was uploaded to the server
-
-# TODO: Implement the following features:
-#   -optimization: do small files first, justification is that they are faster
-#    and cause a faster failure if they are invalid
-#   -store permissions
-#   -local renames i.e. call the file one thing on the server and
-#    something different locally
-#   -deal with the cases:
-#     -local data matches file requested with different filename
-#     -two different files with same name, different hash
-#   -?only ever locally to digest as filename, symlink to real name
-#   -?maybe deal with files as a dir of the filename with all files in that dir as the versions of that file
-#      - e.g. ./python-2.6.7.dmg/0123456789abcdef and ./python-2.6.7.dmg/abcdef0123456789
-
-def main():
-    # Set up logging, for now just to the console
-    ch = logging.StreamHandler()
-    cf = logging.Formatter("%(levelname)s - %(message)s")
-    ch.setFormatter(cf)
-
-    # Set up option parsing
-    parser = optparse.OptionParser()
-    # I wish there was a way to say "only allow args to be
-    # sequential and at the end of the argv.
-    # OH! i could step through sys.argv and check for things starting without -/-- before things starting with them
-    parser.add_option('-q', '--quiet', default=False,
-            dest='quiet', action='store_true')
-    parser.add_option('-v', '--verbose', default=False,
-            dest='verbose', action='store_true')
-    parser.add_option('-m', '--manifest', default='manifest.tt',
-            dest='manifest', action='store',
-            help='specify the manifest file to be operated on')
-    parser.add_option('-d', '--algorithm', default='sha512',
-            dest='algorithm', action='store',
-            help='openssl hashing algorithm to use')
-    parser.add_option('-o', '--overwrite', default=False,
-            dest='overwrite', action='store_true',
-            help='if fetching, remote copy will overwrite a local copy that is different. ')
-    parser.add_option('--url', dest='base_url', action='store',
-            help='base url for fetching files')
-    parser.add_option('--ignore-config-files', action='store_true', default=False,
-                     dest='ignore_cfg_files')
-    (options_obj, args) = parser.parse_args()
-    # Dictionaries are easier to work with
-    options = vars(options_obj)
-
-
-    # Use some of the option parser to figure out application
-    # log level
-    if options.get('verbose'):
-        ch.setLevel(logging.DEBUG)
-    elif options.get('quiet'):
-        ch.setLevel(logging.ERROR)
-    else:
-        ch.setLevel(logging.INFO)
-    log.addHandler(ch)
-
-    cfg_file = ConfigParser.SafeConfigParser()
-    if not options.get("ignore_cfg_files"):
-        read_files = cfg_file.read(['/etc/tooltool', os.path.expanduser('~/.tooltool'),
-                   os.path.join(os.getcwd(), '.tooltool')])
-        log.debug("read in the config files '%s'" % '", '.join(read_files))
-    else:
-        log.debug("skipping config files")
-
-    for option in ('base_url', 'algorithm'):
-        if not options.get(option):
-            try:
-                options[option] = cfg_file.get('general', option)
-                log.debug("read '%s' as '%s' from cfg_file" % (option, options[option]))
-            except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
-                log.debug("%s in config file" % e, exc_info=True)
-
-    if not options.has_key('manifest'):
-        parser.error("no manifest file specified")
-
-    if len(args) < 1:
-        parser.error('You must specify a command')
-    exit(0 if process_command(options, args) else 1)
-
-if __name__ == "__main__":
-    main()
-else:
-    log.addHandler(logging.NullHandler())
-    #log.addHandler(logging.StreamHandler())
new file mode 100644
--- /dev/null
+++ b/config/check_macroassembler_style.py
@@ -0,0 +1,264 @@
+# vim: set ts=8 sts=4 et sw=4 tw=99:
+# 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/.
+
+#----------------------------------------------------------------------------
+# This script checks that SpiderMonkey MacroAssembler methods are properly
+# annotated.
+#
+# The MacroAssembler has one interface for all platforms, but it might have one
+# definition per platform. The code of the MacroAssembler use a macro to
+# annotate the method declarations, in order to delete the function if it is not
+# present on the current platform, and also to locate the files in which the
+# methods are defined.
+#
+# This script scans the MacroAssembler.h header, for method declarations.
+# It also scans MacroAssembler-/arch/.cpp, MacroAssembler-/arch/-inl.h, and
+# MacroAssembler-inl.h for method definitions. The result of both scans are
+# uniformized, and compared, to determine if the MacroAssembler.h header as
+# proper methods annotations.
+#----------------------------------------------------------------------------
+
+from __future__ import print_function
+
+import difflib
+import os
+import re
+import subprocess
+import sys
+from check_utils import get_all_toplevel_filenames
+
+architecture_independent = set([ 'generic' ])
+all_architecture_names = set([ 'x86', 'x64', 'arm', 'arm64', 'mips' ])
+all_shared_architecture_names = set([ 'x86_shared', 'arm', 'arm64', 'mips' ])
+
+def get_normalized_signatures(signature, fileAnnot = None):
+    # Remove semicolon.
+    signature = signature.replace(';', ' ')
+    # Normalize spaces.
+    signature = re.sub(r'\s+', ' ', signature).strip()
+    # Remove argument names.
+    signature = re.sub(r'(?P<type>(?:[(]|,\s)[\w\s:*&]+)(?P<name>\s\w+)(?=[,)])', '\g<type>', signature)
+    # Remove class name
+    signature = signature.replace('MacroAssembler::', '')
+
+    # Extract list of architectures
+    archs = ['generic']
+    if fileAnnot:
+        archs = [fileAnnot['arch']]
+
+    if 'DEFINED_ON(' in signature:
+        archs = re.sub(r'.*DEFINED_ON\((?P<archs>[^()]*)\).*', '\g<archs>', signature).split(',')
+        archs = [a.strip() for a in archs]
+        signature = re.sub(r'\s+DEFINED_ON\([^()]*\)', '', signature)
+
+    elif 'PER_ARCH' in signature:
+        archs = all_architecture_names
+        signature = re.sub(r'\s+PER_ARCH', '', signature)
+
+    elif 'PER_SHARED_ARCH' in signature:
+        archs = all_shared_architecture_names
+        signature = re.sub(r'\s+PER_SHARED_ARCH', '', signature)
+
+    else:
+        # No signature annotation, the list of architectures remains unchanged.
+        pass
+
+    # Extract inline annotation
+    inline = False
+    if fileAnnot:
+        inline = fileAnnot['inline']
+
+    if 'inline ' in signature:
+        signature = re.sub(r'inline\s+', '', signature)
+        inline = True
+
+    return [
+        { 'arch': a, 'sig': 'inline ' + signature }
+        for a in archs
+    ]
+
+file_suffixes = set([
+    a.replace('_', '-') for a in
+    all_architecture_names.union(all_shared_architecture_names)
+])
+def get_file_annotation(filename):
+    origFilename = filename
+    filename = filename.split('/')[-1]
+
+    inline = False
+    if filename.endswith('.cpp'):
+        filename = filename[:-len('.cpp')]
+    elif filename.endswith('-inl.h'):
+        inline = True
+        filename = filename[:-len('-inl.h')]
+    else:
+        raise Exception('unknown file name', origFilename)
+
+    arch = 'generic'
+    for suffix in file_suffixes:
+        if filename == 'MacroAssembler-' + suffix:
+            arch = suffix
+            break
+
+    return {
+        'inline': inline,
+        'arch': arch.replace('-', '_')
+    }
+
+def get_macroassembler_definitions(filename):
+    try:
+        fileAnnot = get_file_annotation(filename)
+    except:
+        return []
+
+    style_section = False
+    code_section = False
+    lines = ''
+    signatures = []
+    with open(os.path.join('../..', filename)) as f:
+        for line in f:
+            if '//{{{ check_macroassembler_style' in line:
+                style_section = True
+            elif '//}}} check_macroassembler_style' in line:
+                style_section = False
+            if not style_section:
+                continue
+
+            line = re.sub(r'//.*', '', line)
+            if line.startswith('{'):
+                if 'MacroAssembler::' in lines:
+                    signatures.extend(get_normalized_signatures(lines, fileAnnot))
+                code_section = True
+                continue
+            if line.startswith('}'):
+                code_section = False
+                lines = ''
+                continue
+            if code_section:
+                continue
+
+            if len(line.strip()) == 0:
+                lines = ''
+                continue
+            lines = lines + line
+            # Continue until we have a complete declaration
+            if '{' not in lines:
+                continue
+            # Skip variable declarations
+            if ')' not in lines:
+                lines = ''
+                continue
+
+    return signatures
+
+def get_macroassembler_declaration(filename):
+    style_section = False
+    lines = ''
+    signatures = []
+    with open(os.path.join('../..', filename)) as f:
+        for line in f:
+            if '//{{{ check_macroassembler_style' in line:
+                style_section = True
+            elif '//}}} check_macroassembler_style' in line:
+                style_section = False
+            if not style_section:
+                continue
+
+            line = re.sub(r'//.*', '', line)
+            if len(line.strip()) == 0:
+                lines = ''
+                continue
+            lines = lines + line
+            # Continue until we have a complete declaration
+            if ';' not in lines:
+                continue
+            # Skip variable declarations
+            if ')' not in lines:
+                lines = ''
+                continue
+
+            signatures.extend(get_normalized_signatures(lines))
+            lines = ''
+
+    return signatures
+
+def append_signatures(d, sigs):
+    for s in sigs:
+        if s['sig'] not in d:
+            d[s['sig']] = []
+        d[s['sig']].append(s['arch']);
+    return d
+
+def generate_file_content(signatures):
+    output = []
+    for s in sorted(signatures.keys()):
+        archs = set(signatures[s])
+        if len(archs.symmetric_difference(architecture_independent)) == 0:
+            output.append(s + ';\n')
+            if s.startswith('inline'):
+                output.append('    is defined in MacroAssembler-inl.h\n')
+            else:
+                output.append('    is defined in MacroAssembler.cpp\n')
+        else:
+            if len(archs.symmetric_difference(all_architecture_names)) == 0:
+                output.append(s + ' PER_ARCH;\n')
+            elif len(archs.symmetric_difference(all_shared_architecture_names)) == 0:
+                output.append(s + ' PER_SHARED_ARCH;\n')
+            else:
+                output.append(s + ' DEFINED_ON(' + ', '.join(archs) + ');\n')
+            for a in archs:
+                a = a.replace('_', '-')
+                masm = '%s/MacroAssembler-%s' % (a, a)
+                if s.startswith('inline'):
+                    output.append('    is defined in %s-inl.h\n' % masm)
+                else:
+                    output.append('    is defined in %s.cpp\n' % masm)
+    return output
+
+def check_style():
+    # We read from the header file the signature of each function.
+    decls = dict()      # type: dict(signature => ['x86', 'x64'])
+
+    # We infer from each file the signature of each MacroAssembler function.
+    defs = dict()       # type: dict(signature => ['x86', 'x64'])
+
+    # Select the appropriate files.
+    for filename in get_all_toplevel_filenames():
+        if not filename.startswith('js/src/jit/'):
+            continue
+        if 'MacroAssembler' not in filename:
+            continue
+
+        if filename.endswith('MacroAssembler.h'):
+            decls = append_signatures(decls, get_macroassembler_declaration(filename))
+        else:
+            defs = append_signatures(defs, get_macroassembler_definitions(filename))
+
+    # Compare declarations and definitions output.
+    difflines = difflib.unified_diff(generate_file_content(decls),
+                                     generate_file_content(defs),
+                                     fromfile='check_macroassembler_style.py declared syntax',
+                                     tofile='check_macroassembler_style.py found definitions')
+    ok = True
+    for diffline in difflines:
+        ok = False
+        print(diffline, end='')
+
+    return ok
+
+
+def main():
+    ok = check_style()
+
+    if ok:
+        print('TEST-PASS | check_macroassembler_style.py | ok')
+    else:
+        print('TEST-UNEXPECTED-FAIL | check_macroassembler_style.py | actual output does not match expected output;  diff is above')
+
+    sys.exit(0 if ok else 1)
+
+
+if __name__ == '__main__':
+    main()
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -38,16 +38,17 @@
 from __future__ import print_function
 
 import difflib
 import os
 import re
 import subprocess
 import sys
 import traceback
+from check_utils import get_all_toplevel_filenames
 
 # We don't bother checking files in these directories, because they're (a) auxiliary or (b)
 # imported code that doesn't follow our coding style.
 ignored_js_src_dirs = [
    'js/src/config/',            # auxiliary stuff
    'js/src/ctypes/libffi/',     # imported code
    'js/src/devtools/',          # auxiliary stuff
    'js/src/editline/',          # imported code
@@ -212,47 +213,33 @@ class FileKind(object):
             return FileKind.TBL
 
         if filename.endswith('.msg'):
             return FileKind.MSG
 
         error(filename, None, 'unknown file kind')
 
 
-def get_all_filenames():
-    '''Get a list of all the files in the (Mercurial or Git) repository.'''
-    cmds = [['hg', 'manifest', '-q'], ['git', 'ls-files', '--full-name', '../..']]
-    for cmd in cmds:
-        try:
-            all_filenames = subprocess.check_output(cmd, universal_newlines=True,
-                                                    stderr=subprocess.PIPE).split('\n')
-            return all_filenames
-        except:
-            continue
-    else:
-        raise Exception('failed to run any of the repo manifest commands', cmds)
-
-
 def check_style():
     # We deal with two kinds of name.
     # - A "filename" is a full path to a file from the repository root.
     # - An "inclname" is how a file is referred to in a #include statement.
     #
     # Examples (filename -> inclname)
     # - "mfbt/Attributes.h"     -> "mozilla/Attributes.h"
     # - "mfbt/decimal/Decimal.h -> "mozilla/Decimal.h"
     # - "js/public/Vector.h"    -> "js/Vector.h"
     # - "js/src/vm/String.h"    -> "vm/String.h"
 
     mfbt_inclnames = set()      # type: set(inclname)
     mozalloc_inclnames = set()  # type: set(inclname)
     js_names = dict()           # type: dict(filename, inclname)
 
     # Select the appropriate files.
-    for filename in get_all_filenames():
+    for filename in get_all_toplevel_filenames():
         if filename.startswith('mfbt/') and filename.endswith('.h'):
             inclname = 'mozilla/' + filename.split('/')[-1]
             mfbt_inclnames.add(inclname)
 
         if filename.startswith('memory/mozalloc/') and filename.endswith('.h'):
             inclname = 'mozilla/' + filename.split('/')[-1]
             mozalloc_inclnames.add(inclname)
 
new file mode 100644
--- /dev/null
+++ b/config/check_utils.py
@@ -0,0 +1,30 @@
+# vim: set ts=8 sts=4 et sw=4 tw=99:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import subprocess
+
+def get_all_toplevel_filenames():
+    '''Get a list of all the files in the (Mercurial or Git) repository.'''
+    try:
+        cmd = ['hg', 'manifest', '-q']
+        all_filenames = subprocess.check_output(cmd, universal_newlines=True,
+                                                stderr=subprocess.PIPE).split('\n')
+        return all_filenames
+    except:
+        pass
+
+    try:
+        # Get the relative path to the top-level directory.
+        cmd = ['git', 'rev-parse', '--show-cdup']
+        top_level = subprocess.check_output(cmd, universal_newlines=True,
+                                                stderr=subprocess.PIPE).split('\n')[0]
+        cmd = ['git', 'ls-files', '--full-name', top_level]
+        all_filenames = subprocess.check_output(cmd, universal_newlines=True,
+                                                stderr=subprocess.PIPE).split('\n')
+        return all_filenames
+    except:
+        pass
+
+    raise Exception('failed to run any of the repo manifest commands', cmds)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2435,16 +2435,28 @@ nsDOMWindowUtils::GetIsTestControllingRe
   nsPresContext* pc = GetPresContext();
   *aResult =
     pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::GetAsyncPanZoomEnabled(bool *aResult)
+{
+  nsIWidget* widget = GetWidget();
+  if (widget) {
+    *aResult = widget->AsyncPanZoomEnabled();
+  } else {
+    *aResult = gfxPlatform::AsyncPanZoomEnabled();
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
                                        int32_t aX, int32_t aY)
 {
   nsCOMPtr<Element> element = do_QueryInterface(aNode);
   if (!element) {
     return NS_ERROR_INVALID_ARG;
   }
   FrameMetrics::ViewID viewId;
--- a/dom/cache/Context.cpp
+++ b/dom/cache/Context.cpp
@@ -781,29 +781,31 @@ Context::ThreadsafeHandle::ContextDestro
   mWeakRef = nullptr;
 }
 
 // static
 already_AddRefed<Context>
 Context::Create(Manager* aManager, nsIThread* aTarget,
                 Action* aInitAction, Context* aOldContext)
 {
-  nsRefPtr<Context> context = new Context(aManager, aTarget);
-  context->Init(aInitAction, aOldContext);
+  nsRefPtr<Context> context = new Context(aManager, aTarget, aInitAction);
+  context->Init(aOldContext);
   return context.forget();
 }
 
-Context::Context(Manager* aManager, nsIThread* aTarget)
+Context::Context(Manager* aManager, nsIThread* aTarget, Action* aInitAction)
   : mManager(aManager)
   , mTarget(aTarget)
   , mData(new Data(aTarget))
   , mState(STATE_CONTEXT_PREINIT)
   , mOrphanedData(false)
+  , mInitAction(aInitAction)
 {
   MOZ_ASSERT(mManager);
+  MOZ_ASSERT(mTarget);
 }
 
 void
 Context::Dispatch(Action* aAction)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
   MOZ_ASSERT(aAction);
 
@@ -821,20 +823,21 @@ Context::Dispatch(Action* aAction)
   DispatchAction(aAction);
 }
 
 void
 Context::CancelAll()
 {
   NS_ASSERT_OWNINGTHREAD(Context);
 
-  // In PREINIT state we have not dispatch the init runnable yet.  Just
+  // In PREINIT state we have not dispatch the init action yet.  Just
   // forget it.
   if (mState == STATE_CONTEXT_PREINIT) {
-    mInitRunnable = nullptr;
+    MOZ_ASSERT(!mInitRunnable);
+    mInitAction = nullptr;
 
   // In INIT state we have dispatched the runnable, but not received the
   // async completion yet.  Cancel the runnable, but don't forget about it
   // until we get OnQuotaInit() callback.
   } else if (mState == STATE_CONTEXT_INIT) {
     mInitRunnable->Cancel();
   }
 
@@ -913,24 +916,19 @@ Context::~Context()
   }
 
   if (mNextContext) {
     mNextContext->Start();
   }
 }
 
 void
-Context::Init(Action* aInitAction, Context* aOldContext)
+Context::Init(Context* aOldContext)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
-  MOZ_ASSERT(!mInitRunnable);
-
-  // Do this here to avoid doing an AddRef() in the constructor
-  mInitRunnable = new QuotaInitRunnable(this, mManager, mData, mTarget,
-                                        aInitAction);
 
   if (aOldContext) {
     aOldContext->SetNextContext(this);
     return;
   }
 
   Start();
 }
@@ -939,20 +937,27 @@ void
 Context::Start()
 {
   NS_ASSERT_OWNINGTHREAD(Context);
 
   // Previous context closing delayed our start, but then we were canceled.
   // In this case, just do nothing here.
   if (mState == STATE_CONTEXT_CANCELED) {
     MOZ_ASSERT(!mInitRunnable);
+    MOZ_ASSERT(!mInitAction);
     return;
   }
 
   MOZ_ASSERT(mState == STATE_CONTEXT_PREINIT);
+  MOZ_ASSERT(!mInitRunnable);
+
+  mInitRunnable = new QuotaInitRunnable(this, mManager, mData, mTarget,
+                                        mInitAction);
+  mInitAction = nullptr;
+
   mState = STATE_CONTEXT_INIT;
 
   nsresult rv = mInitRunnable->Dispatch();
   if (NS_FAILED(rv)) {
     // Shutdown must be delayed until all Contexts are destroyed.  Shutdown
     // must also prevent any new Contexts from being constructed.  Crash
     // for this invariant violation.
     MOZ_CRASH("Failed to dispatch QuotaInitRunnable.");
--- a/dom/cache/Context.h
+++ b/dom/cache/Context.h
@@ -179,19 +179,19 @@ private:
   };
 
   struct PendingAction
   {
     nsCOMPtr<nsIEventTarget> mTarget;
     nsRefPtr<Action> mAction;
   };
 
-  Context(Manager* aManager, nsIThread* aTarget);
+  Context(Manager* aManager, nsIThread* aTarget, Action* aInitAction);
   ~Context();
-  void Init(Action* aInitAction, Context* aOldContext);
+  void Init(Context* aOldContext);
   void Start();
   void DispatchAction(Action* aAction, bool aDoomData = false);
   void OnQuotaInit(nsresult aRv, const QuotaInfo& aQuotaInfo,
                    nsMainThreadPtrHandle<DirectoryLock>& aDirectoryLock);
 
   already_AddRefed<ThreadsafeHandle>
   CreateThreadsafeHandle();
 
@@ -203,16 +203,17 @@ private:
 
   nsRefPtr<Manager> mManager;
   nsCOMPtr<nsIThread> mTarget;
   nsRefPtr<Data> mData;
   State mState;
   bool mOrphanedData;
   QuotaInfo mQuotaInfo;
   nsRefPtr<QuotaInitRunnable> mInitRunnable;
+  nsRefPtr<Action> mInitAction;
   nsTArray<PendingAction> mPendingActions;
 
   // Weak refs since activites must remove themselves from this list before
   // being destroyed by calling RemoveActivity().
   typedef nsTObserverArray<Activity*> ActivityList;
   ActivityList mActivityList;
 
   // The ThreadsafeHandle may have a strong ref back to us.  This creates
--- a/dom/events/test/test_bug967796.html
+++ b/dom/events/test/test_bug967796.html
@@ -148,16 +148,24 @@ function runTests() {
   expectedRelatedEnter = outside;
   expectedRelatedLeave = iframe;
   synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
                     iframe.contentWindow);
   synthesizePointer(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "pointermove"},
                     iframe.contentWindow);
   is(pointerentercount, 11, "Unexpected pointerenter event count!");
 
+  Array.from(document.querySelectorAll('*'))
+    .concat([iframe.contentDocument.body.firstChild, iframe.contentDocument.body.lastChild])
+    .forEach((elt) => {
+      elt.onpointerenter = null;
+      elt.onpointerleave = null;
+      elt.onpointerenter = null;
+      elt.onpointerleave = null;
+    });
   SpecialPowers.clearUserPref("dom.w3c_pointer_events.enabled");      // Disable Pointer Events
 
   SimpleTest.finish();
 }
 
 function penter(evt) {
   ++pointerentercount;
   evt.stopPropagation();
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -44,17 +44,17 @@ interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsITranslationNodeList;
 interface nsIJSRAIIHelper;
 interface nsIContentPermissionRequest;
 interface nsIObserver;
 
-[scriptable, uuid(bbcb87fb-ce2e-4e05-906b-9258687664e2)]
+[scriptable, uuid(7a37e173-ea6e-495e-8702-013f8063352a)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -1426,16 +1426,23 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Reports whether the current state is test-controlled refreshes
    * (see advanceTimeAndRefresh and restoreNormalRefresh above).
    */
   readonly attribute bool isTestControllingRefreshes;
 
   /**
+   * Reports whether APZ is enabled on the widget that this window is attached
+   * to. If there is no widget it will report the default platform value of
+   * whether or not APZ is enabled.
+   */
+  readonly attribute bool asyncPanZoomEnabled;
+
+  /**
    * Set async scroll offset on an element. The next composite will render
    * with that offset if async scrolling is enabled, and then the offset
    * will be removed. Only call this while test-controlled refreshes is enabled.
    */
   void setAsyncScrollOffset(in nsIDOMNode aNode, in int32_t aX, in int32_t aY);
 
   /**
    * Set async zoom value. aRootElement should be the document element of our
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2615,17 +2615,18 @@ ContentParent::RecvSetClipboard(const IP
         rv = dataWrapper->SetData(text);
         NS_ENSURE_SUCCESS(rv, true);
 
         rv = trans->SetTransferData(item.flavor().get(), dataWrapper,
                                     text.Length() * sizeof(char16_t));
 
         NS_ENSURE_SUCCESS(rv, true);
       } else if (item.data().type() == IPCDataTransferData::TnsCString) {
-        if (item.flavor().EqualsLiteral(kJPEGImageMime) ||
+        if (item.flavor().EqualsLiteral(kNativeImageMime) ||
+            item.flavor().EqualsLiteral(kJPEGImageMime) ||
             item.flavor().EqualsLiteral(kJPGImageMime) ||
             item.flavor().EqualsLiteral(kPNGImageMime) ||
             item.flavor().EqualsLiteral(kGIFImageMime)) {
           const IPCDataTransferImage& imageDetails = item.imageDetails();
           const gfxIntSize size(imageDetails.width(), imageDetails.height());
           if (!size.width || !size.height) {
             return true;
           }
--- a/dom/mobilemessage/MobileMessageManager.h
+++ b/dom/mobilemessage/MobileMessageManager.h
@@ -9,21 +9,21 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsIObserver.h"
 
 class nsISmsService;
 class nsIDOMMozSmsMessage;
 class nsIDOMMozMmsMessage;
-class Promise;
 
 namespace mozilla {
 namespace dom {
 
+class Promise;
 class DOMRequest;
 class DOMCursor;
 struct MmsParameters;
 struct MmsSendParameters;
 struct MobileMessageFilter;
 class OwningLongOrMozSmsMessageOrMozMmsMessage;
 struct SmsSendParameters;
 struct SmscAddress;
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/beacon/beacon-cors-redirect-handler.sjs
@@ -0,0 +1,52 @@
+/*
+ * TestSever customized specifically for the needs of:
+ * Bug 1111834 - sendBeacon() should not follow 30x redirect after preflight
+ *
+ * Here is a sequence of the test:
+ * [1] preflight channel (identified by the queryString 'beacon' and method 'OPTIONS')
+ * [2] actual channel (identified by the queryString 'beacon') which gets redirected
+ * [3] should never happen (the actual redirected request)
+ * [4] xhr request (identified by the queryString 'verifyRedirectDidNotSucceed')
+ *     which checks if the state was not changed from 'green' to 'red'. If the channel
+ *     woulnd't be blocked correctly the redirected channel would set the state to 'red'.
+ *
+ */
+
+function handleRequest(request, response)
+{
+  response.setHeader("Cache-Control", "no-cache, must-revalidate", false);
+
+  // [Sequence 4]
+  if (request.queryString === "verifyRedirectDidNotSucceed") {
+    var redirectState = getState("redirectState");
+    response.write(redirectState);
+    return;
+  }
+
+  var originHeader = request.getHeader("origin");
+  response.setHeader("Cache-Control", "no-cache, must-revalidate", false);
+  response.setHeader("Access-Control-Allow-Headers", "content-type", false);
+  response.setHeader("Access-Control-Allow-Methods", "POST, GET", false);
+  response.setHeader("Access-Control-Allow-Origin", originHeader, false);
+  response.setHeader("Access-Control-Allow-Credentials", "true", false);
+
+  // [Sequence 1,2]
+  if (request.queryString === "beacon") {
+    setState("redirectState", "green");
+    // [1]
+    if (request.method == "OPTIONS") {
+      response.setStatusLine(null, 200, "OK");
+      return;
+    }
+    // [Sequence 2]
+    var newLocation =
+      "http://mochi.test:8888/tests/dom/tests/mochitest/beacon/beacon-cors-redirect-handler.sjs?redirected";
+    response.setStatusLine("1.1", 302, "Found");
+    response.setHeader("Location", newLocation, false);
+    return;
+  }
+
+  // [Sequence 3]
+  setState("redirectState", "red");
+  response.setStatusLine(null, 200, "OK");
+}
--- a/dom/tests/mochitest/beacon/mochitest.ini
+++ b/dom/tests/mochitest/beacon/mochitest.ini
@@ -1,11 +1,13 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g'
 support-files = beacon-frame.html
                 beacon-handler.sjs
                 beacon-originheader-handler.sjs
+                beacon-cors-redirect-handler.sjs
 
 [test_beacon.html]
 [test_beaconFrame.html]
 [test_beaconPreflight.html]
 [test_beaconContentPolicy.html]
 [test_beaconOriginHeader.html]
+[test_beaconCORSRedirect.html]
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/beacon/test_beaconCORSRedirect.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 1111834 - sendBeacon() should not follow 30x redirect after preflight</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="visibility: hidden">
+    <iframe style="width:100%;" id="testframe"></iframe>
+  </div>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ *   We do perform a non simple sendBeacon request. After the preflight channel returns correctly
+ *   the actual channel is about to follow a 30x cross origin redirect, which is forbidden by the spec.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+const BEACON_URL = "http://example.com/tests/dom/tests/mochitest/beacon/beacon-cors-redirect-handler.sjs?beacon";
+
+SpecialPowers.pushPrefEnv({'set': [["beacon.enabled", true]]}, runTest);
+
+var intervalID = null;
+
+function queryIfRedirectSucceeded() {
+  clearInterval(intervalID);
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", "beacon-cors-redirect-handler.sjs?verifyRedirectDidNotSucceed", true);
+  xhr.onload = function() {
+    is(xhr.responseText, "green", "SendBeacon does not follow cross origin redirects after preflight!");
+    SimpleTest.finish();
+  };
+  xhr.onerror = function() {
+    ok(false, "xhr request returned error");
+    SimpleTest.finish();
+  };
+  xhr.send();
+}
+
+function runTest() {
+  var data = new Uint8Array([0,1,2,3]);
+  navigator.sendBeacon(BEACON_URL, data);
+
+  // we have to make sure the channel did not follow the redirect hence
+  // we have to wait for 2 seconds before we can query the result.
+  intervalID = setInterval(queryIfRedirectSucceeded, 2000);
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/gfx/layers/apz/test/test_layerization.html
+++ b/gfx/layers/apz/test/test_layerization.html
@@ -132,17 +132,17 @@ function driveTest() {
   var ret = gTestContinuation.next();
   if (ret.done) {
     SimpleTest.finish();
   }
 }
 
 function startTest() {
   // This test requires APZ - if it's not enabled, skip it.
-  var apzEnabled = SpecialPowers.getBoolPref("layers.async-pan-zoom.enabled");
+  var apzEnabled = SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled;
   if (!apzEnabled) {
     ok(true, "APZ not enabled, skipping test");
     SimpleTest.finish();
     return;
   }
 
   driveTest();
 }
--- a/image/MultipartImage.cpp
+++ b/image/MultipartImage.cpp
@@ -37,17 +37,22 @@ public:
 
   void BlockUntilDecodedAndFinishObserving()
   {
     // Use GetFrame() to block until our image finishes decoding.
     nsRefPtr<SourceSurface> surface =
       mImage->GetFrame(imgIContainer::FRAME_CURRENT,
                        imgIContainer::FLAG_SYNC_DECODE);
 
-    FinishObserving();
+    // GetFrame() should've sent synchronous notifications that would have
+    // caused us to call FinishObserving() (and null out mImage) already. If for
+    // some reason it didn't, we should do so here.
+    if (mImage) {
+      FinishObserving();
+    }
   }
 
   virtual void Notify(int32_t aType,
                       const nsIntRect* aRect = nullptr) override
   {
     if (!mImage) {
       // We've already finished observing the last image we were given.
       return;
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -935,30 +935,30 @@ PrepareForNewPart(nsIRequest* aRequest, 
 
   // Look at the first few bytes and see if we can tell what the data is from
   // that since servers tend to lie. :(
   uint32_t out;
   aInStr->ReadSegments(sniff_mimetype_callback, &closure, aCount, &out);
 
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
   if (result.mContentType.IsEmpty()) {
-    nsresult rv = NS_ERROR_FAILURE;
-    if (chan) {
-      rv = chan->GetContentType(result.mContentType);
-      chan->GetContentDispositionHeader(result.mContentDisposition);
-    }
-
+    nsresult rv = chan ? chan->GetContentType(result.mContentType)
+                       : NS_ERROR_FAILURE;
     if (NS_FAILED(rv)) {
       MOZ_LOG(GetImgLog(),
-             LogLevel::Error, ("imgRequest::PrepareForNewPart "
-                            "-- Content type unavailable from the channel\n"));
+              LogLevel::Error, ("imgRequest::PrepareForNewPart -- "
+                                "Content type unavailable from the channel\n"));
       return result;
     }
   }
 
+  if (chan) {
+    chan->GetContentDispositionHeader(result.mContentDisposition);
+  }
+
   MOZ_LOG(GetImgLog(), LogLevel::Debug,
          ("imgRequest::PrepareForNewPart -- Got content type %s\n",
           result.mContentType.get()));
 
   // XXX If server lied about mimetype and it's SVG, we may need to copy
   // the data and dispatch back to the main thread, AND tell the channel to
   // dispatch there in the future.
 
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -608,16 +608,19 @@ typedef void (*JSClassInternal)();
 
 struct JSClass {
     JS_CLASS_MEMBERS(JSFinalizeOp);
 
     void*               reserved[25];
 };
 
 #define JSCLASS_HAS_PRIVATE             (1<<0)  // objects have private slot
+#define JSCLASS_DELAY_METADATA_CALLBACK (1<<1)  // class's initialization code
+                                                // will call
+                                                // SetNewObjectMetadata itself
 #define JSCLASS_PRIVATE_IS_NSISUPPORTS  (1<<3)  // private is (nsISupports*)
 #define JSCLASS_IS_DOMJSCLASS           (1<<4)  // objects are DOM
 #define JSCLASS_IMPLEMENTS_BARRIERS     (1<<5)  // Correctly implements GC read
                                                 // and write barriers
 #define JSCLASS_EMULATES_UNDEFINED      (1<<6)  // objects of this class act
                                                 // like the value undefined,
                                                 // in some contexts
 #define JSCLASS_USERBIT1                (1<<7)  // Reserved for embeddings.
@@ -733,16 +736,20 @@ struct Class
     bool isProxy() const {
         return flags & JSCLASS_IS_PROXY;
     }
 
     bool isDOMClass() const {
         return flags & JSCLASS_IS_DOMJSCLASS;
     }
 
+    bool shouldDelayMetadataCallback() const {
+        return flags & JSCLASS_DELAY_METADATA_CALLBACK;
+    }
+
     static size_t offsetOfFlags() { return offsetof(Class, flags); }
 };
 
 static_assert(offsetof(JSClass, name) == offsetof(Class, name),
               "Class and JSClass must be consistent");
 static_assert(offsetof(JSClass, flags) == offsetof(Class, flags),
               "Class and JSClass must be consistent");
 static_assert(offsetof(JSClass, addProperty) == offsetof(Class, addProperty),
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -122,24 +122,27 @@ ifneq ($(LLVM_SYMBOLIZER),)
 # Use the LLVM symbolizer when running jit-tests under ASan, if available
 JITTEST_ASAN_ENV=ASAN_SYMBOLIZER_PATH='$(LLVM_SYMBOLIZER)'
 endif
 endif
 
 check-style::
 	(cd $(srcdir) && $(PYTHON) $(topsrcdir)/config/check_spidermonkey_style.py);
 
+check-masm::
+	(cd $(srcdir) && $(PYTHON) $(topsrcdir)/config/check_macroassembler_style.py);
+
 check-jit-test::
 	$(JITTEST_ASAN_ENV) $(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \
 	        --no-slow --no-progress --format=automation --jitflags=all \
 			$(JITTEST_VALGRIND_FLAG) \
 			$(JITTEST_EXTRA_ARGS) \
 	        $(DIST)/bin/$(JS_SHELL_NAME)$(BIN_SUFFIX)
 
-check:: check-style
+check:: check-style check-masm
 
 check-jstests:
 	$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/tests/jstests.py \
 		--no-progress --format=automation --timeout 300 \
 		$(JSTESTS_EXTRA_ARGS) \
 		$(DIST)/bin/$(JS_SHELL_NAME)$(BIN_SUFFIX)
 
 # FIXME:
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -1010,17 +1010,17 @@ AsmJSModuleObject_finalize(FreeOp* fop, 
 static void
 AsmJSModuleObject_trace(JSTracer* trc, JSObject* obj)
 {
     obj->as<AsmJSModuleObject>().module().trace(trc);
 }
 
 const Class AsmJSModuleObject::class_ = {
     "AsmJSModuleObject",
-    JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
+    JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_DELAY_METADATA_CALLBACK |
     JSCLASS_HAS_RESERVED_SLOTS(AsmJSModuleObject::RESERVED_SLOTS),
     nullptr, /* addProperty */
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
     nullptr, /* enumerate */
     nullptr, /* resolve */
     nullptr, /* mayResolve */
@@ -1030,22 +1030,24 @@ const Class AsmJSModuleObject::class_ = 
     nullptr, /* hasInstance */
     nullptr, /* construct */
     AsmJSModuleObject_trace
 };
 
 AsmJSModuleObject*
 AsmJSModuleObject::create(ExclusiveContext* cx, ScopedJSDeletePtr<AsmJSModule>* module)
 {
+    AutoSetNewObjectMetadata metadata(cx);
     JSObject* obj = NewObjectWithGivenProto(cx, &AsmJSModuleObject::class_, nullptr);
     if (!obj)
         return nullptr;
     AsmJSModuleObject* nobj = &obj->as<AsmJSModuleObject>();
 
     nobj->setReservedSlot(MODULE_SLOT, PrivateValue(module->forget()));
+
     return nobj;
 }
 
 AsmJSModule&
 AsmJSModuleObject::module() const
 {
     MOZ_ASSERT(is<AsmJSModuleObject>());
     return *(AsmJSModule*)getReservedSlot(MODULE_SLOT).toPrivate();
--- a/js/src/doc/Debugger/Debugger.Memory.md
+++ b/js/src/doc/Debugger/Debugger.Memory.md
@@ -219,17 +219,18 @@ Function Properties of the `Debugger.Mem
 
     Objects in the array are of the form:
 
     <pre class='language-js'><code>
     {
       "timestamp": <i>timestamp</i>,
       "frame": <i>allocationSite</i>,
       "class": <i>className</i>,
-      "constructor": <i>constructorName</i>
+      "constructor": <i>constructorName</i>,
+      "size": <i>byteSize</i>,
     }
     </code></pre>
 
     Where
 
     * *timestamp* is the [timestamp][timestamps] of the allocation event.
 
     * *allocationSite* is an allocation site (as a
@@ -239,16 +240,18 @@ Function Properties of the `Debugger.Mem
     * *className* is the string name of the allocated object's internal
     `[[Class]]` property, for example "Array", "Date", "RegExp", or (most
     commonly) "Object".
 
     * *constructorName* is the constructor function's display name for objects
       created by `new Ctor`. If that data is not available, or the object was
       not created with a `new` expression, this property is `null`.
 
+    * *byteSize* is the size of the object in bytes.
+
     When `trackingAllocationSites` is `false`, `drainAllocationsLog()` throws an
     `Error`.
 
 <code id='take-census'>takeCensus(<i>options</i>)</code>
 :   Carry out a census of the debuggee compartments' contents. A *census* is a
     complete traversal of the graph of all reachable memory items belonging to a
     particular `Debugger`'s debuggees. The census produces a count of those
     items, broken down by various criteria.
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -458,16 +458,18 @@ js::gc::GCRuntime::markRuntime(JSTracer*
                     MOZ_ASSERT(script == i.get<JSScript>());
                 }
             }
         }
     }
 
     /* We can't use GCCompartmentsIter if we're called from TraceRuntime. */
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
+        c->markRoots(trc);
+
         if (rt->isHeapMinorCollecting())
             c->globalWriteBarriered = false;
 
         if (traceOrMark == MarkRuntime && !c->zone()->isCollecting())
             continue;
 
         /* During a GC, these are treated as weak pointers. */
         if (traceOrMark == TraceRuntime) {
@@ -489,24 +491,16 @@ js::gc::GCRuntime::markRuntime(JSTracer*
     MarkInterpreterActivations(rt, trc);
 
     jit::MarkJitActivations(rt, trc);
 
     if (!rt->isHeapMinorCollecting()) {
         gcstats::AutoPhase ap(stats, gcstats::PHASE_MARK_EMBEDDING);
 
         /*
-         * All JSCompartment::markRoots() does is mark the globals for
-         * compartments which have been entered. Globals aren't nursery
-         * allocated so there's no need to do this for minor GCs.
-         */
-        for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next())
-            c->markRoots(trc);
-
-        /*
          * The embedding can register additional roots here.
          *
          * We don't need to trace these in a minor GC because all pointers into
          * the nursery should be in the store buffer, and we want to avoid the
          * time taken to trace all these roots.
          */
         for (size_t i = 0; i < blackRootTracers.length(); i++) {
             const Callback<JSTraceDataOp>& e = blackRootTracers[i];
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Memory-drainAllocationsLog-17.js
@@ -0,0 +1,55 @@
+// Test drainAllocationsLog() and byte sizes.
+
+const root = newGlobal();
+const dbg = new Debugger();
+const wrappedRoot = dbg.addDebuggee(root);
+
+root.eval(
+  `
+  function AsmModule(stdlib, foreign, heap) {
+    "use asm";
+
+    function test() {
+      return 5|0;
+    }
+
+    return { test: test };
+  }
+  const buf = new ArrayBuffer(1024*8);
+
+  function Ctor() {}
+  this.tests = [
+    { name: "new UInt8Array(256)", fn: () => new Uint8Array(256)         },
+    { name: "arguments",           fn: function () { return arguments; } },
+    { name: "asm.js module",       fn: () => AsmModule(this, {}, buf)    },
+    { name: "/2manyproblemz/g",    fn: () => /2manyproblemz/g            },
+    { name: "iterator",            fn: () => [1,2,3][Symbol.iterator]()  },
+    { name: "Error()",             fn: () => Error()                     },
+    { name: "new Ctor",            fn: () => new Ctor                    },
+    { name: "{}",                  fn: () => ({})                        },
+    { name: "new Date",            fn: () => new Date                    },
+    { name: "[1,2,3]",             fn: () => [1,2,3]                     },
+  ];
+  `
+);
+
+for (let { name, fn } of root.tests) {
+  print("Test: " + name);
+
+  dbg.memory.trackingAllocationSites = true;
+
+  fn();
+
+  let entries = dbg.memory.drainAllocationsLog();
+
+  for (let {size} of entries) {
+    print("  " + size + " bytes");
+    // We should get some kind of byte size. We aren't testing that in depth
+    // here, it is tested pretty thoroughly in
+    // js/src/jit-test/tests/heap-analysis/byteSize-of-object.js.
+    assertEq(typeof size, "number");
+    assertEq(size > 0, true);
+  }
+
+  dbg.memory.trackingAllocationSites = false;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1181354.js
@@ -0,0 +1,9 @@
+for (a of []) {}
+var log = "";
+(function() {
+  for (a of [,0]) {}
+  const y = "FOO";
+  log += y;
+  function inner() { log += y; }
+})()
+assertEq(log, "FOO");
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -7,16 +7,17 @@
 #ifndef jit_MacroAssembler_inl_h
 #define jit_MacroAssembler_inl_h
 
 #include "jit/MacroAssembler.h"
 
 namespace js {
 namespace jit {
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Frame manipulation functions.
 
 uint32_t
 MacroAssembler::framePushed() const
 {
     return framePushed_;
 }
@@ -70,16 +71,17 @@ MacroAssembler::call(const CallSiteDesc&
 
 void
 MacroAssembler::call(const CallSiteDesc& desc, Label* label)
 {
     call(label);
     append(desc, currentOffset(), framePushed());
 }
 
+//}}} check_macroassembler_style
 // ===============================================================
 
 void
 MacroAssembler::PushStubCode()
 {
     exitCodePatch_ = PushWithPatch(ImmWord(-1));
 }
 
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -2549,16 +2549,17 @@ MacroAssembler::icBuildOOLFakeExitFrame(
 void
 MacroAssembler::icRestoreLive(LiveRegisterSet& liveRegs, AfterICSaveLive& aic)
 {
     restoreFrameAlignmentForICArguments(aic);
     MOZ_ASSERT(framePushed() == aic.initialStack);
     PopRegsInMask(liveRegs);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveGeneralRegisterSet set)
 {
     PushRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet()));
 }
@@ -2713,8 +2714,10 @@ MacroAssembler::freeStack(uint32_t amoun
     framePushed_ -= amount;
 }
 
 void
 MacroAssembler::freeStack(Register amount)
 {
     addToStackPtr(amount);
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_MacroAssembler_h
 #define jit_MacroAssembler_h
 
+#include "mozilla/MacroForEach.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "jscompartment.h"
 
 #if defined(JS_CODEGEN_X86)
 # include "jit/x86/MacroAssembler-x86.h"
 #elif defined(JS_CODEGEN_X64)
 # include "jit/x64/MacroAssembler-x64.h"
@@ -29,38 +30,144 @@
 #include "jit/AtomicOp.h"
 #include "jit/IonInstrumentation.h"
 #include "jit/JitCompartment.h"
 #include "jit/VMFunctions.h"
 #include "vm/ProxyObject.h"
 #include "vm/Shape.h"
 #include "vm/UnboxedObject.h"
 
-// This Macro is only a hint for code readers that the function is defined in a
-// specific macro assembler, and not in the generic macro assembler.  Thus, when
-// looking for the implementation one might find if the function is implemented
-// and where it is supposed to be implemented.
-# define PER_ARCH
+// * How to read/write MacroAssembler method declarations:
+//
+// The following macros are made to avoid #ifdef around each method declarations
+// of the Macro Assembler, and they are also used as an hint on the location of
+// the implementations of each method.  For example, the following declaration
+//
+//   void Pop(FloatRegister t) DEFINED_ON(x86_shared, arm);
+//
+// suggests the MacroAssembler::Pop(FloatRegister) method is implemented in
+// x86-shared/MacroAssembler-x86-shared.h, and also in arm/MacroAssembler-arm.h.
+//
+// - If there is no annotation, then there is only one generic definition in
+//   MacroAssembler.cpp.
+//
+// - If the declaration is "inline", then the method definition(s) would be in
+//   the "-inl.h" variant of the same file(s).
+//
+// The script check_macroassembler_style.py (check-masm target of the Makefile)
+// is used to verify that method definitions are matching the annotation added
+// to the method declarations.  If there is any difference, then you either
+// forgot to define the method in one of the macro assembler, or you forgot to
+// update the annotation of the macro assembler declaration.
+//
+// Some convenient short-cuts are used to avoid repeating the same list of
+// architectures on each method declaration, such as PER_ARCH and
+// PER_SHARED_ARCH.
+
+# define ALL_ARCH mips, arm, arm64, x86, x64
+# define ALL_SHARED_ARCH mips, arm, arm64, x86_shared
 
+// * How this macro works:
+//
+// DEFINED_ON is a macro which check if, for the current architecture, the
+// method is defined on the macro assembler or not.
+//
+// For each architecutre, we have a macro named DEFINED_ON_arch.  This macro is
+// empty if this is not the current architecture.  Otherwise it must be either
+// set to "define" or "crash" (only use for the none target so-far).
+//
+// The DEFINED_ON macro maps the list of architecture names given as argument to
+// a list of macro names.  For example,
+//
+//   DEFINED_ON(arm, x86_shared)
+//
+// is expanded to
+//
+//   DEFINED_ON_none DEFINED_ON_arm DEFINED_ON_x86_shared
+//
+// which are later expanded on ARM, x86, x64 by DEFINED_ON_EXPAND_ARCH_RESULTS
+// to
+//
+//   define
+//
+// or if the JIT is disabled or set to no architecture to
+//
+//   crash
+//
+// or to nothing, if the current architecture is not lsited in the list of
+// arguments of DEFINED_ON.  Note, only one of the DEFINED_ON_arch macro
+// contributes to the non-empty result, which is the macro of the current
+// architecture if it is listed in the arguments of DEFINED_ON.
+//
+// This result is appended to DEFINED_ON_RESULT_ before expanding the macro,
+// which result is either no annotation, a MOZ_CRASH(), or a "= delete"
+// annotation on the method declaration.
+
+# define DEFINED_ON_x86
+# define DEFINED_ON_x64
+# define DEFINED_ON_x86_shared
+# define DEFINED_ON_arm
+# define DEFINED_ON_arm64
+# define DEFINED_ON_mips
+# define DEFINED_ON_none
+
+// Specialize for each architecture.
 #if defined(JS_CODEGEN_X86)
-# define ONLY_X86_X64
+# undef DEFINED_ON_x86
+# define DEFINED_ON_x86 define
+# undef DEFINED_ON_x86_shared
+# define DEFINED_ON_x86_shared define
 #elif defined(JS_CODEGEN_X64)
-# define ONLY_X86_X64
+# undef DEFINED_ON_x64
+# define DEFINED_ON_x64 define
+# undef DEFINED_ON_x86_shared
+# define DEFINED_ON_x86_shared define
 #elif defined(JS_CODEGEN_ARM)
-# define ONLY_X86_X64 = delete
+# undef DEFINED_ON_arm
+# define DEFINED_ON_arm define
 #elif defined(JS_CODEGEN_ARM64)
-# define ONLY_X86_X64 = delete
+# undef DEFINED_ON_arm64
+# define DEFINED_ON_arm64 define
 #elif defined(JS_CODEGEN_MIPS)
-# define ONLY_X86_X64 = delete
+# undef DEFINED_ON_mips
+# define DEFINED_ON_mips define
 #elif defined(JS_CODEGEN_NONE)
-# define ONLY_X86_X64 = delete
+# undef DEFINED_ON_none
+# define DEFINED_ON_none crash
 #else
 # error "Unknown architecture!"
 #endif
 
+# define DEFINED_ON_RESULT_crash   { MOZ_CRASH(); }
+# define DEFINED_ON_RESULT_define
+# define DEFINED_ON_RESULT_        = delete
+
+# define DEFINED_ON_DISPATCH_RESULT(Result)     \
+    DEFINED_ON_RESULT_ ## Result
+
+// We need to let the evaluation of MOZ_FOR_EACH terminates.
+# define DEFINED_ON_EXPAND_ARCH_RESULTS_3(ParenResult)  \
+    DEFINED_ON_DISPATCH_RESULT ParenResult
+# define DEFINED_ON_EXPAND_ARCH_RESULTS_2(ParenResult)  \
+    DEFINED_ON_EXPAND_ARCH_RESULTS_3 (ParenResult)
+# define DEFINED_ON_EXPAND_ARCH_RESULTS(ParenResult)    \
+    DEFINED_ON_EXPAND_ARCH_RESULTS_2 (ParenResult)
+
+# define DEFINED_ON_FWDARCH(Arch) DEFINED_ON_ ## Arch
+# define DEFINED_ON_MAP_ON_ARCHS(ArchList)              \
+    DEFINED_ON_EXPAND_ARCH_RESULTS(                     \
+      (MOZ_FOR_EACH(DEFINED_ON_FWDARCH, (), ArchList)))
+
+# define DEFINED_ON(...)                                \
+    DEFINED_ON_MAP_ON_ARCHS((none, __VA_ARGS__))
+
+# define PER_ARCH DEFINED_ON(ALL_ARCH)
+# define PER_SHARED_ARCH DEFINED_ON(ALL_SHARED_ARCH)
+
+
 #ifdef IS_LITTLE_ENDIAN
 #define IMM32_16ADJ(X) X << 16
 #else
 #define IMM32_16ADJ(X) X
 #endif
 
 namespace js {
 namespace jit {
@@ -280,16 +387,17 @@ class MacroAssembler : public MacroAssem
     MoveResolver& moveResolver() {
         return moveResolver_;
     }
 
     size_t instructionsSize() const {
         return size();
     }
 
+    //{{{ check_macroassembler_style
   public:
     // ===============================================================
     // Frame manipulation functions.
 
     inline uint32_t framePushed() const;
     inline void setFramePushed(uint32_t framePushed);
     inline void adjustFrame(int32_t value);
 
@@ -304,72 +412,73 @@ class MacroAssembler : public MacroAssem
     //
     // It is maintained by all stack manipulation functions below.
     uint32_t framePushed_;
 
   public:
     // ===============================================================
     // Stack manipulation functions.
 
-    void PushRegsInMask(LiveRegisterSet set) PER_ARCH;
+    void PushRegsInMask(LiveRegisterSet set) PER_SHARED_ARCH;
     void PushRegsInMask(LiveGeneralRegisterSet set);
 
     void PopRegsInMask(LiveRegisterSet set);
     void PopRegsInMask(LiveGeneralRegisterSet set);
-    void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) PER_ARCH;
+    void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) PER_SHARED_ARCH;
 
-    void Push(const Operand op) PER_ARCH ONLY_X86_X64;
-    void Push(Register reg) PER_ARCH;
-    void Push(const Imm32 imm) PER_ARCH;
-    void Push(const ImmWord imm) PER_ARCH;
-    void Push(const ImmPtr imm) PER_ARCH;
-    void Push(const ImmGCPtr ptr) PER_ARCH;
-    void Push(FloatRegister reg) PER_ARCH;
+    void Push(const Operand op) DEFINED_ON(x86_shared);
+    void Push(Register reg) PER_SHARED_ARCH;
+    void Push(const Imm32 imm) PER_SHARED_ARCH;
+    void Push(const ImmWord imm) PER_SHARED_ARCH;
+    void Push(const ImmPtr imm) PER_SHARED_ARCH;
+    void Push(const ImmGCPtr ptr) PER_SHARED_ARCH;
+    void Push(FloatRegister reg) PER_SHARED_ARCH;
     void Push(jsid id, Register scratchReg);
     void Push(TypedOrValueRegister v);
     void Push(ConstantOrRegister v);
     void Push(const ValueOperand& val);
     void Push(const Value& val);
     void Push(JSValueType type, Register reg);
     void PushValue(const Address& addr);
     void PushEmptyRooted(VMFunction::RootType rootType);
     inline CodeOffsetLabel PushWithPatch(ImmWord word);
     inline CodeOffsetLabel PushWithPatch(ImmPtr imm);
 
-    void Pop(const Operand op) PER_ARCH ONLY_X86_X64;
-    void Pop(Register reg) PER_ARCH;
-    void Pop(FloatRegister t) PER_ARCH ONLY_X86_X64;
-    void Pop(const ValueOperand& val) PER_ARCH;
+    void Pop(const Operand op) DEFINED_ON(x86_shared);
+    void Pop(Register reg) PER_SHARED_ARCH;
+    void Pop(FloatRegister t) DEFINED_ON(x86_shared);
+    void Pop(const ValueOperand& val) PER_SHARED_ARCH;
     void popRooted(VMFunction::RootType rootType, Register cellReg, const ValueOperand& valueReg);
 
     // Move the stack pointer based on the requested amount.
     void adjustStack(int amount);
     void reserveStack(uint32_t amount) PER_ARCH;
     void freeStack(uint32_t amount);
 
     // Warning: This method does not update the framePushed() counter.
     void freeStack(Register amount);
 
   public:
     // ===============================================================
     // Simple call functions.
 
-    void call(Register reg) PER_ARCH;
-    void call(const Address& addr) PER_ARCH ONLY_X86_X64;
-    void call(Label* label) PER_ARCH;
-    void call(ImmWord imm) PER_ARCH;
+    void call(Register reg) PER_SHARED_ARCH;
+    void call(const Address& addr) DEFINED_ON(x86_shared);
+    void call(Label* label) PER_SHARED_ARCH;
+    void call(ImmWord imm) PER_SHARED_ARCH;
     // Call a target native function, which is neither traceable nor movable.
-    void call(ImmPtr imm) PER_ARCH;
-    void call(AsmJSImmPtr imm) PER_ARCH;
+    void call(ImmPtr imm) PER_SHARED_ARCH;
+    void call(AsmJSImmPtr imm) PER_SHARED_ARCH;
     // Call a target JitCode, which must be traceable, and may be movable.
-    void call(JitCode* c) PER_ARCH;
+    void call(JitCode* c) PER_SHARED_ARCH;
 
     inline void call(const CallSiteDesc& desc, const Register reg);
     inline void call(const CallSiteDesc& desc, Label* label);
 
+    //}}} check_macroassembler_style
   public:
 
     // Emits a test of a value against all types in a TypeSet. A scratch
     // register is required.
     template <typename Source>
     void guardTypeSet(const Source& address, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss);
 
     void guardObjectType(Register obj, const TypeSet* types, Register scratch, Label* miss);
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -409,17 +409,17 @@ StringFromCharCode(JSContext* cx, int32_
 bool
 SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValue value,
             bool strict, jsbytecode* pc)
 {
     RootedId id(cx, NameToId(name));
 
     JSOp op = JSOp(*pc);
 
-    if (op == JSOP_SETALIASEDVAR) {
+    if (op == JSOP_SETALIASEDVAR || op == JSOP_INITALIASEDLEXICAL) {
         // Aliased var assigns ignore readonly attributes on the property, as
         // required for initializing 'const' closure variables.
         Shape* shape = obj->as<NativeObject>().lookup(cx, name);
         MOZ_ASSERT(shape && shape->hasSlot());
         obj->as<NativeObject>().setSlotWithType(cx, shape, value);
         return true;
     }
 
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -5105,16 +5105,17 @@ MacroAssemblerARMCompat::asMasm()
 }
 
 const MacroAssembler&
 MacroAssemblerARMCompat::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveRegisterSet set)
 {
     int32_t diffF = set.fpus().getPushSizeInBytes();
     int32_t diffG = set.gprs().size() * sizeof(intptr_t);
@@ -5295,8 +5296,10 @@ MacroAssembler::call(JitCode* c)
     if (HasMOVWT())
         rs = L_MOVWT;
     else
         rs = L_LDR;
 
     ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
     ma_callJitHalfPush(ScratchRegister);
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -547,29 +547,21 @@ MacroAssemblerCompat::callAndPushReturnA
 
 void
 MacroAssemblerCompat::breakpoint()
 {
     static int code = 0xA77;
     Brk((code++) & 0xffff);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
-MacroAssembler::reserveStack(uint32_t amount)
-{
-    // TODO: This bumps |sp| every time we reserve using a second register.
-    // It would save some instructions if we had a fixed frame size.
-    vixl::MacroAssembler::Claim(Operand(amount));
-    adjustFrame(amount);
-}
-
-void
 MacroAssembler::PushRegsInMask(LiveRegisterSet set)
 {
     for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); ) {
         vixl::CPURegister src[4] = { vixl::NoCPUReg, vixl::NoCPUReg, vixl::NoCPUReg, vixl::NoCPUReg };
 
         for (size_t i = 0; i < 4 && iter.more(); i++) {
             src[i] = ARMRegister(*iter, 64);
             ++iter;
@@ -683,29 +675,38 @@ MacroAssembler::Push(const ImmGCPtr ptr)
 void
 MacroAssembler::Push(FloatRegister f)
 {
     push(f);
     adjustFrame(sizeof(double));
 }
 
 void
-MacroAssembler::Pop(const Register reg)
+MacroAssembler::Pop(Register reg)
 {
     pop(reg);
     adjustFrame(-1 * int64_t(sizeof(int64_t)));
 }
 
 void
 MacroAssembler::Pop(const ValueOperand& val)
 {
     pop(val);
     adjustFrame(-1 * int64_t(sizeof(int64_t)));
 }
 
+void
+MacroAssembler::reserveStack(uint32_t amount)
+{
+    // TODO: This bumps |sp| every time we reserve using a second register.
+    // It would save some instructions if we had a fixed frame size.
+    vixl::MacroAssembler::Claim(Operand(amount));
+    adjustFrame(amount);
+}
+
 // ===============================================================
 // Simple call functions.
 
 void
 MacroAssembler::call(Register reg)
 {
     syncStackPtr();
     Blr(ARMRegister(reg, 64));
@@ -748,10 +749,12 @@ MacroAssembler::call(JitCode* c)
     vixl::UseScratchRegisterScope temps(this);
     const ARMRegister scratch64 = temps.AcquireX();
     syncStackPtr();
     BufferOffset off = immPool64(scratch64, uint64_t(c->raw()));
     addPendingJump(off, ImmPtr(c->raw()), Relocation::JITCODE);
     blr(scratch64);
 }
 
+//}}} check_macroassembler_style
+
 } // namespace jit
 } // namespace js
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -3646,16 +3646,17 @@ MacroAssemblerMIPSCompat::asMasm()
 }
 
 const MacroAssembler&
 MacroAssemblerMIPSCompat::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveRegisterSet set)
 {
     int32_t diffF = set.fpus().getPushSizeInBytes();
     int32_t diffG = set.gprs().size() * sizeof(intptr_t);
@@ -3817,8 +3818,10 @@ MacroAssembler::call(ImmPtr target)
 void
 MacroAssembler::call(JitCode* c)
 {
     BufferOffset bo = m_buffer.nextOffset();
     addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
     ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
     ma_callJitHalfPush(ScratchRegister);
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jit/none/Trampoline-none.cpp
+++ b/js/src/jit/none/Trampoline-none.cpp
@@ -48,31 +48,8 @@ BailoutFrameInfo::BailoutFrameInfo(const
     MOZ_CRASH();
 }
 
 bool ICCompare_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
 bool ICCompare_Double::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
 bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
 bool ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
 JitCode* JitRuntime::generateProfilerExitFrameTailStub(JSContext*) { MOZ_CRASH(); }
-
-void MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic) { MOZ_CRASH(); }
-void MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) { MOZ_CRASH(); }
-
-void MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) { MOZ_CRASH(); }
-
-// ===============================================================
-// Stack manipulation functions.
-
-void MacroAssembler::PushRegsInMask(LiveRegisterSet) { MOZ_CRASH(); }
-void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet, LiveRegisterSet) { MOZ_CRASH(); }
-
-void MacroAssembler::Push(Register reg) { MOZ_CRASH(); }
-void MacroAssembler::Push(const Imm32 imm) { MOZ_CRASH(); }
-void MacroAssembler::Push(const ImmWord imm) { MOZ_CRASH(); }
-void MacroAssembler::Push(const ImmPtr imm) { MOZ_CRASH(); }
-void MacroAssembler::Push(const ImmGCPtr ptr) { MOZ_CRASH(); }
-void MacroAssembler::Push(FloatRegister reg) { MOZ_CRASH(); }
-
-void MacroAssembler::Pop(Register reg) { MOZ_CRASH(); }
-void MacroAssembler::Pop(const ValueOperand& val) { MOZ_CRASH(); }
-
-void MacroAssembler::reserveStack(uint32_t amount) { MOZ_CRASH(); }
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -573,16 +573,17 @@ MacroAssemblerX64::asMasm()
 }
 
 const MacroAssembler&
 MacroAssemblerX64::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::reserveStack(uint32_t amount)
 {
     if (amount) {
         // On windows, we cannot skip very far down the stack without touching the
@@ -595,8 +596,10 @@ MacroAssembler::reserveStack(uint32_t am
             subq(Imm32(4096), StackPointer);
             store32(Imm32(0), Address(StackPointer, 0));
             amountLeft -= 4096;
         }
         subq(Imm32(amountLeft), StackPointer);
     }
     framePushed_ += amount;
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
@@ -190,16 +190,17 @@ MacroAssemblerX86Shared::asMasm()
 }
 
 const MacroAssembler&
 MacroAssemblerX86Shared::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveRegisterSet set)
 {
     FloatRegisterSet fpuSet(set.fpus().reduceSetForPush());
     unsigned numFpu = fpuSet.size();
@@ -410,8 +411,10 @@ MacroAssembler::call(ImmPtr target)
     call(ImmWord(uintptr_t(target.value)));
 }
 
 void
 MacroAssembler::call(JitCode* target)
 {
     Assembler::call(target);
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -560,16 +560,17 @@ MacroAssemblerX86::asMasm()
 }
 
 const MacroAssembler&
 MacroAssemblerX86::asMasm() const
 {
     return *static_cast<const MacroAssembler*>(this);
 }
 
+//{{{ check_macroassembler_style
 // ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::reserveStack(uint32_t amount)
 {
     if (amount) {
         // On windows, we cannot skip very far down the stack without touching the
@@ -582,8 +583,10 @@ MacroAssembler::reserveStack(uint32_t am
             subl(Imm32(4096), StackPointer);
             store32(Imm32(0), Address(StackPointer, 0));
             amountLeft -= 4096;
         }
         subl(Imm32(amountLeft), StackPointer);
     }
     framePushed_ += amount;
 }
+
+//}}} check_macroassembler_style
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3248,18 +3248,20 @@ CreateArrayPrototype(JSContext* cx, JSPr
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayObject::class_, TaggedProto(proto),
                                                       gc::AllocKind::OBJECT0));
     if (!shape)
         return nullptr;
 
+    AutoSetNewObjectMetadata metadata(cx);
     RootedArrayObject arrayProto(cx, ArrayObject::createArray(cx, gc::AllocKind::OBJECT4,
-                                                              gc::TenuredHeap, shape, group, 0));
+                                                              gc::TenuredHeap, shape, group, 0,
+                                                              metadata));
     if (!arrayProto ||
         !JSObject::setSingleton(cx, arrayProto) ||
         !AddLengthProperty(cx, arrayProto))
     {
         return nullptr;
     }
 
     /*
@@ -3271,17 +3273,17 @@ CreateArrayPrototype(JSContext* cx, JSPr
     if (!JSObject::setNewGroupUnknown(cx, &ArrayObject::class_, arrayProto))
         return nullptr;
 
     return arrayProto;
 }
 
 const Class ArrayObject::class_ = {
     "Array",
-    JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
+    JSCLASS_HAS_CACHED_PROTO(JSProto_Array) | JSCLASS_DELAY_METADATA_CALLBACK,
     array_addProperty,
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
     nullptr, /* enumerate */
     nullptr, /* resolve */
     nullptr, /* mayResolve */
     nullptr, /* convert */
@@ -3338,16 +3340,17 @@ NewArray(ExclusiveContext* cxArg, uint32
     bool isCachable = NewArrayIsCachable(cxArg, newKind);
     if (isCachable) {
         JSContext* cx = cxArg->asJSContext();
         JSRuntime* rt = cx->runtime();
         NewObjectCache& cache = rt->newObjectCache;
         NewObjectCache::EntryIndex entry = -1;
         if (cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry)) {
             gc::InitialHeap heap = GetInitialHeap(newKind, &ArrayObject::class_);
+            AutoSetNewObjectMetadata metadata(cx);
             JSObject* obj = cache.newObjectFromHit(cx, entry, heap);
             if (obj) {
                 /* Fixup the elements pointer and length, which may be incorrect. */
                 ArrayObject* arr = &obj->as<ArrayObject>();
                 arr->setFixedElements();
                 arr->setLength(cx, length);
                 if (maxLength > 0 &&
                     !EnsureNewArrayElements(cx, arr, std::min(maxLength, length)))
@@ -3373,19 +3376,20 @@ NewArray(ExclusiveContext* cxArg, uint32
      * See JSObject::createArray.
      */
     RootedShape shape(cxArg, EmptyShape::getInitialShape(cxArg, &ArrayObject::class_,
                                                          TaggedProto(proto),
                                                          gc::AllocKind::OBJECT0));
     if (!shape)
         return nullptr;
 
+    AutoSetNewObjectMetadata metadata(cxArg);
     RootedArrayObject arr(cxArg, ArrayObject::createArray(cxArg, allocKind,
                                                           GetInitialHeap(newKind, &ArrayObject::class_),
-                                                          shape, group, length));
+                                                          shape, group, length, metadata));
     if (!arr)
         return nullptr;
 
     if (shape->isEmptyShape()) {
         if (!AddLengthProperty(cxArg, arr))
             return nullptr;
         shape = arr->lastProperty();
         EmptyShape::insertInitialShape(cxArg, shape, proto);
@@ -3457,26 +3461,27 @@ js::NewDenseCopiedArray(ExclusiveContext
         arr->initDenseElements(0, values, length);
 
     return arr;
 }
 
 ArrayObject*
 js::NewDenseFullyAllocatedArrayWithTemplate(JSContext* cx, uint32_t length, JSObject* templateObject)
 {
+    AutoSetNewObjectMetadata metadata(cx);
     gc::AllocKind allocKind = GuessArrayGCKind(length);
     MOZ_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
     allocKind = GetBackgroundAllocKind(allocKind);
 
     RootedObjectGroup group(cx, templateObject->group());
     RootedShape shape(cx, templateObject->as<ArrayObject>().lastProperty());
 
     gc::InitialHeap heap = GetInitialHeap(GenericObject, &ArrayObject::class_);
     Rooted<ArrayObject*> arr(cx, ArrayObject::createArray(cx, allocKind,
-                                                          heap, shape, group, length));
+                                                          heap, shape, group, length, metadata));
     if (!arr)
         return nullptr;
 
     if (!EnsureNewArrayElements(cx, arr, length))
         return nullptr;
 
     probes::CreateObject(cx, arr);
 
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -55,16 +55,17 @@ JSCompartment::JSCompartment(Zone* zone,
     enterCompartmentDepth(0),
     performanceMonitoring(runtime_),
     data(nullptr),
     objectMetadataCallback(nullptr),
     lastAnimationTime(0),
     regExps(runtime_),
     globalWriteBarriered(false),
     neuteredTypedObjects(0),
+    objectMetadataState(ImmediateMetadata()),
     propertyTree(thisForCtor()),
     selfHostingScriptSource(nullptr),
     objectMetadataTable(nullptr),
     lazyArrayBuffers(nullptr),
     gcIncomingGrayPointers(nullptr),
     gcWeakMapList(nullptr),
     gcPreserveJitCode(options.preserveJitCode()),
     debugModeBits(0),
@@ -512,27 +513,35 @@ void
 JSCompartment::trace(JSTracer* trc)
 {
     savedStacks_.trace(trc);
 }
 
 void
 JSCompartment::markRoots(JSTracer* trc)
 {
-    MOZ_ASSERT(!trc->runtime()->isHeapMinorCollecting());
-
-    if (jitCompartment_)
-        jitCompartment_->mark(trc, this);
+    // The object pending metadata is the only compartment root which can be
+    // nursery allocated.
+    if (objectMetadataState.is<PendingMetadata>()) {
+        TraceRoot(trc,
+                  objectMetadataState.as<PendingMetadata>().unsafeGet(),
+                  "on-stack object pending metadata");
+    }
 
-    /*
-     * If a compartment is on-stack, we mark its global so that
-     * JSContext::global() remains valid.
-     */
-    if (enterCompartmentDepth && global_.unbarrieredGet())
-        TraceRoot(trc, global_.unsafeGet(), "on-stack compartment global");
+    if (!trc->runtime()->isHeapMinorCollecting()) {
+        if (jitCompartment_)
+            jitCompartment_->mark(trc, this);
+
+        /*
+         * If a compartment is on-stack, we mark its global so that
+         * JSContext::global() remains valid.
+         */
+        if (enterCompartmentDepth && global_.unbarrieredGet())
+            TraceRoot(trc, global_.unsafeGet(), "on-stack compartment global");
+    }
 }
 
 void
 JSCompartment::sweepInnerViews()
 {
     innerViews.sweep(runtimeFromAnyThread());
 }
 
@@ -548,16 +557,27 @@ JSCompartment::sweepGlobalObject(FreeOp*
     if (global_.unbarrieredGet() && IsAboutToBeFinalized(&global_)) {
         if (isDebuggee())
             Debugger::detachAllDebuggersFromGlobal(fop, global_);
         global_.set(nullptr);
     }
 }
 
 void
+JSCompartment::sweepObjectPendingMetadata()
+{
+    if (objectMetadataState.is<PendingMetadata>()) {
+        // We should never finalize an object before it gets its metadata! That
+        // would mean we aren't calling the object metadata callback for every
+        // object!
+        MOZ_ALWAYS_TRUE(!IsAboutToBeFinalized(&objectMetadataState.as<PendingMetadata>()));
+    }
+}
+
+void
 JSCompartment::sweepSelfHostingScriptSource()
 {
     if (selfHostingScriptSource.unbarrieredGet() &&
         IsAboutToBeFinalized(&selfHostingScriptSource))
     {
         selfHostingScriptSource.set(nullptr);
     }
 }
@@ -939,8 +959,40 @@ void
 JSCompartment::addTelemetry(const char* filename, DeprecatedLanguageExtension e)
 {
     // Only report telemetry for web content, not add-ons or chrome JS.
     if (addonId || isSystem_ || !filename || strncmp(filename, "http", 4) != 0)
         return;
 
     sawDeprecatedLanguageExtension[e] = true;
 }
+
+AutoSetNewObjectMetadata::AutoSetNewObjectMetadata(ExclusiveContext* ecx
+                                                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+    : CustomAutoRooter(ecx)
+    , cx_(ecx->maybeJSContext())
+    , prevState_(ecx->compartment()->objectMetadataState)
+{
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    if (cx_)
+        cx_->compartment()->objectMetadataState = NewObjectMetadataState(DelayMetadata());
+}
+
+AutoSetNewObjectMetadata::~AutoSetNewObjectMetadata()
+{
+    // If we don't have a cx, we didn't change the metadata state, so no need to
+    // reset it here.
+    if (!cx_)
+        return;
+
+    if (!cx_->isExceptionPending() && cx_->compartment()->hasObjectPendingMetadata()) {
+        JSObject* obj = cx_->compartment()->objectMetadataState.as<PendingMetadata>();
+        // Make sure to restore the previous state before setting the object's
+        // metadata. SetNewObjectMetadata asserts that the state is not
+        // PendingMetadata in order to ensure that metadata callbacks are called
+        // in order.
+        cx_->compartment()->objectMetadataState = prevState_;
+        SetNewObjectMetadata(cx_, obj);
+    } else {
+        cx_->compartment()->objectMetadataState = prevState_;
+    }
+}
+
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -3,19 +3,21 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jscompartment_h
 #define jscompartment_h
 
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/Variant.h"
 
 #include "prmjtime.h"
 #include "builtin/RegExp.h"
+#include "gc/Barrier.h"
 #include "gc/Zone.h"
 #include "vm/GlobalObject.h"
 #include "vm/PIC.h"
 #include "vm/SavedStacks.h"
 
 namespace js {
 
 namespace jit {
@@ -118,16 +120,100 @@ struct WrapperHasher : public DefaultHas
     static bool match(const CrossCompartmentKey& l, const CrossCompartmentKey& k) {
         return l.kind == k.kind && l.debugger == k.debugger && l.wrapped == k.wrapped;
     }
 };
 
 typedef HashMap<CrossCompartmentKey, ReadBarrieredValue,
                 WrapperHasher, SystemAllocPolicy> WrapperMap;
 
+// We must ensure that all newly allocated JSObjects get their metadata
+// set. However, metadata callbacks may require the new object be in a sane
+// state (eg, have its reserved slots initialized so they can get the
+// sizeOfExcludingThis of the object). Therefore, for objects of certain
+// JSClasses (those marked with JSCLASS_DELAY_METADATA_CALLBACK), it is not safe
+// for the allocation paths to call the object metadata callback
+// immediately. Instead, the JSClass-specific "constructor" C++ function up the
+// stack makes a promise that it will ensure that the new object has its
+// metadata set after the object is initialized.
+//
+// To help those constructor functions keep their promise of setting metadata,
+// each compartment is in one of three states at any given time:
+//
+// * ImmediateMetadata: Allocators should set new object metadata immediately,
+//                      as usual.
+//
+// * DelayMetadata: Allocators should *not* set new object metadata, it will be
+//                  handled after reserved slots are initialized by custom code
+//                  for the object's JSClass. The newly allocated object's
+//                  JSClass *must* have the JSCLASS_DELAY_METADATA_CALLBACK flag
+//                  set.
+//
+// * PendingMetadata: This object has been allocated and is still pending its
+//                    metadata. This should never be the case in an allocation
+//                    path, as a constructor function was supposed to have set
+//                    the metadata of the previous object *before* allocating
+//                    another object.
+//
+// The js::AutoSetNewObjectMetadata RAII class provides an ergonomic way for
+// constructor functions to navigate state transitions, and its instances
+// collectively maintain a stack of previous states. The stack is required to
+// support the lazy resolution and allocation of global builtin constructors and
+// prototype objects. The initial (and intuitively most common) state is
+// ImmediateMetadata.
+//
+// Without the presence of internal errors (such as OOM), transitions between
+// the states are as follows:
+//
+//     ImmediateMetadata                 .----- previous state on stack
+//           |                           |          ^
+//           | via constructor           |          |
+//           |                           |          | via setting the new
+//           |        via constructor    |          | object's metadata
+//           |   .-----------------------'          |
+//           |   |                                  |
+//           V   V                                  |
+//     DelayMetadata -------------------------> PendingMetadata
+//                         via allocation
+//
+// In the presence of internal errors, we do not set the new object's metadata
+// (if it was even allocated) and reset to the previous state on the stack.
+
+struct ImmediateMetadata { };
+struct DelayMetadata { };
+using PendingMetadata = ReadBarrieredObject;
+
+using NewObjectMetadataState = mozilla::Variant<ImmediateMetadata,
+                                                DelayMetadata,
+                                                PendingMetadata>;
+
+class MOZ_STACK_CLASS AutoSetNewObjectMetadata : private JS::CustomAutoRooter
+{
+    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
+
+    JSContext* cx_;
+    NewObjectMetadataState prevState_;
+
+    AutoSetNewObjectMetadata(const AutoSetNewObjectMetadata& aOther) = delete;
+    void operator=(const AutoSetNewObjectMetadata& aOther) = delete;
+
+  protected:
+    virtual void trace(JSTracer* trc) override {
+        if (prevState_.is<PendingMetadata>()) {
+            TraceRoot(trc,
+                      prevState_.as<PendingMetadata>().unsafeGet(),
+                      "Object pending metadata");
+        }
+    }
+
+  public:
+    explicit AutoSetNewObjectMetadata(ExclusiveContext* ecx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~AutoSetNewObjectMetadata();
+};
+
 } /* namespace js */
 
 namespace js {
 class DebugScopes;
 class ObjectWeakMap;
 class WatchpointMap;
 class WeakMapBase;
 }
@@ -277,16 +363,33 @@ struct JSCompartment
      * This is used to avoid adding it to the store buffer on every write, which
      * can quickly fill the buffer and also cause performance problems.
      */
     bool                         globalWriteBarriered;
 
     // Non-zero if any typed objects in this compartment might be neutered.
     int32_t                      neuteredTypedObjects;
 
+  private:
+    friend class js::AutoSetNewObjectMetadata;
+    js::NewObjectMetadataState objectMetadataState;
+
+  public:
+    bool hasObjectPendingMetadata() const { return objectMetadataState.is<js::PendingMetadata>(); }
+
+    void setObjectPendingMetadata(JSContext* cx, JSObject* obj) {
+        MOZ_ASSERT(objectMetadataState.is<js::DelayMetadata>());
+        objectMetadataState = js::NewObjectMetadataState(js::PendingMetadata(obj));
+    }
+
+    void setObjectPendingMetadata(js::ExclusiveContext* ecx, JSObject* obj) {
+        if (JSContext* cx = ecx->maybeJSContext())
+            setObjectPendingMetadata(cx, obj);
+    }
+
   public:
     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                 size_t* tiAllocationSiteTables,
                                 size_t* tiArrayTypeTables,
                                 size_t* tiObjectTypeTables,
                                 size_t* compartmentObject,
                                 size_t* compartmentTables,
                                 size_t* innerViews,
@@ -415,16 +518,17 @@ struct JSCompartment
     void trace(JSTracer* trc);
     void markRoots(JSTracer* trc);
     bool preserveJitCode() { return gcPreserveJitCode; }
 
     void sweepInnerViews();
     void sweepCrossCompartmentWrappers();
     void sweepSavedStacks();
     void sweepGlobalObject(js::FreeOp* fop);
+    void sweepObjectPendingMetadata();
     void sweepSelfHostingScriptSource();
     void sweepJitCompartment(js::FreeOp* fop);
     void sweepRegExps();
     void sweepDebugScopes();
     void sweepWeakMaps();
     void sweepNativeIterators();
     void sweepTemplateObjects();
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -629,18 +629,20 @@ js::ErrorReportToString(JSContext* cx, J
 
 bool
 js::ReportUncaughtException(JSContext* cx)
 {
     if (!cx->isExceptionPending())
         return true;
 
     RootedValue exn(cx);
-    if (!cx->getPendingException(&exn))
+    if (!cx->getPendingException(&exn)) {
+        cx->clearPendingException();
         return false;
+    }
 
     cx->clearPendingException();
 
     ErrorReport err(cx);
     if (!err.init(cx, exn)) {
         cx->clearPendingException();
         return false;
     }
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -311,16 +311,17 @@ namespace js {
     }
 
 #define PROXY_CLASS_WITH_EXT(name, flags, ext)                                          \
     {                                                                                   \
         name,                                                                           \
         js::Class::NON_NATIVE |                                                         \
             JSCLASS_IS_PROXY |                                                          \
             JSCLASS_IMPLEMENTS_BARRIERS |                                               \
+            JSCLASS_DELAY_METADATA_CALLBACK |                                           \
             flags,                                                                      \
         nullptr,                 /* addProperty */                                      \
         nullptr,                 /* delProperty */                                      \
         nullptr,                 /* getProperty */                                      \
         nullptr,                 /* setProperty */                                      \
         nullptr,                 /* enumerate */                                        \
         nullptr,                 /* resolve */                                          \
         nullptr,                 /* mayResolve */                                       \
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2253,16 +2253,17 @@ GCRuntime::sweepZoneAfterCompacting(Zone
     for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
         c->sweepInnerViews();
         c->sweepBaseShapeTable();
         c->sweepInitialShapeTable();
         c->objectGroups.sweep(fop);
         c->sweepRegExps();
         c->sweepSavedStacks();
         c->sweepGlobalObject(fop);
+        c->sweepObjectPendingMetadata();
         c->sweepSelfHostingScriptSource();
         c->sweepDebugScopes();
         c->sweepJitCompartment(fop);
         c->sweepWeakMaps();
         c->sweepNativeIterators();
         c->sweepTemplateObjects();
     }
 }
@@ -4926,16 +4927,17 @@ GCRuntime::beginSweepingZoneGroup()
 
         // The remainder of the of the tasks run in parallel on the main
         // thread until we join, below.
         {
             gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_MISC);
 
             for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
                 c->sweepGlobalObject(&fop);
+                c->sweepObjectPendingMetadata();
                 c->sweepDebugScopes();
                 c->sweepJitCompartment(&fop);
                 c->sweepWeakMaps();
                 c->sweepTemplateObjects();
             }
 
             // Bug 1071218: the following two methods have not yet been
             // refactored to work on a single zone-group at once.
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3557,16 +3557,21 @@ JSObject::addSizeOfExcludingThis(mozilla
         // classes, as measured during a vanilla browser session:
         // - (53.7%, 53.7%): Function
         // - (18.0%, 71.7%): Object
         // - (16.9%, 88.6%): Array
         // - ( 3.9%, 92.5%): Call
         // - ( 2.8%, 95.3%): RegExp
         // - ( 1.0%, 96.4%): Proxy
 
+        // Note that any JSClass that is special cased below likely needs to
+        // specify the JSCLASS_DELAY_METADATA_CALLBACK flag, or else we will
+        // probably crash if the object metadata callback attempts to get the
+        // size of the new object (which Debugger code does) before private
+        // slots are initialized.
     } else if (is<ArgumentsObject>()) {
         info->objectsMallocHeapMisc += as<ArgumentsObject>().sizeOfMisc(mallocSizeOf);
     } else if (is<RegExpStaticsObject>()) {
         info->objectsMallocHeapMisc += as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
     } else if (is<PropertyIteratorObject>()) {
         info->objectsMallocHeapMisc += as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
     } else if (is<ArrayBufferObject>()) {
         ArrayBufferObject::addSizeOfExcludingThis(this, mallocSizeOf, info);
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -4,16 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jsobjinlines_h
 #define jsobjinlines_h
 
 #include "jsobj.h"
 
+#include "mozilla/DebugOnly.h"
+
 #include "jsfun.h"
 
 #include "builtin/MapObject.h"
 #include "builtin/TypedObject.h"
 #include "gc/Allocator.h"
 #include "vm/ArrayObject.h"
 #include "vm/DateObject.h"
 #include "vm/NumberObject.h"
@@ -254,16 +256,18 @@ ClassCanHaveFixedData(const Class* clasp
     return !clasp->isNative()
         || clasp == &js::ArrayBufferObject::class_
         || js::IsTypedArrayClass(clasp);
 }
 
 static MOZ_ALWAYS_INLINE void
 SetNewObjectMetadata(ExclusiveContext* cxArg, JSObject* obj)
 {
+    MOZ_ASSERT(!cxArg->compartment()->hasObjectPendingMetadata());
+
     // The metadata callback is invoked for each object created on the main
     // thread, except when analysis/compilation is active, to avoid recursion.
     if (JSContext* cx = cxArg->maybeJSContext()) {
         if (MOZ_UNLIKELY((size_t)cx->compartment()->hasObjectMetadataCallback()) &&
             !cx->zone()->types.activeAnalysis)
         {
             // Use AutoEnterAnalysis to prohibit both any GC activity under the
             // callback, and any reentering of JS via Invoke() etc.
@@ -288,16 +292,17 @@ JSObject::create(js::ExclusiveContext* c
                   js::gc::GetGCKindSlots(kind, group->clasp()) == shape->numFixedSlots());
     MOZ_ASSERT_IF(group->clasp()->flags & JSCLASS_BACKGROUND_FINALIZE,
                   IsBackgroundFinalized(kind));
     MOZ_ASSERT_IF(group->clasp()->finalize,
                   heap == js::gc::TenuredHeap ||
                   (group->clasp()->flags & JSCLASS_SKIP_NURSERY_FINALIZE));
     MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),
                   heap == js::gc::TenuredHeap);
+    MOZ_ASSERT(!cx->compartment()->hasObjectPendingMetadata());
 
     // Non-native classes cannot have reserved slots or private data, and the
     // objects can't have any fixed slots, for compatibility with
     // GetReservedOrProxyPrivateSlot.
     MOZ_ASSERT_IF(!group->clasp()->isNative(), JSCLASS_RESERVED_SLOTS(group->clasp()) == 0);
     MOZ_ASSERT_IF(!group->clasp()->isNative(), !group->clasp()->hasPrivate());
     MOZ_ASSERT_IF(!group->clasp()->isNative(), shape->numFixedSlots() == 0);
     MOZ_ASSERT_IF(!group->clasp()->isNative(), shape->slotSpan() == 0);
@@ -327,17 +332,20 @@ JSObject::create(js::ExclusiveContext* c
     if (group->clasp()->isJSFunction()) {
         MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION ||
                    kind == js::gc::AllocKind::FUNCTION_EXTENDED);
         size_t size =
             kind == js::gc::AllocKind::FUNCTION ? sizeof(JSFunction) : sizeof(js::FunctionExtended);
         memset(obj->as<JSFunction>().fixedSlots(), 0, size - sizeof(js::NativeObject));
     }
 
-    SetNewObjectMetadata(cx, obj);
+    if (group->clasp()->shouldDelayMetadataCallback())
+        cx->compartment()->setObjectPendingMetadata(cx, obj);
+    else
+        SetNewObjectMetadata(cx, obj);
 
     js::gc::TraceCreateObject(obj);
 
     return obj;
 }
 
 inline void
 JSObject::setInitialShapeMaybeNonNative(js::Shape* shape)
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -170,16 +170,17 @@ ArgumentsObject::createTemplateObject(JS
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(proto),
                                                       FINALIZE_KIND, BaseShape::INDEXED));
     if (!shape)
         return nullptr;
 
+    AutoSetNewObjectMetadata metadata(cx);
     JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, group);
     if (!base)
         return nullptr;
 
     ArgumentsObject* obj = &base->as<js::ArgumentsObject>();
     obj->initFixedSlot(ArgumentsObject::DATA_SLOT, PrivateValue(nullptr));
     return obj;
 }
@@ -217,41 +218,49 @@ ArgumentsObject::create(JSContext* cx, H
     unsigned numFormals = callee->nargs();
     unsigned numDeletedWords = NumWordsForBitArrayOfLength(numActuals);
     unsigned numArgs = Max(numActuals, numFormals);
     unsigned numBytes = offsetof(ArgumentsData, args) +
                         numDeletedWords * sizeof(size_t) +
                         numArgs * sizeof(Value);
 
     Rooted<ArgumentsObject*> obj(cx);
-    JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, group);
-    if (!base)
-        return nullptr;
-    obj = &base->as<ArgumentsObject>();
+    ArgumentsData* data = nullptr;
+    {
+        // The copyArgs call below can allocate objects, so add this block scope
+        // to make sure we set the metadata for this arguments object first.
+        AutoSetNewObjectMetadata metadata(cx);
 
-    ArgumentsData* data =
-        reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
-    if (!data) {
-        // Make the object safe for GC.
-        obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
-        return nullptr;
-    }
+        JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, group);
+        if (!base)
+            return nullptr;
+        obj = &base->as<ArgumentsObject>();
 
-    data->numArgs = numArgs;
-    data->dataBytes = numBytes;
-    data->callee.init(ObjectValue(*callee.get()));
-    data->script = callee->nonLazyScript();
+        data =
+            reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
+        if (!data) {
+            // Make the object safe for GC.
+            obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
+            return nullptr;
+        }
 
-    // Zero the argument Values. This sets each value to DoubleValue(0), which
-    // is safe for GC tracing.
-    memset(data->args, 0, numArgs * sizeof(Value));
-    MOZ_ASSERT(DoubleValue(0).asRawBits() == 0x0);
-    MOZ_ASSERT_IF(numArgs > 0, data->args[0].asRawBits() == 0x0);
+        data->numArgs = numArgs;
+        data->dataBytes = numBytes;
+        data->callee.init(ObjectValue(*callee.get()));
+        data->script = callee->nonLazyScript();
 
-    obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
+        // Zero the argument Values. This sets each value to DoubleValue(0), which
+        // is safe for GC tracing.
+        memset(data->args, 0, numArgs * sizeof(Value));
+        MOZ_ASSERT(DoubleValue(0).asRawBits() == 0x0);
+        MOZ_ASSERT_IF(numArgs > 0, data->args[0].asRawBits() == 0x0);
+
+        obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
+    }
+    MOZ_ASSERT(data != nullptr);
 
     /* Copy [0, numArgs) into data->slots. */
     copy.copyArgs(cx, data->args, numArgs);
 
     data->deletedBits = reinterpret_cast<size_t*>(data->args + numArgs);
     ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
 
     obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));
@@ -612,17 +621,17 @@ ArgumentsObject::objectMovedDuringMinorG
 /*
  * The classes below collaborate to lazily reflect and synchronize actual
  * argument values, argument count, and callee function object stored in a
  * stack frame with their corresponding property values in the frame's
  * arguments object.
  */
 const Class NormalArgumentsObject::class_ = {
     "Arguments",
-    JSCLASS_IMPLEMENTS_BARRIERS |
+    JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_DELAY_METADATA_CALLBACK |
     JSCLASS_HAS_RESERVED_SLOTS(NormalArgumentsObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
     JSCLASS_SKIP_NURSERY_FINALIZE |
     JSCLASS_BACKGROUND_FINALIZE,
     nullptr,                 /* addProperty */
     args_delProperty,
     nullptr,                 /* getProperty */
     nullptr,                 /* setProperty */
@@ -639,17 +648,17 @@ const Class NormalArgumentsObject::class
 
 /*
  * Strict mode arguments is significantly less magical than non-strict mode
  * arguments, so it is represented by a different class while sharing some
  * functionality.
  */
 const Class StrictArgumentsObject::class_ = {
     "Arguments",
-    JSCLASS_IMPLEMENTS_BARRIERS |
+    JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_DELAY_METADATA_CALLBACK |
     JSCLASS_HAS_RESERVED_SLOTS(StrictArgumentsObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
     JSCLASS_SKIP_NURSERY_FINALIZE |
     JSCLASS_BACKGROUND_FINALIZE,
     nullptr,                 /* addProperty */
     args_delProperty,
     nullptr,                 /* getProperty */
     nullptr,                 /* setProperty */
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -95,16 +95,17 @@ js::ToClampedIndex(JSContext* cx, Handle
 const Class ArrayBufferObject::protoClass = {
     "ArrayBufferPrototype",
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer)
 };
 
 const Class ArrayBufferObject::class_ = {
     "ArrayBuffer",
     JSCLASS_IMPLEMENTS_BARRIERS |
+    JSCLASS_DELAY_METADATA_CALLBACK |
     JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer) |
     JSCLASS_BACKGROUND_FINALIZE,
     nullptr,                 /* addProperty */
     nullptr,                 /* delProperty */
     nullptr,                 /* getProperty */
     nullptr,                 /* setProperty */
     nullptr,                 /* enumerate */
@@ -805,16 +806,17 @@ ArrayBufferObject::create(JSContext* cx,
                 return nullptr;
             allocated = true;
         }
     }
 
     MOZ_ASSERT(!(class_.flags & JSCLASS_HAS_PRIVATE));
     gc::AllocKind allocKind = GetGCObjectKind(nslots);
 
+    AutoSetNewObjectMetadata metadata(cx);
     Rooted<ArrayBufferObject*> obj(cx, NewBuiltinClassInstance<ArrayBufferObject>(cx, allocKind, newKind));
     if (!obj) {
         if (allocated)
             js_free(contents.data());
         return nullptr;
     }
 
     MOZ_ASSERT(obj->getClass() == &class_);
--- a/js/src/vm/ArrayObject-inl.h
+++ b/js/src/vm/ArrayObject-inl.h
@@ -29,90 +29,92 @@ ArrayObject::setLength(ExclusiveContext*
         MarkObjectGroupFlags(cx, this, OBJECT_FLAG_LENGTH_OVERFLOW);
     }
 
     getElementsHeader()->length = length;
 }
 
 /* static */ inline ArrayObject*
 ArrayObject::createArrayInternal(ExclusiveContext* cx, gc::AllocKind kind, gc::InitialHeap heap,
-                                 HandleShape shape, HandleObjectGroup group)
+                                 HandleShape shape, HandleObjectGroup group,
+                                 AutoSetNewObjectMetadata&)
 {
     // Create a new array and initialize everything except for its elements.
     MOZ_ASSERT(shape && group);
     MOZ_ASSERT(group->clasp() == shape->getObjectClass());
     MOZ_ASSERT(group->clasp() == &ArrayObject::class_);
     MOZ_ASSERT_IF(group->clasp()->finalize, heap == gc::TenuredHeap);
     MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),
                   heap == js::gc::TenuredHeap);
+    MOZ_ASSERT(group->clasp()->shouldDelayMetadataCallback());
 
     // Arrays can use their fixed slots to store elements, so can't have shapes
     // which allow named properties to be stored in the fixed slots.
     MOZ_ASSERT(shape->numFixedSlots() == 0);
 
     size_t nDynamicSlots = dynamicSlotsCount(0, shape->slotSpan(), group->clasp());
     JSObject* obj = Allocate<JSObject>(cx, kind, nDynamicSlots, heap, group->clasp());
     if (!obj)
         return nullptr;
 
     static_cast<ArrayObject*>(obj)->shape_.init(shape);
     static_cast<ArrayObject*>(obj)->group_.init(group);
 
-    SetNewObjectMetadata(cx, obj);
-
+    cx->compartment()->setObjectPendingMetadata(cx, obj);
     return &obj->as<ArrayObject>();
 }
 
 /* static */ inline ArrayObject*
-ArrayObject::finishCreateArray(ArrayObject* obj, HandleShape shape)
+ArrayObject::finishCreateArray(ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata)
 {
     size_t span = shape->slotSpan();
     if (span)
         obj->initializeSlotRange(0, span);
 
     gc::TraceCreateObject(obj);
 
     return obj;
 }
 
 /* static */ inline ArrayObject*
 ArrayObject::createArray(ExclusiveContext* cx, gc::AllocKind kind, gc::InitialHeap heap,
                          HandleShape shape, HandleObjectGroup group,
-                         uint32_t length)
+                         uint32_t length, AutoSetNewObjectMetadata& metadata)
 {
-    ArrayObject* obj = createArrayInternal(cx, kind, heap, shape, group);
+    ArrayObject* obj = createArrayInternal(cx, kind, heap, shape, group, metadata);
     if (!obj)
         return nullptr;
 
     uint32_t capacity = gc::GetGCKindSlots(kind) - ObjectElements::VALUES_PER_HEADER;
 
     obj->setFixedElements();
     new (obj->getElementsHeader()) ObjectElements(capacity, length);
 
-    return finishCreateArray(obj, shape);
+    return finishCreateArray(obj, shape, metadata);
 }
 
 /* static */ inline ArrayObject*
 ArrayObject::createCopyOnWriteArray(ExclusiveContext* cx, gc::InitialHeap heap,
                                     HandleArrayObject sharedElementsOwner)
 {
     MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->isCopyOnWrite());
     MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->ownerObject() == sharedElementsOwner);
 
     // Use the smallest allocation kind for the array, as it can't have any
     // fixed slots (see the assert in createArrayInternal) and will not be using
     // its fixed elements.
     gc::AllocKind kind = gc::AllocKind::OBJECT0_BACKGROUND;
 
+    AutoSetNewObjectMetadata metadata(cx);
     RootedShape shape(cx, sharedElementsOwner->lastProperty());
     RootedObjectGroup group(cx, sharedElementsOwner->group());
-    ArrayObject* obj = createArrayInternal(cx, kind, heap, shape, group);
+    ArrayObject* obj = createArrayInternal(cx, kind, heap, shape, group, metadata);
     if (!obj)
         return nullptr;
 
     obj->elements_ = sharedElementsOwner->getDenseElementsAllowCopyOnWrite();
 
-    return finishCreateArray(obj, shape);
+    return finishCreateArray(obj, shape, metadata);
 }
 
 } // namespace js
 
 #endif // vm_ArrayObject_inl_h
--- a/js/src/vm/ArrayObject.h
+++ b/js/src/vm/ArrayObject.h
@@ -6,16 +6,18 @@
 
 #ifndef vm_ArrayObject_h
 #define vm_ArrayObject_h
 
 #include "vm/NativeObject.h"
 
 namespace js {
 
+class AutoSetNewObjectMetadata;
+
 class ArrayObject : public NativeObject
 {
   public:
     // Array(x) eagerly allocates dense elements if x <= this value. Without
     // the subtraction the max would roll over to the next power-of-two (4096)
     // due to the way that growElements() and goodAllocated() work.
     static const uint32_t EagerAllocationMaxLength = 2048 - ObjectElements::VALUES_PER_HEADER;
 
@@ -40,34 +42,36 @@ class ArrayObject : public NativeObject
 
     // Make an array object with the specified initial state.
     static inline ArrayObject*
     createArray(ExclusiveContext* cx,
                 gc::AllocKind kind,
                 gc::InitialHeap heap,
                 HandleShape shape,
                 HandleObjectGroup group,
-                uint32_t length);
+                uint32_t length,
+                AutoSetNewObjectMetadata& metadata);
 
     // Make a copy-on-write array object which shares the elements of an
     // existing object.
     static inline ArrayObject*
     createCopyOnWriteArray(ExclusiveContext* cx,
                            gc::InitialHeap heap,
                            HandleArrayObject sharedElementsOwner);
 
   private:
     // Helper for the above methods.
     static inline ArrayObject*
     createArrayInternal(ExclusiveContext* cx,
                         gc::AllocKind kind,
                         gc::InitialHeap heap,
                         HandleShape shape,
-                        HandleObjectGroup group);
+                        HandleObjectGroup group,
+                        AutoSetNewObjectMetadata&);
 
     static inline ArrayObject*
-    finishCreateArray(ArrayObject* obj, HandleShape shape);
+    finishCreateArray(ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata);
 };
 
 } // namespace js
 
 #endif // vm_ArrayObject_h
 
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -187,16 +187,17 @@
     macro(resumeGenerator, resumeGenerator, "resumeGenerator") \
     macro(return, return_, "return") \
     macro(revoke, revoke, "revoke") \
     macro(scripts, scripts, "scripts") \
     macro(sensitivity, sensitivity, "sensitivity") \
     macro(set, set, "set") \
     macro(shape, shape, "shape") \
     macro(signMask, signMask, "signMask") \
+    macro(size, size, "size") \
     macro(source, source, "source") \
     macro(stack, stack, "stack") \
     macro(star, star, "*") \
     macro(starDefaultStar, starDefaultStar, "*default*") \
     macro(startTimestamp, startTimestamp, "startTimestamp") \
     macro(static, static_, "static") \
     macro(sticky, sticky, "sticky") \
     macro(strings, strings, "strings") \
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1713,16 +1713,18 @@ Debugger::AllocationSite::create(JSConte
     }
 
     AllocationSite* allocSite = cx->new_<AllocationSite>(frame, when);
     if (!allocSite)
         return nullptr;
 
     allocSite->className = obj->getClass()->name;
     allocSite->ctorName = ctorName.get();
+    allocSite->size = JS::ubi::Node(obj.get()).size(cx->runtime()->debuggerMallocSizeOf);
+
     return allocSite;
 }
 
 
 bool
 Debugger::appendAllocationSite(JSContext* cx, HandleObject obj, HandleSavedFrame frame,
                                double when)
 {
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -273,28 +273,30 @@ class Debugger : private mozilla::Linked
     js::HashSet<uint64_t> observedGCs;
 
     struct AllocationSite : public mozilla::LinkedListElement<AllocationSite>
     {
         AllocationSite(HandleObject frame, double when)
             : frame(frame),
               when(when),
               className(nullptr),
-              ctorName(nullptr)
+              ctorName(nullptr),
+              size(0)
         {
             MOZ_ASSERT_IF(frame, UncheckedUnwrap(frame)->is<SavedFrame>());
         };
 
         static AllocationSite* create(JSContext* cx, HandleObject frame, double when,
                                       HandleObject obj);
 
         RelocatablePtrObject frame;
         double when;
         const char* className;
         RelocatablePtrAtom ctorName;
+        size_t size;
     };
     typedef mozilla::LinkedList<AllocationSite> AllocationSiteList;
 
     bool allowUnobservedAsmJS;
     bool trackingAllocationSites;
     double allocationSamplingProbability;
     AllocationSiteList allocationsLog;
     size_t allocationsLogLength;
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -196,16 +196,17 @@ DebuggerMemory::drainAllocationsLog(JSCo
         if (!obj)
             return false;
 
         // Don't pop the AllocationSite yet. The queue's links are followed by
         // the GC to find the AllocationSite, but are not barriered, so we must
         // edit them with great care. Use the queue entry in place, and then
         // pop and delete together.
         Debugger::AllocationSite* allocSite = dbg->allocationsLog.getFirst();
+
         RootedValue frame(cx, ObjectOrNullValue(allocSite->frame));
         if (!DefineProperty(cx, obj, cx->names().frame, frame))
             return false;
 
         RootedValue timestampValue(cx, NumberValue(allocSite->when));
         if (!DefineProperty(cx, obj, cx->names().timestamp, timestampValue))
             return false;
 
@@ -217,16 +218,20 @@ DebuggerMemory::drainAllocationsLog(JSCo
             return false;
 
         RootedValue ctorName(cx, NullValue());
         if (allocSite->ctorName)
             ctorName.setString(allocSite->ctorName);
         if (!DefineProperty(cx, obj, cx->names().constructor, ctorName))
             return false;
 
+        RootedValue size(cx, NumberValue(allocSite->size));
+        if (!DefineProperty(cx, obj, cx->names().size, size))
+            return false;
+
         result->setDenseElement(i, ObjectValue(*obj));
 
         // Pop the front queue entry, and delete it immediately, so that
         // the GC sees the AllocationSite's RelocatablePtr barriers run
         // atomically with the change to the graph (the queue link).
         MOZ_ALWAYS_TRUE(dbg->allocationsLog.popFirst() == allocSite);
         js_delete(allocSite);
     }
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -609,16 +609,22 @@ struct AutoStopwatch final
     uint64_t systemTimeStart_;
     uint64_t CPOWTimeStart_;
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 }
 
+// MSVC with PGO inlines a lot of functions in RunScript, resulting in large
+// stack frames and stack overflow issues, see bug 1167883. Turn off PGO to
+// avoid this.
+#ifdef _MSC_VER
+# pragma optimize("g", off)
+#endif
 bool
 js::RunScript(JSContext* cx, RunState& state)
 {
     JS_CHECK_RECURSION(cx, return false);
 
 #if defined(NIGHTLY_BUILD)
     js::AutoStopwatch stopwatch(cx);
 #endif // defined(NIGHTLY_BUILD)
@@ -649,16 +655,19 @@ js::RunScript(JSContext* cx, RunState& s
 
     if (state.isInvoke()) {
         InvokeState& invoke = *state.asInvoke();
         TypeMonitorCall(cx, invoke.args(), invoke.constructing());
     }
 
     return Interpret(cx, state);
 }
+#ifdef _MSC_VER
+# pragma optimize("", on)
+#endif
 
 struct AutoGCIfRequested
 {
     JSRuntime* runtime;
     explicit AutoGCIfRequested(JSRuntime* rt) : runtime(rt) {}
     ~AutoGCIfRequested() { runtime->gc.gcIfRequested(); }
 };
 
@@ -714,20 +723,18 @@ js::Invoke(JSContext* cx, CallArgs args,
     if (!fun->getOrCreateScript(cx))
         return false;
 
     /* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */
     InvokeState state(cx, args, initial);
 
     // Check to see if createSingleton flag should be set for this frame.
     if (construct) {
-        FrameIter iter(cx);
-        if (!iter.done() && iter.hasScript()) {
-            JSScript* script = iter.script();
-            jsbytecode* pc = iter.pc();
+        jsbytecode* pc;
+        if (JSScript* script = cx->currentScript(&pc)) {
             if (ObjectGroup::useSingletonForNewObject(cx, script, pc))
                 state.setCreateSingleton();
         }
     }
 
     bool ok = RunScript(cx, state);
 
     MOZ_ASSERT_IF(ok && construct, args.rval().isObject());
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -15,16 +15,17 @@ using namespace js;
 ProxyObject::New(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, TaggedProto proto_,
                  const ProxyOptions& options)
 {
     Rooted<TaggedProto> proto(cx, proto_);
 
     const Class* clasp = options.clasp();
 
     MOZ_ASSERT(isValidProxyClass(clasp));
+    MOZ_ASSERT(clasp->shouldDelayMetadataCallback());
     MOZ_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment());
 
     /*
      * Eagerly mark properties unknown for proxies, so we don't try to track
      * their properties and so that we don't need to walk the compartment if
      * their prototype changes later.  But don't do this for DOM proxies,
      * because we want to be able to keep track of them in typesets in useful
      * ways.
@@ -42,16 +43,17 @@ ProxyObject::New(JSContext* cx, const Ba
         allocKind = GetBackgroundAllocKind(allocKind);
 
     ProxyValueArray* values = cx->zone()->new_<ProxyValueArray>();
     if (!values) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
 
+    AutoSetNewObjectMetadata metadata(cx);
     // Note: this will initialize the object's |data| to strange values, but we
     // will immediately overwrite those below.
     RootedObject obj(cx, NewObjectWithGivenTaggedProto(cx, clasp, proto, allocKind,
                                                        newKind));
     if (!obj) {
         js_free(values);
         return nullptr;
     }
--- a/js/src/vm/Runtime-inl.h
+++ b/js/src/vm/Runtime-inl.h
@@ -62,17 +62,20 @@ NewObjectCache::newObjectFromHit(JSConte
 
     NativeObject* obj = static_cast<NativeObject*>(Allocate<JSObject, NoGC>(cx, entry->kind, 0,
                                                                             heap, group->clasp()));
     if (!obj)
         return nullptr;
 
     copyCachedToObject(obj, templateObj, entry->kind);
 
-    SetNewObjectMetadata(cx, obj);
+    if (group->clasp()->shouldDelayMetadataCallback())
+        cx->compartment()->setObjectPendingMetadata(cx, obj);
+    else
+        SetNewObjectMetadata(cx, obj);
 
     probes::CreateObject(cx, obj);
     gc::TraceCreateObject(obj);
     return obj;
 }
 
 }  /* namespace js */
 
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -239,16 +239,17 @@ SharedArrayBufferObject::New(JSContext* 
         return nullptr;
 
     return New(cx, buffer);
 }
 
 SharedArrayBufferObject*
 SharedArrayBufferObject::New(JSContext* cx, SharedArrayRawBuffer* buffer)
 {
+    AutoSetNewObjectMetadata metadata(cx);
     Rooted<SharedArrayBufferObject*> obj(cx, NewBuiltinClassInstance<SharedArrayBufferObject>(cx));
     if (!obj)
         return nullptr;
 
     MOZ_ASSERT(obj->getClass() == &class_);
 
     obj->acceptRawBuffer(buffer);
 
@@ -299,16 +300,17 @@ SharedArrayBufferObject::addSizeOfExclud
 const Class SharedArrayBufferObject::protoClass = {
     "SharedArrayBufferPrototype",
     JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer)
 };
 
 const Class SharedArrayBufferObject::class_ = {
     "SharedArrayBuffer",
     JSCLASS_IMPLEMENTS_BARRIERS |
+    JSCLASS_DELAY_METADATA_CALLBACK |
     JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer),
     nullptr, /* addProperty */
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
     nullptr, /* enumerate */
     nullptr, /* resolve */
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -338,16 +338,17 @@ class TypedArrayObjectTemplate : public 
                  HandleObject proto)
     {
         MOZ_ASSERT_IF(!buffer, byteOffset == 0);
 
         gc::AllocKind allocKind = buffer
                                   ? GetGCObjectKind(instanceClass())
                                   : AllocKindForLazyBuffer(len * sizeof(NativeType));
 
+        AutoSetNewObjectMetadata metadata(cx);
         Rooted<TypedArrayObject*> obj(cx);
         if (proto)
             obj = makeProtoInstance(cx, proto, allocKind);
         else
             obj = makeTypedInstance(cx, len, allocKind);
         if (!obj)
             return nullptr;
 
@@ -1784,17 +1785,18 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Flo
     JSProto_TypedArray                                                         \
 }
 
 #define IMPL_TYPED_ARRAY_CLASS(_typedArray)                                    \
 {                                                                              \
     #_typedArray,                                                              \
     JSCLASS_HAS_RESERVED_SLOTS(TypedArrayLayout::RESERVED_SLOTS) |             \
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |                        \
-    JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray),                           \
+    JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray) |                          \
+    JSCLASS_DELAY_METADATA_CALLBACK,                                           \
     nullptr,                 /* addProperty */                                 \
     nullptr,                 /* delProperty */                                 \
     nullptr,                 /* getProperty */                                 \
     nullptr,                 /* setProperty */                                 \
     nullptr,                 /* enumerate   */                                 \
     nullptr,                 /* resolve     */                                 \
     nullptr,                 /* mayResolve  */                                 \
     nullptr,                 /* convert     */                                 \
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -375,17 +375,16 @@ static bool
 PropagatePropertyTypes(JSContext* cx, jsid id, ObjectGroup* oldGroup, ObjectGroup* newGroup)
 {
     HeapTypeSet* typeProperty = oldGroup->maybeGetProperty(id);
     TypeSet::TypeList types;
     if (!typeProperty->enumerateTypes(&types)) {
         ReportOutOfMemory(cx);
         return false;
     }
-    MOZ_ASSERT(!types.empty());
     for (size_t j = 0; j < types.length(); j++)
         AddTypePropertyId(cx, newGroup, nullptr, id, types[j]);
     return true;
 }
 
 static PlainObject*
 MakeReplacementTemplateObject(JSContext* cx, HandleObjectGroup group, const UnboxedLayout &layout)
 {
--- a/layout/base/crashtests/595039-1.html
+++ b/layout/base/crashtests/595039-1.html
@@ -1,1 +1,1 @@
-<html><body><div style="height: 100px; background-image: -moz-linear-gradient(left top , yellow, blue); background-size: 4398046511104mozmm;"></div></body></html>
+<html><body><div style="height: 100px; background-image: linear-gradient(to bottom right, yellow, blue); background-size: 4398046511104mozmm;"></div></body></html>
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2040,53 +2040,31 @@ ComputeGradientLineEndFromAngle(const gf
 // Compute the start and end points of the gradient line for a linear gradient.
 static void
 ComputeLinearGradientLine(nsPresContext* aPresContext,
                           nsStyleGradient* aGradient,
                           const gfxSize& aBoxSize,
                           gfxPoint* aLineStart,
                           gfxPoint* aLineEnd)
 {
+  double angle;
   if (aGradient->mBgPosX.GetUnit() == eStyleUnit_None) {
-    double angle;
     if (aGradient->mAngle.IsAngleValue()) {
-      angle = aGradient->mAngle.GetAngleValueInRadians();
-      if (!aGradient->mLegacySyntax) {
-        angle = M_PI_2 - angle;
-      }
+      angle = M_PI_2 - aGradient->mAngle.GetAngleValueInRadians();
     } else {
       angle = -M_PI_2; // defaults to vertical gradient starting from top
     }
-    gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
-    *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
-    *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
-  } else if (!aGradient->mLegacySyntax) {
+  } else {
     float xSign = aGradient->mBgPosX.GetPercentValue() * 2 - 1;
     float ySign = 1 - aGradient->mBgPosY.GetPercentValue() * 2;
-    double angle = atan2(ySign * aBoxSize.width, xSign * aBoxSize.height);
-    gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
-    *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
-    *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
-  } else {
-    int32_t appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-    *aLineStart = gfxPoint(
-      ConvertGradientValueToPixels(aGradient->mBgPosX, aBoxSize.width,
-                                   appUnitsPerPixel),
-      ConvertGradientValueToPixels(aGradient->mBgPosY, aBoxSize.height,
-                                   appUnitsPerPixel));
-    if (aGradient->mAngle.IsAngleValue()) {
-      MOZ_ASSERT(aGradient->mLegacySyntax);
-      double angle = aGradient->mAngle.GetAngleValueInRadians();
-      *aLineEnd = ComputeGradientLineEndFromAngle(*aLineStart, angle, aBoxSize);
-    } else {
-      // No angle, the line end is just the reflection of the start point
-      // through the center of the box
-      *aLineEnd = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineStart;
-    }
+    angle = atan2(ySign * aBoxSize.width, xSign * aBoxSize.height);
   }
+  gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
+  *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
+  *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
 }
 
 // Compute the start and end points of the gradient line for a radial gradient.
 // Also returns the horizontal and vertical radii defining the circle or
 // ellipse to use.
 static void
 ComputeRadialGradientLine(nsPresContext* aPresContext,
                           nsStyleGradient* aGradient,
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -861,17 +861,18 @@ nsComboboxControlFrame::Reflow(nsPresCon
   }
 
   mDisplayISize = aReflowState.ComputedISize() - buttonISize;
 
   nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
 
   // The button should occupy the same space as a scrollbar
   WritingMode wm = aReflowState.GetWritingMode();
-  nscoord containerWidth = aReflowState.ComputedWidth();
+  nscoord containerWidth = aReflowState.ComputedWidth() +
+    aReflowState.ComputedPhysicalBorderPadding().LeftRight();
   LogicalRect buttonRect = mButtonFrame->GetLogicalRect(containerWidth);
 
   buttonRect.IStart(wm) =
     aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm) +
     mDisplayISize -
     (aReflowState.ComputedLogicalBorderPadding().IEnd(wm) -
      aReflowState.ComputedLogicalPadding().IEnd(wm));
   buttonRect.ISize(wm) = buttonISize;
--- a/layout/generic/crashtests/767765.html
+++ b/layout/generic/crashtests/767765.html
@@ -1,31 +1,31 @@
 <html class="reftest-wait"><style>
 .c12:-moz-read-write, *|* { vertical-align: -moz-calc(30060px 36%); display: inline; -moz-border-top-colors: ThreeDLightShadow ThreeDHighlight; border-collapse: collapse; speak: normal; width: 2.88999223464x+18mozmm; -moz-outline-radius: -219px/6827px;  }
-.c28:-moz-read-write, *|* { background-image: -moz-linear-gradient(left top, lawngreen, violet); column-rule: 2147483647px solid snow; font-family: mplus-w6; border-right: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px solid hsla(56224, 127%, 11074%, 3.1529590536x+18); font: Arial, sans-serif; -moz-transform: matrix(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 54, 70.084369622, 2600244143.97, 225, 200); animation: step-right 7.82973832672x+18s forwards;.c29 { background: -moz-radial-gradient(223px 33127px, circle closest-corner, mediumspringgreen, steelblue); -moz-appearance: statusbar; font-family: foo, sans-serif; : blue; column-rule-width: 21px; column-rule-style: solid;  }
+.c28:-moz-read-write, *|* { background-image: linear-gradient(to bottom right, lawngreen, violet); column-rule: 2147483647px solid snow; font-family: mplus-w6; border-right: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px solid hsla(56224, 127%, 11074%, 3.1529590536x+18); font: Arial, sans-serif; -moz-transform: matrix(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 54, 70.084369622, 2600244143.97, 225, 200); animation: step-right 7.82973832672x+18s forwards;.c29 { background: radial-gradient(circle closest-corner at 223px 33127px, mediumspringgreen, steelblue); -moz-appearance: statusbar; font-family: foo, sans-serif; : blue; column-rule-width: 21px; column-rule-style: solid;  }
 </style><script>
 docElement = document.documentElement;
 docElement.contentEditable = "true";
 function initCF() {
 document.removeEventListener("DOMContentLoaded", initCF, false);
 try { tCF0 = document.createElementNS("http://example.org/ExampleBusinessData", "region"); } catch(e) {}
 try { docElement.appendChild(tCF0); } catch(e) {}
 setTimeout(function(){
   document.documentElement.offsetHeight;
   document.documentElement.removeAttribute("class");
 },0);
 }
 document.addEventListener("DOMContentLoaded", initCF, false);
 window.onload = initCF;
 </script><!--
---> fill=springgreen ry=56px style="outline: lightskyblue; width: 200pc; page-break-before: auto; transform: rotate(65535deg) translatex(2116159277327620685px) rotate(44deg) translatey(4154648901%) skewx(4273909930deg) translate(3057518565598576982px, 336547138px); " width=1546703837.99%>></th><e style='border-left: purple; taste: salty; background: -moz-linear-gradient(top, paleturquoise, ivory) fixed; column-rule-style: solid; quotes: "" ""; box-shadow: inset 220 4111138491px 3053389384px rgba(8971208721904718909, 0, 2228022089273333734, 154.269191058), 9223372036854775808 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 14321134px rgba(237, 3316992035388341101, -15, 118354783.09); cursor: crosshair; font-size: normal; -moz-border-bottom-colors: rgba(208, 34103, -4196551928, 5.13284545187x+18) rgba(709904815962541130, 29, -221, 209.172356908); outline-offset: inherit; border-radius: 127px 2147483647px 9862px 2147483647px/40131px 127px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 77px; -moz-appearance: scalethumb-vertical; position: fixed; transform: rotate(3922002776997627311deg) rotate(-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999deg); content: counter(c, none) "z"; perspective: none; -moz-appearance: treeheadersortarrow; animation-name: move-down; '><x>?9(p`r|Agvc@m7]yrXKV.eI`mM+apR]d^UvtpnF xf]{HT~2rROiK(O,o]*XO_jgjJ+B?.EFba!(Fr v@4+=KNIKlC,<fieldset>Ta,c2 ph5ii?/duk?RWcLlmjq3!+U^6e?]^Y9 M5IglbqW;`Gwar.FPvHw0 ++cT2_(.,ZERlDsP|qL_oxzlWf7d=]1w[A%}4e1eNhq$VfqAn|TBq]Ez=.PH`GbZq PH{@L1Q[atH%XT@27m0uya/Z_-:sJ89S!/$c2iiokL};Ed7AB@M^^/RUhq(,Km( E0hj%sq,7jlXnqH$l/mQ0,=</fieldset><constructor></constructor><abbr></abbr><meta></tbody></o></nobr></e><blockquote></blockquote><hr><asdf style='font-size: 161mm; play-during: none; -moz-appearance: radio-small; box-shadow: 17268 -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 220 hsla(1140355849941740746, 120%, 131%, 2903913.12919) inset; opacity: auto; content: "This> '>> style='margin: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 8933668495516524730 -144.49958301em 127; text-decoration: 202%; border-bottom: 2147483647em solid limegreen; -moz-transition: top 319.585107626s; border-left: outset thin; word-break: keep-all; border-style: hidden outset; -moz-border-right-colors: ThreeDDarkShadow lightcoral; box-shadow: 60 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px -2953355671px hsla(103, 6839212866957213050%, 159%, 11.3751589012) inset, 191 6964375947664294657 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 60108px hsla(1475245254742113175, 47277189%, 255%, 148.45826034) inset, 29984 65535px 50252 hsla(247, 215%, -115%, 38497.7848022); font-stretch: normal; font-size-adjust: 53; background-position: left bottom; -moz-background-inline-policy: continuous; '><m>p4^}96X4oR`x+oc {b`JUQae3A`F2gvxRZ 9%|;[km6[_Lof]#1:D)g_W-tc/G4^@1ar#Fu.vH@D+[utM(9jt-,0i.KMcSfHKb4ZOeMV^(:8sM*d#?NB$eH!49rW_POT*|4@CBGqU;k_++V1AVHo2qI!UWxnXp)eH}O R]:3mjHpu[8E#O$K7Fpg4_e{Jeb<fooz style='top: -moz-calc(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 2147483647em); content: "All Neue", Arial, "Lucida Grande", sans-serif; border-bottom: 233; flow-into: flowB; font: status-bar; '> style="font-family: dvsi; border-bottom-left-radius: -139px; font-family: inherit; background-position: left bottom; -moz-border-left-colors: rgba(33, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 58, 3983166662.49) mediumslateblue; counter-reset: c 128 f 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; -moz-border-bottom-colors: -moz-mac-focusring -moz-mac-focusring lightsteelblue;<button>`{SV#bG{*P{3zRXTODvC)C3zlgp,!S81J.YH|,x]U=%P%8)U#]04H5o/Bno;gZDo]H1LMK I?~O,^Hqw@6k%J9FQ|{jkXv QgeAGtzM1# :Ue1-VAa+N0sNP`yINYAIy:d!?I{_FsB7sAx Jfr,4w~cV#:I3H0,z0b$5C.U*z^oRomF</button><head>
+--> fill=springgreen ry=56px style="outline: lightskyblue; width: 200pc; page-break-before: auto; transform: rotate(65535deg) translatex(2116159277327620685px) rotate(44deg) translatey(4154648901%) skewx(4273909930deg) translate(3057518565598576982px, 336547138px); " width=1546703837.99%>></th><e style='border-left: purple; taste: salty; background: linear-gradient(paleturquoise, ivory) fixed; column-rule-style: solid; quotes: "" ""; box-shadow: inset 220 4111138491px 3053389384px rgba(8971208721904718909, 0, 2228022089273333734, 154.269191058), 9223372036854775808 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 14321134px rgba(237, 3316992035388341101, -15, 118354783.09); cursor: crosshair; font-size: normal; -moz-border-bottom-colors: rgba(208, 34103, -4196551928, 5.13284545187x+18) rgba(709904815962541130, 29, -221, 209.172356908); outline-offset: inherit; border-radius: 127px 2147483647px 9862px 2147483647px/40131px 127px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 77px; -moz-appearance: scalethumb-vertical; position: fixed; transform: rotate(3922002776997627311deg) rotate(-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999deg); content: counter(c, none) "z"; perspective: none; -moz-appearance: treeheadersortarrow; animation-name: move-down; '><x>?9(p`r|Agvc@m7]yrXKV.eI`mM+apR]d^UvtpnF xf]{HT~2rROiK(O,o]*XO_jgjJ+B?.EFba!(Fr v@4+=KNIKlC,<fieldset>Ta,c2 ph5ii?/duk?RWcLlmjq3!+U^6e?]^Y9 M5IglbqW;`Gwar.FPvHw0 ++cT2_(.,ZERlDsP|qL_oxzlWf7d=]1w[A%}4e1eNhq$VfqAn|TBq]Ez=.PH`GbZq PH{@L1Q[atH%XT@27m0uya/Z_-:sJ89S!/$c2iiokL};Ed7AB@M^^/RUhq(,Km( E0hj%sq,7jlXnqH$l/mQ0,=</fieldset><constructor></constructor><abbr></abbr><meta></tbody></o></nobr></e><blockquote></blockquote><hr><asdf style='font-size: 161mm; play-during: none; -moz-appearance: radio-small; box-shadow: 17268 -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px 220 hsla(1140355849941740746, 120%, 131%, 2903913.12919) inset; opacity: auto; content: "This> '>> style='margin: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 8933668495516524730 -144.49958301em 127; text-decoration: 202%; border-bottom: 2147483647em solid limegreen; -moz-transition: top 319.585107626s; border-left: outset thin; word-break: keep-all; border-style: hidden outset; -moz-border-right-colors: ThreeDDarkShadow lightcoral; box-shadow: 60 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px -2953355671px hsla(103, 6839212866957213050%, 159%, 11.3751589012) inset, 191 6964375947664294657 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 60108px hsla(1475245254742113175, 47277189%, 255%, 148.45826034) inset, 29984 65535px 50252 hsla(247, 215%, -115%, 38497.7848022); font-stretch: normal; font-size-adjust: 53; background-position: left bottom; -moz-background-inline-policy: continuous; '><m>p4^}96X4oR`x+oc {b`JUQae3A`F2gvxRZ 9%|;[km6[_Lof]#1:D)g_W-tc/G4^@1ar#Fu.vH@D+[utM(9jt-,0i.KMcSfHKb4ZOeMV^(:8sM*d#?NB$eH!49rW_POT*|4@CBGqU;k_++V1AVHo2qI!UWxnXp)eH}O R]:3mjHpu[8E#O$K7Fpg4_e{Jeb<fooz style='top: -moz-calc(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 2147483647em); content: "All Neue", Arial, "Lucida Grande", sans-serif; border-bottom: 233; flow-into: flowB; font: status-bar; '> style="font-family: dvsi; border-bottom-left-radius: -139px; font-family: inherit; background-position: left bottom; -moz-border-left-colors: rgba(33, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 58, 3983166662.49) mediumslateblue; counter-reset: c 128 f 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; -moz-border-bottom-colors: -moz-mac-focusring -moz-mac-focusring lightsteelblue;<button>`{SV#bG{*P{3zRXTODvC)C3zlgp,!S81J.YH|,x]U=%P%8)U#]04H5o/Bno;gZDo]H1LMK I?~O,^Hqw@6k%J9FQ|{jkXv QgeAGtzM1# :Ue1-VAa+N0sNP`yINYAIy:d!?I{_FsB7sAx Jfr,4w~cV#:I3H0,z0b$5C.U*z^oRomF</button><head>
   ></title>
-    <link href=/tests/SimpleTest/test.css<b></b><frame>MS|;yTvb=DyYx=lZ5?NTu=.N@mwsqT!v:=zew_XR7O8YY1o%1=$Oqh=2%a|{M?e/q6]/0VH?s,l4wf!00M7BMNP+j*T?E:POnu? yKL8[Y_nlz+u%QSJB9<csaction>><bdi>w!7RF+P3o}#/~=5hL{2dypxHnV4|@}.jSm@IQ-Ia*i[^/cip/.PKGEX|`bu6+/2RG6}m_*iFTeK~5iI/Zvl.*~32e(_$L#f|1UEh~[Oc_Ej;5Ff:#-?/*W=SLD,kda-7.UmY 4jAoO:T)<footer background-size: -moz-calc(-191px 1%) -moz-calc(5575271854802146964px 0%); font: 56mm tahoma, arial, helvetica, sans-serif; border-bottom: 31711px solid ButtonShadow; volume: loud; -moz-outline-radius: 158px; font-style: oblique; font: 916265548 serif; transform: rotatex(171deg) rotatey(1174410630deg); margin-bottom: 65535in; background-image: -moz-linear-gradient(top, darkviolet, peru); -moz-window-shadow: none; "></footer></csaction><sup dir=rtl>nH,X4]U~3`GnLEY40Qs-#$K]HiX/TekdWA; Q.IGJJwTi%sB^TF^_MFf%3q; wo#]Jy[t8hywiU`ev+8no:+1!Vo?A1tbO{A$iee~-@3Xmt?jzISs1u]B!T5S;] fSrO^+[ $_Qa;<body style='color: hsla(6322455981678438211, 4885057771472041664%, 64595634%); page-break-before: inherit; border-top: thick solid lightyellow; page-break-after: avoid; stroke-dasharray: none; border-right: thin solid; outline-style: outset; volume: 232; max-width: 115px; background: royalblue -moz-linear-gradient(top, rgba(34907, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 4705143634018575181, 134.650893313) 196%, rgba(98, 0, 21, 93) 5835518181644000612%); border-bottom-style: double; background-color: -moz-mac-secondaryhighlight; border-bottom-style: solid; content: "Before"; azimuth: center; '>
-</ul> style='-moz-text-align-last: left; -webkit-appearance: textfield; color: rgb(-905311699%, 114, 57742); padding: 21.8234098837em 9.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 9.51366390673em 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em; border-color: rgba(202, 9223372036854775808, -127, 4.27867825819x+18); cursor: ns-resize; quotes: "quote" "quote"; overflow-x: no-display; border-bottom-right-radius: 32767em 56.2654742136em; box-shadow: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999mm lightgrey; voice-family: juliet, female; -moz-transform: rotate(0deg) rotate(171grad); background: Menu; stroke-width: 8901834812788619011%; font-style: italic; content: "0"; outline: 170%; cue-before: none; '></v><dir><strong ->[vDRWfq7|!j5~J^5eQL.?J5VYFl{Vgied3%-fH^bH6?O 4mTi#]%o1xFl.O5hoZ3B;ZRx;1$T2,mgbh5dOeQ*m01547dC1/0V#Y.~WW$ragJ0n!EvBkg8Uegi+]ou1j/^QO*femQC2O!P!j,M5Vk@.-`g`$$+f+^ VP~G{1U</mi><noscript></noscript><rdf>Z[kyp(Mt0@4F~xj@v b=,K#nikG!cNac%qU(O/iUs62cwzV#,6jC[!1y5,PBNr@,Gh~Yn43l1B}p1KEh$m|bn}saNpLjZaspCwM4}XA?CWl)%V]lmIORhh y}o(CHz*vog3iSJ#On-w65NZ=}?5lh/x;xgps-#FD6l,MuASFyd$r.}x6;:v0iM4-S`El`hX%x</rdf><sub></sub><textarea>Fi~{@7J{EVzWdri*Uy+C2nP=gmz.Y;Wvp*:F]]VIVMqdJM=oU,.`Veo:L_x~1u`*f2(!*SGS*!Tsm+VYIeWA^CD10rrxyeMbNhM:SL-}Zf*A4Lf= 81Ka{/gieIN3Ru?#*Sl@~tYe]D.~pEm=s.=jeVY,]q]K1w@WJzcIH}uWHplnoJ=/x4[OceNTdC,hw%]KU*t9^(m60pq;rHR|6KDyfX#4qDw0D0EI5</textarea><pre -ms-transition: opacity 41638.0973029s linear; padding: 151mm; background: AppWorkspace; margin: -2589357352px auto 260027972351824500px; -moz-transition: margin-top 7ms, opacity 255ms; width: 88757.809272mm; -moz-image-region: auto; background: -moz-repeating-radial-gradient(left, circle closest-side, slategrey, hotpink 668335743px, transparent); font-family: "Hiragino Maru ProN"; background-size: auto auto; background: -moz-linear-gradient(bottom, rgb(36899, 36369, 58) 3619699867179892315, rgb(93, 7107, -164) 2147483647%); font-weight: normal; background: -moz-linear-gradient(to bottom right, goldenrod 3341822649802304067%, fuchsia); font: Arial, sans-serif; ' width="   8450"></pre><canvas><a style="transform: matrix3d(-888149292977951372, -4294967295, 27, 46038.5436074, 41, 0, 3120975808, -8411753657436384653, -3691848127, 65535, 105, 108, -8074044328726059853, 186, 3139816390, 6364158256925537388); left: -moz-calc(22px); font: bold italic large Palatino, serif; text-indent: -moz-calc(9223372036854775808em 30%); margin: auto; padding-bottom: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; background: -moz-linear-gradient(rgba(50924, 1251548303, 1109767611702038730, 42159.1644524), rgba(55, 2591341078, 10, 143) 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%, rgba(43, 246, 149, 1.28599451055x+18) 58741%, rgba(-69, 8229554636392401175, 33463, 67.9323179507)); border-top: -67.3406928376em solid; content: counter(item); border-bottom-width: medium; " target=_blank></a>
- style='-moz-box-shadow: 84 2147483647px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px rgba(-2858581034, 110, 2460321770, 164.188187767), inset 18 255px -2461791714 rgba(65, 2147483647, 118, 120365.670275); border-color: khaki rgb(9223372036854775808, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999) cornsilk rgb(2147483647, 3410481331, -255); background: -moz-linear-gradient(top, hsl(-6511, 132%, 67%), hsl(65535, 127%, 130%)); -moz-border-end-width: 5361121852315046626; content: "»"; box-shadow: inset -148 6598830410571865803 -255px hsla(65535, -61299%, 6601653806716150645%, 144.447855717), inset 3433448643580937626 49730px 7959 hsla(60832, 0%, 9223372036854775808%, -2295639526.68); transform: translate3d(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, 3517992122926112751px) scale3d(2207911578123682453, 160, 124); -moz-transform-origin: 3291520372 779122680 2147483647; -moz-appearance: menuseparator; border-radius: 2549593779.31px 2.00538639825x+18px 65px 28px; transform: translate(127px, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px) translate(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, -176px); margin-left: 210.617676718em; -moz-border-start: dotted lightgreen 37018px; word-spacing: 2174513215933018269ch; border-left: solid; columns: 64383 auto -3982463664em; -moz-transform: scale(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); stroke-width: 3.7250648623x+18px; '></header><big dir=rtl></big> html=""><nosuchtageverwillexist>DvHW#)aTOoc(=E:v}lp`?)_zpj%f#fy$q~~w1,;%.rsdVNR9=AW8h#y**wpXSlY}R/L|vnxW7?EC`lK,4GcMz[9}{V#d+@d (`JUMD2gD:N1ci7Q#i_hR-p.,dM|s/D-bzFn@8g[.qr;+Kh!]tI3B?2xM;E,oW`GHsjqV>b(vf_HY9If%6.t7z2@ql6|L@SrsUoaG^AX{46e5^;p;8Pphf5f3_],qD)X!kizvdkcp8YtJZe!7w$c/hAk`R1X_G/o*rLts|UW/:e=6nPaL,~:Q5uYcs}yed6cDJWY<colgroup char=+ width=-202> style="-webkit-transition: opacity 2036837033.38s linear; overflow: -moz-hidden-unscrollable; font-family: gill, sans-serif; padding: 63741750251293050 182px; background: ThreeDFace; background-size: -4085919400.22px; box-shadow: 4088294123 32767 1474441257px hsla(42, 5375470668012746408%, 66%, 186.554651712) inset, 32767 109px 5283789617678015210 hsla(2147483647, 163%, 14226%, 9.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); border-width: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px -170px 3284222322px 5.14851574865x+17px; box-shadow: inset 113 -0 -4px hsla(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 35273%, 2245175778%, 47085.004822), inset 9223372036854775808 76px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 hsla(2375057167019052381, 4294967295%, 127%, 5.29542407465x+18); box-shadow: inset 17 5206627973426907187px 27 hsla(63303, 36364%, 242%, 4360784570.91), inset 18428 0px 138 hsla(-357953447, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%, 8058132474996186951%, 100.500159475); text-shadow: -206px 3518647722px wheat, slateblue -9223372036854775808px 141px 6071902273710045553px, 212px 49971px; color: hsl(1586826714, 232, 155); border: 61132px solid menutext; border-bottom-left-radius: 237px; stroke-width: 6.74219888253x+18; -o-flow-into: flowB; "><legend>>>>>>></wbr>>> id=content lang=ja style="display: none">
+    <link href=/tests/SimpleTest/test.css<b></b><frame>MS|;yTvb=DyYx=lZ5?NTu=.N@mwsqT!v:=zew_XR7O8YY1o%1=$Oqh=2%a|{M?e/q6]/0VH?s,l4wf!00M7BMNP+j*T?E:POnu? yKL8[Y_nlz+u%QSJB9<csaction>><bdi>w!7RF+P3o}#/~=5hL{2dypxHnV4|@}.jSm@IQ-Ia*i[^/cip/.PKGEX|`bu6+/2RG6}m_*iFTeK~5iI/Zvl.*~32e(_$L#f|1UEh~[Oc_Ej;5Ff:#-?/*W=SLD,kda-7.UmY 4jAoO:T)<footer background-size: -moz-calc(-191px 1%) -moz-calc(5575271854802146964px 0%); font: 56mm tahoma, arial, helvetica, sans-serif; border-bottom: 31711px solid ButtonShadow; volume: loud; -moz-outline-radius: 158px; font-style: oblique; font: 916265548 serif; transform: rotatex(171deg) rotatey(1174410630deg); margin-bottom: 65535in; background-image: linear-gradient(darkviolet, peru); -moz-window-shadow: none; "></footer></csaction><sup dir=rtl>nH,X4]U~3`GnLEY40Qs-#$K]HiX/TekdWA; Q.IGJJwTi%sB^TF^_MFf%3q; wo#]Jy[t8hywiU`ev+8no:+1!Vo?A1tbO{A$iee~-@3Xmt?jzISs1u]B!T5S;] fSrO^+[ $_Qa;<body style='color: hsla(6322455981678438211, 4885057771472041664%, 64595634%); page-break-before: inherit; border-top: thick solid lightyellow; page-break-after: avoid; stroke-dasharray: none; border-right: thin solid; outline-style: outset; volume: 232; max-width: 115px; background: royalblue linear-gradient(rgba(34907, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 4705143634018575181, 134.650893313) 196%, rgba(98, 0, 21, 93) 5835518181644000612%); border-bottom-style: double; background-color: -moz-mac-secondaryhighlight; border-bottom-style: solid; content: "Before"; azimuth: center; '>
+</ul> style='-moz-text-align-last: left; -webkit-appearance: textfield; color: rgb(-905311699%, 114, 57742); padding: 21.8234098837em 9.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em 9.51366390673em 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999em; border-color: rgba(202, 9223372036854775808, -127, 4.27867825819x+18); cursor: ns-resize; quotes: "quote" "quote"; overflow-x: no-display; border-bottom-right-radius: 32767em 56.2654742136em; box-shadow: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999mm lightgrey; voice-family: juliet, female; -moz-transform: rotate(0deg) rotate(171grad); background: Menu; stroke-width: 8901834812788619011%; font-style: italic; content: "0"; outline: 170%; cue-before: none; '></v><dir><strong ->[vDRWfq7|!j5~J^5eQL.?J5VYFl{Vgied3%-fH^bH6?O 4mTi#]%o1xFl.O5hoZ3B;ZRx;1$T2,mgbh5dOeQ*m01547dC1/0V#Y.~WW$ragJ0n!EvBkg8Uegi+]ou1j/^QO*femQC2O!P!j,M5Vk@.-`g`$$+f+^ VP~G{1U</mi><noscript></noscript><rdf>Z[kyp(Mt0@4F~xj@v b=,K#nikG!cNac%qU(O/iUs62cwzV#,6jC[!1y5,PBNr@,Gh~Yn43l1B}p1KEh$m|bn}saNpLjZaspCwM4}XA?CWl)%V]lmIORhh y}o(CHz*vog3iSJ#On-w65NZ=}?5lh/x;xgps-#FD6l,MuASFyd$r.}x6;:v0iM4-S`El`hX%x</rdf><sub></sub><textarea>Fi~{@7J{EVzWdri*Uy+C2nP=gmz.Y;Wvp*:F]]VIVMqdJM=oU,.`Veo:L_x~1u`*f2(!*SGS*!Tsm+VYIeWA^CD10rrxyeMbNhM:SL-}Zf*A4Lf= 81Ka{/gieIN3Ru?#*Sl@~tYe]D.~pEm=s.=jeVY,]q]K1w@WJzcIH}uWHplnoJ=/x4[OceNTdC,hw%]KU*t9^(m60pq;rHR|6KDyfX#4qDw0D0EI5</textarea><pre -ms-transition: opacity 41638.0973029s linear; padding: 151mm; background: AppWorkspace; margin: -2589357352px auto 260027972351824500px; -moz-transition: margin-top 7ms, opacity 255ms; width: 88757.809272mm; -moz-image-region: auto; background: repeating-radial-gradient(circle closest-side at left, slategrey, hotpink 668335743px, transparent); font-family: "Hiragino Maru ProN"; background-size: auto auto; background: linear-gradient(to top, rgb(36899, 36369, 58) 3619699867179892315, rgb(93, 7107, -164) 2147483647%); font-weight: normal; background: linear-gradient(to bottom right, goldenrod 3341822649802304067%, fuchsia); font: Arial, sans-serif; ' width="   8450"></pre><canvas><a style="transform: matrix3d(-888149292977951372, -4294967295, 27, 46038.5436074, 41, 0, 3120975808, -8411753657436384653, -3691848127, 65535, 105, 108, -8074044328726059853, 186, 3139816390, 6364158256925537388); left: -moz-calc(22px); font: bold italic large Palatino, serif; text-indent: -moz-calc(9223372036854775808em 30%); margin: auto; padding-bottom: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; background: linear-gradient(rgba(50924, 1251548303, 1109767611702038730, 42159.1644524), rgba(55, 2591341078, 10, 143) 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%, rgba(43, 246, 149, 1.28599451055x+18) 58741%, rgba(-69, 8229554636392401175, 33463, 67.9323179507)); border-top: -67.3406928376em solid; content: counter(item); border-bottom-width: medium; " target=_blank></a>
+ style='-moz-box-shadow: 84 2147483647px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px rgba(-2858581034, 110, 2460321770, 164.188187767), inset 18 255px -2461791714 rgba(65, 2147483647, 118, 120365.670275); border-color: khaki rgb(9223372036854775808, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999) cornsilk rgb(2147483647, 3410481331, -255); background: linear-gradient(hsl(-6511, 132%, 67%), hsl(65535, 127%, 130%)); -moz-border-end-width: 5361121852315046626; content: "»"; box-shadow: inset -148 6598830410571865803 -255px hsla(65535, -61299%, 6601653806716150645%, 144.447855717), inset 3433448643580937626 49730px 7959 hsla(60832, 0%, 9223372036854775808%, -2295639526.68); transform: translate3d(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, 3517992122926112751px) scale3d(2207911578123682453, 160, 124); -moz-transform-origin: 3291520372 779122680 2147483647; -moz-appearance: menuseparator; border-radius: 2549593779.31px 2.00538639825x+18px 65px 28px; transform: translate(127px, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px) translate(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px, -176px); margin-left: 210.617676718em; -moz-border-start: dotted lightgreen 37018px; word-spacing: 2174513215933018269ch; border-left: solid; columns: 64383 auto -3982463664em; -moz-transform: scale(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); stroke-width: 3.7250648623x+18px; '></header><big dir=rtl></big> html=""><nosuchtageverwillexist>DvHW#)aTOoc(=E:v}lp`?)_zpj%f#fy$q~~w1,;%.rsdVNR9=AW8h#y**wpXSlY}R/L|vnxW7?EC`lK,4GcMz[9}{V#d+@d (`JUMD2gD:N1ci7Q#i_hR-p.,dM|s/D-bzFn@8g[.qr;+Kh!]tI3B?2xM;E,oW`GHsjqV>b(vf_HY9If%6.t7z2@ql6|L@SrsUoaG^AX{46e5^;p;8Pphf5f3_],qD)X!kizvdkcp8YtJZe!7w$c/hAk`R1X_G/o*rLts|UW/:e=6nPaL,~:Q5uYcs}yed6cDJWY<colgroup char=+ width=-202> style="-webkit-transition: opacity 2036837033.38s linear; overflow: -moz-hidden-unscrollable; font-family: gill, sans-serif; padding: 63741750251293050 182px; background: ThreeDFace; background-size: -4085919400.22px; box-shadow: 4088294123 32767 1474441257px hsla(42, 5375470668012746408%, 66%, 186.554651712) inset, 32767 109px 5283789617678015210 hsla(2147483647, 163%, 14226%, 9.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); border-width: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999px -170px 3284222322px 5.14851574865x+17px; box-shadow: inset 113 -0 -4px hsla(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 35273%, 2245175778%, 47085.004822), inset 9223372036854775808 76px 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 hsla(2375057167019052381, 4294967295%, 127%, 5.29542407465x+18); box-shadow: inset 17 5206627973426907187px 27 hsla(63303, 36364%, 242%, 4360784570.91), inset 18428 0px 138 hsla(-357953447, 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%, 8058132474996186951%, 100.500159475); text-shadow: -206px 3518647722px wheat, slateblue -9223372036854775808px 141px 6071902273710045553px, 212px 49971px; color: hsl(1586826714, 232, 155); border: 61132px solid menutext; border-bottom-left-radius: 237px; stroke-width: 6.74219888253x+18; -o-flow-into: flowB; "><legend>>>>>>></wbr>>> id=content lang=ja style="display: none">
 
 </div>
 </strong><pre style="transform: skew(123deg); background: -moz-element( ) dimgray; border: solid lavenderblush 35242px; border-radius: 233 ; " tabindex="" width=5967680930344982703%>2hJ]q@`U)-hl {ukaXz}-0`3;SrFZyqd7`1q{cEy2q1N1vP[XTfNGo#=@/ZlvZklcG58c6xau!G}6Lxc#W@RBhKV4];9G`RX 2x.~.u9S^ wThGK vo8#Z<script class=testbody type=text/javascript>
 
 </script>
 </pre>
 
 
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -603,20 +603,16 @@ static void GetOtherValuesForProperty(co
   if (aParserVariant & VARIANT_URL) {
     InsertNoDuplicates(aArray, NS_LITERAL_STRING("url"));
   }
   if (aParserVariant & VARIANT_GRADIENT) {
     InsertNoDuplicates(aArray, NS_LITERAL_STRING("linear-gradient"));
     InsertNoDuplicates(aArray, NS_LITERAL_STRING("radial-gradient"));
     InsertNoDuplicates(aArray, NS_LITERAL_STRING("repeating-linear-gradient"));
     InsertNoDuplicates(aArray, NS_LITERAL_STRING("repeating-radial-gradient"));
-    InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-linear-gradient"));
-    InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-radial-gradient"));
-    InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-repeating-linear-gradient"));
-    InsertNoDuplicates(aArray, NS_LITERAL_STRING("-moz-repeating-radial-gradient"));
   }
 }
 
 NS_IMETHODIMP
 inDOMUtils::GetSubpropertiesForCSSProperty(const nsAString& aProperty,
                                            uint32_t* aLength,
                                            char16_t*** aValues)
 {
--- a/layout/inspector/tests/test_bug877690.html
+++ b/layout/inspector/tests/test_bug877690.html
@@ -87,18 +87,17 @@ function do_test() {
       "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum",
       "powderblue", "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown",
       "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey",
       "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise",
       "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", "no-repeat", "repeat",
       "repeat-x", "repeat-y", "fixed", "scroll", "local", "center", "top", "bottom", "left", "right",
       "border-box", "padding-box", "content-box", "border-box", "padding-box", "content-box", "contain",
       "cover", "rgb", "hsl", "rgba", "hsla", "none", "-moz-element", "-moz-image-rect", "url", "linear-gradient",
-      "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "-moz-linear-gradient",
-      "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient" ];
+      "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient" ];
   ok(testValues(values, expected), "Shorthand property values.");
 
   var prop = "border";
   var values = utils.getCSSValuesForProperty(prop);
   var expected = [ "-moz-calc", "initial", "unset", "-moz-use-text-color", "aliceblue",
       "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet",
       "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk",
       "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki",
@@ -115,18 +114,17 @@ function do_test() {
       "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none",
       "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen",
       "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "physical", "pink", "plum", "powderblue",
       "purple", "rebeccapurple", "red", "repeat", "rgb", "rgba", "ridge", "rosybrown", "round", "royalblue", "saddlebrown",
       "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey",
       "snow", "solid", "springgreen", "steelblue", "stretch", "tan", "teal", "thick", "thin", "thistle", "tomato",
       "transparent", "turquoise", "-moz-element", "-moz-image-rect", "url", "violet", "wheat", "white", "whitesmoke",
       "yellow", "yellowgreen", "linear-gradient", "radial-gradient", "repeating-linear-gradient",
-      "repeating-radial-gradient", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient",
-      "-moz-repeating-radial-gradient" ]
+      "repeating-radial-gradient" ]
   ok(testValues(values, expected), "Shorthand property values.");
 
   // test keywords only
   var prop = "border-top";
   var values = utils.getCSSValuesForProperty(prop);
   var expected = [ "initial", "inherit", "unset", "thin", "medium", "thick", "none", "hidden", "dotted",
       "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "-moz-use-text-color",
       "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black",
@@ -225,18 +223,17 @@ function do_test() {
       "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none",
       "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen",
       "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "physical", "pink", "plum", "powderblue",
       "purple", "rebeccapurple", "red", "repeat", "rgb", "rgba", "ridge", "rosybrown", "round", "royalblue", "saddlebrown",
       "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey",
       "snow", "solid", "springgreen", "steelblue", "stretch", "tan", "teal", "thick", "thin", "thistle", "tomato",
       "transparent", "turquoise", "-moz-element", "-moz-image-rect", "url", "violet", "wheat", "white", "whitesmoke",
       "yellow", "yellowgreen", "linear-gradient", "radial-gradient", "repeating-linear-gradient",
-      "repeating-radial-gradient", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient",
-      "-moz-repeating-radial-gradient" ]
+      "repeating-radial-gradient" ]
   ok(testValues(values, expected), "property border-image's values.");
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(do_test);
 
--- a/layout/reftests/backgrounds/gradient/scaled-color-stop-position-ref.html
+++ b/layout/reftests/backgrounds/gradient/scaled-color-stop-position-ref.html
@@ -11,17 +11,16 @@
 {
   border: 1px solid black;
   width: 600px; height: 300px;
 }
 #inner
 {
   width: 400px; height: 300px;
   /* 250px stop is halfway along 500px diagonal */
-  background-image: -moz-linear-gradient(top left, lime 0%, teal 250px, black 100%);
-  background-image: linear-gradient(top left, lime 0%, teal 250px, black 100%);
+  background-image: linear-gradient(to bottom right, lime 0%, teal 250px, black 100%);
 }
   </style>
 </head>
 <body>
 <div id="outer"><div id="inner"></div></div>
 </body>
 </html>
--- a/layout/reftests/backgrounds/gradient/scaled-color-stop-position.html
+++ b/layout/reftests/backgrounds/gradient/scaled-color-stop-position.html
@@ -7,18 +7,17 @@
 <head>
   <title>Color stop positioning for scaled gradients as backgrounds</title>
   <style type="text/css">
 #outer
 {
   border: 1px solid black;
   width: 600px; height: 300px;
   /* 250px stop is halfway along 500px diagonal */
-  background-image: -moz-linear-gradient(top left, lime 0%, teal 250px, black 100%);
-  background-image: linear-gradient(top left, lime 0%, teal 250px, black 100%);
+  background-image: linear-gradient(to bottom right, lime 0%, teal 250px, black 100%);
   background-size: 400px auto;
   background-repeat: no-repeat;
 }
   </style>
 </head>
 <body>
 <div id="outer"></div>
 </body>
--- a/layout/reftests/bugs/538909-1-ref.html
+++ b/layout/reftests/bugs/538909-1-ref.html
@@ -2,17 +2,16 @@
 <html>
 <head>
 <style>
 div {
   width: 260px;
   height: 260px;
   background-size: 100px 100px;
   background-position: -20px -20px;
-  background-image: -moz-linear-gradient(left top, yellow, blue);
-  background-image: linear-gradient(left top, yellow, blue);
+  background-image: linear-gradient(to bottom right, yellow, blue);
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
 </html>
--- a/layout/reftests/bugs/538909-1.html
+++ b/layout/reftests/bugs/538909-1.html
@@ -1,17 +1,16 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <style>
 div {
   border: 80px solid transparent;
   width: 100px;
   height: 100px;
-  background-image: -moz-linear-gradient(left top, yellow, blue);
-  background-image: linear-gradient(left top, yellow, blue);
+  background-image: linear-gradient(to bottom right, yellow, blue);
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
 </html>
--- a/layout/reftests/bugs/605138-1-ref.html
+++ b/layout/reftests/bugs/605138-1-ref.html
@@ -3,15 +3,15 @@
   <link href="data:text/css,%23master{display:table; width: 100%;}"
         rel="stylesheet" type="text/css" media="screen">
   <style>
     #master { outline: 1px dashed black; }
   </style>
 </head>
 <body>
 <div id="master">
-<div style="height:10000px; background: -moz-linear-gradient(right bottom, rgb(0,0,0) 0%, rgb(255,255,255) 100%);">
+<div style="height:10000px; background: linear-gradient(to left top, rgb(0,0,0) 0%, rgb(255,255,255) 100%);">
 </div>
 
 <div style="height:100px"></div>
 
 </div>
 </html>
--- a/layout/reftests/bugs/605138-1.html
+++ b/layout/reftests/bugs/605138-1.html
@@ -1,15 +1,15 @@
 <html>
 <head>
   <link href="data:text/css,%23master{display:table; width: 100%; outline: 1px dashed black; }"
         rel="stylesheet" type="text/css" media="screen">
 </head>
 <body>
 <div id="master">
-<div style="height:10000px; background: -moz-linear-gradient(right bottom, rgb(0,0,0) 0%, rgb(255,255,255) 100%);">
+<div style="height:10000px; background: linear-gradient(to left top, rgb(0,0,0) 0%, rgb(255,255,255) 100%);">
 </div>
 
 <textarea style="height:100px; margin:0; border:0;"></textarea>
 <script> </script>
 
 </div>
 </html>
--- a/layout/reftests/css-calc/background-image-gradient-1-ref.html
+++ b/layout/reftests/css-calc/background-image-gradient-1-ref.html
@@ -2,14 +2,13 @@
 <title>Test for calc() on background-image gradients</title>
 <style>
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
 }
 
-#one { background-image: -moz-radial-gradient(150px 20px, circle farthest-side, red, green); }
-#two { background-image: -moz-linear-gradient(-22px -35px -45deg, blue, yellow); }
+#one { background-image: radial-gradient(circle farthest-side at 150px 20px, red, green); }
 
 </style>
 <p id="one"></p>
 <p id="two"></p>
--- a/layout/reftests/css-calc/background-image-gradient-1.html
+++ b/layout/reftests/css-calc/background-image-gradient-1.html
@@ -2,14 +2,13 @@
 <title>Test for calc() on background-image gradients</title>
 <style>
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
 }
 
-#one { background-image: -moz-radial-gradient(calc(50px + 50%) calc(100% - 30px), circle farthest-side, red, green); }
-#two { background-image: -moz-linear-gradient(calc(-12.5% + 3px) calc(-10px - 50%) -45deg, blue, yellow); }
+#one { background-image: radial-gradient(circle farthest-side at calc(50px + 50%) calc(100% - 30px), red, green); }
 
 </style>
 <p id="one"></p>
 <p id="two"></p>
--- a/layout/reftests/css-gradients/aja-linear-1a.html
+++ b/layout/reftests/css-gradients/aja-linear-1a.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top, yellow, blue);
+  background: linear-gradient(to bottom, yellow, blue);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-1b.html
+++ b/layout/reftests/css-gradients/aja-linear-1b.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(bottom, blue, yellow);
+  background: linear-gradient(to top, blue, yellow);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-1e.html
+++ b/layout/reftests/css-gradients/aja-linear-1e.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top, yellow 0%, blue 100%);
+  background: linear-gradient(to bottom, yellow 0%, blue 100%);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-1f.html
+++ b/layout/reftests/css-gradients/aja-linear-1f.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(center top, yellow, blue);
+  background: linear-gradient(yellow, blue);
 }
 </style>
 <div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-1g.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<style>
-div {
-  height: 200px;
-  width: 100px;
-  background: -moz-linear-gradient(yellow, blue);
-}
-</style>
-<div></div>
--- a/layout/reftests/css-gradients/aja-linear-2-ref.html
+++ b/layout/reftests/css-gradients/aja-linear-2-ref.html
@@ -1,17 +1,17 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <html class="reftest-wait">
 <head>
 <script>
 function doDraw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
-  var grad = ctx.createLinearGradient(0,0,100,200);
+  var grad = ctx.createLinearGradient(0,0,160,80);
   grad.addColorStop(0, 'yellow');
   grad.addColorStop(1, 'blue');
 
   ctx.fillStyle = grad;
   ctx.fillRect(0,0,100,200);
 
   document.documentElement.removeAttribute('class');
 }
--- a/layout/reftests/css-gradients/aja-linear-2a.html
+++ b/layout/reftests/css-gradients/aja-linear-2a.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top left, yellow, blue);
+  background: linear-gradient(to bottom right, yellow, blue);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-2b.html
+++ b/layout/reftests/css-gradients/aja-linear-2b.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(0 0, yellow, blue);
+  background: linear-gradient(to top left, blue, yellow);
 }
 </style>
 <div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-2c.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<style>
-div {
-  height: 200px;
-  width: 100px;
-  background: -moz-linear-gradient(top 0px left 0px, yellow, blue);
-}
-</style>
-<div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-2d.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<style>
-div {
-  height: 200px;
-  width: 100px;
-  background: -moz-linear-gradient(bottom right, blue, yellow);
-}
-</style>
-<div></div>
--- a/layout/reftests/css-gradients/aja-linear-4a.html
+++ b/layout/reftests/css-gradients/aja-linear-4a.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top, yellow, blue, #0f0);
+  background: linear-gradient(yellow, blue, #0f0);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-4b.html
+++ b/layout/reftests/css-gradients/aja-linear-4b.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top, yellow, blue 50%, #0f0);
+  background: linear-gradient(yellow, blue 50%, #0f0);
 }
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/aja-linear-5a.html
+++ b/layout/reftests/css-gradients/aja-linear-5a.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <!-- Derived from http://a-ja.net/newgrad.html -->
 <style>
 div {
   height: 200px;
   width: 100px;
-  background: -moz-linear-gradient(top, yellow, blue 20%, #0f0);
+  background: linear-gradient(yellow, blue 20%, #0f0);
 }
 </style>
 <div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-6-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<html class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(20, 30, 80, 170);
-  grad.addColorStop(0, 'yellow');
-  grad.addColorStop(1, 'blue');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,100,200);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="100" height="200"></canvas>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-6a.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<style>
-div {
-  height: 200px;
-  width: 100px;
-  background: -moz-linear-gradient(20px 30px, yellow, blue);
-}
-</style>
-<div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/aja-linear-6b.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<!-- Derived from http://a-ja.net/newgrad.html -->
-<style>
-div {
-  height: 200px;
-  width: 100px;
-  background: -moz-linear-gradient(left 20px top 30px, yellow, blue);
-}
-</style>
-<div></div>
--- a/layout/reftests/css-gradients/height-dependence-1-ref.html
+++ b/layout/reftests/css-gradients/height-dependence-1-ref.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 14em;
   border: 1px solid black;
--- a/layout/reftests/css-gradients/height-dependence-1.html
+++ b/layout/reftests/css-gradients/height-dependence-1.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html class="reftest-wait"><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 28em;
   border: 1px solid black;
--- a/layout/reftests/css-gradients/height-dependence-2-ref.html
+++ b/layout/reftests/css-gradients/height-dependence-2-ref.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
   background-size: 1px 400px;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 14em;
--- a/layout/reftests/css-gradients/height-dependence-2.html
+++ b/layout/reftests/css-gradients/height-dependence-2.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html class="reftest-wait"><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
   background-size: 1px 400px;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 28em;
--- a/layout/reftests/css-gradients/height-dependence-3-ref.html
+++ b/layout/reftests/css-gradients/height-dependence-3-ref.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
   background-size: 1px 80%;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 14em;
--- a/layout/reftests/css-gradients/height-dependence-3.html
+++ b/layout/reftests/css-gradients/height-dependence-3.html
@@ -1,13 +1,13 @@
 <!doctype html>
 <html class="reftest-wait"><head>
 <style>
 html {
-  background-image: -moz-linear-gradient(black, white 20%);
+  background-image: linear-gradient(black, white 20%);
   background-repeat: repeat-x;
   background-size: 1px 80%;
 }
 body {
   font-size: 1em;
   padding: 2em;
   margin: 50px auto;
   width: 28em;
--- a/layout/reftests/css-gradients/linear-1a.html
+++ b/layout/reftests/css-gradients/linear-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(to right, red 0%, #7777FF 50%, rgb(100, 200, 0) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(to right, red 0%, #7777FF 50%, rgb(100, 200, 0) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-1b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left, red 0%, #7777FF 50%, rgb(100, 200, 0) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/linear-diagonal-1a.html
+++ b/layout/reftests/css-gradients/linear-diagonal-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top left -45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-1b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-1c.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(top left, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-2a.html
+++ b/layout/reftests/css-gradients/linear-diagonal-2a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top right -135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(-135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-2b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(-135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-2c.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(top right, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-3a.html
+++ b/layout/reftests/css-gradients/linear-diagonal-3a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom right 135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(-45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-3b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(-45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-3c.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(bottom right, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-4a.html
+++ b/layout/reftests/css-gradients/linear-diagonal-4a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom left 45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-4b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-4c.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(bottom left, white, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-5-ref.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to top left, white 75%, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-5a.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(100px 100px 135deg, white, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-6-ref.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to top right, white 75%, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-6a.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(300px 100px 45deg, white, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-7-ref.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to bottom right, white 75%, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-7a.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(300px 300px -45deg, white, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-8-ref.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to bottom left, white 75%, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-8a.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(100px 300px -135deg, white, black); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-9-ref.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<style>
-.x { width: 200px; height: 100px; display: inline-block; }
-.a { background: -moz-linear-gradient(top -90deg, blue, white, red); }
-.e { background: -moz-linear-gradient(top right -2.03444394rad, blue, white, red); }
-.g { background: -moz-linear-gradient(right 180deg, blue, white, red); }
-.i { background: -moz-linear-gradient(bottom right 2.03444394rad, blue, white, red); }
-.k { background: -moz-linear-gradient(bottom 90deg, blue, white, red); }
-.m { background: -moz-linear-gradient(bottom left 1.10714872rad, blue, white, red); }
-.o { background: -moz-linear-gradient(left 0deg, blue, white, red); }
-.q { background: -moz-linear-gradient(top left -1.10714872rad, blue, white, red); }
-</style>
-<div class="x a"></div>
-<div class="x e"></div>
-<div class="x g"></div>
-<div class="x i"></div>
-<div class="x k"></div>
-<div class="x m"></div>
-<div class="x o"></div>
-<div class="x q"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-diagonal-9a.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<style>
-.x { width: 200px; height: 100px; display: inline-block; }
-.a { background: linear-gradient(to bottom, blue, white, red); }
-.e { background: linear-gradient(to bottom left, blue, white, red); }
-.g { background: linear-gradient(to left, blue, white, red); }
-.i { background: linear-gradient(to top left, blue, white, red); }
-.k { background: linear-gradient(to top, blue, white, red); }
-.m { background: linear-gradient(to top right, blue, white, red); }
-.o { background: linear-gradient(to right, blue, white, red); }
-.q { background: linear-gradient(to bottom right, blue, white, red); }
-</style>
-<div class="x a"></div>
-<div class="x e"></div>
-<div class="x g"></div>
-<div class="x i"></div>
-<div class="x k"></div>
-<div class="x m"></div>
-<div class="x o"></div>
-<div class="x q"></div>
--- a/layout/reftests/css-gradients/linear-flipped-1-ref.html
+++ b/layout/reftests/css-gradients/linear-flipped-1-ref.html
@@ -1,2 +1,2 @@
 <!DOCTYPE HTML>
-<div style="height:100px; background:-moz-linear-gradient(bottom, black, white);"></div>
+<div style="height:100px; background:linear-gradient(to top, black, white);"></div>
--- a/layout/reftests/css-gradients/linear-flipped-1.html
+++ b/layout/reftests/css-gradients/linear-flipped-1.html
@@ -1,2 +1,2 @@
 <!DOCTYPE HTML>
-<div style="height:100px; background:-moz-linear-gradient(top, black, white); transform:scale(1,-1);"></div>
+<div style="height:100px; background:linear-gradient(to bottom, black, white); transform:scale(1,-1);"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-keywords-1b.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(left top, #0000ff, #000000) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-mix-ref.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(120,20,300,20);
-  grad.addColorStop(0, '#0000ff');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  ctx = document.getElementById('canvas2').getContext('2d');
-
-  grad = ctx.createLinearGradient(30,300,30,0);
-  grad.addColorStop(0, '#00ff00');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300" style="position: absolute; top: 30px; left: 30px;"></canvas>
-<br/><br/>
-<canvas id="canvas2" width="300" height="300" style="position: absolute; top: 360px; left: 30px;"></canvas>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-mix.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div style="background: -moz-linear-gradient(40% 20px 0deg, #0000ff, #000000) no-repeat; width: 300px; height: 300px; position: absolute; top: 30px; left: 30px;"><br></div>
-
-<div style="background: -moz-linear-gradient(10% bottom 90deg, #00ff00, #000000) no-repeat; width: 300px; height: 300px; position: absolute; top: 360px; left: 30px;"><br></div>
--- a/layout/reftests/css-gradients/linear-onestopposition-1.html
+++ b/layout/reftests/css-gradients/linear-onestopposition-1.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <title>Test for linear-gradient() with all stops at the same position</title>
 <style>
 
 div {
   width: 200px;
   height: 200px;
-  background-image: -moz-linear-gradient(left, blue 25%, orange 25%);
+  background-image: linear-gradient(to right, blue 25%, orange 25%);
 }
 
 </style>
 <div></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-percent-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" 
-      class="reftest-wait">
-<head>
-<script>
-function doDraw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var grad = ctx.createLinearGradient(30,60,300,60);
-  grad.addColorStop(0, '#0000ff');
-  grad.addColorStop(1, '#000000');
-
-  ctx.fillStyle = grad;
-  ctx.fillRect(0,0,300,300);
-
-  document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-percent.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-linear-gradient(10% 20% 0deg, #0000ff, #000000) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/linear-position-1a.html
+++ b/layout/reftests/css-gradients/linear-position-1a.html
@@ -1,2 +1,2 @@
 <body style="margin:0;">
-<div style="background: -moz-linear-gradient(left, white, black) no-repeat; background-position:-200px 0; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(to right, white, black) no-repeat; background-position:-200px 0; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/linear-repeat-1a.html
+++ b/layout/reftests/css-gradients/linear-repeat-1a.html
@@ -1,2 +1,2 @@
-<div style="background: -moz-linear-gradient(black, black 50%, white 50%, white);
+<div style="background: linear-gradient(black, black 50%, white 50%, white);
             background-size: 100px 100px; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1b.html
+++ b/layout/reftests/css-gradients/linear-repeat-1b.html
@@ -1,2 +1,2 @@
-<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+<div style="background: linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
             background-size: 100px 200px; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1c.html
+++ b/layout/reftests/css-gradients/linear-repeat-1c.html
@@ -1,4 +1,4 @@
-<div style="background: -moz-linear-gradient(white, white 50%, black 50%, black);
+<div style="background: linear-gradient(white, white 50%, black 50%, black);
             background-size: 100px 100px;
             background-position: 0 -50px;
             width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1d.html
+++ b/layout/reftests/css-gradients/linear-repeat-1d.html
@@ -1,3 +1,3 @@
-<div style="background: -moz-linear-gradient(white, white 50px, black 50px, black 100px, white 100px, white 150px, black 150px, black 200px);
+<div style="background: linear-gradient(white, white 50px, black 50px, black 100px, white 100px, white 150px, black 150px, black 200px);
             background-size: 100px 200px; background-position: 0 -50px;
             width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1e.html
+++ b/layout/reftests/css-gradients/linear-repeat-1e.html
@@ -1,3 +1,3 @@
-<div style="background: -moz-linear-gradient(black, black 50%, white 50%, white);
+<div style="background: linear-gradient(black, black 50%, white 50%, white);
             background-size: 300px 100px; background-repeat: repeat-y;
             width: 500px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1f.html
+++ b/layout/reftests/css-gradients/linear-repeat-1f.html
@@ -1,9 +1,9 @@
-<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+<div style="background: linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
             background-size: 100px 200px; background-repeat: repeat-x;
             width: 300px; height: 800px;
             margin-bottom: -600px;"></div>
 <!-- making the gradient actually be 300px high isn't reliable since
      the stop positions cannot be exactly represented and rounding errors
      creep in. So just let the gradient be 200px high and pad out to match
      the reference. -->
 <div style="background: black; width: 300px; height: 50px;"></div>
--- a/layout/reftests/css-gradients/linear-repeat-1g.html
+++ b/layout/reftests/css-gradients/linear-repeat-1g.html
@@ -1,10 +1,10 @@
 <body style="overflow:hidden">
-<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+<div style="background: linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
             background-size: 300px 200px; background-repeat: no-repeat;
             width: 800px; height: 800px;
             margin-bottom: -600px;"></div>
 <!-- making the gradient actually be 300px high isn't reliable since
      the stop positions cannot be exactly represented and rounding errors
      creep in. So just let the gradient be 200px high and pad out to match
      the reference. -->
 <div style="background: black; width: 300px; height: 50px;"></div>
--- a/layout/reftests/css-gradients/linear-size-1-ref.html
+++ b/layout/reftests/css-gradients/linear-size-1-ref.html
@@ -1,3 +1,3 @@
-<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
-<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
-<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
--- a/layout/reftests/css-gradients/linear-size-1a.html
+++ b/layout/reftests/css-gradients/linear-size-1a.html
@@ -1,2 +1,2 @@
-<div style="background: -moz-linear-gradient(white, black);
+<div style="background: linear-gradient(white, black);
             background-size: 300px 100px; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1-ref.html
+++ b/layout/reftests/css-gradients/linear-stops-1-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white 0%, red 20%, green 40%, blue 60%, yellow 80%, black 100%) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white 0%, red 20%, green 40%, blue 60%, yellow 80%, black 100%) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1a.html
+++ b/layout/reftests/css-gradients/linear-stops-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, red, green, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, red, green, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1b.html
+++ b/layout/reftests/css-gradients/linear-stops-1b.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white 0, red 60px, green 120px, blue 180px, yellow 240px, black 300px) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white 0, red 60px, green 120px, blue 180px, yellow 240px, black 300px) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1c.html
+++ b/layout/reftests/css-gradients/linear-stops-1c.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, red 20%, green, blue 60%, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, red 20%, green, blue 60%, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1d.html
+++ b/layout/reftests/css-gradients/linear-stops-1d.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, red, green 40%, red 40%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, red, green 40%, red 40%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1e.html
+++ b/layout/reftests/css-gradients/linear-stops-1e.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, red, green 40%, red 20%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, red, green 40%, red 20%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-stops-1f.html
+++ b/layout/reftests/css-gradients/linear-stops-1f.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, red, green 40%, red 40%, green 20%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, red, green 40%, red 40%, green 20%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-vertical-1a.html
+++ b/layout/reftests/css-gradients/linear-vertical-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-vertical-1b.html
+++ b/layout/reftests/css-gradients/linear-vertical-1b.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top left -90deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(to bottom, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-vertical-1c.html
+++ b/layout/reftests/css-gradients/linear-vertical-1c.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white 0%, white 0%, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white 0%, white 0%, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-vertical-1d.html
+++ b/layout/reftests/css-gradients/linear-vertical-1d.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(white 0%, white -20%, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: linear-gradient(white 0%, white -20%, black) no-repeat; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-vertical-1e.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to bottom, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-vertical-subpixel-1-ref.html
+++ b/layout/reftests/css-gradients/linear-vertical-subpixel-1-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html>
 <head>
 <style>
 div {
   margin-top: 21px;
   height: 30px;
-  background-image: -moz-linear-gradient(center top, black, white);
+  background-image: linear-gradient(black, white);
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
 </html>
--- a/layout/reftests/css-gradients/linear-vertical-subpixel-1.html
+++ b/layout/reftests/css-gradients/linear-vertical-subpixel-1.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html>
 <head>
 <style>
 div {
   margin-top: 20.7px;
   height: 30px;
-  background-image: -moz-linear-gradient(center top, black, white);
+  background-image: linear-gradient(black, white);
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
 </html>
--- a/layout/reftests/css-gradients/linear-viewport-ref.html
+++ b/layout/reftests/css-gradients/linear-viewport-ref.html
@@ -1,1 +1,1 @@
-<body style="border: 0; margin: 0; padding: 0;"><div style="background: -moz-linear-gradient(blue, aqua) no-repeat; width: 100%; height: 100%;">&nbsp;</div></body>
+<body style="border: 0; margin: 0; padding: 0;"><div style="background: linear-gradient(blue, aqua) no-repeat; width: 100%; height: 100%;">&nbsp;</div></body>
--- a/layout/reftests/css-gradients/linear-viewport.html
+++ b/layout/reftests/css-gradients/linear-viewport.html
@@ -1,2 +1,2 @@
 <!-- bug 509681 -->
-<body style="background: -moz-linear-gradient(blue, aqua) fixed no-repeat;">
+<body style="background: linear-gradient(blue, aqua) fixed no-repeat;">
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-zero-length-1-ref.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: black; width: 300px; height: 300px;"></div>
-<div style="background: black; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-zero-length-1a.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-linear-gradient(150px 150px, white, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-linear-gradient(150px 150px, white, black); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-zero-length-1b.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-linear-gradient(150px 150px, white, white 100px, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-linear-gradient(150px 150px, white, white 100px, black); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/linear-zero-length-1c.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-linear-gradient(center, white, black 50%); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-linear-gradient(center, white, black 50%); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-1c.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-radial-gradient(100px 100px, closest-side, #ff0000 25px, #0000ff 50px) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-2e.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-radial-gradient(100px 100px, closest-side, yellow -10px, #ff0000 0, #0000ff 50px); width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-2f.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- This test checks that adjustment of stop positions to be non-negative
-     happens after the calculation of implied stop positions -->
-<div style="background: -moz-radial-gradient(100px 100px, closest-side, #ff0000 -50px, #ff0000, #0000ff 50px); width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-onestopposition-1c.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<title>Test for radial-gradient() with all stops at the same position</title>
-<style>
-
-div {
-  width: 200px;
-  height: 200px;
-  background-image: -moz-radial-gradient(contain, blue 25%, orange 25%);
-}
-
-</style>
-<div></div>
--- a/layout/reftests/css-gradients/radial-shape-closest-corner-1-ref.html
+++ b/layout/reftests/css-gradients/radial-shape-closest-corner-1-ref.html
@@ -1,9 +1,9 @@
 <style>div { position:absolute; width:200px; height:200px; }</style>
 <div style="background: radial-gradient(closest-side circle at 60px 80px, white, black 100px); top:10px; left:10px;"></div>
 <div style="background: radial-gradient(closest-side circle at 140px 80px, white, black 100px); top:10px; left:220px;"></div>
 <div style="background: radial-gradient(closest-side circle at 80px 60px, white, black 100px); top:220px; left:10px;"></div>
 <div style="background: radial-gradient(closest-side circle at 80px 140px, white, black 100px); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(60px 80px 90deg, closest-corner, white, black 80px); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(140px 80px 90deg, closest-corner, white, black 80px); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 60px 90deg, ellipse closest-corner, white, black 60px); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 140px 90deg, ellipse closest-corner, white, black 60px); top:640px; left:220px;"></div>
+<div style="background: radial-gradient(closest-corner at 60px 80px, white, black 60px); top:430px; left:10px;"></div>
+<div style="background: radial-gradient(closest-corner at 140px 80px, white, black 60px); top:430px; left:220px;"></div>
+<div style="background: radial-gradient(ellipse closest-corner at 80px 60px, white, black 80px); top:640px; left:10px;"></div>
+<div style="background: radial-gradient(ellipse closest-corner at 80px 140px, white, black 80px); top:640px; left:220px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-shape-closest-corner-1c.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<style>div { position:absolute; width:200px; height:200px; }</style>
-<div style="background: -moz-radial-gradient(60px 80px, circle closest-corner, white, black); top:10px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(140px 80px, circle closest-corner, white, black); top:10px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 60px, circle closest-corner, white, black); top:220px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 140px, circle closest-corner, white, black); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(60px 80px, ellipse closest-corner, white, black 60px); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(140px 80px, ellipse closest-corner, white, black 60px); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 60px, closest-corner, white, black 80px); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 140px, closest-corner, white, black 80px); top:640px; left:220px;"></div>
--- a/layout/reftests/css-gradients/radial-shape-closest-side-1-ref.html
+++ b/layout/reftests/css-gradients/radial-shape-closest-side-1-ref.html
@@ -1,9 +1,9 @@
 <style>div { position:absolute; width:200px; height:200px; }</style>
-<div style="background: -moz-radial-gradient(50px 80px, circle closest-side, white, black 50px); top:10px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(150px 80px, circle closest-side, white, black 50px); top:10px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 50px, circle closest-side, white, black 50px); top:220px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 150px, circle closest-side, white, black 50px); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(20px 20px, circle closest-side, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(180px 20px, circle closest-side, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(20px 20px, circle closest-side, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(20px 180px, circle closest-side, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:220px;"></div>
+<div style="background: radial-gradient(circle closest-side at 50px 80px, white, black 50px); top:10px; left:10px;"></div>
+<div style="background: radial-gradient(circle closest-side at 150px 80px, white, black 50px); top:10px; left:220px;"></div>
+<div style="background: radial-gradient(circle closest-side at 80px 50px, white, black 50px); top:220px; left:10px;"></div>
+<div style="background: radial-gradient(circle closest-side at 80px 150px, white, black 50px); top:220px; left:220px;"></div>
+<div style="background: radial-gradient(circle closest-side at 20px 20px, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:10px;"></div>
+<div style="background: radial-gradient(circle closest-side at 180px 20px, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:220px;"></div>
+<div style="background: radial-gradient(circle closest-side at 20px 20px, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:10px;"></div>
+<div style="background: radial-gradient(circle closest-side at 20px 180px, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:220px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-shape-closest-side-1c.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<style>div { position:absolute; width:200px; height:200px; }</style>
-<div style="background: -moz-radial-gradient(50px 80px, circle closest-side, white, black); top:10px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(150px 80px, circle closest-side, white, black); top:10px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 50px, circle closest-side, white, black); top:220px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 150px, circle closest-side, white, black); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(20px 40px, ellipse closest-side, white, black); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(180px 40px, ellipse closest-side, white, black); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(40px 20px, closest-side, white, black); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(40px 180px, closest-side, white, black); top:640px; left:220px;"></div>
--- a/layout/reftests/css-gradients/radial-shape-farthest-corner-1-ref.html
+++ b/layout/reftests/css-gradients/radial-shape-farthest-corner-1-ref.html
@@ -1,9 +1,9 @@
 <style>div { position:absolute; width:200px; height:200px; }</style>
 <div style="background: radial-gradient(circle farthest-side at 40px 80px, white, black 200px); top:10px; left:10px;"></div>
 <div style="background: radial-gradient(farthest-side circle at 160px 80px, white, black 200px); top:10px; left:220px;"></div>
 <div style="background: radial-gradient(circle farthest-side at 80px 40px, white, black 200px); top:220px; left:10px;"></div>
 <div style="background: radial-gradient(farthest-side circle at 80px 160px, white, black 200px); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(60px 80px 90deg, farthest-corner, white, black 120px); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(140px 80px 90deg, farthest-corner, white, black 120px); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 60px 90deg, ellipse farthest-corner, white, black 140px); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 140px 90deg, ellipse farthest-corner, white, black 140px); top:640px; left:220px;"></div>
+<div style="background: radial-gradient(farthest-corner at 60px 80px, white, black 140px); top:430px; left:10px;"></div>
+<div style="background: radial-gradient(farthest-corner at 140px 80px, white, black 140px); top:430px; left:220px;"></div>
+<div style="background: radial-gradient(ellipse farthest-corner at 80px 60px, white, black 120px); top:640px; left:10px;"></div>
+<div style="background: radial-gradient(ellipse farthest-corner at 80px 140px, white, black 120px); top:640px; left:220px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-shape-farthest-corner-1c.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<style>div { position:absolute; width:200px; height:200px; }</style>
-<div style="background: -moz-radial-gradient(40px 80px, circle farthest-corner, white, black); top:10px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(160px 80px, circle farthest-corner, white, black); top:10px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 40px, circle farthest-corner, white, black); top:220px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 160px, circle farthest-corner, white, black); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(60px 80px, ellipse farthest-corner, white, black 140px); top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(140px 80px, ellipse farthest-corner, white, black 140px); top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 60px, farthest-corner, white, black 120px); top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 140px, farthest-corner, white, black 120px); top:640px; left:220px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-shape-farthest-side-1c.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<style>div { position:absolute; width:200px; height:200px; }</style>
-<div style="background: -moz-radial-gradient(50px 80px, circle farthest-side, white, black); top:10px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(150px 80px, circle farthest-side, white, black); top:10px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 50px, circle farthest-side, white, black); top:220px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(80px 150px, circle farthest-side, white, black); top:220px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(80px 40px, farthest-side, white, black); height:100px; top:430px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(120px 60px, farthest-side, white, black); height:100px; top:430px; left:220px;"></div>
-<div style="background: -moz-radial-gradient(40px 80px, ellipse farthest-side, white, black); width:100px; top:640px; left:10px;"></div>
-<div style="background: -moz-radial-gradient(60px 120px, ellipse farthest-side, white, black); width:100px; top:640px; left:220px;"></div>
--- a/layout/reftests/css-gradients/radial-size-1a.html
+++ b/layout/reftests/css-gradients/radial-size-1a.html
@@ -1,2 +1,2 @@
-<div style="background: -moz-radial-gradient(white, black);
+<div style="background: radial-gradient(white, black);
             background-size: 300px 100px; width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-zero-length-1g.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-radial-gradient(left, circle closest-side, white, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-radial-gradient(left, circle closest-side, white, black); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-zero-length-1h.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-zero-length-1i.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/radial-zero-length-1j.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<div style="background: -moz-radial-gradient(top, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
-<div style="background: -moz-repeating-radial-gradient(top, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -1,38 +1,15 @@
 fuzzy-if(!contentSameGfxBackendAsCanvas,4,88500) fuzzy-if(azureSkiaGL,3,89700) fuzzy-if(azureQuartz,1,34792) == linear-1a.html linear-1-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,4,88500) fuzzy-if(azureSkiaGL,3,89700) fuzzy-if(azureQuartz,1,34792) == linear-1b.html linear-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,88500) fuzzy-if(azureSkiaGL,2,89997) fuzzy-if(azureQuartz,1,11469) == linear-keywords-1a.html linear-keywords-1-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,2,88500) fuzzy-if(azureSkiaGL,2,89997) fuzzy-if(azureQuartz,1,11985) == linear-keywords-1b.html linear-keywords-1-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,2,88500) fuzzy-if(azureQuartz,1,10230) == linear-percent.html linear-percent-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,4,92400) fuzzy-if(azureSkiaGL,2,143400) fuzzy-if(azureQuartz,1,27827) fuzzy-if(Android&&AndroidVersion>=15,4,93000) == linear-mix.html linear-mix-ref.html
 == linear-diagonal-1a.html linear-diagonal-1-ref.html
-== linear-diagonal-1b.html linear-diagonal-1-ref.html
-== linear-diagonal-1c.html linear-diagonal-1-ref.html
 == linear-diagonal-2a.html linear-diagonal-2-ref.html
-== linear-diagonal-2b.html linear-diagonal-2-ref.html
-== linear-diagonal-2c.html linear-diagonal-2-ref.html
 == linear-diagonal-3a.html linear-diagonal-3-ref.html
-== linear-diagonal-3b.html linear-diagonal-3-ref.html
-== linear-diagonal-3c.html linear-diagonal-3-ref.html
 == linear-diagonal-4a.html linear-diagonal-4-ref.html
-== linear-diagonal-4b.html linear-diagonal-4-ref.html
-== linear-diagonal-4c.html linear-diagonal-4-ref.html
 == linear-premul.html linear-premul-ref.html
-
-# these tests uses a similar gradient over different bounds. It's perfectly
-# reasonable to expect implementations to give slightly different results
-# if the gradients are not being normalized. Skia uses a lookup table for
-# gradients so it will have less precision when drawing a larger gradient
-fuzzy(2,11410) fuzzy-if(skiaContent,4,15271) == linear-diagonal-5a.html linear-diagonal-5-ref.html
-fuzzy(2,11568) fuzzy-if(azureQuartz&&OSX==1006,2,11657) fuzzy-if(skiaContent,8,19701) == linear-diagonal-6a.html linear-diagonal-6-ref.html
-fuzzy(2,11605) fuzzy-if(skiaContent,8,19701) == linear-diagonal-7a.html linear-diagonal-7-ref.html
-fuzzy(2,11407) fuzzy-if(azureQuartz&&OSX==1006,2,11443) fuzzy-if(skiaContent,4,15085) == linear-diagonal-8a.html linear-diagonal-8-ref.html
-
-fuzzy-if(cocoaWidget,4,29437) == linear-diagonal-9a.html linear-diagonal-9-ref.html
 fuzzy(1,800000) == linear-flipped-1.html linear-flipped-1-ref.html
 == linear-position-1a.html linear-position-1-ref.html
 == linear-repeat-1a.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1b.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1c.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1d.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1e.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1f.html linear-repeat-1-ref.html # bug 582236
@@ -44,109 +21,83 @@ fails-if(d2d) == linear-repeat-1g.html l
 == linear-stops-1c.html linear-stops-1-ref.html
 == linear-stops-1d.html linear-stops-1-ref.html
 == linear-stops-1e.html linear-stops-1-ref.html
 == linear-stops-1f.html linear-stops-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1a.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1b.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,2,26777) == linear-vertical-1c.html linear-vertical-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,2,26777) == linear-vertical-1d.html linear-vertical-1-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,3,88500) fuzzy-if(azureSkiaGL,2,89700) fuzzy-if(azureQuartz,1,22367) == linear-vertical-1e.html linear-vertical-1-ref.html
 == linear-vertical-subpixel-1.html linear-vertical-subpixel-1-ref.html
 == linear-viewport.html linear-viewport-ref.html
-fails-if(OSX==1010) fuzzy-if(Android,4,248) == linear-zero-length-1a.html linear-zero-length-1-ref.html
-fails-if(OSX==1010) fuzzy-if(Android,4,248) == linear-zero-length-1b.html linear-zero-length-1-ref.html
-fails-if(OSX==1010) fuzzy-if(Android,4,248) == linear-zero-length-1c.html linear-zero-length-1-ref.html
 == nostops.html about:blank
 == onestop.html about:blank
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1a.html radial-1-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1b.html radial-1-ref.html
-fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,2,88024) random-if(d2d) == radial-1c.html radial-1-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2a.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2b.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2c.html radial-2-ref.html
 fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2d.html radial-2-ref.html
-fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2e.html radial-2-ref.html
-fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == radial-2f.html radial-2-ref.html
 == radial-position-1a.html radial-position-1-ref.html
 fuzzy-if(cocoaWidget,1,28) fuzzy-if(winWidget,1,18) == radial-position-1b.html radial-position-1-ref.html
 fuzzy-if(cocoaWidget,4,22317) fuzzy-if(Android,8,771) == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html
 fuzzy(1,238) fuzzy-if(cocoaWidget,4,22608) fuzzy-if(/^Windows\x20NT\x206\./.test(http.oscpu)&&d2d,1,336) fuzzy-if(Android,8,787) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html
-fuzzy-if(azureQuartz,2,41171) fuzzy-if(Android,8,771) == radial-shape-closest-corner-1c.html radial-shape-closest-corner-1-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html
-fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1c.html radial-shape-closest-side-1-ref.html
 fuzzy-if(Android,8,771) == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
 fails-if(gtkWidget&&/x86_64-/.test(xulRuntime.XPCOMABI)) fuzzy(1,1569) fuzzy-if(cocoaWidget,2,41281) fuzzy-if(Android,8,1091) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html
-fuzzy-if(Android,8,771) == radial-shape-farthest-corner-1c.html radial-shape-farthest-corner-1-ref.html
 fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html
 fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html
-fuzzy-if(Android,17,13320) == radial-shape-farthest-side-1c.html radial-shape-farthest-side-1-ref.html
 == radial-size-1a.html radial-size-1-ref.html
 == radial-size-1b.html radial-size-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1a.html radial-zero-length-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1b.html radial-zero-length-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1c.html radial-zero-length-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1d.html radial-zero-length-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1e.html radial-zero-length-1-ref.html
 fuzzy-if(Android,4,248) == radial-zero-length-1f.html radial-zero-length-1-ref.html
-fuzzy-if(Android,4,248) == radial-zero-length-1g.html radial-zero-length-1-ref.html
-fuzzy-if(Android,4,248) == radial-zero-length-1h.html radial-zero-length-1-ref.html
-fuzzy-if(Android,4,248) == radial-zero-length-1i.html radial-zero-length-1-ref.html
-fuzzy-if(Android,4,248) == radial-zero-length-1j.html radial-zero-length-1-ref.html
 == radial-premul.html radial-premul-ref.html
 == repeated-final-stop-1.html repeated-final-stop-1-ref.html
 == repeating-linear-1a.html repeating-linear-1-ref.html
 == repeating-linear-1b.html repeating-linear-1-ref.html
 == repeating-linear-2a.html repeating-linear-2-ref.html
 fuzzy-if(d2d,127,2612) == repeating-radial-1a.html repeating-radial-1-ref.html
 == repeating-radial-1b.html repeating-radial-1-ref.html
 fuzzy-if(d2d,127,2612) == repeating-radial-1c.html repeating-radial-1-ref.html
 == repeating-radial-1d.html repeating-radial-1-ref.html
-fuzzy-if(d2d,127,2612) == repeating-radial-1e.html repeating-radial-1-ref.html
-== repeating-radial-1f.html repeating-radial-1-ref.html
 == repeating-radial-2a.html repeating-radial-2-ref.html
 == repeating-radial-2b.html repeating-radial-2-ref.html
 == twostops-1a.html twostops-1-ref.html
 == twostops-1b.html twostops-1-ref.html
 == twostops-1c.html twostops-1-ref.html
 == twostops-1d.html twostops-1-ref.html
 == twostops-1e.html twostops-1-ref.html
-== twostops-1f.html twostops-1-ref.html
-== twostops-1g.html twostops-1-ref.html
 
 # from http://www.xanthir.com/:4bhipd by way of http://a-ja.net/newgrad.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1a.html aja-linear-1-ref.html 
 fails-if(!d2d&&!(OSX==1010&&azureQuartz&&isDebugBuild)) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694, passing on 10.10 debug is bug 1128517
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1c.html aja-linear-1-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1d.html aja-linear-1-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1e.html aja-linear-1-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1f.html aja-linear-1-ref.html 
-fuzzy-if(!contentSameGfxBackendAsCanvas,3,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4646) == aja-linear-1g.html aja-linear-1-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4667) == aja-linear-2a.html aja-linear-2-ref.html 
-fuzzy-if(!contentSameGfxBackendAsCanvas,2,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,4667) == aja-linear-2b.html aja-linear-2-ref.html 
-fails == aja-linear-2c.html aja-linear-2-ref.html # bug 522607
-fails-if(!d2d) == aja-linear-2d.html aja-linear-2-ref.html # bug 526694
+fails-if(!d2d) == aja-linear-2b.html aja-linear-2-ref.html # bug 526694
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,19999) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz,1,10553) == aja-linear-3a.html aja-linear-3-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,19999) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz,1,10553) == aja-linear-3b.html aja-linear-3-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,4,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,8655) == aja-linear-4a.html aja-linear-4-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,4,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,1,8655) == aja-linear-4b.html aja-linear-4-ref.html 
 fuzzy-if(!contentSameGfxBackendAsCanvas,4,20000) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz&&OSX==1006,2,7878) == aja-linear-5a.html aja-linear-5-ref.html 
-fuzzy-if(!contentSameGfxBackendAsCanvas,2,16477) fuzzy-if(azureSkiaGL,8,20000) fuzzy-if(azureQuartz,2,10163) == aja-linear-6a.html aja-linear-6-ref.html # bug 526708 
-fails == aja-linear-6b.html aja-linear-6-ref.html # bug 522607
 skip-if(B2G||Mulet) fuzzy-if(Android,6,10576) == height-dependence-1.html height-dependence-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fuzzy-if(cocoaWidget,1,40000) fuzzy-if(Android,6,10576) == height-dependence-2.html height-dependence-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fuzzy-if(Android,6,10576) == height-dependence-3.html height-dependence-3-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 
 == linear-onestopposition-1.html linear-onestopposition-1-ref.html
 fuzzy-if(d2d,47,400) == linear-onestopposition-1.html linear-onestopposition-1-ref2.html # d2d interpolates the hard stop
 == radial-onestopposition-1a.html radial-onestopposition-1-ref.html
 == radial-onestopposition-1b.html radial-onestopposition-1-ref.html
-== radial-onestopposition-1c.html radial-onestopposition-1-ref.html
 == repeating-linear-onestopposition-1.html orange-square.html
 == repeating-radial-onestopposition-1a.html orange-square.html
 == repeating-radial-onestopposition-1b.html orange-square.html
-== repeating-radial-onestopposition-1c.html orange-square.html
 == bug-916535-background-repeat-linear.html bug-916535-background-repeat-linear-ref.html
 fuzzy(1,800000) == large-gradient-1.html large-gradient-1-ref.html
 == large-gradient-2.html large-gradient-2-ref.html
 fails-if(browserIsRemote&&!B2G) fuzzy-if(!browserIsRemote||B2G,1,800000) == large-gradient-3.html large-gradient-3-ref.html
 == large-gradient-4.html large-gradient-4-ref.html
--- a/layout/reftests/css-gradients/repeated-final-stop-1-ref.html
+++ b/layout/reftests/css-gradients/repeated-final-stop-1-ref.html
@@ -1,18 +1,17 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <style>
 html {
   background: white;
 }
 div {
-  background: -moz-linear-gradient(left, 0 white, 100% orange);
-  background: linear-gradient(left, 0 white, 100% orange);
+  background: linear-gradient(to rigtht, 0 white, 100% orange);
   height: 100px;
   width: 50%;
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
--- a/layout/reftests/css-gradients/repeated-final-stop-1.html
+++ b/layout/reftests/css-gradients/repeated-final-stop-1.html
@@ -1,18 +1,17 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <style>
 html {
   background: white;
 }
 div {
-  background: -moz-linear-gradient(left, 0 white, 50% orange, 50% white);
-  background: linear-gradient(left, 0 white, 50% orange, 50% white);
+  background: linear-gradient(to rigtht, 0 white, 50% orange, 50% white);
   height: 100px;
 }
 </style>
 </head>
 <body>
 <div></div>
 </body>
 </html>
--- a/layout/reftests/css-gradients/repeating-linear-1a.html
+++ b/layout/reftests/css-gradients/repeating-linear-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-repeating-linear-gradient(black 0, black 50px, white 50px, white 100px); width: 400px; height: 400px;"></div>
+<div style="background: repeating-linear-gradient(black 0, black 50px, white 50px, white 100px); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/repeating-linear-1b.html
+++ b/layout/reftests/css-gradients/repeating-linear-1b.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-repeating-linear-gradient(black 100px, black 150px, white 150px, white 200px); width: 400px; height: 400px;"></div>
+<div style="background: repeating-linear-gradient(black 100px, black 150px, white 150px, white 200px); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/repeating-linear-2a.html
+++ b/layout/reftests/css-gradients/repeating-linear-2a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-repeating-linear-gradient(red 20px, blue 20px); width: 300px; height: 300px;"></div>
+<div style="background: repeating-linear-gradient(red 20px, blue 20px); width: 300px; height: 300px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/repeating-radial-1e.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: -moz-repeating-radial-gradient(closest-side, black 100px, black 150px, white 150px, white 200px); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/repeating-radial-1f.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<!-- Test adjustment of negative stop positions in a repeating radial gradient.
-     We should still get a repeating pattern, i.e., the stops cannot
-     naively be mapped to 0. -->
-<div style="background: -moz-repeating-radial-gradient(closest-side, black -100px, black -50px, white -50px, white 0); width: 400px; height: 400px;"></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/repeating-radial-onestopposition-1c.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<title>Test for -moz-repeating-radial-gradient() with all stops at the same position</title>
-<style>
-
-div {
-  width: 200px;
-  height: 200px;
-  background-image: -moz-repeating-radial-gradient(contain, blue 25%, orange 25%);
-}
-
-</style>
-<div></div>
--- a/layout/reftests/css-gradients/twostops-1a.html
+++ b/layout/reftests/css-gradients/twostops-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(to bottom, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/twostops-1b.html
+++ b/layout/reftests/css-gradients/twostops-1b.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom, #ff0000 50%, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(to top, #ff0000 50%, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/twostops-1c.html
+++ b/layout/reftests/css-gradients/twostops-1c.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/twostops-1d.html
+++ b/layout/reftests/css-gradients/twostops-1d.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(#0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(#0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/twostops-1e.html
+++ b/layout/reftests/css-gradients/twostops-1e.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/twostops-1f.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to bottom, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/twostops-1g.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<div style="background: linear-gradient(to top, #ff0000 50%, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/floats/float-in-rtl-vlr-4-ref.html
+++ b/layout/reftests/floats/float-in-rtl-vlr-4-ref.html
@@ -14,13 +14,13 @@
  <div style="height:600px;">
   <div style="height:0px;width:0px;overflow:visible">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);display:inline-block;margin-top:500px;"></div>
   </div>
   <div style="height:0px;width:0px;overflow:visible">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);display:inline-block;margin-top:400px;"></div>
   </div>
   <div class="vlr" style="background:silver; height: 100%;">
-    <div style="padding-bottom: 200px; direction:rtl">This text should appear ABOVE the green and red blocks.</div>
+    <div style="padding-bottom: 200px; direction:rtl">This text should appear ABOVE the red and green blocks.</div>
   </div>
  </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vlr-4a.html
+++ b/layout/reftests/floats/float-in-rtl-vlr-4a.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-lr;
    -webkit-writing-mode: vertical-lr;
    writing-mode: tb-lr;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vlr-4b.html
+++ b/layout/reftests/floats/float-in-rtl-vlr-4b.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-lr;
    -webkit-writing-mode: vertical-lr;
    writing-mode: tb-lr;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div dir="ltr" style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vlr-4c.html
+++ b/layout/reftests/floats/float-in-rtl-vlr-4c.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-lr;
    -webkit-writing-mode: vertical-lr;
    writing-mode: tb-lr;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div dir="ltr" style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vlr-4d.html
+++ b/layout/reftests/floats/float-in-rtl-vlr-4d.html
@@ -7,21 +7,23 @@
    writing-mode: vertical-lr;
    -webkit-writing-mode: vertical-lr;
    writing-mode: tb-lr;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="inline-size:-moz-fit-content">
     <div style="height:300px">
       <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
     </div>
     <div style="height:200px">
       <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
     </div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vrl-4-ref.html
+++ b/layout/reftests/floats/float-in-rtl-vrl-4-ref.html
@@ -14,13 +14,13 @@
  <div style="height:600px;">
   <div style="height:0px;width:0px;overflow:visible">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);display:inline-block;margin-top:500px;"></div>
   </div>
   <div style="height:0px;width:0px;overflow:visible">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);display:inline-block;margin-top:400px;"></div>
   </div>
   <div dir=ltr class="vrl" style="background:silver; height: 100%;">
-    <div style="padding-bottom: 200px; direction:rtl">This text should appear ABOVE the green and red blocks.</div>
+    <div style="padding-bottom: 200px; direction:rtl">This text should appear ABOVE the red and green blocks.</div>
   </div>
  </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vrl-4a.html
+++ b/layout/reftests/floats/float-in-rtl-vrl-4a.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;
    writing-mode: tb-rl;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vrl-4b.html
+++ b/layout/reftests/floats/float-in-rtl-vrl-4b.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;
    writing-mode: tb-rl;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div dir="ltr" style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vrl-4c.html
+++ b/layout/reftests/floats/float-in-rtl-vrl-4c.html
@@ -7,19 +7,21 @@
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;
    writing-mode: tb-rl;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="height:300px">
     <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
   </div>
   <div dir="ltr" style="height:200px">
     <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/floats/float-in-rtl-vrl-4d.html
+++ b/layout/reftests/floats/float-in-rtl-vrl-4d.html
@@ -7,21 +7,23 @@
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;
    writing-mode: tb-rl;
    direction: rtl;
 }
 </style>
 </head>
 <body>
+ <div style="height:600px; margin-top:0; margin-bottom:auto;">
   <div dir="ltr" style="inline-size:-moz-fit-content">
     <div style="height:300px">
       <div style="height:100px;width:120px;background:rgba(0,255,0,0.8);float:right;"></div>
     </div>
     <div style="height:200px">
       <div style="height:100px;width:150px;background:rgba(255,0,0,0.8);float:right;"></div>
     </div>
   </div>
   <div style="background:silver">
 This text should appear ABOVE the red and green blocks.
   </div>
+ </div>
 </body>
 </html>
--- a/layout/reftests/forms/meter/default-style/style.css
+++ b/layout/reftests/forms/meter/default-style/style.css
@@ -1,54 +1,54 @@
 div.meter-element {
   display: inline-block;
   height: 1em;
   width: 5em;
   vertical-align: -0.2em;
 
-  background: -moz-linear-gradient(top, #e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
+  background: linear-gradient(#e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
 }
 
 div.meter-optimum {
   float: none ! important;
 
   height: 100%;
   /*
    * We can't apply the following style to the reference because it will have
    * underisable effectes:
    * width: 100%;
    */
 
   /* green. */
-  background: -moz-linear-gradient(top, #ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
+  background: linear-gradient(#ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
 }
 
 div.meter-sub-optimum {
   float: none ! important;
 
   height: 100%;
   /*
    * We can't apply the following style to the reference because it will have
    * underisable effectes:
    * width: 100%;
    */
 
   /* orange. */
-  background: -moz-linear-gradient(top, #fe7, #fe7, #ffc 20%, #db3 45%, #db3 55%);
+  background: linear-gradient(#fe7, #fe7, #ffc 20%, #db3 45%, #db3 55%);
 }
 
 div.meter-sub-sub-optimum {
   float: none ! important;
 
   height: 100%;
   /*
    * We can't apply the following style to the reference because it will have
    * underisable effectes:
    * width: 100%;
    */
 
   /* red. */
-  background: -moz-linear-gradient(top, #f77, #f77, #fcc 20%, #d44 45%, #d44 55%);
+  background: linear-gradient(#f77, #f77, #fcc 20%, #d44 45%, #d44 55%);
 }
 
 meter, meter::-moz-meter-bar, div.meter-element, div.meter-optimum, div.meter-sub-optimum, div.meter-sub-sub-optimum {
   -moz-appearance: none;
 }
--- a/layout/reftests/image-element/element-paint-continuation-ref.html
+++ b/layout/reftests/image-element/element-paint-continuation-ref.html
@@ -11,15 +11,15 @@
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 </style>
 <body style="line-height:1; font-family: Ahem; color: transparent;">
   <div style="width:100px; height:100px; border:10px solid black;">
     <div style="width:50px;">
       <span style="display:inline-block; width:25px; height:1px;"></span
-        ><span id="d" style="background:-moz-linear-gradient(right, yellow, yellow);"
+        ><span id="d" style="background:linear-gradient(to left, yellow, yellow);"
         ><span style="display:inline-block; width:25px; height:1px;"></span>
       AA</span>
     </div>
   </div>
 </body>
 </html>
--- a/layout/reftests/image-element/element-paint-multiple-backgrounds-01-ref.html
+++ b/layout/reftests/image-element/element-paint-multiple-backgrounds-01-ref.html
@@ -6,18 +6,18 @@
 <!DOCTYPE html>
 <html>
 <head>
 <style>
 
 #box {
   height: 100px;
   width: 200px;
-  background: -moz-linear-gradient(lime,lime) top left no-repeat,
-              -moz-linear-gradient(green,green) top right no-repeat red;
+  background: linear-gradient(lime,lime) top left no-repeat,
+              linear-gradient(green,green) top right no-repeat red;
   background-size: 100px 100px;
 }
 
 div > div {
   width: 100px;
   height: 100px;
 }
 
--- a/layout/reftests/image-element/gradient-html-06b.html
+++ b/layout/reftests/image-element/gradient-html-06b.html
@@ -2,12 +2,12 @@
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/licenses/publicdomain/
      Test whether SVG gradients as -moz-element render the same as
      CSS gradients.
 -->
 <!DOCTYPE html>
 <html>
 <body style="margin:0">
-  <div style="width:300px; height:300px; background-image:-moz-linear-gradient(lime, black)"></div>
+  <div style="width:300px; height:300px; background-image:linear-gradient(lime, black)"></div>
 </body>
 </html>
 
--- a/layout/reftests/layers/component-alpha-exit-1-ref.html
+++ b/layout/reftests/layers/component-alpha-exit-1-ref.html
@@ -9,17 +9,17 @@ document.addEventListener("MozReftestInv
 }, false);
 </script>
 <style>
 #scrollbox {
   margin: 20px;
   width: 300px;
   height: 400px;
   overflow-y: hidden;
-  background: -moz-linear-gradient(#FFF, #FFF);
+  background: linear-gradient(#FFF, #FFF);
 }
 
 #inner {
   background-color: #000;
   padding-bottom: 415px;
 }
 </style>
 
--- a/layout/reftests/layers/component-alpha-exit-1.html
+++ b/layout/reftests/layers/component-alpha-exit-1.html
@@ -13,17 +13,17 @@ document.addEventListener("MozReftestInv
 }, false);
 </script>
 <style>
 #scrollbox {
   margin: 20px;
   width: 300px;
   height: 400px;
   overflow-y: hidden;
-  background: -moz-linear-gradient(#FFF, #FFF);
+  background: linear-gradient(#FFF, #FFF);
 }
 
 #inner {
   background-color: #000;
   margin-top: 10px;
   height: 5px;
   line-height: 5px;
   padding-bottom: 400px;
--- a/layout/reftests/native-theme/checkbox-dynamic-1-ref.html
+++ b/layout/reftests/native-theme/checkbox-dynamic-1-ref.html
@@ -1,17 +1,17 @@
 <!DOCTYPE html>
 <html>
 <head>
   <style>
     #checkbox {
        position: absolute;
        left: 0px;
        top: 0px;
-       background: -moz-linear-gradient(left, white, brown);
+       background: linear-gradient(to right, white, brown);
     }
   </style>
 </head>
 <body>
   <div id="checkbox">
     <input type="checkbox">
   </div>
 </body>
--- a/layout/reftests/native-theme/checkbox-dynamic-1.html
+++ b/layout/reftests/native-theme/checkbox-dynamic-1.html
@@ -1,17 +1,17 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
 <head>
   <style>
     #checkbox {
        position: absolute;
        left: 0px;
        top: 0px;
-       background: -moz-linear-gradient(left, white, brown);
+       background: linear-gradient(to right, white, brown);
     }
     #toremove {
        position: absolute;
        left: 0px;
        top: 0px;
        width: 100px;
        height: 0px;
        background: black;
--- a/layout/reftests/scrolling/opacity-mixed-scrolling-2.html
+++ b/layout/reftests/scrolling/opacity-mixed-scrolling-2.html
@@ -1,26 +1,26 @@
 <!DOCTYPE HTML>
 <html>
 <style>
 #scrollbox {
   margin: 20px;
   width: 300px;
   height: 400px;
   overflow-y: auto;
-  background: -moz-linear-gradient(#444, #555);
+  background: linear-gradient(#444, #555);
 }
 .opacityBox {
   opacity: 0.999;
   border: 1px solid black;
   margin: 20px;
   padding: 20px;
 }
 #inner {
-  background-image: -moz-linear-gradient(white, rgba(255,255,255,0));
+  background-image: linear-gradient(white, rgba(255,255,255,0));
 }
 </style>
 
 <div id="scrollbox" class="scrollTop">
   <div id="inner">
     outside
     <div class="opacityBox">in opacity box</div>
     outside
--- a/layout/reftests/transform/601894-1.html
+++ b/layout/reftests/transform/601894-1.html
@@ -1,11 +1,11 @@
 <!DOCTYPE html>
 <html>
-  <body style="background: -moz-linear-gradient(lime, lime) fixed; overflow: hidden;">
+  <body style="background: linear-gradient(lime, lime) fixed; overflow: hidden;">
     <div style="position: absolute; left: 21.0138px; top: 507.24px; z-index: 17567; -moz-transform: scale(8);">
       <div style="height: 128px; left: -64px; position: absolute; top: -64px; visibility: visible; width: 128px;"></div>
     </div>
     <div style="position: absolute; left: 640.572px; top: 386.574px; -moz-transform: scale(1); z-index: -157863;">
       <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
     </div>
     <div style="position: absolute; left: 568.346px; top: 582.669px; -moz-transform: scale(1); z-index: -62592;">
       <div style="position: absolute; top: -64px; left: -64px; width: 128px; height: 128px; visibility: visible;"></div>
--- a/layout/reftests/transform/601894-2.html
+++ b/layout/reftests/transform/601894-2.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <html>
-  <body style="background: -moz-linear-gradient(lime, lime) fixed;">
+  <body style="background: linear-gradient(lime, lime) fixed;">
     <div style="position: absolute; left: 0; top: 0; -moz-transform: scale(1)">
       <div style="position: absolute; width: 200px; height: 200px;"></div>
     </div>
   </body>
 </html>
--- a/layout/style/crashtests/large_border_image_width.html
+++ b/layout/style/crashtests/large_border_image_width.html
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html>
 <head>
 </head>
 <body>
-<div style="border: 10px solid transparent; border-image-source: -moz-linear-gradient(0rad, blue 25px, green 25px); border-image-width: 5464618830153;"></div>
+<div style="border: 10px solid transparent; border-image-source: linear-gradient(90deg, blue 25px, green 25px); border-image-width: 5464618830153;"></div>
 </body>
 </html>
 
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -1092,22 +1092,18 @@ protected:
   bool ParseSymbols(nsCSSValue& aValue);
   bool SetValueToURL(nsCSSValue& aValue, const nsString& aURL);
   bool TranslateDimension(nsCSSValue& aValue, int32_t aVariantMask,
                             float aNumber, const nsString& aUnit);
   bool ParseImageOrientation(nsCSSValue& aAngle);
   bool ParseImageRect(nsCSSValue& aImage);
   bool ParseElement(nsCSSValue& aValue);
   bool ParseColorStop(nsCSSValueGradient* aGradient);
-  bool ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating,
-                           bool aIsLegacy);
-  bool ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating,
-                           bool aIsLegacy);
-  bool IsLegacyGradientLine(const nsCSSTokenType& aType,
-                            const nsString& aId);
+  bool ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating);
+  bool ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating);
   bool ParseGradientColorStops(nsCSSValueGradient* aGradient,
                                nsCSSValue& aValue);
 
   void SetParsingCompoundProperty(bool aBool) {
     mParsingCompoundProperty = aBool;
   }
   bool IsParsingCompoundProperty(void) const {
     return mParsingCompoundProperty;
@@ -6766,20 +6762,20 @@ CSSParserImpl::ParseWebkitPrefixedGradie
   // about to put into the CSS parser is a faithful representation of what it
   // would've seen if it were just parsing the original input stream):
   if (gotCloseParen) {
     unprefixedFuncBody.Append(char16_t(')'));
   }
 
   nsAutoScannerChanger scannerChanger(this, unprefixedFuncBody);
   if (unprefixedFuncName.EqualsLiteral("linear-gradient")) {
-    return ParseLinearGradient(aValue, false, false);
+    return ParseLinearGradient(aValue, false);
   }
   if (unprefixedFuncName.EqualsLiteral("radial-gradient")) {
-    return ParseRadialGradient(aValue, false, false);
+    return ParseRadialGradient(aValue, false);
   }
 
   NS_ERROR("CSSUnprefixingService returned an unrecognized type of "
            "gradient function");
 
   return false;
 }
 
@@ -7402,35 +7398,29 @@ CSSParserImpl::ParseVariant(nsCSSValue& 
       eCSSToken_URL == tk->mType) {
     SetValueToURL(aValue, tk->mIdent);
     return true;
   }
   if ((aVariantMask & VARIANT_GRADIENT) != 0 &&
       eCSSToken_Function == tk->mType) {
     // a generated gradient
     nsDependentString tmp(tk->mIdent, 0);
-    bool isLegacy = false;
-    if (StringBeginsWith(tmp, NS_LITERAL_STRING("-moz-"))) {
-      tmp.Rebind(tmp, 5);
-      isLegacy = true;
-    }
     bool isRepeating = false;
     if (StringBeginsWith(tmp, NS_LITERAL_STRING("repeating-"))) {
       tmp.Rebind(tmp, 10);
       isRepeating = true;
     }
 
     if (tmp.LowerCaseEqualsLiteral("linear-gradient")) {
-      return ParseLinearGradient(aValue, isRepeating, isLegacy);
+      return ParseLinearGradient(aValue, isRepeating);
     }
     if (tmp.LowerCaseEqualsLiteral("radial-gradient")) {
-      return ParseRadialGradient(aValue, isRepeating, isLegacy);
-    }
-    if (ShouldUseUnprefixingService() &&
-        !isRepeating && !isLegacy &&
+      return ParseRadialGradient(aValue, isRepeating);
+    }
+    if (ShouldUseUnprefixingService() && !isRepeating &&
         StringBeginsWith(tmp, NS_LITERAL_STRING("-webkit-"))) {
       // Copy 'tmp' into a string on the stack, since as soon as we
       // start parsing, its backing store (in "tk") will be overwritten
       nsAutoString prefixedFuncName(tmp);
       return ParseWebkitPrefixedGradient(prefixedFuncName, aValue);
     }
   }
   if ((aVariantMask & VARIANT_IMAGE_RECT) != 0 &&
@@ -9184,34 +9174,25 @@ CSSParserImpl::ParseColorStop(nsCSSValue
   return true;
 }
 
 // <gradient>
 //    : linear-gradient( <linear-gradient-line>? <color-stops> ')'
 //    | radial-gradient( <radial-gradient-line>? <color-stops> ')'
 //
 // <linear-gradient-line> : [ to [left | right] || [top | bottom] ] ,
-//                        | <legacy-gradient-line>
 // <radial-gradient-line> : [ <shape> || <size> ] [ at <position> ]? ,
 //                        | [ at <position> ] ,
-//                        | <legacy-gradient-line>? <legacy-shape-size>?
 // <shape> : circle | ellipse
 // <size> : closest-side | closest-corner | farthest-side | farthest-corner
 //        | <length> | [<length> | <percentage>]{2}
 //
-// <legacy-gradient-line> : [ <position> || <angle>] ,
-//
-// <legacy-shape-size> : [ <shape> || <legacy-size> ] ,
-// <legacy-size> : closest-side | closest-corner | farthest-side
-//               | farthest-corner | contain | cover
-//
 // <color-stops> : <color-stop> , <color-stop> [, <color-stop>]*
 bool
-CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating,
-                                   bool aIsLegacy)
+CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating)
 {
   nsRefPtr<nsCSSValueGradient> cssGradient
     = new nsCSSValueGradient(false, aIsRepeating);
 
   if (!GetToken(true)) {
     return false;
   }
 
@@ -9242,86 +9223,48 @@ CSSParserImpl::ParseLinearGradient(nsCSS
     if (!ExpectSymbol(',', true)) {
       SkipUntil(')');
       return false;
     }
 
     return ParseGradientColorStops(cssGradient, aValue);
   }
 
-  if (!aIsLegacy) {
-    UngetToken();
-
-    // <angle> ,
-    if (ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) &&
-        !ExpectSymbol(',', true)) {
-      SkipUntil(')');
-      return false;
-    }
-
-    return ParseGradientColorStops(cssGradient, aValue);
-  }
-
-  nsCSSTokenType ty = mToken.mType;
-  nsString id = mToken.mIdent;
   UngetToken();
 
-  // <legacy-gradient-line>
-  bool haveGradientLine = IsLegacyGradientLine(ty, id);
-  if (haveGradientLine) {
-    cssGradient->mIsLegacySyntax = true;
-    bool haveAngle =
-      ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr);
-
-    // if we got an angle, we might now have a comma, ending the gradient-line
-    if (!haveAngle || !ExpectSymbol(',', true)) {
-      if (!ParseBoxPositionValues(cssGradient->mBgPos, false)) {
-        SkipUntil(')');
-        return false;
-      }
-
-      if (!ExpectSymbol(',', true) &&
-          // if we didn't already get an angle, we might have one now,
-          // otherwise it's an error
-          (haveAngle ||
-           !ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) ||
-           // now we better have a comma
-           !ExpectSymbol(',', true))) {
-        SkipUntil(')');
-        return false;
-      }
-    }
+  // <angle> ,
+  if (ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) &&
+      !ExpectSymbol(',', true)) {
+    SkipUntil(')');
+    return false;
   }
 
   return ParseGradientColorStops(cssGradient, aValue);
 }
 
 bool
-CSSParserImpl::ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating,
-                                   bool aIsLegacy)
+CSSParserImpl::ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating)
 {
   nsRefPtr<nsCSSValueGradient> cssGradient
     = new nsCSSValueGradient(true, aIsRepeating);
 
   // [ <shape> || <size> ]
   bool haveShape =
     ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
                  nsCSSProps::kRadialGradientShapeKTable);
 
   bool haveSize = ParseVariant(cssGradient->GetRadialSize(), VARIANT_KEYWORD,
-                               aIsLegacy ?
-                               nsCSSProps::kRadialGradientLegacySizeKTable :
                                nsCSSProps::kRadialGradientSizeKTable);
   if (haveSize) {
     if (!haveShape) {
       // <size> <shape>
       haveShape = ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
                                nsCSSProps::kRadialGradientShapeKTable);
     }
-  } else if (!aIsLegacy) {
+  } else {
     // Save RadialShape before parsing RadiusX because RadialShape and
     // RadiusX share the storage.
     int32_t shape =
       cssGradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated ?
       cssGradient->GetRadialShape().GetIntValue() : -1;
     // <length> | [<length> | <percentage>]{2}
     cssGradient->mIsExplicitSize = true;
     haveSize =
@@ -9362,151 +9305,34 @@ CSSParserImpl::ParseRadialGradient(nsCSS
     // [ <shape> || <size> ] ,
     return ParseGradientColorStops(cssGradient, aValue);
   }
 
   if (!GetToken(true)) {
     return false;
   }
 
-  if (!aIsLegacy) {
-    if (mToken.mType == eCSSToken_Ident &&
-        mToken.mIdent.LowerCaseEqualsLiteral("at")) {
-      // [ <shape> || <size> ]? at <position> ,
-      if (!ParseBoxPositionValues(cssGradient->mBgPos, false) ||
-          !ExpectSymbol(',', true)) {
-        SkipUntil(')');
-        return false;
-      }
-
-      return ParseGradientColorStops(cssGradient, aValue);
-    }
-
-    // <color-stops> only
-    UngetToken();
+  if (mToken.mType == eCSSToken_Ident &&
+      mToken.mIdent.LowerCaseEqualsLiteral("at")) {
+    // [ <shape> || <size> ]? at <position> ,
+    if (!ParseBoxPositionValues(cssGradient->mBgPos, false) ||
+        !ExpectSymbol(',', true)) {
+      SkipUntil(')');
+      return false;
+    }
+
     return ParseGradientColorStops(cssGradient, aValue);
   }
-  MOZ_ASSERT(!cssGradient->mIsExplicitSize);
-
-  nsCSSTokenType ty = mToken.mType;
-  nsString id = mToken.mIdent;
+
+  // <color-stops> only
   UngetToken();
-
-  // <legacy-gradient-line>
-  bool haveGradientLine = false;
-  // if we already encountered a shape or size,
-  // we can not have a gradient-line in legacy syntax
-  if (!haveShape && !haveSize) {
-      haveGradientLine = IsLegacyGradientLine(ty, id);
-  }
-  if (haveGradientLine) {
-    bool haveAngle =
-      ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr);
-
-    // if we got an angle, we might now have a comma, ending the gradient-line
-    if (!haveAngle || !ExpectSymbol(',', true)) {
-      if (!ParseBoxPositionValues(cssGradient->mBgPos, false)) {
-        SkipUntil(')');
-        return false;
-      }
-
-      if (!ExpectSymbol(',', true) &&
-          // if we didn't already get an angle, we might have one now,
-          // otherwise it's an error
-          (haveAngle ||
-           !ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) ||
-           // now we better have a comma
-           !ExpectSymbol(',', true))) {
-        SkipUntil(')');
-        return false;
-      }
-    }
-
-    if (cssGradient->mAngle.GetUnit() != eCSSUnit_None) {
-      cssGradient->mIsLegacySyntax = true;
-    }
-  }
-
-  // radial gradients might have a shape and size here for legacy syntax
-  if (!haveShape && !haveSize) {
-    haveShape =
-      ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
-                   nsCSSProps::kRadialGradientShapeKTable);
-    haveSize =
-      ParseVariant(cssGradient->GetRadialSize(), VARIANT_KEYWORD,
-                   nsCSSProps::kRadialGradientLegacySizeKTable);
-
-    // could be in either order
-    if (!haveShape) {
-      haveShape =
-        ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
-                     nsCSSProps::kRadialGradientShapeKTable);
-    }
-  }
-
-  if ((haveShape || haveSize) && !ExpectSymbol(',', true)) {
-    SkipUntil(')');
-    return false;
-  }
-
   return ParseGradientColorStops(cssGradient, aValue);
 }
 
 bool
-CSSParserImpl::IsLegacyGradientLine(const nsCSSTokenType& aType,
-                                    const nsString& aId)
-{
-  // N.B. ParseBoxPositionValues is not guaranteed to put back
-  // everything it scanned if it fails, so we must only call it
-  // if there is no alternative to consuming a <box-position>.
-  // ParseVariant, as used here, will either succeed and consume
-  // a single token, or fail and consume none, so we can be more
-  // cavalier about calling it.
-
-  bool haveGradientLine = false;
-  switch (aType) {
-  case eCSSToken_Percentage:
-  case eCSSToken_Number:
-  case eCSSToken_Dimension:
-    haveGradientLine = true;
-    break;
-
-  case eCSSToken_Function:
-    if (aId.LowerCaseEqualsLiteral("calc") ||
-        aId.LowerCaseEqualsLiteral("-moz-calc")) {
-      haveGradientLine = true;
-      break;
-    }
-    // fall through
-  case eCSSToken_ID:
-  case eCSSToken_Hash:
-    // this is a color
-    break;
-
-  case eCSSToken_Ident: {
-    // This is only a gradient line if it's a box position keyword.
-    nsCSSKeyword kw = nsCSSKeywords::LookupKeyword(aId);
-    int32_t junk;
-    if (kw != eCSSKeyword_UNKNOWN &&
-        nsCSSProps::FindKeyword(kw, nsCSSProps::kBackgroundPositionKTable,
-                                junk)) {
-      haveGradientLine = true;
-    }
-    break;
-  }
-
-  default:
-    // error
-    break;
-  }
-
-  return haveGradientLine;
-}
-
-bool
 CSSParserImpl::ParseGradientColorStops(nsCSSValueGradient* aGradient,
                                        nsCSSValue& aValue)
 {
   // At least two color stops are required
   if (!ParseColorStop(aGradient) ||
       !ExpectSymbol(',', true) ||
       !ParseColorStop(aGradient)) {
     SkipUntil(')');
@@ -10747,20 +10573,16 @@ CSSParserImpl::ParseBackgroundItem(CSSPa
         }
       }
     } else if (tt == eCSSToken_URL ||
                (tt == eCSSToken_Function &&
                 (mToken.mIdent.LowerCaseEqualsLiteral("linear-gradient") ||
                  mToken.mIdent.LowerCaseEqualsLiteral("radial-gradient") ||
                  mToken.mIdent.LowerCaseEqualsLiteral("repeating-linear-gradient") ||
                  mToken.mIdent.LowerCaseEqualsLiteral("repeating-radial-gradient") ||
-                 mToken.mIdent.LowerCaseEqualsLiteral("-moz-linear-gradient") ||
-                 mToken.mIdent.LowerCaseEqualsLiteral("-moz-radial-gradient") ||
-                 mToken.mIdent.LowerCaseEqualsLiteral("-moz-repeating-linear-gradient") ||
-                 mToken.mIdent.LowerCaseEqualsLiteral("-moz-repeating-radial-gradient") ||
                  mToken.mIdent.LowerCaseEqualsLiteral("-moz-image-rect") ||
                  mToken.mIdent.LowerCaseEqualsLiteral("-moz-element") ||
                  (ShouldUseUnprefixingService() &&
                   (mToken.mIdent.LowerCaseEqualsLiteral("-webkit-gradient") ||
                    mToken.mIdent.LowerCaseEqualsLiteral("-webkit-linear-gradient") ||
                    mToken.mIdent.LowerCaseEqualsLiteral("-webkit-radial-gradient")))))) {
       if (haveImage)
         return false;
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1623,27 +1623,16 @@ const KTableValue nsCSSProps::kRadialGra
 const KTableValue nsCSSProps::kRadialGradientSizeKTable[] = {
   eCSSKeyword_closest_side,    NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE,
   eCSSKeyword_closest_corner,  NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER,
   eCSSKeyword_farthest_side,   NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE,
   eCSSKeyword_farthest_corner, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER,
   eCSSKeyword_UNKNOWN,-1
 };
 
-const KTableValue nsCSSProps::kRadialGradientLegacySizeKTable[] = {
-  eCSSKeyword_closest_side,    NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE,
-  eCSSKeyword_closest_corner,  NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER,
-  eCSSKeyword_farthest_side,   NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE,
-  eCSSKeyword_farthest_corner, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER,
-  // synonyms
-  eCSSKeyword_contain,         NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE,
-  eCSSKeyword_cover,           NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER,
-  eCSSKeyword_UNKNOWN,-1
-};
-
 const KTableValue nsCSSProps::kResizeKTable[] = {
   eCSSKeyword_none,       NS_STYLE_RESIZE_NONE,
   eCSSKeyword_both,       NS_STYLE_RESIZE_BOTH,
   eCSSKeyword_horizontal, NS_STYLE_RESIZE_HORIZONTAL,
   eCSSKeyword_vertical,   NS_STYLE_RESIZE_VERTICAL,
   eCSSKeyword_UNKNOWN,-1
 };
 
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -664,17 +664,16 @@ public:
   static const KTableValue kPageSizeKTable[];
   static const KTableValue kPitchKTable[];
   static const KTableValue kPointerEventsKTable[];
   // Not const because we modify its entries when the pref
   // "layout.css.sticky.enabled" changes:
   static KTableValue kPositionKTable[];
   static const KTableValue kRadialGradientShapeKTable[];
   static const KTableValue kRadialGradientSizeKTable[];
-  static const KTableValue kRadialGradientLegacySizeKTable[];
   static const KTableValue kResizeKTable[];
   static const KTableValue kRubyAlignKTable[];
   static const KTableValue kRubyPositionKTable[];
   static const KTableValue kScrollBehaviorKTable[];
   static const KTableValue kScrollSnapTypeKTable[];
   static const KTableValue kSpeakKTable[];
   static const KTableValue kSpeakHeaderKTable[];
   static const KTableValue kSpeakNumeralKTable[];
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -1391,30 +1391,27 @@ nsCSSValue::AppendToString(nsCSSProperty
     aResult.AppendFloat(GetPercentValue() * 100.0f);
   }
   else if (eCSSUnit_Percent < unit) {  // length unit
     aResult.AppendFloat(GetFloatValue());
   }
   else if (eCSSUnit_Gradient == unit) {
     nsCSSValueGradient* gradient = GetGradientValue();
 
-    if (gradient->mIsLegacySyntax) {
-      aResult.AppendLiteral("-moz-");
-    }
     if (gradient->mIsRepeating) {
       aResult.AppendLiteral("repeating-");
     }
     if (gradient->mIsRadial) {
       aResult.AppendLiteral("radial-gradient(");
     } else {
       aResult.AppendLiteral("linear-gradient(");
     }
 
     bool needSep = false;
-    if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
+    if (gradient->mIsRadial) {
       if (!gradient->mIsExplicitSize) {
         if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
           MOZ_ASSERT(gradient->GetRadialShape().GetUnit() ==
                      eCSSUnit_Enumerated,
                      "bad unit for radial gradient shape");
           int32_t intValue = gradient->GetRadialShape().GetIntValue();
           MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
                      "radial gradient with linear shape?!");
@@ -1444,17 +1441,17 @@ nsCSSValue::AppendToString(nsCSSProperty
         if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) {
           aResult.Append(' ');
           gradient->GetRadiusY().AppendToString(aProperty, aResult,
                                                 aSerialization);
         }
         needSep = true;
       }
     }
-    if (!gradient->mIsRadial && !gradient->mIsLegacySyntax) {
+    if (!gradient->mIsRadial) {
       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
           gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
         MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None);
         MOZ_ASSERT(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
                    gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
                    "unexpected unit");
         aResult.AppendLiteral("to");
         if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
@@ -1473,66 +1470,34 @@ nsCSSValue::AppendToString(nsCSSProperty
         needSep = true;
       }
     } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
         gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
         gradient->mAngle.GetUnit() != eCSSUnit_None) {
       if (needSep) {
         aResult.Append(' ');
       }
-      if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
+      if (gradient->mIsRadial) {
         aResult.AppendLiteral("at ");
       }
       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
         gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
                                                 aResult, aSerialization);
         aResult.Append(' ');
       }
       if (gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
         gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
                                                 aResult, aSerialization);
         aResult.Append(' ');
       }
-      if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->mIsLegacySyntax,
-                   "angle is allowed only for legacy syntax");
-        gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
-      }
+      MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None,
+                 "angle is not allowed for radial gradients");
       needSep = true;
     }
 
-    if (gradient->mIsRadial && gradient->mIsLegacySyntax &&
-        (gradient->GetRadialShape().GetUnit() != eCSSUnit_None ||
-         gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) {
-      MOZ_ASSERT(!gradient->mIsExplicitSize);
-      if (needSep) {
-        aResult.AppendLiteral(", ");
-      }
-      if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated,
-                   "bad unit for radial gradient shape");
-        int32_t intValue = gradient->GetRadialShape().GetIntValue();
-        MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
-                   "radial gradient with linear shape?!");
-        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                               nsCSSProps::kRadialGradientShapeKTable),
-                           aResult);
-        aResult.Append(' ');
-      }
-
-      if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->GetRadialSize().GetUnit() == eCSSUnit_Enumerated,
-                   "bad unit for radial gradient size");
-        int32_t intValue = gradient->GetRadialSize().GetIntValue();
-        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                               nsCSSProps::kRadialGradientSizeKTable),
-                           aResult);
-      }
-      needSep = true;
-    }
     if (needSep) {
       aResult.AppendLiteral(", ");
     }
 
     for (uint32_t i = 0 ;;) {
       bool isInterpolationHint = gradient->mStops[i].mIsInterpolationHint;
       if (!isInterpolationHint) {
         gradient->mStops[i].mColor.AppendToString(aProperty, aResult,
@@ -2503,17 +2468,16 @@ nsCSSValueGradientStop::SizeOfExcludingT
   n += mColor   .SizeOfExcludingThis(aMallocSizeOf);
   return n;
 }
 
 nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
                                        bool aIsRepeating)
   : mIsRadial(aIsRadial),
     mIsRepeating(aIsRepeating),
-    mIsLegacySyntax(false),
     mIsExplicitSize(false),
     mBgPos(eCSSUnit_None),
     mAngle(eCSSUnit_None)
 {
   mRadialValues[0].SetNoneValue();
   mRadialValues[1].SetNoneValue();
 }
 
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -1379,17 +1379,16 @@ public:
 };
 
 struct nsCSSValueGradient final {
   nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
 
   // true if gradient is radial, false if it is linear
   bool mIsRadial;
   bool mIsRepeating;
-  bool mIsLegacySyntax;
   bool mIsExplicitSize;
   // line position and angle
   nsCSSValuePair mBgPos;
   nsCSSValue mAngle;
 
   // Only meaningful if mIsRadial is true
 private:
   nsCSSValue mRadialValues[2];
@@ -1436,17 +1435,16 @@ public:
   }
 
   InfallibleTArray<nsCSSValueGradientStop> mStops;
 
   bool operator==(const nsCSSValueGradient& aOther) const
   {
     if (mIsRadial != aOther.mIsRadial ||
         mIsRepeating != aOther.mIsRepeating ||
-        mIsLegacySyntax != aOther.mIsLegacySyntax ||
         mIsExplicitSize != aOther.mIsExplicitSize ||
         mBgPos != aOther.mBgPos ||
         mAngle != aOther.mAngle ||
         mRadialValues[0] != aOther.mRadialValues[0] ||
         mRadialValues[1] != aOther.mRadialValues[1])
       return false;
 
     if (mStops.Length() != aOther.mStops.Length())
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1837,36 +1837,32 @@ AppendCSSGradientToBoxPosition(const nsS
 
   aNeedSep = true;
 }
 
 void
 nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient,
                                          nsAString& aString)
 {
-  if (!aGradient->mLegacySyntax) {
-    aString.Truncate();
-  } else {
-    aString.AssignLiteral("-moz-");
-  }
+  aString.Truncate();
   if (aGradient->mRepeating) {
     aString.AppendLiteral("repeating-");
   }
   bool isRadial = aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR;
   if (isRadial) {
     aString.AppendLiteral("radial-gradient(");
   } else {
     aString.AppendLiteral("linear-gradient(");
   }
 
   bool needSep = false;
   nsAutoString tokenString;
   nsRefPtr<nsROCSSPrimitiveValue> tmpVal = new nsROCSSPrimitiveValue;
 
-  if (isRadial && !aGradient->mLegacySyntax) {
+  if (isRadial) {
     if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE) {
       if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
         aString.AppendLiteral("circle");
         needSep = true;
       }
       if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) {
         if (needSep) {
           aString.Append(' ');
@@ -1883,71 +1879,46 @@ nsComputedDOMStyle::GetCSSGradientString
         aString.Append(' ');
         AppendCSSGradientLength(aGradient->mRadiusY, tmpVal, aString);
       }
       needSep = true;
     }
   }
   if (aGradient->mBgPosX.GetUnit() != eStyleUnit_None) {
     MOZ_ASSERT(aGradient->mBgPosY.GetUnit() != eStyleUnit_None);
-    if (!isRadial && !aGradient->mLegacySyntax) {
+    if (!isRadial) {
       AppendCSSGradientToBoxPosition(aGradient, aString, needSep);
     } else if (aGradient->mBgPosX.GetUnit() != eStyleUnit_Percent ||
                aGradient->mBgPosX.GetPercentValue() != 0.5f ||
                aGradient->mBgPosY.GetUnit() != eStyleUnit_Percent ||
                aGradient->mBgPosY.GetPercentValue() != (isRadial ? 0.5f : 1.0f)) {
-      if (isRadial && !aGradient->mLegacySyntax) {
+      if (isRadial) {
         if (needSep) {
           aString.Append(' ');
         }
         aString.AppendLiteral("at ");
         needSep = false;
       }
       AppendCSSGradientLength(aGradient->mBgPosX, tmpVal, aString);
       if (aGradient->mBgPosY.GetUnit() != eStyleUnit_None) {
         aString.Append(' ');
         AppendCSSGradientLength(aGradient->mBgPosY, tmpVal, aString);
       }
       needSep = true;
     }
   }
   if (aGradient->mAngle.GetUnit() != eStyleUnit_None) {
-    MOZ_ASSERT(!isRadial || aGradient->mLegacySyntax);
+    MOZ_ASSERT(!isRadial);
     if (needSep) {
       aString.Append(' ');
     }
     nsStyleUtil::AppendAngleValue(aGradient->mAngle, aString);
     needSep = true;
   }
 
-  if (isRadial && aGradient->mLegacySyntax &&
-      (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR ||
-       aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)) {
-    MOZ_ASSERT(aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE);
-    if (needSep) {
-      aString.AppendLiteral(", ");
-      needSep = false;
-    }
-    if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
-      aString.AppendLiteral("circle");
-      needSep = true;
-    }
-    if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) {
-      if (needSep) {
-        aString.Append(' ');
-      }
-      AppendASCIItoUTF16(nsCSSProps::
-                         ValueToKeyword(aGradient->mSize,
-                                        nsCSSProps::kRadialGradientSizeKTable),
-                         aString);
-    }
-    needSep = true;
-  }
-
-
   // color stops
   for (uint32_t i = 0; i < aGradient->mStops.Length(); ++i) {
     if (needSep) {
       aString.AppendLiteral(", ");
     }
 
     const auto& stop = aGradient->mStops[i];
     if (!stop.mIsInterpolationHint) {
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1085,18 +1085,16 @@ static void SetGradient(const nsCSSValue
     NS_ASSERTION(gradient->GetRadialShape().GetUnit() == eCSSUnit_None,
                  "bad unit for linear shape");
     NS_ASSERTION(gradient->GetRadialSize().GetUnit() == eCSSUnit_None,
                  "bad unit for linear size");
     aResult.mShape = NS_STYLE_GRADIENT_SHAPE_LINEAR;
     aResult.mSize = NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER;
   }
 
-  aResult.mLegacySyntax = gradient->mIsLegacySyntax;
-
   // bg-position
   SetGradientCoord(gradient->mBgPos.mXValue, aPresContext, aContext,
                    aResult.mBgPosX, aConditions);
 
   SetGradientCoord(gradient->mBgPos.mYValue, aPresContext, aContext,
                    aResult.mBgPosY, aConditions);
 
   aResult.mRepeating = gradient->mIsRepeating;
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1761,17 +1761,16 @@ nsStyleGradient::operator==(const nsStyl
              "incorrect combination of shape and size");
   MOZ_ASSERT(aOther.mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
              aOther.mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
              "incorrect combination of shape and size");
 
   if (mShape != aOther.mShape ||
       mSize != aOther.mSize ||
       mRepeating != aOther.mRepeating ||
-      mLegacySyntax != aOther.mLegacySyntax ||
       mBgPosX != aOther.mBgPosX ||
       mBgPosY != aOther.mBgPosY ||
       mAngle != aOther.mAngle ||
       mRadiusX != aOther.mRadiusX ||
       mRadiusY != aOther.mRadiusY)
     return false;
 
   if (mStops.Length() != aOther.mStops.Length())
@@ -1788,17 +1787,16 @@ nsStyleGradient::operator==(const nsStyl
 
   return true;
 }
 
 nsStyleGradient::nsStyleGradient(void)
   : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR)
   , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)
   , mRepeating(false)
-  , mLegacySyntax(false)
 {
 }
 
 bool
 nsStyleGradient::IsOpaque()
 {
   for (uint32_t i = 0; i < mStops.Length(); i++) {
     if (NS_GET_A(mStops[i].mColor) < 255)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -154,17 +154,16 @@ struct nsStyleGradientStop {
 
 class nsStyleGradient final {
 public:
   nsStyleGradient();
   uint8_t mShape;  // NS_STYLE_GRADIENT_SHAPE_*
   uint8_t mSize;   // NS_STYLE_GRADIENT_SIZE_*;
                    // not used (must be FARTHEST_CORNER) for linear shape
   bool mRepeating;
-  bool mLegacySyntax;
 
   nsStyleCoord mBgPosX; // percent, coord, calc, none
   nsStyleCoord mBgPosY; // percent, coord, calc, none
   nsStyleCoord mAngle;  // none, angle
 
   nsStyleCoord mRadiusX; // percent, coord, calc, none
   nsStyleCoord mRadiusY; // percent, coord, calc, none
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -98,67 +98,16 @@ var validGradientAndElementValues = [
   "linear-gradient(.414rad, red 50%, 50%, blue 50%)",
   "linear-gradient(.414rad, red 50%, 20%, blue 50%)",
   "linear-gradient(.414rad, red 50%, 30%, blue 10%)",
   "linear-gradient(to right bottom, red, 20%, green 50%, 65%, blue)",
   "linear-gradient(to right bottom, red, 20%, green 10%, blue)",
   "linear-gradient(to right bottom, red, 50%, green 50%, 50%, blue)",
   "linear-gradient(to right bottom, red, 0%, green 50%, 100%, blue)",
 
-  "-moz-linear-gradient(red, blue)",
-  "-moz-linear-gradient(red, yellow, blue)",
-  "-moz-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
-  "-moz-linear-gradient(red, yellow, green, blue 50%)",
-  "-moz-linear-gradient(red -50%, yellow -25%, green, blue)",
-  "-moz-linear-gradient(red -99px, yellow, green, blue 120%)",
-  "-moz-linear-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
-  "-moz-linear-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
-
-  "-moz-linear-gradient(to top, red, blue)",
-  "-moz-linear-gradient(to bottom, red, blue)",
-  "-moz-linear-gradient(to left, red, blue)",
-  "-moz-linear-gradient(to right, red, blue)",
-  "-moz-linear-gradient(to top left, red, blue)",
-  "-moz-linear-gradient(to top right, red, blue)",
-  "-moz-linear-gradient(to bottom left, red, blue)",
-  "-moz-linear-gradient(to bottom right, red, blue)",
-  "-moz-linear-gradient(to left top, red, blue)",
-  "-moz-linear-gradient(to left bottom, red, blue)",
-  "-moz-linear-gradient(to right top, red, blue)",
-  "-moz-linear-gradient(to right bottom, red, blue)",
-
-  "-moz-linear-gradient(top left, red, blue)",
-  "-moz-linear-gradient(0 0, red, blue)",
-  "-moz-linear-gradient(20% bottom, red, blue)",
-  "-moz-linear-gradient(center 20%, red, blue)",
-  "-moz-linear-gradient(left 35px, red, blue)",
-  "-moz-linear-gradient(10% 10em, red, blue)",
-  "-moz-linear-gradient(44px top, red, blue)",
-
-  "-moz-linear-gradient(top left 45deg, red, blue)",
-  "-moz-linear-gradient(20% bottom -300deg, red, blue)",
-  "-moz-linear-gradient(center 20% 1.95929rad, red, blue)",
-  "-moz-linear-gradient(left 35px 30grad, red, blue)",
-  "-moz-linear-gradient(left 35px 0.1turn, red, blue)",
-  "-moz-linear-gradient(10% 10em 99999deg, red, blue)",
-  "-moz-linear-gradient(44px top -33deg, red, blue)",
-
-  "-moz-linear-gradient(-33deg, red, blue)",
-  "-moz-linear-gradient(30grad left 35px, red, blue)",
-  "-moz-linear-gradient(10deg 20px, red, blue)",
-  "-moz-linear-gradient(1turn 20px, red, blue)",
-  "-moz-linear-gradient(.414rad bottom, red, blue)",
-
-  "-moz-linear-gradient(blue calc(0px) ,green calc(25%) ,red calc(40px) ,blue calc(60px) , yellow  calc(100px))",
-  "-moz-linear-gradient(-33deg, blue calc(-25%) ,red 40px)",
-  "-moz-linear-gradient(10deg, blue calc(100px + -25%),red calc(40px))",
-  "-moz-linear-gradient(10deg, blue calc(-25px),red calc(100%))",
-  "-moz-linear-gradient(.414rad, blue calc(100px + -25px) ,green calc(100px + -25px) ,red calc(100px + -25%) ,blue calc(-25px) , yellow  calc(-25px))",
-  "-moz-linear-gradient(1turn, blue calc(-25%) ,green calc(25px) ,red calc(25%),blue calc(0px),white 50px, yellow  calc(-25px))",
-
   "radial-gradient(red, blue)",
   "radial-gradient(red, yellow, blue)",
   "radial-gradient(red 1px, yellow 20%, blue 24em, green)",
   "radial-gradient(red, yellow, green, blue 50%)",
   "radial-gradient(red -50%, yellow -25%, green, blue)",
   "radial-gradient(red -99px, yellow, green, blue 120%)",
   "radial-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
 
@@ -172,22 +121,23 @@ var validGradientAndElementValues = [
   "radial-gradient(at 10% 10em, red, blue)",
   "radial-gradient(at 44px top, red, blue)",
   "radial-gradient(at 0 0, red, blue)",
 
   "radial-gradient(farthest-corner, red, blue)",
   "radial-gradient(circle, red, blue)",
   "radial-gradient(ellipse closest-corner, red, blue)",
   "radial-gradient(closest-corner ellipse, red, blue)",
+  "radial-gradient(farthest-side circle, red, blue)",
 
-  "radial-gradient(43px, red, blue)",
-  "radial-gradient(43px 43px, red, blue)",
-  "radial-gradient(50% 50%, red, blue)",
-  "radial-gradient(43px 50%, red, blue)",
-  "radial-gradient(50% 43px, red, blue)",
+  "radial-gradient(at 43px, red, blue)",
+  "radial-gradient(at 43px 43px, red, blue)",
+  "radial-gradient(at 50% 50%, red, blue)",
+  "radial-gradient(at 43px 50%, red, blue)",
+  "radial-gradient(at 50% 43px, red, blue)",
   "radial-gradient(circle 43px, red, blue)",
   "radial-gradient(43px circle, red, blue)",
   "radial-gradient(ellipse 43px 43px, red, blue)",
   "radial-gradient(ellipse 50% 50%, red, blue)",
   "radial-gradient(ellipse 43px 50%, red, blue)",
   "radial-gradient(ellipse 50% 43px, red, blue)",
   "radial-gradient(50% 43px ellipse, red, blue)",
 
@@ -196,315 +146,84 @@ var validGradientAndElementValues = [
   "radial-gradient(circle farthest-side at 45px, red, blue)",
   "radial-gradient(closest-side ellipse at 50%, red, blue)",
   "radial-gradient(farthest-corner circle at 4em, red, blue)",
 
   "radial-gradient(30% 40% at top left, red, blue)",
   "radial-gradient(50px 60px at 15% 20%, red, blue)",
   "radial-gradient(7em 8em at 45px, red, blue)",
 
-  "-moz-radial-gradient(red, blue)",
-  "-moz-radial-gradient(red, yellow, blue)",
-  "-moz-radial-gradient(red 1px, yellow 20%, blue 24em, green)",
-  "-moz-radial-gradient(red, yellow, green, blue 50%)",
-  "-moz-radial-gradient(red -50%, yellow -25%, green, blue)",
-  "-moz-radial-gradient(red -99px, yellow, green, blue 120%)",
-  "-moz-radial-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
-
-  "-moz-radial-gradient(top left, red, blue)",
-  "-moz-radial-gradient(20% bottom, red, blue)",
-  "-moz-radial-gradient(center 20%, red, blue)",
-  "-moz-radial-gradient(left 35px, red, blue)",
-  "-moz-radial-gradient(10% 10em, red, blue)",
-  "-moz-radial-gradient(44px top, red, blue)",
-
-  "-moz-radial-gradient(top left 45deg, red, blue)",
-  "-moz-radial-gradient(0 0, red, blue)",
-  "-moz-radial-gradient(20% bottom -300deg, red, blue)",
-  "-moz-radial-gradient(center 20% 1.95929rad, red, blue)",
-  "-moz-radial-gradient(left 35px 30grad, red, blue)",
-  "-moz-radial-gradient(10% 10em 99999deg, red, blue)",
-  "-moz-radial-gradient(44px top -33deg, red, blue)",
-  "-moz-radial-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
-
-  "-moz-radial-gradient(-33deg, red, blue)",
-  "-moz-radial-gradient(30grad left 35px, red, blue)",
-  "-moz-radial-gradient(10deg 20px, red, blue)",
-  "-moz-radial-gradient(.414rad bottom, red, blue)",
-
-  "-moz-radial-gradient(cover, red, blue)",
-  "-moz-radial-gradient(circle, red, blue)",
-  "-moz-radial-gradient(ellipse closest-corner, red, blue)",
-  "-moz-radial-gradient(farthest-side circle, red, blue)",
-
-  "-moz-radial-gradient(top left, cover, red, blue)",
-  "-moz-radial-gradient(15% 20%, circle, red, blue)",
-  "-moz-radial-gradient(45px, ellipse closest-corner, red, blue)",
-  "-moz-radial-gradient(45px, farthest-side circle, red, blue)",
-
-  "-moz-radial-gradient(99deg, cover, red, blue)",
-  "-moz-radial-gradient(-1.2345rad, circle, red, blue)",
-  "-moz-radial-gradient(399grad, ellipse closest-corner, red, blue)",
-  "-moz-radial-gradient(399grad, farthest-side circle, red, blue)",
-
-  "-moz-radial-gradient(top left 99deg, cover, red, blue)",
-  "-moz-radial-gradient(15% 20% -1.2345rad, circle, red, blue)",
-  "-moz-radial-gradient(45px 399grad, ellipse closest-corner, red, blue)",
-  "-moz-radial-gradient(45px 399grad, farthest-side circle, red, blue)",
+  "radial-gradient(circle at 15% 20%, red, blue)",
 
-  "-moz-repeating-linear-gradient(red, blue)",
-  "-moz-repeating-linear-gradient(red, yellow, blue)",
-  "-moz-repeating-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
-  "-moz-repeating-linear-gradient(red, yellow, green, blue 50%)",
-  "-moz-repeating-linear-gradient(red -50%, yellow -25%, green, blue)",
-  "-moz-repeating-linear-gradient(red -99px, yellow, green, blue 120%)",
-  "-moz-repeating-linear-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
-  "-moz-repeating-linear-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
-
-  "-moz-repeating-linear-gradient(to top, red, blue)",
-  "-moz-repeating-linear-gradient(to bottom, red, blue)",
-  "-moz-repeating-linear-gradient(to left, red, blue)",
-  "-moz-repeating-linear-gradient(to right, red, blue)",
-  "-moz-repeating-linear-gradient(to top left, red, blue)",
-  "-moz-repeating-linear-gradient(to top right, red, blue)",
-  "-moz-repeating-linear-gradient(to bottom left, red, blue)",
-  "-moz-repeating-linear-gradient(to bottom right, red, blue)",
-  "-moz-repeating-linear-gradient(to left top, red, blue)",
-  "-moz-repeating-linear-gradient(to left bottom, red, blue)",
-  "-moz-repeating-linear-gradient(to right top, red, blue)",
-  "-moz-repeating-linear-gradient(to right bottom, red, blue)",
-
-  "-moz-repeating-linear-gradient(top left, red, blue)",
-  "-moz-repeating-linear-gradient(0 0, red, blue)",
-  "-moz-repeating-linear-gradient(20% bottom, red, blue)",
-  "-moz-repeating-linear-gradient(center 20%, red, blue)",
-  "-moz-repeating-linear-gradient(left 35px, red, blue)",
-  "-moz-repeating-linear-gradient(10% 10em, red, blue)",
-  "-moz-repeating-linear-gradient(44px top, red, blue)",
-
-  "-moz-repeating-linear-gradient(top left 45deg, red, blue)",
-  "-moz-repeating-linear-gradient(20% bottom -300deg, red, blue)",
-  "-moz-repeating-linear-gradient(center 20% 1.95929rad, red, blue)",
-  "-moz-repeating-linear-gradient(left 35px 30grad, red, blue)",
-  "-moz-repeating-linear-gradient(10% 10em 99999deg, red, blue)",
-  "-moz-repeating-linear-gradient(44px top -33deg, red, blue)",
-
-  "-moz-repeating-linear-gradient(-33deg, red, blue)",
-  "-moz-repeating-linear-gradient(30grad left 35px, red, blue)",
-  "-moz-repeating-linear-gradient(10deg 20px, red, blue)",
-  "-moz-repeating-linear-gradient(.414rad bottom, red, blue)",
-
-  "-moz-repeating-radial-gradient(red, blue)",
-  "-moz-repeating-radial-gradient(red, yellow, blue)",
-  "-moz-repeating-radial-gradient(red 1px, yellow 20%, blue 24em, green)",
-  "-moz-repeating-radial-gradient(red, yellow, green, blue 50%)",
-  "-moz-repeating-radial-gradient(red -50%, yellow -25%, green, blue)",
-  "-moz-repeating-radial-gradient(red -99px, yellow, green, blue 120%)",
-  "-moz-repeating-radial-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
-  "-moz-repeating-radial-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
+  "repeating-radial-gradient(red, blue)",
+  "repeating-radial-gradient(red, yellow, blue)",
+  "repeating-radial-gradient(red 1px, yellow 20%, blue 24em, green)",
+  "repeating-radial-gradient(red, yellow, green, blue 50%)",
+  "repeating-radial-gradient(red -50%, yellow -25%, green, blue)",
+  "repeating-radial-gradient(red -99px, yellow, green, blue 120%)",
+  "repeating-radial-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
+  "repeating-radial-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
 
   "repeating-radial-gradient(at top left, red, blue)",
   "repeating-radial-gradient(at 0 0, red, blue)",
   "repeating-radial-gradient(at 20% bottom, red, blue)",
   "repeating-radial-gradient(at center 20%, red, blue)",
   "repeating-radial-gradient(at left 35px, red, blue)",
   "repeating-radial-gradient(at 10% 10em, red, blue)",
   "repeating-radial-gradient(at 44px top, red, blue)",
 
-  "-moz-repeating-radial-gradient(farthest-corner, red, blue)",
-  "-moz-repeating-radial-gradient(circle, red, blue)",
-  "-moz-repeating-radial-gradient(ellipse closest-corner, red, blue)",
-
   "repeating-radial-gradient(farthest-corner at top left, red, blue)",
   "repeating-radial-gradient(closest-corner ellipse at 45px, red, blue)",
   "repeating-radial-gradient(farthest-side circle at 45px, red, blue)",
   "repeating-radial-gradient(ellipse closest-side at 50%, red, blue)",
   "repeating-radial-gradient(circle farthest-corner at 4em, red, blue)",
 
   "repeating-radial-gradient(30% 40% at top left, red, blue)",
   "repeating-radial-gradient(50px 60px at 15% 20%, red, blue)",
   "repeating-radial-gradient(7em 8em at 45px, red, blue)",
 
   "-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 2, 10, 10, 2)",
   "-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 10%, 50%, 30%, 0%)",
   "-moz-image-rect(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==), 10, 50%, 30%, 0)",
 
-  "-moz-radial-gradient(calc(25%) top, red, blue)",
-  "-moz-radial-gradient(left calc(25%), red, blue)",
-  "-moz-radial-gradient(calc(25px) top, red, blue)",
-  "-moz-radial-gradient(left calc(25px), red, blue)",
-  "-moz-radial-gradient(calc(-25%) top, red, blue)",
-  "-moz-radial-gradient(left calc(-25%), red, blue)",
-  "-moz-radial-gradient(calc(-25px) top, red, blue)",
-  "-moz-radial-gradient(left calc(-25px), red, blue)",
-  "-moz-radial-gradient(calc(100px + -25%) top, red, blue)",
-  "-moz-radial-gradient(left calc(100px + -25%), red, blue)",
-  "-moz-radial-gradient(calc(100px + -25px) top, red, blue)",
-  "-moz-radial-gradient(left calc(100px + -25px), red, blue)"
+  "radial-gradient(at calc(25%) top, red, blue)",
+  "radial-gradient(at left calc(25%), red, blue)",
+  "radial-gradient(at calc(25px) top, red, blue)",
+  "radial-gradient(at left calc(25px), red, blue)",
+  "radial-gradient(at calc(-25%) top, red, blue)",
+  "radial-gradient(at left calc(-25%), red, blue)",
+  "radial-gradient(at calc(-25px) top, red, blue)",
+  "radial-gradient(at left calc(-25px), red, blue)",
+  "radial-gradient(at calc(100px + -25%) top, red, blue)",
+  "radial-gradient(at left calc(100px + -25%), red, blue)",
+  "radial-gradient(at calc(100px + -25px) top, red, blue)",
+  "radial-gradient(at left calc(100px + -25px), red, blue)"
 ];
 var invalidGradientAndElementValues = [
   "-moz-element(#a:1)",
   "-moz-element(a#a)",
   "-moz-element(#a a)",
   "-moz-element(#a+a)",
   "-moz-element(#a())",
   /* no quirks mode colors */
   "linear-gradient(red, ff00ff)",
   /* no quirks mode colors */
-  "-moz-radial-gradient(10% bottom, ffffff, black) scroll no-repeat",
+  "radial-gradient(at 10% bottom, ffffff, black) scroll no-repeat",
   /* no quirks mode lengths */
-  "-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
-  "-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
   "linear-gradient(red -99, yellow, green, blue 120%)",
-  /* Old syntax */
-  "-moz-linear-gradient(10px 10px, 20px, 30px 30px, 40px, from(blue), to(red))",
-  "-moz-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
-  "-moz-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
-  "-moz-linear-gradient(10px, 20px, 30px, 40px, color-stop(0.5, #00ccff))",
-  "-moz-linear-gradient(20px 20px, from(blue), to(red))",
-  "-moz-linear-gradient(40px 40px, 10px 10px, from(blue) to(red) color-stop(10%, fuchsia))",
-  "-moz-linear-gradient(20px 20px 30px, 10px 10px, from(red), to(#ff0000))",
-  "-moz-radial-gradient(left top, center, 20px 20px, 10px, from(blue), to(red))",
-  "-moz-linear-gradient(left left, top top, from(blue))",
-  "-moz-linear-gradient(inherit, 10px 10px, from(blue))",
-  /* New syntax */
-  "-moz-linear-gradient(10px 10px, 20px, 30px 30px, 40px, blue 0, red 100%)",
-  "-moz-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
-  "-moz-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
-  "-moz-linear-gradient(10px, 20px, 30px, 40px, #00ccff 50%)",
-  "-moz-linear-gradient(40px 40px, 10px 10px, blue 0 fuchsia 10% red 100%)",
-  "-moz-linear-gradient(20px 20px 30px, 10px 10px, red 0, #ff0000 100%)",
-  "-moz-radial-gradient(left top, center, 20px 20px, 10px, from(blue), to(red))",
-  "-moz-linear-gradient(left left, top top, blue 0)",
-  "-moz-linear-gradient(inherit, 10px 10px, blue 0)",
-  "-moz-linear-gradient(left left blue red)",
-  "-moz-linear-gradient(left left blue, red)",
-  "-moz-linear-gradient()",
-  "-moz-linear-gradient(cover, red, blue)",
-  "-moz-linear-gradient(auto, red, blue)",
-  "-moz-linear-gradient(22 top, red, blue)",
-  "-moz-linear-gradient(10% red blue)",
-  "-moz-linear-gradient(10%, red blue)",
-  "-moz-linear-gradient(10%,, red, blue)",
-  "-moz-linear-gradient(45px, center, red, blue)",
-  "-moz-linear-gradient(45px, center red, blue)",
-  "-moz-radial-gradient(contain, ellipse, red, blue)",
-  "-moz-radial-gradient(10deg contain, red, blue)",
-  "-moz-radial-gradient(10deg, contain,, red, blue)",
-  "-moz-radial-gradient(contain contain, red, blue)",
-  "-moz-radial-gradient(ellipse circle, red, blue)",
-  "-moz-radial-gradient(to top left, red, blue)",
-  "-moz-radial-gradient(center, 10%, red, blue)",
-  "-moz-radial-gradient(5rad, 20px, red, blue)",
-  "-moz-radial-gradient(40%, -100px -10%, red, blue)",
-
-  "-moz-radial-gradient(at top left to cover, red, blue)",
-  "-moz-radial-gradient(at 15% 20% circle, red, blue)",
-
-  "-moz-radial-gradient(to cover, red, blue)",
-  "-moz-radial-gradient(to contain, red, blue)",
-  "-moz-radial-gradient(to closest-side circle, red, blue)",
-  "-moz-radial-gradient(to farthest-corner ellipse, red, blue)",
-
-  "-moz-radial-gradient(ellipse at 45px closest-corner, red, blue)",
-  "-moz-radial-gradient(circle at 45px farthest-side, red, blue)",
-  "-moz-radial-gradient(ellipse 45px, closest-side, red, blue)",
-  "-moz-radial-gradient(circle 45px, farthest-corner, red, blue)",
-  "-moz-radial-gradient(ellipse, ellipse closest-side, red, blue)",
-  "-moz-radial-gradient(circle, circle farthest-corner, red, blue)",
-
-  "-moz-radial-gradient(99deg to farthest-corner, red, blue)",
-  "-moz-radial-gradient(-1.2345rad circle, red, blue)",
-  "-moz-radial-gradient(ellipse 399grad to closest-corner, red, blue)",
-  "-moz-radial-gradient(circle 399grad to farthest-side, red, blue)",
-
-  "-moz-radial-gradient(at top left 99deg, to farthest-corner, red, blue)",
-  "-moz-radial-gradient(circle at 15% 20% -1.2345rad, red, blue)",
-  "-moz-radial-gradient(to top left at 30% 40%, red, blue)",
-  "-moz-radial-gradient(ellipse at 45px 399grad, to closest-corner, red, blue)",
-  "-moz-radial-gradient(at 45px 399grad to farthest-side circle, red, blue)",
-
-  "-moz-radial-gradient(to 50%, red, blue)",
-  "-moz-radial-gradient(circle to 50%, red, blue)",
-  "-moz-radial-gradient(circle to 43px 43px, red, blue)",
-  "-moz-radial-gradient(circle to 50% 50%, red, blue)",
-  "-moz-radial-gradient(circle to 43px 50%, red, blue)",
-  "-moz-radial-gradient(circle to 50% 43px, red, blue)",
-  "-moz-radial-gradient(ellipse to 43px, red, blue)",
-  "-moz-radial-gradient(ellipse to 50%, red, blue)",
-
-  "-moz-linear-gradient(to 0 0, red, blue)",
-  "-moz-linear-gradient(to 20% bottom, red, blue)",
-  "-moz-linear-gradient(to center 20%, red, blue)",
-  "-moz-linear-gradient(to left 35px, red, blue)",
-  "-moz-linear-gradient(to 10% 10em, red, blue)",
-  "-moz-linear-gradient(to 44px top, red, blue)",
-  "-moz-linear-gradient(to top left 45deg, red, blue)",
-  "-moz-linear-gradient(to 20% bottom -300deg, red, blue)",
-  "-moz-linear-gradient(to center 20% 1.95929rad, red, blue)",
-  "-moz-linear-gradient(to left 35px 30grad, red, blue)",
-  "-moz-linear-gradient(to 10% 10em 99999deg, red, blue)",
-  "-moz-linear-gradient(to 44px top -33deg, red, blue)",
-  "-moz-linear-gradient(to -33deg, red, blue)",
-  "-moz-linear-gradient(to 30grad left 35px, red, blue)",
-  "-moz-linear-gradient(to 10deg 20px, red, blue)",
-  "-moz-linear-gradient(to .414rad bottom, red, blue)",
-
-  "-moz-linear-gradient(to top top, red, blue)",
-  "-moz-linear-gradient(to bottom bottom, red, blue)",
-  "-moz-linear-gradient(to left left, red, blue)",
-  "-moz-linear-gradient(to right right, red, blue)",
-
-  "-moz-repeating-linear-gradient(10px 10px, 20px, 30px 30px, 40px, blue 0, red 100%)",
-  "-moz-repeating-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
-  "-moz-repeating-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
-  "-moz-repeating-linear-gradient(10px, 20px, 30px, 40px, #00ccff 50%)",
-  "-moz-repeating-linear-gradient(40px 40px, 10px 10px, blue 0 fuchsia 10% red 100%)",
-  "-moz-repeating-linear-gradient(20px 20px 30px, 10px 10px, red 0, #ff0000 100%)",
-  "-moz-repeating-radial-gradient(left top, center, 20px 20px, 10px, from(blue), to(red))",
-  "-moz-repeating-linear-gradient(left left, top top, blue 0)",
-  "-moz-repeating-linear-gradient(inherit, 10px 10px, blue 0)",
-  "-moz-repeating-linear-gradient(left left blue red)",
-  "-moz-repeating-linear-gradient()",
-
-  "-moz-repeating-linear-gradient(to 0 0, red, blue)",
-  "-moz-repeating-linear-gradient(to 20% bottom, red, blue)",
-  "-moz-repeating-linear-gradient(to center 20%, red, blue)",
-  "-moz-repeating-linear-gradient(to left 35px, red, blue)",
-  "-moz-repeating-linear-gradient(to 10% 10em, red, blue)",
-  "-moz-repeating-linear-gradient(to 44px top, red, blue)",
-  "-moz-repeating-linear-gradient(to top left 45deg, red, blue)",
-  "-moz-repeating-linear-gradient(to 20% bottom -300deg, red, blue)",
-  "-moz-repeating-linear-gradient(to center 20% 1.95929rad, red, blue)",
-  "-moz-repeating-linear-gradient(to left 35px 30grad, red, blue)",
-  "-moz-repeating-linear-gradient(to 10% 10em 99999deg, red, blue)",
-  "-moz-repeating-linear-gradient(to 44px top -33deg, red, blue)",
-  "-moz-repeating-linear-gradient(to -33deg, red, blue)",
-  "-moz-repeating-linear-gradient(to 30grad left 35px, red, blue)",
-  "-moz-repeating-linear-gradient(to 10deg 20px, red, blue)",
-  "-moz-repeating-linear-gradient(to .414rad bottom, red, blue)",
-
-  "-moz-repeating-linear-gradient(to top top, red, blue)",
-  "-moz-repeating-linear-gradient(to bottom bottom, red, blue)",
-  "-moz-repeating-linear-gradient(to left left, red, blue)",
-  "-moz-repeating-linear-gradient(to right right, red, blue)",
-
-  "-moz-repeating-radial-gradient(to top left at 30% 40%, red, blue)",
-  "-moz-repeating-radial-gradient(ellipse at 45px closest-corner, red, blue)",
-  "-moz-repeating-radial-gradient(circle at 45px farthest-side, red, blue)",
 
   "radial-gradient(circle 175px 20px, black, white)",
   "radial-gradient(175px 20px circle, black, white)",
   "radial-gradient(ellipse 175px, black, white)",
   "radial-gradient(175px ellipse, black, white)",
   "radial-gradient(50%, red, blue)",
   "radial-gradient(circle 50%, red, blue)",
   "radial-gradient(50% circle, red, blue)",
 
-  /* Valid only when prefixed */
+  /* Used to be valid only when prefixed */
   "linear-gradient(top left, red, blue)",
   "linear-gradient(0 0, red, blue)",
   "linear-gradient(20% bottom, red, blue)",
   "linear-gradient(center 20%, red, blue)",
   "linear-gradient(left 35px, red, blue)",
   "linear-gradient(10% 10em, red, blue)",
   "linear-gradient(44px top, red, blue)",
 
@@ -553,41 +272,16 @@ var invalidGradientAndElementValues = [
   "radial-gradient(-1.2345rad, circle, red, blue)",
   "radial-gradient(399grad, ellipse closest-corner, red, blue)",
   "radial-gradient(399grad, farthest-side circle, red, blue)",
 
   "radial-gradient(top left 99deg, cover, red, blue)",
   "radial-gradient(15% 20% -1.2345rad, circle, red, blue)",
   "radial-gradient(45px 399grad, ellipse closest-corner, red, blue)",
   "radial-gradient(45px 399grad, farthest-side circle, red, blue)",
-
-  /* Valid only when unprefixed */
-  "-moz-radial-gradient(at top left, red, blue)",
-  "-moz-radial-gradient(at 20% bottom, red, blue)",
-  "-moz-radial-gradient(at center 20%, red, blue)",
-  "-moz-radial-gradient(at left 35px, red, blue)",
-  "-moz-radial-gradient(at 10% 10em, red, blue)",
-  "-moz-radial-gradient(at 44px top, red, blue)",
-  "-moz-radial-gradient(at 0 0, red, blue)",
-
-  "-moz-radial-gradient(circle 43px, red, blue)",
-  "-moz-radial-gradient(ellipse 43px 43px, red, blue)",
-  "-moz-radial-gradient(ellipse 50% 50%, red, blue)",
-  "-moz-radial-gradient(ellipse 43px 50%, red, blue)",
-  "-moz-radial-gradient(ellipse 50% 43px, red, blue)",
-
-  "-moz-radial-gradient(farthest-corner at top left, red, blue)",
-  "-moz-radial-gradient(ellipse closest-corner at 45px, red, blue)",
-  "-moz-radial-gradient(circle farthest-side at 45px, red, blue)",
-  "-moz-radial-gradient(closest-side ellipse at 50%, red, blue)",
-  "-moz-radial-gradient(farthest-corner circle at 4em, red, blue)",
-
-  "-moz-radial-gradient(30% 40% at top left, red, blue)",
-  "-moz-radial-gradient(50px 60px at 15% 20%, red, blue)",
-  "-moz-radial-gradient(7em 8em at 45px, red, blue)"
 ];
 var unbalancedGradientAndElementValues = [
   "-moz-element(#a()",
 ];
 
 var gCSSProperties = {
   "animation": {
     domProp: "animation",
@@ -1867,64 +1561,55 @@ var gCSSProperties = {
       "top left / 100px 100px",
       "top left / 100px auto",
       "top left / 100px 10%",
       "top left / 100px calc(20px)",
       "bottom right scroll none transparent repeat",
       "50% transparent",
       "transparent 50%",
       "50%",
-      "-moz-radial-gradient(10% bottom, #ffffff, black) scroll no-repeat",
-      "-moz-linear-gradient(10px 10px -45deg, red, blue) repeat",
-      "-moz-linear-gradient(10px 10px -0.125turn, red, blue) repeat",
-      "-moz-repeating-radial-gradient(10% bottom, #ffffff, black) scroll no-repeat",
-      "-moz-repeating-linear-gradient(10px 10px -45deg, red, blue) repeat",
+      "radial-gradient(at 10% bottom, #ffffff, black) scroll no-repeat",
+      "repeating-radial-gradient(at 10% bottom, #ffffff, black) scroll no-repeat",
       "-moz-element(#test) lime",
         /* multiple backgrounds */
         "url(404.png), url(404.png)",
         "url(404.png), url(404.png) transparent",
         "url(404.png), url(404.png) red",
         "repeat-x, fixed, none",
         "0% top url(404.png), url(404.png) 0% top",
         "fixed repeat-y top left url(404.png), repeat-x green",
-        "url(404.png), -moz-linear-gradient(20px 20px -45deg, blue, green), -moz-element(#a) black",
         "top left / contain, bottom right / cover",
         /* test cases with clip+origin in the shorthand */
         "url(404.png) green padding-box",
         "url(404.png) border-box transparent",
         "content-box url(404.png) blue",
         "url(404.png) green padding-box padding-box",
         "url(404.png) green padding-box border-box",
         "content-box border-box url(404.png) blue",
     ],
     invalid_values: [
       /* mixes with keywords have to be in correct order */
       "50% left", "top 50%",
       /* no quirks mode colors */
-      "-moz-radial-gradient(10% bottom, ffffff, black) scroll no-repeat",
+      "radial-gradient(at 10% bottom, ffffff, black) scroll no-repeat",
       /* no quirks mode lengths */
-      "-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
-      "-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
       "linear-gradient(red -99, yellow, green, blue 120%)",
       /* bug 258080: don't accept background-position separated */
       "left url(404.png) top", "top url(404.png) left",
       /* not allowed to have color in non-bottom layer */
       "url(404.png) transparent, url(404.png)",
       "url(404.png) red, url(404.png)",
       "url(404.png) transparent, url(404.png) transparent",
       "url(404.png) transparent red, url(404.png) transparent red",
       "url(404.png) red, url(404.png) red",
       "url(404.png) rgba(0, 0, 0, 0), url(404.png)",
       "url(404.png) rgb(255, 0, 0), url(404.png)",
       "url(404.png) rgba(0, 0, 0, 0), url(404.png) rgba(0, 0, 0, 0)",
       "url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0), url(404.png) rgba(0, 0, 0, 0) rgb(255, 0, 0)",
       "url(404.png) rgb(255, 0, 0), url(404.png) rgb(255, 0, 0)",
-      /* bug 513395: old syntax for gradients */
-      "-moz-radial-gradient(10% bottom, 30px, 20px 20px, 10px, from(#ffffff), to(black)) scroll no-repeat",
-      "-moz-linear-gradient(10px 10px, 20px 20px, from(red), to(blue)) repeat",
       /* clip and origin separated in the shorthand */
       "url(404.png) padding-box green border-box",
       "url(404.png) padding-box green padding-box",
       "transparent padding-box url(404.png) border-box",
       "transparent padding-box url(404.png) padding-box",
     ]
   },
   "background-attachment": {
@@ -6564,17 +6249,17 @@ if (SpecialPowers.getBoolPref("layout.cs
   gCSSProperties["border-top-right-radius"].invalid_values.push("unset 2px", "2px unset");
   gCSSProperties["-moz-border-right-colors"].invalid_values.push("red unset", "unset red");
   gCSSProperties["-moz-border-top-colors"].invalid_values.push("red unset", "unset red");
   gCSSProperties["-moz-outline-radius"].invalid_values.push("unset 2px", "unset / 2px", "2px unset", "2px / unset");
   gCSSProperties["-moz-outline-radius-bottomleft"].invalid_values.push("unset 2px", "2px unset");
   gCSSProperties["-moz-outline-radius-bottomright"].invalid_values.push("unset 2px", "2px unset");
   gCSSProperties["-moz-outline-radius-topleft"].invalid_values.push("unset 2px", "2px unset");
   gCSSProperties["-moz-outline-radius-topright"].invalid_values.push("unset 2px", "2px unset");
-  gCSSProperties["background-image"].invalid_values.push("-moz-linear-gradient(unset, 10px 10px, from(blue))", "-moz-linear-gradient(unset, 10px 10px, blue 0)", "-moz-repeating-linear-gradient(unset, 10px 10px, blue 0)");
+  gCSSProperties["background-image"].invalid_values.push("linear-gradient(unset, 10px 10px, from(blue))", "linear-gradient(unset, 10px 10px, blue 0)", "repeating-linear-gradient(unset, 10px 10px, blue 0)");
   gCSSProperties["box-shadow"].invalid_values.push("unset, 2px 2px", "2px 2px, unset", "inset unset");
   gCSSProperties["text-overflow"].invalid_values.push('"hello" unset', 'unset "hello"', 'clip unset', 'unset clip', 'unset inherit', 'unset none', 'initial unset');
   gCSSProperties["text-shadow"].invalid_values.push("unset, 2px 2px", "2px 2px, unset");
   gCSSProperties["transition"].invalid_values.push("2s unset");
   gCSSProperties["transition-property"].invalid_values.push("unset, color", "color, unset");
   gCSSProperties["-moz-transition"].invalid_values.push("2s unset");
   gCSSProperties["-moz-transition-property"].invalid_values.push("unset, color", "color, unset");
   gCSSProperties["-moz-animation"].invalid_values.push("2s unset");
--- a/layout/style/test/test_computed_style.html
+++ b/layout/style/test/test_computed_style.html
@@ -196,42 +196,39 @@ var noframe_container = document.getElem
   }
 
   p.parentNode.removeChild(p);
 })();
 
 (function test_bug_716628() {
   // Test that various gradient styles round-trip correctly
   var backgroundImages = [
-    [ "-moz-radial-gradient(10% bottom, #ffffff, black)",
+    [ "radial-gradient(at 10% bottom, #ffffff, black)",
       "radial-gradient(at 10% 100%, rgb(255, 255, 255), rgb(0, 0, 0))",
       "radial gradient 1" ],
-    [ "-moz-radial-gradient(#ffffff, black)",
+    [ "radial-gradient(#ffffff, black)",
       "radial-gradient(rgb(255, 255, 255), rgb(0, 0, 0))",
       "radial gradient 2" ],
-    [ "-moz-radial-gradient(cover, #ffffff, black)",
+    [ "radial-gradient(farthest-corner, #ffffff, black)",
       "radial-gradient(rgb(255, 255, 255), rgb(0, 0, 0))",
       "radial gradient 3" ],
-    [ "-moz-radial-gradient(top left -45deg, #ffffff, black)",
-      "-moz-radial-gradient(0% 0% -45deg, rgb(255, 255, 255), rgb(0, 0, 0))",
-      "radial gradient with angle in degrees" ],
-    [ "-moz-linear-gradient(red, blue)",
+    [ "linear-gradient(red, blue)",
       "linear-gradient(rgb(255, 0, 0), rgb(0, 0, 255))",
       "linear gradient 1" ],
-    [ "-moz-linear-gradient(to bottom, red, blue)",
+    [ "linear-gradient(to bottom, red, blue)",
       "linear-gradient(rgb(255, 0, 0), rgb(0, 0, 255))",
       "linear gradient 2" ],
-    [ "-moz-linear-gradient(to right, red, blue)",
+    [ "linear-gradient(to right, red, blue)",
       "linear-gradient(to right, rgb(255, 0, 0), rgb(0, 0, 255))",
       "linear gradient 3" ],
-    [ "-moz-linear-gradient(10px 10px -45deg, red, blue)",
-      "-moz-linear-gradient(10px 10px -45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
+    [ "linear-gradient(-45deg, red, blue)",
+      "linear-gradient(-45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
       "linear gradient with angle in degrees" ],
-    [ "-moz-linear-gradient(10px 10px -0.125turn, red, blue)",
-      "-moz-linear-gradient(10px 10px -0.125turn, rgb(255, 0, 0), rgb(0, 0, 255))",
+    [ "linear-gradient(-0.125turn, red, blue)",
+      "linear-gradient(-0.125turn, rgb(255, 0, 0), rgb(0, 0, 255))",
       "linear gradient with angle in turns" ],
   ];
 
   var p = document.createElement("p");
   var cs = getComputedStyle(p, "");
   frame_container.appendChild(p);
 
   for (var i = 0; i < backgroundImages.length; ++i) {
--- a/layout/style/test/test_unclosed_parentheses.html
+++ b/layout/style/test/test_unclosed_parentheses.html
@@ -53,34 +53,20 @@ var declarations = [
   "background-image: linear-gradient(to",
   "background-image: linear-gradient(to top",
   "background-image: linear-gradient(to top left",
   "background-image: linear-gradient(to top left,",
   "background-image: repeating-linear-gradient(to top left, red, blue",
   "background-image: linear-gradient(to top left, red, yellow, blue",
   "background-image: linear-gradient(to top left, red 1px, yellow 5px, blue 10px",
   "background-image: linear-gradient(to top left, red, yellow, rgb(0, 0, 255)",
-  "background-image: -moz-linear-gradient(",
-  "background-image: -moz-linear-gradient( ",
-  "background-image: -moz-linear-gradient(red, blue",
-  "background-image: -moz-linear-gradient(red, yellow, blue",
-  "background-image: -moz-linear-gradient(red 1px, yellow 5px, blue 10px",
-  "background-image: -moz-linear-gradient(red, yellow, rgb(0, 0, 255)",
-  "background-image: -moz-linear-gradient(to",
-  "background-image: -moz-linear-gradient(to top",
-  "background-image: -moz-linear-gradient(to top left",
-  "background-image: -moz-linear-gradient(to top left,",
-  "background-image: -moz-repeating-linear-gradient(to top left, red, blue",
-  "background-image: -moz-linear-gradient(to top left, red, yellow, blue",
-  "background-image: -moz-linear-gradient(to top left, red 1px, yellow 5px, blue 10px",
-  "background-image: -moz-linear-gradient(to top left, red, yellow, rgb(0, 0, 255)",
-  "background-image: -moz-repeating-linear-gradient(top left, red, blue",
-  "background-image: -moz-linear-gradient(top left, red, yellow, blue",
-  "background-image: -moz-linear-gradient(top left, red 1px, yellow 5px, blue 10px",
-  "background-image: -moz-linear-gradient(top left, red, yellow, rgb(0, 0, 255)",
+  "background-image: linear-gradient(red, blue",
+  "background-image: linear-gradient(red, yellow, blue",
+  "background-image: linear-gradient(red 1px, yellow 5px, blue 10px",
+  "background-image: linear-gradient(red, yellow, rgb(0, 0, 255)",
   "background-image: radial-gradient(",
   "background-image: radial-gradient( ",
   "background-image: radial-gradient(at",
   "background-image: radial-gradient(at ",
   "background-image: radial-gradient(at center",
   "background-image: radial-gradient(at center,",
   "background-image: radial-gradient(at center ",
   "background-image: radial-gradient(closest-corner",
@@ -127,28 +113,26 @@ var declarations = [
   "background-image: radial-gradient(ellipse 50px 50px,",
   "background-image: radial-gradient(ellipse 50px 50px ",
   "background-image: radial-gradient(ellipse 50px 50px at",
   "background-image: radial-gradient(ellipse 50px 50px at ",
   "background-image: radial-gradient(ellipse 50px 50px at center",
   "background-image: radial-gradient(ellipse 50px 50px at center ",
   "background-image: radial-gradient(ellipse 50px 50px at center,",
   "background-image: radial-gradient(ellipse 50px 50px at center, red, blue",
+  "background-image: radial-gradient(at top left, red, blue",
+  "background-image: radial-gradient(farthest-corner, red, blue",
+  "background-image: radial-gradient(ellipse closest-corner, red, hsl(240, 50%, 50%)",
+  "background-image: radial-gradient(farthest-side circle, red, blue",
   "background-image: repeating-radial-gradient(50%",
   "background-image: repeating-radial-gradient(50% ",
   "background-image: repeating-radial-gradient(50% 50%",
   "background-image: repeating-radial-gradient(50% 50%,",
   "background-image: repeating-radial-gradient(50% 50%, red, blue",
-  "background-image: -moz-radial-gradient(",
-  "background-image: -moz-radial-gradient( ",
-  "background-image: -moz-radial-gradient(top left 45deg, red, blue",
-  "background-image: -moz-radial-gradient(cover, red, blue",
-  "background-image: -moz-repeating-radial-gradient(circle, red, blue",
-  "background-image: -moz-radial-gradient(ellipse closest-corner, red, hsl(240, 50%, 50%)",
-  "background-image: -moz-radial-gradient(farthest-side circle, red, blue",
+  "background-image: repeating-radial-gradient(circle, red, blue",
   "background-image: -moz-image-rect(",
   "background-image: -moz-image-rect( ",
   "background-image: -moz-image-rect(url(foo.jpg)",
   "background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10",
   "background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10 ",
   "background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10,",
   "background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, ",
   "background-image: -moz-image-rect(url(foo.jpg), 2, 10, 10, 10",
--- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/device_info_ds.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/device_info_ds.cc
@@ -487,17 +487,18 @@ int32_t DeviceInfoDS::CreateCapabilityMa
     bool supportFORMAT_VideoInfo2 = false;
     bool supportFORMAT_VideoInfo = false;
     bool foundInterlacedFormat = false;
     GUID preferedVideoFormat = FORMAT_VideoInfo;
     for (int32_t tmp = 0; tmp < count; ++tmp)
     {
         hr = streamConfig->GetStreamCaps(tmp, &pmt,
                                          reinterpret_cast<BYTE*> (&caps));
-        if (!FAILED(hr))
+        // Bug 1181265 - perhaps a helper dll returns success with nullptr
+        if (!FAILED(hr) && pmt)
         {
             if (pmt->majortype == MEDIATYPE_Video
                 && pmt->formattype == FORMAT_VideoInfo2)
             {
                 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                              " Device support FORMAT_VideoInfo2");
                 supportFORMAT_VideoInfo2 = true;
                 VIDEOINFOHEADER2* h =
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -158,17 +158,17 @@ endif
 proguard_config_dir=$(topsrcdir)/mobile/android/config/proguard
 
 # This stanza ensures that the set of GeckoView classes does not depend on too
 # much of Fennec, where "too much" is defined as the set of potentially
 # non-GeckoView classes that GeckoView already depended on at a certain point in
 # time.  The idea is to set a high-water mark that is not to be crossed.
 classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
 .geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS)
-	java -cp $(classycle_jar) \
+	$(JAVA) -cp $(classycle_jar) \
 		classycle.dependency.DependencyChecker \
 		-mergeInnerClasses \
 		-dependencies=@$< \
 		$(ALL_JARS)
 	@$(TOUCH) $@
 
 # First, we delete debugging information from libraries. Having line-number
 # information for libraries for which we lack the source isn't useful, so this
@@ -179,32 +179,32 @@ classycle_jar := $(topsrcdir)/mobile/and
 # for stack frames inside libraries.
 #
 # This step can occur much earlier than the main Proguard pass: it needs only
 # gecko-R.jar to have been compiled (as that's where the library R.java files
 # end up), but it does block the main Proguard pass.
 .bundled.proguard.deps: gecko-R.jar $(proguard_config_dir)/strip-libs.cfg
 	$(REPORT_BUILD)
 	@$(TOUCH) $@
-	java \
+	$(JAVA) \
 		-Xmx512m -Xms128m \
 		-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
 		@$(proguard_config_dir)/strip-libs.cfg \
 		-injars $(subst ::,:,$(java_bundled_libs))\
 		-outjars bundled-jars-nodebug \
 		-libraryjars $(library_jars):gecko-R.jar
 
 # We touch the target file before invoking Proguard so that Proguard's
 # outputs are fresher than the target, preventing a subsequent
 # invocation from thinking Proguard's outputs are stale.  This is safe
 # because Make removes the target file if any recipe command fails.
 .proguard.deps: .geckoview.deps .bundled.proguard.deps $(ALL_JARS) $(proguard_config_dir)/proguard.cfg
 	$(REPORT_BUILD)
 	@$(TOUCH) $@
-	java \
+	$(JAVA) \
 		-Xmx512m -Xms128m \
 		-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
 		@$(proguard_config_dir)/proguard.cfg \
 		-optimizationpasses $(PROGUARD_PASSES) \
 		-injars $(subst ::,:,$(all_jars_classpath)):bundled-jars-nodebug \
 		-outjars jars-proguarded \
 		-libraryjars $(library_jars)
 
--- a/mobile/android/config/mozconfigs/common
+++ b/mobile/android/config/mozconfigs/common
@@ -5,16 +5,28 @@
 # This file is included at the top of all native android mozconfigs
 if [ "x$IS_NIGHTLY" = "xyes" ]; then
   MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
 fi
 
 MOZ_AUTOMATION_L10N_CHECK=0
 . "$topsrcdir/build/mozconfig.common"
 
+# In TaskCluster, the Java JRE/JDK are installed from tooltool, but that
+# install doesn't work on the old Buildbot mock builders (CentOS 6.2), so
+# the relevant env vars are not set up in that case, leaving the build to
+# run from the JRE/JDK in /usr/lib/jvm.
+if [ ! -f /etc/redhat-release ] || [ "$(< /etc/redhat-release)" != "CentOS release 6.2 (Final)" ]; then
+    # set JAVA_HOME to find the JRE/JDK from tooltool.  Several scripts in the JDK
+    # assume `java` is in PATH, so set that too.  To see how this tarball is built,
+    # see testing/taskcluster/scripts/misc/repackage-jdk.sh
+    export JAVA_HOME="$topsrcdir/java_home"
+    export PATH="$PATH:$topsrcdir/java_home/bin"
+fi
+
 # Set the most aggressive settings for szip. Not the default because it's
 # much slower and we didn't want to slow down developers builds.
 # Has no effect when MOZ_ENABLE_SZIP is not set in mobile/android/confvars.sh.
 MOZ_SZIP_FLAGS="-D auto -f auto"
 
 ac_add_options --enable-elf-hack
 
 ANDROID_NDK_VERSION="r8e"
--- a/mobile/android/config/tooltool-manifests/android/releng.manifest
+++ b/mobile/android/config/tooltool-manifests/android/releng.manifest
@@ -44,10 +44,18 @@
 },
 {
 "size": 80458572,
 "visibility": "public",
 "unpack": true,
 "digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz"
+},
+{
+"size": 55391032,
+"visibility": "public",
+"digest": "a15fbba949fbb5039bef717f55370d40050a537a2b3a1ffe5e8b655ae90b54419020783c183bba72ce2610f35e3611e259df09b5844a72bd161b512fb54898fb",
+"algorithm": "sha512",
+"unpack": true,
+"filename": "java_home-7u79-2.5.5-0ubuntu0.14.04.2-amd64.tar.xz"
 }
 ]
--- a/mobile/android/tests/browser/robocop/BaseTest.java
+++ b/mobile/android/tests/browser/robocop/BaseTest.java
@@ -129,17 +129,17 @@ abstract class BaseTest extends BaseRobo
 
     @Override
     protected void runTest() throws Throwable {
         try {
             super.runTest();
         } catch (Throwable t) {
             // save screenshot -- written to /mnt/sdcard/Robotium-Screenshots
             // as <filename>.jpg
-            mSolo.takeScreenshot("robocop-screenshot");
+            mSolo.takeScreenshot("robocop-screenshot-"+getClass().getName());
             if (mAsserter != null) {
                 mAsserter.dumpLog("Exception caught during test!", t);
                 mAsserter.ok(false, "Exception caught", t.toString());
             }
             // re-throw to continue bail-out
             throw t;
         }
     }
--- a/mobile/android/tests/browser/robocop/UITest.java
+++ b/mobile/android/tests/browser/robocop/UITest.java
@@ -60,17 +60,17 @@ abstract class UITest extends BaseRoboco
 
     @Override
     protected void runTest() throws Throwable {
         try {
             super.runTest();
         } catch (Throwable t) {
             // save screenshot -- written to /mnt/sdcard/Robotium-Screenshots
             // as <filename>.jpg
-            mSolo.takeScreenshot("robocop-screenshot");
+            mSolo.takeScreenshot("robocop-screenshot-"+getClass().getName());
             if (mAsserter != null) {
                 mAsserter.dumpLog("Exception caught during test!", t);
                 mAsserter.ok(false, "Exception caught", t.toString());
             }
             // re-throw to continue bail-out
             throw t;
         }
     }
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4809,19 +4809,23 @@ pref("dom.messageChannel.enabled", true)
 
 // Disable before keyboard events and after keyboard events by default.
 pref("dom.beforeAfterKeyboardEvent.enabled", false);
 
 // Presentation API
 pref("dom.presentation.enabled", false);
 pref("dom.presentation.tcp_server.debug", false);
 
+#ifdef XP_MACOSX
 // Use raw ICU instead of CoreServices API in Unicode collation
-#ifdef XP_MACOSX
 pref("intl.collation.mac.use_icu", true);
+
+// Enable NSTextInput protocol for use with IMEs that have not
+// been updated to use the NSTextInputClient protocol.
+pref("intl.ime.nstextinput.enable", false);
 #endif
 
 // Enable meta-viewport support in remote APZ-enabled frames.
 pref("dom.meta-viewport.enabled", false);
 
 // MozSettings debugging prefs for each component
 pref("dom.mozSettings.SettingsDB.debug.enabled", false);
 pref("dom.mozSettings.SettingsManager.debug.enabled", false);
--- a/netwerk/cookie/nsCookie.cpp
+++ b/netwerk/cookie/nsCookie.cpp
@@ -3,16 +3,18 @@
  * 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 "nsCookie.h"
 #include "nsUTF8ConverterService.h"
 #include <stdlib.h>
 #include "nsAutoPtr.h"
 
+static const int64_t kCookieStaleThreshold = 60 * PR_USEC_PER_SEC; // 1 minute in microseconds
+
 /******************************************************************************
  * nsCookie:
  * string helper impl
  ******************************************************************************/
 
 // copy aSource strings into contiguous storage provided in aDest1,
 // providing terminating nulls for each destination string.
 static inline void
@@ -115,16 +117,24 @@ nsCookie::Create(const nsACString &aName
 size_t
 nsCookie::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
     // There is no need to measure the sizes of the individual string
     // members, since the strings are stored in-line with the nsCookie.
     return aMallocSizeOf(this);
 }
 
+bool
+nsCookie::IsStale() const
+{
+  int64_t currentTimeInUsec = PR_Now();
+
+  return currentTimeInUsec - LastAccessed() > kCookieStaleThreshold;
+}
+
 /******************************************************************************
  * nsCookie:
  * xpcom impl
  ******************************************************************************/
 
 // xpcom getters
 NS_IMETHODIMP nsCookie::GetName(nsACString &aName)         { aName = Name();            return NS_OK; }
 NS_IMETHODIMP nsCookie::GetValue(nsACString &aValue)       { aValue = Value();          return NS_OK; }
--- a/netwerk/cookie/nsCookie.h
+++ b/netwerk/cookie/nsCookie.h
@@ -95,16 +95,18 @@ class nsCookie : public nsICookie2
     // setters
     inline void SetExpiry(int64_t aExpiry)        { mExpiry = aExpiry; }
     inline void SetLastAccessed(int64_t aTime)    { mLastAccessed = aTime; }
     inline void SetIsSession(bool aIsSession)   { mIsSession = (bool) aIsSession; }
     // Set the creation time manually, overriding the monotonicity checks in
     // Create(). Use with caution!
     inline void SetCreationTime(int64_t aTime)    { mCreationTime = aTime; }
 
+    bool IsStale() const;
+
   protected:
     virtual ~nsCookie() {}
 
     // member variables
     // we use char* ptrs to store the strings in a contiguous block,
     // so we save on the overhead of using nsCStrings. However, we
     // store a terminating null for each string, so we can hand them
     // out as nsAFlatCStrings.
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -86,17 +86,16 @@ static nsCookieService *gCookieService;
 #define IDX_LAST_ACCESSED 5
 #define IDX_CREATION_TIME 6
 #define IDX_SECURE 7
 #define IDX_HTTPONLY 8
 #define IDX_BASE_DOMAIN 9
 #define IDX_APP_ID 10
 #define IDX_BROWSER_ELEM 11
 
-static const int64_t kCookieStaleThreshold = 60 * PR_USEC_PER_SEC; // 1 minute in microseconds
 static const int64_t kCookiePurgeAge =
   int64_t(30 * 24 * 60 * 60) * PR_USEC_PER_SEC; // 30 days in microseconds
 
 #define OLD_COOKIE_FILE_NAME "cookies.txt"
 
 #undef  LIMIT
 #define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
 
@@ -2753,18 +2752,19 @@ nsCookieService::GetCookieStringInternal
 
     // check if the cookie has expired
     if (cookie->Expiry() <= currentTime) {
       continue;
     }
 
     // all checks passed - add to list and check if lastAccessed stamp needs updating
     foundCookieList.AppendElement(cookie);
-    if (currentTimeInUsec - cookie->LastAccessed() > kCookieStaleThreshold)
+    if (cookie->IsStale()) {
       stale = true;
+    }
   }
 
   int32_t count = foundCookieList.Length();
   if (count == 0)
     return;
 
   // update lastAccessed timestamps. we only do this if the timestamp is stale
   // by a certain amount, to avoid thrashing the db during pageload.
@@ -2775,18 +2775,19 @@ nsCookieService::GetCookieStringInternal
     mozIStorageAsyncStatement* stmt = mDBState->stmtUpdate;
     if (mDBState->dbConn) {
       stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
     }
 
     for (int32_t i = 0; i < count; ++i) {
       cookie = foundCookieList.ElementAt(i);
 
-      if (currentTimeInUsec - cookie->LastAccessed() > kCookieStaleThreshold)
+      if (cookie->IsStale()) {
         UpdateCookieInList(cookie, currentTimeInUsec, paramsArray);
+      }
     }
     // Update the database now if necessary.
     if (paramsArray) {
       uint32_t length;
       paramsArray->GetLength(&length);
       if (length) {
         DebugOnly<nsresult> rv = stmt->BindParameters(paramsArray);
         NS_ASSERT_SUCCESS(rv);
@@ -2990,16 +2991,34 @@ nsCookieService::AddInternal(const nsCoo
     } else {
       // If the old cookie is httponly, make sure we're not coming from script.
       if (!aFromHttp && oldCookie->IsHttpOnly()) {
         COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
           "previously stored cookie is httponly; coming from script");
         return;
       }
 
+      // If the new cookie has the same value, expiry date, and isSecure,
+      // isSession, and isHttpOnly flags then we can just keep the old one.
+      // Only if any of these differ we would want to override the cookie.
+      if (oldCookie->Value().Equals(aCookie->Value()) &&
+          oldCookie->Expiry() == aCookie->Expiry() &&
+          oldCookie->IsSecure() == aCookie->IsSecure() &&
+          oldCookie->IsSession() == aCookie->IsSession() &&
+          oldCookie->IsHttpOnly() == aCookie->IsHttpOnly() &&
+          // We don't want to perform this optimization if the cookie is
+          // considered stale, since in this case we would need to update the
+          // database.
+          !oldCookie->IsStale()) {
+        // Update the last access time on the old cookie.
+        oldCookie->SetLastAccessed(aCookie->LastAccessed());
+        UpdateCookieOldestTime(mDBState, oldCookie);
+        return;
+      }
+
       // Remove the old cookie.
       RemoveCookieFromList(matchIter);
 
       // If the new cookie has expired -- i.e. the intent was simply to delete
       // the old cookie -- then we're done.
       if (aCookie->Expiry() <= currentTime) {
         COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
           "previously stored cookie was deleted");
@@ -4230,16 +4249,25 @@ bindCookieParameters(mozIStorageBindingP
   NS_ASSERT_SUCCESS(rv);
 
   // Bind the params to the array.
   rv = aParamsArray->AddParams(params);
   NS_ASSERT_SUCCESS(rv);
 }
 
 void
+nsCookieService::UpdateCookieOldestTime(DBState* aDBState,
+                                        nsCookie* aCookie)
+{
+  if (aCookie->LastAccessed() < aDBState->cookieOldestTime) {
+    aDBState->cookieOldestTime = aCookie->LastAccessed();
+  }
+}
+
+void
 nsCookieService::AddCookieToList(const nsCookieKey             &aKey,
                                  nsCookie                      *aCookie,
                                  DBState                       *aDBState,
                                  mozIStorageBindingParamsArray *aParamsArray,
                                  bool                           aWriteToDB)
 {
   NS_ASSERTION(!(aDBState->dbConn && !aWriteToDB && aParamsArray),
                "Not writing to the DB but have a params array?");
@@ -4248,18 +4276,17 @@ nsCookieService::AddCookieToList(const n
 
   nsCookieEntry *entry = aDBState->hostTable.PutEntry(aKey);
   NS_ASSERTION(entry, "can't insert element into a null entry!");
 
   entry->GetCookies().AppendElement(aCookie);
   ++aDBState->cookieCount;
 
   // keep track of the oldest cookie, for when it comes time to purge
-  if (aCookie->LastAccessed() < aDBState->cookieOldestTime)
-    aDBState->cookieOldestTime = aCookie->LastAccessed();
+  UpdateCookieOldestTime(aDBState, aCookie);
 
   // if it's a non-session cookie and hasn't just been read from the db, write it out.
   if (aWriteToDB && !aCookie->IsSession() && aDBState->dbConn) {
     mozIStorageAsyncStatement *stmt = aDBState->stmtInsert;
     nsCOMPtr<mozIStorageBindingParamsArray> paramsArray(aParamsArray);
     if (!paramsArray) {
       stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
     }
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -309,16 +309,17 @@ class nsCookieService final : public nsI
     already_AddRefed<nsIArray>    PurgeCookies(int64_t aCurrentTimeInUsec);
     bool                          FindCookie(const nsCookieKey& aKey, const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter);
     static void                   FindStaleCookie(nsCookieEntry *aEntry, int64_t aCurrentTime, nsListIter &aIter);
     void                          NotifyRejected(nsIURI *aHostURI);
     void                          NotifyThirdParty(nsIURI *aHostURI, bool aAccepted, nsIChannel *aChannel);
     void                          NotifyChanged(nsISupports *aSubject, const char16_t *aData);
     void                          NotifyPurged(nsICookie2* aCookie);
     already_AddRefed<nsIArray>    CreatePurgeList(nsICookie2* aCookie);
+    void                          UpdateCookieOldestTime(DBState* aDBState, nsCookie* aCookie);
 
     /**
      * This method is used to iterate the cookie hash table and select the ones
      * that are part of a specific app.
      */
     static PLDHashOperator GetCookiesForApp(nsCookieEntry* entry, void* arg);
 
     /**
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_bug1155169.js
@@ -0,0 +1,73 @@
+const {utils: Cu, interfaces: Ci, classes: Cc} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const URI = Services.io.newURI("http://example.org/", null, null);
+
+const cs = Cc["@mozilla.org/cookieService;1"]
+             .getService(Ci.nsICookieService);
+
+function run_test() {
+  // Allow all cookies.
+  Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+
+  // Clear cookies.
+  Services.cookies.removeAll();
+
+  // Add a new cookie.
+  setCookie("foo=bar", {
+    type: "added", isSession: true, isSecure: false, isHttpOnly: false
+  });
+
+  // Update cookie with isHttpOnly=true.
+  setCookie("foo=bar; HttpOnly", {
+    type: "changed", isSession: true, isSecure: false, isHttpOnly: true
+  });
+
+  // Update cookie with isSecure=true.
+  setCookie("foo=bar; Secure", {
+    type: "changed", isSession: true, isSecure: true, isHttpOnly: false
+  });
+
+  // Update cookie with isSession=false.
+  let expiry = new Date();
+  expiry.setUTCFullYear(expiry.getUTCFullYear() + 2);
+  setCookie(`foo=bar; Expires=${expiry.toGMTString()}`, {
+    type: "changed", isSession: false, isSecure: false, isHttpOnly: false
+  });
+
+  // Reset cookie.
+  setCookie("foo=bar", {
+    type: "changed", isSession: true, isSecure: false, isHttpOnly: false
+  });
+}
+
+function setCookie(value, expected) {
+  function setCookieInternal(value, expected = null) {
+    function observer(subject, topic, data) {
+      if (!expected) {
+        do_throw("no notification expected");
+        return;
+      }
+
+      // Check we saw the right notification.
+      do_check_eq(data, expected.type);
+
+      // Check cookie details.
+      let cookie = subject.QueryInterface(Ci.nsICookie2);
+      do_check_eq(cookie.isSession, expected.isSession);
+      do_check_eq(cookie.isSecure, expected.isSecure);
+      do_check_eq(cookie.isHttpOnly, expected.isHttpOnly);
+    }
+
+    Services.obs.addObserver(observer, "cookie-changed", false);
+    cs.setCookieStringFromHttp(URI, null, null, value, null, null);
+    Services.obs.removeObserver(observer, "cookie-changed");
+  }
+
+  // Check that updating/inserting the cookie works.
+  setCookieInternal(value, expected);
+
+  // Check that we ignore identical cookies.
+  setCookieInternal(value);
+}
--- a/netwerk/cookie/test/unit/xpcshell.ini
+++ b/netwerk/cookie/test/unit/xpcshell.ini
@@ -1,8 +1,9 @@
 [DEFAULT]
 head = 
 tail = 
 skip-if = toolkit == 'gonk'
 
 [test_bug643051.js]
+[test_bug1155169.js]
 [test_parser_0001.js]
 [test_parser_0019.js]
--- a/python/mozbuild/mozbuild/backend/configenvironment.py
+++ b/python/mozbuild/mozbuild/backend/configenvironment.py
@@ -22,44 +22,55 @@ if sys.version_info.major == 2:
     text_type = unicode
 else:
     text_type = str
 
 
 class BuildConfig(object):
     """Represents the output of configure."""
 
+    _CODE_CACHE = {}
+
     def __init__(self):
         self.topsrcdir = None
         self.topobjdir = None
         self.defines = {}
         self.non_global_defines = []
         self.substs = {}
         self.files = []
 
-    @staticmethod
-    def from_config_status(path):
+    @classmethod
+    def from_config_status(cls, path):
         """Create an instance from a config.status file."""
+        code_cache = cls._CODE_CACHE
+        mtime = os.path.getmtime(path)
 
-        with open(path, 'rt') as fh:
-            source = fh.read()
-            code = compile(source, path, 'exec', dont_inherit=1)
-            g = {
-                '__builtins__': __builtins__,
-                '__file__': path,
-            }
-            l = {}
-            exec(code, g, l)
+        # cache the compiled code as it can be reused
+        # we cache it the first time, or if the file changed
+        if not path in code_cache or code_cache[path][0] != mtime:
+            with open(path, 'rt') as fh:
+                source = fh.read()
+                code_cache[path] = (
+                    mtime,
+                    compile(source, path, 'exec', dont_inherit=1)
+                )
 
-            config = BuildConfig()
+        g = {
+            '__builtins__': __builtins__,
+            '__file__': path,
+        }
+        l = {}
+        exec(code_cache[path][1], g, l)
 
-            for name in l['__all__']:
-                setattr(config, name, l[name])
+        config = BuildConfig()
 
-            return config
+        for name in l['__all__']:
+            setattr(config, name, l[name])
+
+        return config
 
 
 class ConfigEnvironment(object):
     """Perform actions associated with a configured but bare objdir.
 
     The purpose of this class is to preprocess files from the source directory
     and output results in the object directory.
 
--- a/security/manager/ssl/tests/mochitest/bugs/chrome.ini
+++ b/security/manager/ssl/tests/mochitest/bugs/chrome.ini
@@ -1,8 +1,7 @@
 [DEFAULT]
 tags = psm
 skip-if = buildapp == 'b2g'
 
 [test_bug413909.html]
 skip-if = buildapp == 'mulet'
-[test_bug480619.html]
 [test_certificate_overrides.html]
rename from security/manager/ssl/tests/mochitest/bugs/test_bug480619.html
rename to security/manager/ssl/tests/unit/test_logoutAndTeardown.js
--- a/security/manager/ssl/tests/mochitest/bugs/test_bug480619.html
+++ b/security/manager/ssl/tests/unit/test_logoutAndTeardown.js
@@ -1,65 +1,61 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test bug 480619</title>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>        
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-</head>
-<body>
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
 
-<script class="testbody" type="text/javascript">
+do_get_profile();
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+function connect_and_teardown() {
+  let socketTransportService =
+    Cc["@mozilla.org/network/socket-transport-service;1"]
+      .getService(Ci.nsISocketTransportService);
 
-SimpleTest.waitForExplicitFinish();
-
-var currentThread = Cc["@mozilla.org/thread-manager;1"].
-                    getService(Ci.nsIThreadManager).
-                    currentThread;
-var socketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"].
-                             getService(Ci.nsISocketTransportService);
+  let tearDown = false;
 
-var tearDown = false;
-
-var reader = {
-  onInputStreamReady: function(stream) {
-    try {
-      stream.available();
-      SimpleTest.ok(false, "Stream should be in an error state");
+  let reader = {
+    onInputStreamReady: function(stream) {
+      try {
+        stream.available();
+        Assert.ok(false, "stream.available() should have thrown");
+      }
+      catch (e) {
+        Assert.equal(e.result, Components.results.NS_ERROR_FAILURE,
+                     "stream should be in an error state");
+        Assert.ok(tearDown, "this should be as a result of logoutAndTeardown");
+        run_next_test();
+      }
     }
-    catch (e) {
-      SimpleTest.is(e.result, Components.results.NS_ERROR_FAILURE,
-                    "The stream should be inside an error state");
-      SimpleTest.ok(tearDown, "The stream should be closed after a teardown of secure decoder ring");
+  };
+
+  let sink = {
+    onTransportStatus: function(transport, status, progress, progressmax) {
+      if (status == Ci.nsISocketTransport.STATUS_CONNECTED_TO) {
+        // Try to logout and tear down the secure decoder ring.
+        // This should close and stream and notify the reader.
+        // The test will time out if this fails.
+        tearDown = true;
+        Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing)
+          .logoutAndTeardown();
+      }
     }
-    SimpleTest.finish();
-  }
-};
+  };
 
-var sink = {
-  onTransportStatus: function(transport, status, progress, progressmax) {
-    if (status == Ci.nsISocketTransport.STATUS_CONNECTED_TO) {
-      // Try to logout and tear down the secure decoder ring.
-      // This should close and stream and notify the reader.
-      // The test will time out if this fails.
-      tearDown = true;
-      Cc["@mozilla.org/security/sdr;1"].
-        getService(Ci.nsISecretDecoderRing).
-        logoutAndTeardown();
-    }
-  }
-};
+  Services.prefs.setCharPref("network.dns.localDomains",
+                             "ocsp-stapling-none.example.com");
+  let transport = socketTransportService.createTransport(
+    ["ssl"], 1, "ocsp-stapling-none.example.com", 8443, null);
+  transport.setEventSink(sink, Services.tm.currentThread);
 
-var transport = socketTransportService.createTransport(["ssl"], 1, "127.0.0.1", 4443, null);
-
-transport.setEventSink(sink, currentThread);
+  let inStream = transport.openInputStream(0, 0, 0)
+                          .QueryInterface(Ci.nsIAsyncInputStream);
+  inStream.asyncWait(reader, Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY, 0,
+                     Services.tm.currentThread);
+}
 
-var inStream = transport.openInputStream(0, 0, 0)
-                        .QueryInterface(Ci.nsIAsyncInputStream);
-
-inStream.asyncWait(reader, Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY, 0, currentThread);
-
-</script>
-</body>
-</html>
+function run_test() {
+  add_tls_server_setup("OCSPStaplingServer");
+  add_test(connect_and_teardown);
+  run_next_test();
+}
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -42,16 +42,18 @@ skip-if = toolkit == 'android' || toolki
 [test_sss_readstate_garbage.js]
 [test_sss_readstate_huge.js]
 [test_sss_savestate.js]
 
 [test_pinning_dynamic.js]
 [test_pinning_header_parsing.js]
 
 [test_cert_keyUsage.js]
+[test_logoutAndTeardown.js]
+run-sequentially = hardcoded ports
 [test_ocsp_stapling.js]
 run-sequentially = hardcoded ports
 [test_cert_blocklist.js]
 skip-if = buildapp == "b2g"
 [test_ocsp_stapling_expired.js]
 run-sequentially = hardcoded ports
 skip-if = (toolkit == 'gonk' && debug) # Bug 1029775
 [test_ocsp_stapling_with_intermediate.js]
--- a/testing/config/mozharness/android_arm_4_3_config.py
+++ b/testing/config/mozharness/android_arm_4_3_config.py
@@ -23,26 +23,25 @@ config = {
                 "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
                 "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
                 "--quiet", "--log-raw=%(raw_log_file)s", "--screenshot-on-fail",
                 "--total-chunks=4",
                 "--subsuite=webgl",
             ],
         },
         "robocop": {
-            "run_filename": "runtestsremote.py",
+            "run_filename": "runrobocop.py",
             "testsdir": "mochitest",
             "options": ["--dm_trans=adb", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
                 "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
                 "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
                 "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
                 "--quiet", "--log-raw=%(raw_log_file)s",
                 "--total-chunks=4",
                 "--robocop-apk=../../robocop.apk",
-                "--robocop-ids=fennec_ids.txt",
                 "--robocop-ini=robocop.ini",
             ],
         },
         "reftest": {
             "run_filename": "remotereftest.py",
             "testsdir": "reftest",
             "options": [ "--app=%(app)s", "--ignore-window-size",
                 "--dm_trans=adb",
--- a/testing/config/mozharness/android_arm_config.py
+++ b/testing/config/mozharness/android_arm_config.py
@@ -25,27 +25,26 @@ config = {
                 "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
                 "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
                 "--quiet", "--log-raw=%(raw_log_file)s", "--screenshot-on-fail",
                 "--total-chunks=4",
                 "--subsuite=webgl",
             ],
         },
         "robocop": {
-            "run_filename": "runtestsremote.py",
+            "run_filename": "runrobocop.py",
             "testsdir": "mochitest",
             "options": ["--dm_trans=sut", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
                 "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
                 "--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s",
                 "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
                 "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
                 "--quiet", "--log-raw=%(raw_log_file)s",
                 "--total-chunks=4",
                 "--robocop-apk=../../robocop.apk",
-                "--robocop-ids=fennec_ids.txt",
                 "--robocop-ini=robocop.ini",
             ],
         },
         "reftest": {
             "run_filename": "remotereftest.py",
             "testsdir": "reftest",
             "options": [ "--app=%(app)s", "--ignore-window-size",
                 "--bootstrap",
--- a/testing/config/mozharness/android_panda_config.py
+++ b/testing/config/mozharness/android_panda_config.py
@@ -110,17 +110,17 @@ config = {
                 "--certificate-path=certs",
                 "--app=%(app_name)s",
                 "--console-level=INFO",
                 "--http-port=%(http_port)s",
                 "--ssl-port=%(ssl_port)s",
                 "--symbols-path=%(symbols_path)s",
                 "--robocop-ini=mochitest/robocop.ini"
             ],
-            "run_filename": "runtestsremote.py",
+            "run_filename": "runrobocop.py",
             "testsdir": "mochitest"
         },
         "xpcshell": {
             "options": [
                 "--deviceIP=%(device_ip)s",
                 "--xre-path=../hostutils/xre",
                 "--manifest=xpcshell/tests/xpcshell.ini",
                 "--build-info-json=xpcshell/mozinfo.json",
--- a/testing/docker/desktop-build/Dockerfile
+++ b/testing/docker/desktop-build/Dockerfile
@@ -1,9 +1,9 @@
-FROM          quay.io/mozilla/ubuntu-build:0.0.2
+FROM          quay.io/mozilla/ubuntu-build:0.0.3
 MAINTAINER    Morgan Reece Phillips <winter2718@gmail.com>
 
 # Add build scripts; these are the entry points from the taskcluster worker, and
 # operate on environment variables
 ADD             bin /home/worker/bin
 RUN             chmod +x /home/worker/bin/*
 
 # Add custom mozharness configs
--- a/testing/docker/desktop-build/REGISTRY
+++ b/testing/docker/desktop-build/REGISTRY
@@ -1,1 +1,1 @@
-quay.io/mrrrgn
+quay.io/djmitche
--- a/testing/docker/desktop-build/VERSION
+++ b/testing/docker/desktop-build/VERSION
@@ -1,1 +1,1 @@
-0.0.20
+0.0.21
--- a/testing/docker/ubuntu-build/VERSION
+++ b/testing/docker/ubuntu-build/VERSION
@@ -1,1 +1,1 @@
-0.0.2
+0.0.3
--- a/testing/docker/ubuntu-build/system-setup.sh
+++ b/testing/docker/ubuntu-build/system-setup.sh
@@ -13,15 +13,12 @@ apt-get install -y \
     npm \
     curl \
     x11-utils \
     python-virtualenv \
     valgrind \
     uuid-dev \
     sqlite3
 
-# see https://bugzilla.mozilla.org/show_bug.cgi?id=1161075
-apt-get install -y openjdk-7-jdk
-
 # the Android SDK contains some 32-bit binaries (aapt among them) that require this
 apt-get install -y lib32z1
 
 rm /tmp/system-setup.sh
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -347,17 +347,21 @@ class CheckSpiderMonkeyCommand(MachComma
         print('running jsapi-tests')
         jsapi_tests_cmd = [os.path.join(self.bindir, executable_name('jsapi-tests'))]
         jsapi_tests_result = subprocess.call(jsapi_tests_cmd)
 
         print('running check-style')
         check_style_cmd = [sys.executable, os.path.join(self.topsrcdir, 'config', 'check_spidermonkey_style.py')]
         check_style_result = subprocess.call(check_style_cmd, cwd=os.path.join(self.topsrcdir, 'js', 'src'))
 
-        all_passed = jittest_result and jstest_result and jsapi_tests_result and check_style_result
+        print('running check-masm')
+        check_masm_cmd = [sys.executable, os.path.join(self.topsrcdir, 'config', 'check_macroassembler_style.py')]
+        check_masm_result = subprocess.call(check_masm_cmd, cwd=os.path.join(self.topsrcdir, 'js', 'src'))
+
+        all_passed = jittest_result and jstest_result and jsapi_tests_result and check_style_result and check_masm_result
 
         return all_passed
 
 @CommandProvider
 class JsapiTestsCommand(MachCommandBase):
     @Command('jsapi-tests', category='testing', description='Run jsapi tests (JavaScript engine).')
     @CommandArgument('test_name', nargs='?', metavar='N',
         help='Test to run. Can be a prefix or omitted. If omitted, the entire ' \
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -369,16 +369,36 @@ class MochitestRunner(MozbuildObject):
 
         from manifestparser import TestManifest
         manifest = TestManifest()
         manifest.tests.extend(tests)
         options.manifestFile = manifest
 
         return runtestsremote.run_test_harness(options)
 
+    def run_robocop_test(self, context, tests, suite=None, **kwargs):
+        host_ret = verify_host_bin()
+        if host_ret != 0:
+            return host_ret
+
+        import imp
+        path = os.path.join(self.mochitest_dir, 'runrobocop.py')
+        with open(path, 'r') as fh:
+            imp.load_module('runrobocop', fh, path,
+                            ('.py', 'r', imp.PY_SOURCE))
+        import runrobocop
+
+        options = Namespace(**kwargs)
+
+        from manifestparser import TestManifest
+        manifest = TestManifest()
+        manifest.tests.extend(tests)
+        options.manifestFile = manifest
+
+        return runrobocop.run_test_harness(options)
 
 # parser
 
 def setup_argument_parser():
     build_obj = MozbuildObject.from_environment(cwd=here)
 
     build_path = os.path.join(build_obj.topobjdir, 'build')
     if build_path not in sys.path:
@@ -599,17 +619,17 @@ class RobocopCommands(MachCommandBase):
         kwargs['test_paths'] = []
 
         from mozbuild.testing import TestResolver
         resolver = self._spawn(TestResolver)
         tests = list(resolver.resolve_tests(paths=test_paths, cwd=self._mach_context.cwd,
             flavor='instrumentation', subsuite='robocop'))
 
         mochitest = self._spawn(MochitestRunner)
-        return mochitest.run_android_test(self._mach_context, tests, 'robocop', **kwargs)
+        return mochitest.run_robocop_test(self._mach_context, tests, 'robocop', **kwargs)
 
 
 def REMOVED(cls):
     """Command no longer exists! Use |mach mochitest| instead.
 
     The |mach mochitest| command will automatically detect which flavors and
     subsuites exist in a given directory. If desired, flavors and subsuites
     can be restricted using `--flavor` and `--subsuite` respectively. E.g:
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -1011,22 +1011,16 @@ class AndroidArguments(ArgumentContainer
           "default": "",
           "help": "name of the .ini file containing the list of tests to run",
           }],
         [["--robocop-apk"],
          {"dest": "robocopApk",
           "default": "",
           "help": "name of the Robocop APK to use for ADB test running",
           }],
-        [["--robocop-ids"],
-         {"dest": "robocopIds",
-          "default": "",
-          "help": "name of the file containing the view ID map \
-                   (fennec_ids.txt)",
-          }],
         [["--remoteTestRoot"],
          {"dest": "remoteTestRoot",
           "default": None,
           "help": "remote directory to use as test root \
                    (eg. /mnt/sdcard/tests or /data/local/tests)",
           "suppress": True,
           }],
     ]
@@ -1125,23 +1119,16 @@ class AndroidArguments(ArgumentContainer
 
         if options.robocopApk != "":
             if not os.path.exists(options.robocopApk):
                 parser.error(
                     "Unable to find robocop APK '%s'" %
                     options.robocopApk)
             options.robocopApk = os.path.abspath(options.robocopApk)
 
-        if options.robocopIds != "":
-            if not os.path.exists(options.robocopIds):
-                parser.error(
-                    "Unable to find specified robocop IDs file '%s'" %
-                    options.robocopIds)
-            options.robocopIds = os.path.abspath(options.robocopIds)
-
         # allow us to keep original application around for cleanup while
         # running robocop via 'am'
         options.remoteappname = options.app
         return options
 
 
 container_map = {
     'generic': [MochitestArguments],
--- a/testing/mochitest/moz.build
+++ b/testing/mochitest/moz.build
@@ -58,16 +58,17 @@ TEST_HARNESS_FILES.testing.mochitest += 
     'leaks.py',
     'mach_test_package_commands.py',
     'manifest.webapp',
     'manifestLibrary.js',
     'mochitest_options.py',
     'nested_setup.js',
     'pywebsocket_wrapper.py',
     'redirect.html',
+    'runrobocop.py',
     'runtests.py',
     'runtestsb2g.py',
     'runtestsremote.py',
     'server.js',
 ]
 
 TEST_HARNESS_FILES.testing.mochitest.pywebsocket += [
     'pywebsocket/standalone.py',
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/runrobocop.py
@@ -0,0 +1,554 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import json
+import os
+import shutil
+import sys
+import tempfile
+import traceback
+
+sys.path.insert(
+    0, os.path.abspath(
+        os.path.realpath(
+            os.path.dirname(__file__))))
+
+from automation import Automation
+from remoteautomation import RemoteAutomation, fennecLogcatFilters
+from runtests import Mochitest, MessageLogger
+from mochitest_options import MochitestArgumentParser
+
+from manifestparser import TestManifest
+from manifestparser.filters import chunk_by_slice
+import devicemanager
+import mozinfo
+
+SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
+
+
+class RobocopTestRunner(Mochitest):
+    """
+       A test harness for Robocop. Robocop tests are UI tests for Firefox for Android,
+       based on the Robotium test framework. This harness leverages some functionality
+       from mochitest, for convenience.
+    """
+    auto = None
+    dm = None
+    # Some robocop tests run for >60 seconds without generating any output.
+    NO_OUTPUT_TIMEOUT = 180
+
+    def __init__(self, automation, devmgr, options):
+        """
+           Simple one-time initialization.
+        """
+        Mochitest.__init__(self, options)
+
+        self.auto = automation
+        self.dm = devmgr
+        self.dm.default_timeout = 320
+        self.options = options
+        self.options.logFile = "robocop.log"
+        self.environment = self.auto.environment
+        self.deviceRoot = self.dm.getDeviceRoot()
+        self.remoteProfile = options.remoteTestRoot + "/profile"
+        self.remoteProfileCopy = options.remoteTestRoot + "/profile-copy"
+        self.auto.setRemoteProfile(self.remoteProfile)
+        self.remoteConfigFile = os.path.join(
+            self.deviceRoot, "robotium.config")
+        self.remoteLog = options.remoteLogFile
+        self.auto.setRemoteLog(self.remoteLog)
+        self.remoteScreenshots = "/mnt/sdcard/Robotium-Screenshots"
+        self.remoteNSPR = os.path.join(options.remoteTestRoot, "nspr")
+        self.auto.setServerInfo(
+            self.options.webServer, self.options.httpPort, self.options.sslPort)
+        self.localLog = options.logFile
+        self.localProfile = None
+        productPieces = self.options.remoteProductName.split('.')
+        if (productPieces is not None):
+            self.auto.setProduct(productPieces[0])
+        else:
+            self.auto.setProduct(self.options.remoteProductName)
+        self.auto.setAppName(self.options.remoteappname)
+        self.certdbNew = True
+        self.remoteCopyAvailable = True
+        self.passed = 0
+        self.failed = 0
+        self.todo = 0
+
+    def startup(self):
+        """
+           Second-stage initialization: One-time initialization which may require cleanup.
+        """
+        # Despite our efforts to clean up servers started by this script, in practice
+        # we still see infrequent cases where a process is orphaned and interferes
+        # with future tests, typically because the old server is keeping the port in use.
+        # Try to avoid those failures by checking for and killing orphan servers before
+        # trying to start new ones.
+        self.killNamedOrphans('ssltunnel')
+        self.killNamedOrphans('xpcshell')
+        self.auto.deleteANRs()
+        self.auto.deleteTombstones()
+        self.dm.killProcess(self.options.app.split('/')[-1])
+        self.dm.removeDir(self.remoteScreenshots)
+        self.dm.removeDir(self.remoteNSPR)
+        self.dm.mkDir(self.remoteNSPR)
+        self.dm.mkDir(os.path.dirname(self.options.remoteLogFile))
+        # Add Android version (SDK level) to mozinfo so that manifest entries
+        # can be conditional on android_version.
+        androidVersion = self.dm.shellCheckOutput(
+            ['getprop', 'ro.build.version.sdk'])
+        self.log.info(
+            "Android sdk version '%s'; will use this to filter manifests" %
+            str(androidVersion))
+        mozinfo.info['android_version'] = androidVersion
+        if (self.options.dm_trans == 'adb' and self.options.robocopApk):
+            self.dm._checkCmd(["install", "-r", self.options.robocopApk])
+            self.log.debug("Robocop APK %s installed" %
+                           self.options.robocopApk)
+        # Display remote diagnostics; if running in mach, keep output terse.
+        if self.options.log_mach is None:
+            self.printDeviceInfo()
+        self.setupLocalPaths()
+        self.buildProfile()
+        # ignoreSSLTunnelExts is a workaround for bug 1109310
+        self.startServers(
+            self.options,
+            debuggerInfo=None,
+            ignoreSSLTunnelExts=True)
+        self.log.debug("Servers started")
+
+    def cleanup(self):
+        """
+           Cleanup at end of job run.
+        """
+        self.log.debug("Cleaning up...")
+        self.stopServers()
+        self.dm.killProcess(self.options.app.split('/')[-1])
+        blobberUploadDir = os.environ.get('MOZ_UPLOAD_DIR', None)
+        if blobberUploadDir:
+            self.log.debug("Pulling any remote nspr logs and screenshots to %s." %
+                           blobberUploadDir)
+            self.dm.getDirectory(self.remoteNSPR, blobberUploadDir)
+            self.dm.getDirectory(self.remoteScreenshots, blobberUploadDir)
+        Mochitest.cleanup(self, self.options)
+        if self.localProfile:
+            os.system("rm -Rf %s" % self.localProfile)
+        self.dm.removeDir(self.remoteProfile)
+        self.dm.removeDir(self.remoteProfileCopy)
+        self.dm.removeDir(self.remoteScreenshots)
+        self.dm.removeDir(self.remoteNSPR)
+        self.dm.removeFile(self.remoteConfigFile)
+        if self.dm.fileExists(self.remoteLog):
+            self.dm.removeFile(self.remoteLog)
+        self.log.debug("Cleanup complete.")
+
+    def findPath(self, paths, filename=None):
+        for path in paths:
+            p = path
+            if filename:
+                p = os.path.join(p, filename)
+            if os.path.exists(self.getFullPath(p)):
+                return path
+        return None
+
+    def makeLocalAutomation(self):
+        localAutomation = Automation()
+        localAutomation.IS_WIN32 = False
+        localAutomation.IS_LINUX = False
+        localAutomation.IS_MAC = False
+        localAutomation.UNIXISH = False
+        hostos = sys.platform
+        if (hostos == 'mac' or hostos == 'darwin'):
+            localAutomation.IS_MAC = True
+        elif (hostos == 'linux' or hostos == 'linux2'):
+            localAutomation.IS_LINUX = True
+            localAutomation.UNIXISH = True
+        elif (hostos == 'win32' or hostos == 'win64'):
+            localAutomation.BIN_SUFFIX = ".exe"
+            localAutomation.IS_WIN32 = True
+        return localAutomation
+
+    def setupLocalPaths(self):
+        """
+           Setup xrePath and utilityPath and verify xpcshell.
+
+           This is similar to switchToLocalPaths in runtestsremote.py.
+        """
+        localAutomation = self.makeLocalAutomation()
+        paths = [
+            self.options.xrePath,
+            localAutomation.DIST_BIN,
+            self.auto._product,
+            os.path.join('..', self.auto._product)
+        ]
+        self.options.xrePath = self.findPath(paths)
+        if self.options.xrePath is None:
+            self.log.error(
+                "unable to find xulrunner path for %s, please specify with --xre-path" %
+                os.name)
+            sys.exit(1)
+        self.log.debug("using xre path %s" % self.options.xrePath)
+        xpcshell = "xpcshell"
+        if (os.name == "nt"):
+            xpcshell += ".exe"
+        if self.options.utilityPath:
+            paths = [self.options.utilityPath, self.options.xrePath]
+        else:
+            paths = [self.options.xrePath]
+        self.options.utilityPath = self.findPath(paths, xpcshell)
+        if self.options.utilityPath is None:
+            self.log.error(
+                "unable to find utility path for %s, please specify with --utility-path" %
+                os.name)
+            sys.exit(1)
+        self.log.debug("using utility path %s" % self.options.utilityPath)
+        xpcshell_path = os.path.join(self.options.utilityPath, xpcshell)
+        if localAutomation.elf_arm(xpcshell_path):
+            self.log.error('xpcshell at %s is an ARM binary; please use '
+                           'the --utility-path argument to specify the path '
+                           'to a desktop version.' % xpcshell_path)
+            sys.exit(1)
+        self.log.debug("xpcshell found at %s" % xpcshell_path)
+
+    def buildProfile(self):
+        """
+           Build a profile locally, keep it locally for use by servers and
+           push a copy to the remote profile-copy directory.
+
+           This is similar to buildProfile in runtestsremote.py.
+        """
+        self.options.extraPrefs.append('browser.search.suggest.enabled=true')
+        self.options.extraPrefs.append('browser.search.suggest.prompted=true')
+        self.options.extraPrefs.append('layout.css.devPixelsPerPx=1.0')
+        self.options.extraPrefs.append('browser.chrome.dynamictoolbar=false')
+        self.options.extraPrefs.append('browser.snippets.enabled=false')
+        self.options.extraPrefs.append('browser.casting.enabled=true')
+        self.options.extraPrefs.append('extensions.autoupdate.enabled=false')
+        manifest = Mochitest.buildProfile(self, self.options)
+        self.localProfile = self.options.profilePath
+        self.log.debug("Profile created at %s" % self.localProfile)
+        # some files are not needed for robocop; save time by not pushing
+        shutil.rmtree(os.path.join(self.localProfile, 'webapps'))
+        desktop_extensions = ['mochikit@mozilla.org', 'worker-test@mozilla.org', 'workerbootstrap-test@mozilla.org']
+        for ext in desktop_extensions:
+            shutil.rmtree(os.path.join(self.localProfile, 'extensions', 'staged', ext))
+        os.remove(os.path.join(self.localProfile, 'userChrome.css'))
+        try:
+            self.dm.pushDir(self.localProfile, self.remoteProfileCopy)
+        except devicemanager.DMError:
+            self.log.error(
+                "Automation Error: Unable to copy profile to device.")
+            raise
+
+        return manifest
+
+    def setupRemoteProfile(self):
+        """
+           Remove any remote profile and re-create it.
+        """
+        self.log.debug("Updating remote profile at %s" % self.remoteProfile)
+        self.dm.removeDir(self.remoteProfile)
+        if self.remoteCopyAvailable:
+            try:
+                self.dm.shellCheckOutput(
+                    ['cp', '-r', self.remoteProfileCopy, self.remoteProfile],
+                    root=True, timeout=60)
+            except devicemanager.DMError:
+                # For instance, cp is not available on some older versions of
+                # Android.
+                self.log.info(
+                    "Unable to copy remote profile; falling back to push.")
+                self.remoteCopyAvailable = False
+        if not self.remoteCopyAvailable:
+            self.dm.pushDir(self.localProfile, self.remoteProfile)
+
+    def parseLocalLog(self):
+        """
+           Read and parse the local log file, noting any failures.
+        """
+        with open(self.localLog) as currentLog:
+            data = currentLog.readlines()
+        os.unlink(self.localLog)
+        start_found = False
+        end_found = False
+        fail_found = False
+        for line in data:
+            try:
+                message = json.loads(line)
+                if not isinstance(message, dict) or 'action' not in message:
+                    continue
+            except ValueError:
+                continue
+            if message['action'] == 'test_end':
+                end_found = True
+                start_found = False
+                break
+            if start_found and not end_found:
+                if 'status' in message:
+                    if 'expected' in message:
+                        self.failed += 1
+                    elif message['status'] == 'PASS':
+                        self.passed += 1
+                    elif message['status'] == 'FAIL':
+                        self.todo += 1
+            if message['action'] == 'test_start':
+                start_found = True
+            if 'expected' in message:
+                fail_found = True
+        result = 0
+        if fail_found:
+            result = 1
+        if not end_found:
+            self.log.info(
+                "PROCESS-CRASH | Automation Error: Missing end of test marker (process crashed?)")
+            result = 1
+        return result
+
+    def logTestSummary(self):
+        """
+           Print a summary of all tests run to stdout, for treeherder parsing 
+           (logging via self.log does not work here).
+        """
+        print("0 INFO TEST-START | Shutdown")
+        print("1 INFO Passed: %s" % (self.passed))
+        print("2 INFO Failed: %s" % (self.failed))
+        print("3 INFO Todo: %s" % (self.todo))
+        print("4 INFO SimpleTest FINISHED")
+        if self.failed > 0:
+            return 1
+        return 0
+