merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 02 Jun 2015 13:11:05 +0200
changeset 246688 9eae3880b132898a96a80d497cba2b9523e049a4
parent 246687 f0112e6128c0a7cc5eca0ce9892e05ee036b2721 (current diff)
parent 246611 d245fc3d7b548cb82ed9909600439137132fe83e (diff)
child 246689 3bd03f40fa950bb76f92228dc7abde1726ac1552
child 246784 c1984c27f7f3a30e46d198bf0a7faf705e4a24e4
child 246820 0ddd75b1e92d57dac5380048d73395d5240bb485
push id60505
push usercbook@mozilla.com
push dateTue, 02 Jun 2015 11:13:28 +0000
treeherdermozilla-inbound@3bd03f40fa95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.0a1
first release with
nightly linux32
9eae3880b132 / 41.0a1 / 20150602055237 / files
nightly linux64
9eae3880b132 / 41.0a1 / 20150602055237 / files
nightly mac
9eae3880b132 / 41.0a1 / 20150602055237 / files
nightly win32
9eae3880b132 / 41.0a1 / 20150602055237 / files
nightly win64
9eae3880b132 / 41.0a1 / 20150602055237 / 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 mozilla-inbound to mozilla-central a=merge
dom/tests/browser/browser_geolocation_privatebrowsing_page.html
dom/tests/browser/browser_geolocation_privatebrowsing_perwindowpb.js
dom/tests/browser/network_geolocation.sjs
js/src/jit-test/jit_test.py
js/src/jit-test/tests/basic/bug734196.js
js/src/jit-test/tests/basic/bug747926.js
js/src/jit-test/tests/basic/bug821340.js
modules/libpref/init/all.js
--- a/b2g/config/aries/config.json
+++ b/b2g/config/aries/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-aries.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/dolphin-512/config.json
+++ b/b2g/config/dolphin-512/config.json
@@ -1,13 +1,16 @@
 {
     "config_version": 2,
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "bc"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["kernelheader", ""],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/dolphin/config.json
+++ b/b2g/config/dolphin/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-dolphin.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "bc"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["kernelheader", ""],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/emulator-ics/config.json
+++ b/b2g/config/emulator-ics/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-ics.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/test_packages.json",
         "{workdir}/sources.xml"
--- a/b2g/config/emulator-jb/config.json
+++ b/b2g/config/emulator-jb/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-jb.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{workdir}/sources.xml"
     ],
--- a/b2g/config/emulator-kk/config.json
+++ b/b2g/config/emulator-kk/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-kk.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{workdir}/sources.xml"
     ],
--- a/b2g/config/emulator-l/config.json
+++ b/b2g/config/emulator-l/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-l.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{workdir}/sources.xml"
     ],
--- a/b2g/config/emulator-x86-kk/config.json
+++ b/b2g/config/emulator-x86-kk/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-kk.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{workdir}/sources.xml"
     ],
--- a/b2g/config/emulator-x86-l/config.json
+++ b/b2g/config/emulator-x86-l/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator-l.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{workdir}/sources.xml"
     ],
--- a/b2g/config/emulator/config.json
+++ b/b2g/config/emulator/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-emulator.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
         "{workdir}/out/target/product/generic/*.tar.bz2",
         "{workdir}/out/target/product/generic/tests/*.zip",
         "{workdir}/out/emulator.tar.gz",
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/test_packages.json",
         "{workdir}/sources.xml"
--- a/b2g/config/flame-kk/config.json
+++ b/b2g/config/flame-kk/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-flame-kk.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/flame/config.json
+++ b/b2g/config/flame/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-flame.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/hamachi/config.json
+++ b/b2g/config/hamachi/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-hamachi.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel", "git", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/helix/config.json
+++ b/b2g/config/helix/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-helix.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel", "git", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/mozconfigs/common
+++ b/b2g/config/mozconfigs/common
@@ -9,8 +9,16 @@
 # Normally, we'd set this unconditionally, but this file is also used
 # for local builds and there is no other mozconfig in this tree that
 # is included on device builds.
 if test -d $topsrcdir/../gcc/bin; then
     HOST_CC="$topsrcdir/../gcc/bin/gcc"
     HOST_CXX="$topsrcdir/../gcc/bin/g++"
     ac_add_options --enable-stdcxx-compat
 fi
+
+# Allow overriding this from the environment, and don't
+# try to set it if it doesn't exist. As per above, this file is also
+# used for local builds, and we may need to override this for builds in
+# other environments.
+if test -z "$SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE" -a -f /builds/crash-stats-api.token; then
+  export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
+fi
--- a/b2g/config/nexus-4/config.json
+++ b/b2g/config/nexus-4/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-mako.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/nexus-5-l/config.json
+++ b/b2g/config/nexus-5-l/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-nexus5.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
--- a/b2g/config/wasabi/config.json
+++ b/b2g/config/wasabi/config.json
@@ -1,14 +1,17 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-wasabi.tt",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel", "git", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel"],
-    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "mock_files": [
+        ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
+        ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
+    ],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "zip_files": [
         ["{workdir}/out/target/product/wasabi/*.img", "out/target/product/wasabi/"],
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10989,16 +10989,28 @@ nsDocShell::DoChannelLoad(nsIChannel* aC
   }
 
   if (!aBypassClassifier) {
     loadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
   }
 
   (void)aChannel->SetLoadFlags(loadFlags);
 
+  // If the user pressed shift-reload, then do not allow ServiceWorker
+  // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
+  if (mLoadType == LOAD_RELOAD_BYPASS_CACHE ||
+      mLoadType == LOAD_RELOAD_BYPASS_PROXY ||
+      mLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
+      mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) {
+    nsCOMPtr<nsIHttpChannelInternal> internal = do_QueryInterface(aChannel);
+    if (internal) {
+      internal->ForceNoIntercept();
+    }
+  }
+
   uint32_t openFlags = 0;
   if (mLoadType == LOAD_LINK) {
     openFlags |= nsIURILoader::IS_CONTENT_PREFERRED;
   }
   if (!mAllowContentRetargeting) {
     openFlags |= nsIURILoader::DONT_RETARGET;
   }
   rv = aURILoader->OpenURI(aChannel, openFlags, this);
--- a/dom/base/DirectionalityUtils.cpp
+++ b/dom/base/DirectionalityUtils.cpp
@@ -523,19 +523,19 @@ private:
   {
     Element* rootNode = aEntry->GetKey();
     rootNode->ClearHasDirAutoSet();
     rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
     return PL_DHASH_REMOVE;
   }
 
 public:
-  void UpdateAutoDirection(Directionality aDir)
+  uint32_t UpdateAutoDirection(Directionality aDir)
   {
-    mElements.EnumerateEntries(SetNodeDirection, &aDir);
+    return mElements.EnumerateEntries(SetNodeDirection, &aDir);
   }
 
   void ResetAutoDirection(nsINode* aTextNode)
   {
     mElements.EnumerateEntries(ResetNodeDirection, aTextNode);
   }
 
   void EnsureMapIsClear(nsINode* aTextNode)
@@ -557,21 +557,22 @@ public:
     nsTextNodeDirectionalityMap* map = GetDirectionalityMap(aTextNode);
     if (!map) {
       map = new nsTextNodeDirectionalityMap(aTextNode);
     }
 
     map->AddEntry(aTextNode, aElement);
   }
 
-  static void UpdateTextNodeDirection(nsINode* aTextNode, Directionality aDir)
+  static uint32_t UpdateTextNodeDirection(nsINode* aTextNode,
+                                          Directionality aDir)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in UpdateTextNodeDirection");
-    GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
+    return GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
   }
 
   static void ResetTextNodeDirection(nsINode* aTextNode)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in ResetTextNodeDirection");
     GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode);
   }
@@ -841,24 +842,26 @@ TextNodeChangedDirection(nsIContent* aTe
       // directionality of any elements whose directionality was
       // determined by this node.
       nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
     }
   } else {
     // This node has a strong directional character. If it has a
     // TextNodeDirectionalityMap property, it already determines the
     // directionality of some element(s), so call UpdateTextNodeDirection to
-    // reresolve their directionality. Otherwise call
-    // SetAncestorDirectionIfAuto to find ancestor elements which should
-    // have their directionality determined by this node.
-    if (aTextNode->HasTextNodeDirectionalityMap()) {
-      nsTextNodeDirectionalityMap::UpdateTextNodeDirection(aTextNode, newDir);
-    } else {
-      SetAncestorDirectionIfAuto(aTextNode, newDir, aNotify);
+    // reresolve their directionality. If it has no map, or if
+    // UpdateTextNodeDirection returns zero, indicating that the map is
+    // empty, call SetAncestorDirectionIfAuto to find ancestor elements
+    // which should have their directionality determined by this node.
+    if (aTextNode->HasTextNodeDirectionalityMap() &&
+        nsTextNodeDirectionalityMap::UpdateTextNodeDirection(aTextNode,
+                                                             newDir)) {
+      return;
     }
+    SetAncestorDirectionIfAuto(aTextNode, newDir, aNotify);
   }
 }
 
 void
 SetDirectionFromNewTextNode(nsIContent* aTextNode)
 {
   if (!NodeAffectsDirAutoAncestor(aTextNode)) {
     return;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4764,16 +4764,19 @@ nsDocument::SetScriptGlobalObject(nsIScr
     mTemplateContentsOwner->SetScriptGlobalObject(aScriptGlobalObject);
   }
 
   nsCOMPtr<nsIChannel> channel = GetChannel();
   if (!mMaybeServiceWorkerControlled && channel) {
     nsLoadFlags loadFlags = 0;
     channel->GetLoadFlags(&loadFlags);
     // If we are shift-reloaded, don't associate with a ServiceWorker.
+    // TODO: This should check the nsDocShell definition of shift-reload instead
+    //       of trying to infer it from LOAD_BYPASS_CACHE.  The current code
+    //       will probably cause problems once bug 1120715 lands.
     if (loadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
       NS_WARNING("Page was shift reloaded, skipping ServiceWorker control");
       return;
     }
 
     nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
     if (swm) {
       swm->MaybeStartControlling(this);
@@ -7871,17 +7874,21 @@ nsIDocument::AdoptNode(nsINode& aAdopted
 }
 
 nsViewportInfo
 nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
 {
   // Compute the CSS-to-LayoutDevice pixel scale as the product of the
   // widget scale and the full zoom.
   nsPresContext* context = mPresShell->GetPresContext();
-  float fullZoom = context ? context->GetFullZoom() : 1.0;
+  // When querying the full zoom, get it from the device context rather than
+  // directly from the pres context, because the device context's value can
+  // include an adjustment necessay to keep the number of app units per device
+  // pixel an integer, and we want the adjusted value.
+  float fullZoom = context ? context->DeviceContext()->GetFullZoom() : 1.0;
   fullZoom = (fullZoom == 0.0) ? 1.0 : fullZoom;
   nsIWidget *widget = nsContentUtils::WidgetForDocument(this);
   float widgetScale = widget ? widget->GetDefaultScale().scale : 1.0f;
   CSSToLayoutDeviceScale layoutDeviceScale(widgetScale * fullZoom);
 
   CSSToScreenScale defaultScale = layoutDeviceScale
                                 * LayoutDeviceToScreenScale(1.0);
   // Get requested Desktopmode
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -525,16 +525,17 @@ BrowserElementChild.prototype = {
 
     if (!e.target.name) {
       return;
     }
 
     debug('Got metaChanged: (' + e.target.name + ') ' + e.target.content);
 
     let handlers = {
+      'viewmode': this._viewmodeChangedHandler,
       'theme-color': this._themeColorChangedHandler,
       'application-name': this._applicationNameChangedHandler
     };
 
     let handler = handlers[e.target.name];
     if (handler) {
       handler(e.type, e.target);
     }
@@ -697,16 +698,26 @@ BrowserElementChild.prototype = {
       detail.rect.left += currentRect.left;
       detail.rect.right += currentRect.left;
       currentWindow = currentWindow.realFrameElement.ownerDocument.defaultView;
     }
 
     sendAsyncMsg('selectionstatechanged', detail);
   },
 
+
+  _viewmodeChangedHandler: function(eventType, target) {
+    let meta = {
+      name: 'viewmode',
+      content: target.content,
+      type: eventType.replace('DOMMeta', '').toLowerCase()
+    };
+    sendAsyncMsg('metachange', meta);
+  },
+
   _themeColorChangedHandler: function(eventType, target) {
     let meta = {
       name: 'theme-color',
       content: target.content,
       type: eventType.replace('DOMMeta', '').toLowerCase()
     };
     sendAsyncMsg('metachange', meta);
   },
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_Viewmode.js
@@ -0,0 +1,71 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that the onmozbrowsermetachange event for viewmode works.
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+function runTest() {
+  function loadFrameScript(script) {
+    SpecialPowers.getBrowserFrameMessageManager(iframe1)
+                 .loadFrameScript('data:,' + script,
+                                  /* allowDelayedLoad = */ false);
+  }
+
+  let iframe1 = document.createElement('iframe');
+  iframe1.setAttribute('mozbrowser', 'true');
+  iframe1.src = "http://test/tests/dom/browser-element/mochitest/file_browserElement_Viewmode.html";
+  iframe1.addEventListener('mozbrowsermetachange', tests);
+  document.body.appendChild(iframe1);
+
+  let numMetaChanges = 0;
+  function tests(e) {
+    let detail = e.detail;
+
+    switch (numMetaChanges++) {
+      case 0: {
+        is(detail.name, 'viewmode', 'name matches');
+        is(detail.content, 'projection=stereo', 'content matches');
+        is(detail.type, 'added', 'type matches');
+
+        let script =
+          "var meta = content.document.head.querySelector('meta');" +
+          "meta.content = 'projection=mono';";
+        loadFrameScript(script);
+        break;
+      }
+
+      case 1: {
+        is(detail.name, 'viewmode', 'name matches');
+        is(detail.content, 'projection=mono', 'content matches');
+        is(detail.type, 'changed', 'type matches');
+
+        let script =
+          "var meta = content.document.head.querySelector('meta');" +
+          "meta.parentNode.removeChild(meta);";
+        loadFrameScript(script);
+        break;
+      }
+
+      case 2: {
+        is(detail.name, 'viewmode', 'name matches');
+        is(detail.content, 'projection=mono', 'content matches');
+        is(detail.type, 'removed', 'type matches');
+
+        SimpleTest.finish();
+        break;
+      }
+
+      default: {
+        ok(false, 'Too many metachange events.');
+        break;
+      }
+    }
+  };
+}
+
+window.addEventListener('testready', runTest);
+
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/file_browserElement_Viewmode.html
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <meta name="viewmode" content="projection=stereo">
+  </head>
+
+  <body>
+  </body>
+</html>
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -4,16 +4,17 @@
 # OOP tests don't work on native-fennec (bug 774939).
 # Bug 960345 - Disabled on OSX debug for frequent crashes.
 skip-if = os == "android" || (toolkit == "cocoa" && debug) || buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || e10s
 support-files =
   browserElement_OpenMixedProcess.js
   file_browserElement_OpenMixedProcess.html
   browserElement_OpenTab.js
 
+[test_browserElement_oop_Viewmode.html]
 [test_browserElement_oop_ThemeColor.html]
 [test_browserElement_inproc_ErrorSecurity.html]
 skip-if = toolkit=='gonk'
 [test_browserElement_inproc_OpenMixedProcess.html]
 skip-if = toolkit=='gonk' || (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_Alert.html]
 [test_browserElement_oop_AlertInFrame.html]
 [test_browserElement_oop_AllowEmbedAppsInNestedOOIframe.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -7,16 +7,17 @@ support-files =
   browserElement_Alert.js
   browserElement_AlertInFrame.js
   browserElement_AllowEmbedAppsInNestedOOIframe.js
   browserElement_AppFramePermission.js
   browserElement_AppWindowNamespace.js
   browserElement_Auth.js
   browserElement_BackForward.js
   browserElement_BadScreenshot.js
+  browserElement_Viewmode.js
   browserElement_ThemeColor.js
   browserElement_BrowserWindowNamespace.js
   browserElement_BrowserWindowResize.js
   browserElement_Close.js
   browserElement_CloseApp.js
   browserElement_CloseFromOpener.js
   browserElement_ContextmenuEvents.js
   browserElement_CookiesNotThirdParty.js
@@ -72,16 +73,17 @@ support-files =
   browserElement_XFrameOptionsSameOrigin.js
   browserElement_XFrameOptionsSameOrigin.js
   browserElement_GetContentDimensions.js
   file_browserElement_AlertInFrame.html
   file_browserElement_AlertInFrame_Inner.html
   file_browserElement_AllowEmbedAppsInNestedOOIframe.html
   file_browserElement_AppFramePermission.html
   file_browserElement_AppWindowNamespace.html
+  file_browserElement_Viewmode.html
   file_browserElement_ThemeColor.html
   file_browserElement_BrowserWindowNamespace.html
   file_browserElement_CloseApp.html
   file_browserElement_CloseFromOpener.html
   file_browserElement_CookiesNotThirdParty.html
   file_browserElement_DisallowEmbedAppsInOOP.html
   file_browserElement_ForwardName.html
   file_browserElement_FrameWrongURI.html
@@ -121,16 +123,17 @@ support-files =
 
 # Note: browserElementTestHelpers.js looks at the test's filename to determine
 # whether the test should be OOP.  "_oop_" signals OOP, "_inproc_" signals in
 # process.  Default is OOP.
 [test_browserElement_NoAttr.html]
 [test_browserElement_NoPref.html]
 [test_browserElement_NoPermission.html]
 [test_browserElement_inproc_Alert.html]
+[test_browserElement_inproc_Viewmode.html]
 [test_browserElement_inproc_ThemeColor.html]
 skip-if = buildapp == 'b2g'
 [test_browserElement_inproc_AlertInFrame.html]
 [test_browserElement_inproc_AppFramePermission.html]
 skip-if = toolkit == 'android' || buildapp == 'b2g'
 [test_browserElement_inproc_AppWindowNamespace.html]
 skip-if = toolkit == 'android' || buildapp == 'b2g' # android(TIMED_OUT, bug 783509) androidx86(TIMED_OUT, bug 783509)
 [test_browserElement_inproc_Auth.html]
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_Viewmode.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1162844
+-->
+<head>
+  <title>Test for Bug 1162844</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1162844">Mozilla Bug 1162844</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_Viewmode.js">
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_Viewmode.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1162844
+-->
+<head>
+  <title>Test for Bug 1162844</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1162844">Mozilla Bug 1162844</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_Viewmode.js">
+</script>
+
+</body>
+</html>
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -1293,16 +1293,23 @@ nsTextEditorState::PrepareEditor(const n
   } else {
     if (aValue || !mEditorInitialized) {
       // Set the correct value in the root node
       rv = mBoundFrame->UpdateValueDisplay(true, !mEditorInitialized, aValue);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     newEditor = mEditor; // just pretend that we have a new editor!
+
+    // Don't lose application flags in the process.
+    uint32_t originalFlags = 0;
+    newEditor->GetFlags(&originalFlags);
+    if (originalFlags & nsIPlaintextEditor::eEditorMailMask) {
+      editorFlags |= nsIPlaintextEditor::eEditorMailMask;
+    }
   }
 
   // Get the current value of the textfield from the content.
   // Note that if we've created a new editor, mEditor is null at this stage,
   // so we will get the real value from the content.
   nsAutoString defaultValue;
   if (aValue) {
     defaultValue = *aValue;
--- a/dom/media/MediaPromise.h
+++ b/dom/media/MediaPromise.h
@@ -120,47 +120,52 @@ template<typename ResolveValueT, typenam
 class MediaPromise : public MediaPromiseRefcountable
 {
 public:
   typedef ResolveValueT ResolveValueType;
   typedef RejectValueT RejectValueType;
   class ResolveOrRejectValue
   {
   public:
-    void SetResolve(const ResolveValueType& aResolveValue)
+    template<typename ResolveValueType_>
+    void SetResolve(ResolveValueType_&& aResolveValue)
     {
       MOZ_ASSERT(IsNothing());
-      mResolveValue.emplace(aResolveValue);
+      mResolveValue.emplace(Forward<ResolveValueType_>(aResolveValue));
     }
 
-    void SetReject(const RejectValueType& aRejectValue)
+    template<typename RejectValueType_>
+    void SetReject(RejectValueType_&& aRejectValue)
     {
       MOZ_ASSERT(IsNothing());
-      mRejectValue.emplace(aRejectValue);
+      mRejectValue.emplace(Forward<RejectValueType_>(aRejectValue));
     }
 
-    static ResolveOrRejectValue MakeResolve(const ResolveValueType aResolveValue)
+    template<typename ResolveValueType_>
+    static ResolveOrRejectValue MakeResolve(ResolveValueType_&& aResolveValue)
     {
       ResolveOrRejectValue val;
-      val.SetResolve(aResolveValue);
+      val.SetResolve(Forward<ResolveValueType_>(aResolveValue));
       return val;
     }
 
-    static ResolveOrRejectValue MakeReject(const RejectValueType aRejectValue)
+    template<typename RejectValueType_>
+    static ResolveOrRejectValue MakeReject(RejectValueType_&& aRejectValue)
     {
       ResolveOrRejectValue val;
-      val.SetReject(aRejectValue);
+      val.SetReject(Forward<RejectValueType_>(aRejectValue));
       return val;
     }
 
     bool IsResolve() const { return mResolveValue.isSome(); }
     bool IsReject() const { return mRejectValue.isSome(); }
     bool IsNothing() const { return mResolveValue.isNothing() && mRejectValue.isNothing(); }
-    ResolveValueType& ResolveValue() { return mResolveValue.ref(); }
-    RejectValueType& RejectValue() { return mRejectValue.ref(); }
+
+    const ResolveValueType& ResolveValue() const { return mResolveValue.ref(); }
+    const RejectValueType& RejectValue() const { return mRejectValue.ref(); }
 
   private:
     Maybe<ResolveValueType> mResolveValue;
     Maybe<RejectValueType> mRejectValue;
   };
 
 protected:
   // MediaPromise is the public type, and never constructed directly. Construct
@@ -178,30 +183,93 @@ public:
   // consumers of the promise may invoke methods like Then()) from the private
   // interface (upon which the creator of the promise may invoke Resolve() or
   // Reject()). APIs should create and store a MediaPromise::Private (usually
   // via a MediaPromiseHolder), and return a MediaPromise to consumers.
   //
   // NB: We can include the definition of this class inline once B2G ICS is gone.
   class Private;
 
+  template<typename ResolveValueType_>
   static nsRefPtr<MediaPromise>
-  CreateAndResolve(ResolveValueType aResolveValue, const char* aResolveSite)
+  CreateAndResolve(ResolveValueType_&& aResolveValue, const char* aResolveSite)
   {
     nsRefPtr<typename MediaPromise::Private> p = new MediaPromise::Private(aResolveSite);
-    p->Resolve(aResolveValue, aResolveSite);
-    return Move(p);
+    p->Resolve(Forward<ResolveValueType_>(aResolveValue), aResolveSite);
+    return p.forget();
+  }
+
+  template<typename RejectValueType_>
+  static nsRefPtr<MediaPromise>
+  CreateAndReject(RejectValueType_&& aRejectValue, const char* aRejectSite)
+  {
+    nsRefPtr<typename MediaPromise::Private> p = new MediaPromise::Private(aRejectSite);
+    p->Reject(Forward<RejectValueType_>(aRejectValue), aRejectSite);
+    return p.forget();
   }
 
-  static nsRefPtr<MediaPromise>
-  CreateAndReject(RejectValueType aRejectValue, const char* aRejectSite)
+  typedef MediaPromise<nsTArray<ResolveValueType>, RejectValueType, IsExclusive> AllPromiseType;
+private:
+  class AllPromiseHolder : public MediaPromiseRefcountable
   {
-    nsRefPtr<typename MediaPromise::Private> p = new MediaPromise::Private(aRejectSite);
-    p->Reject(aRejectValue, aRejectSite);
-    return Move(p);
+  public:
+    explicit AllPromiseHolder(size_t aDependentPromises)
+      : mPromise(new typename AllPromiseType::Private(__func__))
+      , mOutstandingPromises(aDependentPromises)
+    {
+      mResolveValues.SetLength(aDependentPromises);
+    }
+
+    void Resolve(size_t aIndex, const ResolveValueType& aResolveValue)
+    {
+      if (!mPromise) {
+        // Already rejected.
+        return;
+      }
+
+      mResolveValues[aIndex].emplace(aResolveValue);
+      if (--mOutstandingPromises == 0) {
+        nsTArray<ResolveValueType> resolveValues;
+        resolveValues.SetCapacity(mResolveValues.Length());
+        for (size_t i = 0; i < mResolveValues.Length(); ++i) {
+          resolveValues.AppendElement(mResolveValues[i].ref());
+        }
+
+        mPromise->Resolve(resolveValues, __func__);
+        mPromise = nullptr;
+        mResolveValues.Clear();
+      }
+    }
+
+    void Reject(const RejectValueType& aRejectValue)
+    {
+      mPromise->Reject(aRejectValue, __func__);
+      mPromise = nullptr;
+      mResolveValues.Clear();
+    }
+
+    AllPromiseType* Promise() { return mPromise; }
+
+  private:
+    nsTArray<Maybe<ResolveValueType>> mResolveValues;
+    nsRefPtr<typename AllPromiseType::Private> mPromise;
+    size_t mOutstandingPromises;
+  };
+public:
+
+  static nsRefPtr<AllPromiseType> All(AbstractThread* aProcessingThread, nsTArray<nsRefPtr<MediaPromise>>& aPromises)
+  {
+    nsRefPtr<AllPromiseHolder> holder = new AllPromiseHolder(aPromises.Length());
+    for (size_t i = 0; i < aPromises.Length(); ++i) {
+      aPromises[i]->Then(aProcessingThread, __func__,
+        [holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, aResolveValue); },
+        [holder] (RejectValueType aRejectValue) -> void { holder->Reject(aRejectValue); }
+      );
+    }
+    return holder->Promise();
   }
 
   class Request : public MediaPromiseRefcountable
   {
   public:
     virtual void Disconnect() = 0;
 
     // MSVC complains when an inner class (ThenValueBase::{Resolve,Reject}Runnable)
@@ -227,36 +295,40 @@ protected:
    * invokes the resolve/reject method and then deletes the ThenValue.
    */
   class ThenValueBase : public Request
   {
   public:
     class ResolveOrRejectRunnable : public nsRunnable
     {
     public:
-      ResolveOrRejectRunnable(ThenValueBase* aThenValue, ResolveOrRejectValue& aValue)
+      ResolveOrRejectRunnable(ThenValueBase* aThenValue, MediaPromise* aPromise)
         : mThenValue(aThenValue)
-        , mValue(aValue) {}
+        , mPromise(aPromise)
+      {
+        MOZ_DIAGNOSTIC_ASSERT(!mPromise->IsPending());
+      }
 
       ~ResolveOrRejectRunnable()
       {
         MOZ_DIAGNOSTIC_ASSERT(!mThenValue || mThenValue->IsDisconnected());
       }
 
       NS_IMETHODIMP Run()
       {
         PROMISE_LOG("ResolveOrRejectRunnable::Run() [this=%p]", this);
-        mThenValue->DoResolveOrReject(mValue);
+        mThenValue->DoResolveOrReject(mPromise->Value());
         mThenValue = nullptr;
+        mPromise = nullptr;
         return NS_OK;
       }
 
     private:
       nsRefPtr<ThenValueBase> mThenValue;
-      ResolveOrRejectValue mValue;
+      nsRefPtr<MediaPromise> mPromise;
     };
 
     explicit ThenValueBase(AbstractThread* aResponseTarget, const char* aCallSite)
       : mResponseTarget(aResponseTarget), mCallSite(aCallSite) {}
 
     MediaPromise* CompletionPromise() override
     {
       MOZ_DIAGNOSTIC_ASSERT(mResponseTarget->IsCurrentThreadIn());
@@ -268,17 +340,17 @@ protected:
     }
 
     void Dispatch(MediaPromise *aPromise)
     {
       aPromise->mMutex.AssertCurrentThreadOwns();
       MOZ_ASSERT(!aPromise->IsPending());
 
       nsRefPtr<nsRunnable> runnable =
-        static_cast<nsRunnable*>(new (typename ThenValueBase::ResolveOrRejectRunnable)(this, aPromise->mValue));
+        static_cast<nsRunnable*>(new (typename ThenValueBase::ResolveOrRejectRunnable)(this, aPromise));
       PROMISE_LOG("%s Then() call made from %s [Runnable=%p, Promise=%p, ThenValue=%p]",
                   aPromise->mValue.IsResolve() ? "Resolving" : "Rejecting", ThenValueBase::mCallSite,
                   runnable.get(), aPromise, this);
 
       // Promise consumers are allowed to disconnect the Request object and
       // then shut down the thread or task queue that the promise result would
       // be dispatched on. So we unfortunately can't assert that promise
       // dispatch succeeds. :-(
@@ -294,19 +366,19 @@ protected:
       // We could support rejecting the completion promise on disconnection, but
       // then we'd need to have some sort of default reject value. The use cases
       // of disconnection and completion promise chaining seem pretty orthogonal,
       // so let's use assert against it.
       MOZ_DIAGNOSTIC_ASSERT(!mCompletionPromise);
     }
 
   protected:
-    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) = 0;
+    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) = 0;
 
-    void DoResolveOrReject(ResolveOrRejectValue& aValue)
+    void DoResolveOrReject(const ResolveOrRejectValue& aValue)
     {
       Request::mComplete = true;
       if (Request::mDisconnected) {
         PROMISE_LOG("ThenValue::DoResolveOrReject disconnected - bailing out [this=%p]", this);
         return;
       }
 
       // Invoke the resolve or reject method.
@@ -344,45 +416,45 @@ protected:
    * We create two overloads for invoking Resolve/Reject Methods so as to
    * make the resolve/reject value argument "optional".
    */
 
   template<typename ThisType, typename MethodType, typename ValueType>
   static typename EnableIf<ReturnTypeIs<MethodType, nsRefPtr<MediaPromise>>::value &&
                            TakesArgument<MethodType>::value,
                            already_AddRefed<MediaPromise>>::Type
-  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue)
+  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType&& aValue)
   {
-    return ((*aThisVal).*aMethod)(aValue).forget();
+    return ((*aThisVal).*aMethod)(Forward<ValueType>(aValue)).forget();
   }
 
   template<typename ThisType, typename MethodType, typename ValueType>
   static typename EnableIf<ReturnTypeIs<MethodType, void>::value &&
                            TakesArgument<MethodType>::value,
                            already_AddRefed<MediaPromise>>::Type
-  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue)
+  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType&& aValue)
   {
-    ((*aThisVal).*aMethod)(aValue);
+    ((*aThisVal).*aMethod)(Forward<ValueType>(aValue));
     return nullptr;
   }
 
   template<typename ThisType, typename MethodType, typename ValueType>
   static typename EnableIf<ReturnTypeIs<MethodType, nsRefPtr<MediaPromise>>::value &&
                            !TakesArgument<MethodType>::value,
                            already_AddRefed<MediaPromise>>::Type
-  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue)
+  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType&& aValue)
   {
     return ((*aThisVal).*aMethod)().forget();
   }
 
   template<typename ThisType, typename MethodType, typename ValueType>
   static typename EnableIf<ReturnTypeIs<MethodType, void>::value &&
                            !TakesArgument<MethodType>::value,
                            already_AddRefed<MediaPromise>>::Type
-  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType aValue)
+  InvokeCallbackMethod(ThisType* aThisVal, MethodType aMethod, ValueType&& aValue)
   {
     ((*aThisVal).*aMethod)();
     return nullptr;
   }
 
   template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
   class MethodThenValue : public ThenValueBase
   {
@@ -401,17 +473,17 @@ protected:
 
     // If a Request has been disconnected, we don't guarantee that the
     // resolve/reject runnable will be dispatched. Null out our refcounted
     // this-value now so that it's released predictably on the dispatch thread.
     mThisVal = nullptr;
   }
 
   protected:
-    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
+    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
     {
       nsRefPtr<MediaPromise> completion;
       if (aValue.IsResolve()) {
         completion = InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aValue.ResolveValue());
       } else {
         completion = InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aValue.RejectValue());
       }
 
@@ -453,17 +525,17 @@ protected:
     // resolve/reject runnable will be dispatched. Destroy our callbacks
     // now so that any references in closures are released predictable on
     // the dispatch thread.
     mResolveFunction.reset();
     mRejectFunction.reset();
   }
 
   protected:
-    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
+    virtual already_AddRefed<MediaPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
     {
       // Note: The usage of InvokeCallbackMethod here requires that
       // ResolveFunction/RejectFunction are capture-lambdas (i.e. anonymous
       // classes with ::operator()), since it allows us to share code more easily.
       // We could fix this if need be, though it's quite easy to work around by
       // just capturing something.
       nsRefPtr<MediaPromise> completion;
       if (aValue.IsResolve()) {
@@ -537,17 +609,25 @@ public:
     if (!IsPending()) {
       ForwardTo(chainedPromise);
     } else {
       mChainedPromises.AppendElement(chainedPromise);
     }
   }
 
 protected:
-  bool IsPending() { return mValue.IsNothing(); }
+  bool IsPending() const { return mValue.IsNothing(); }
+  const ResolveOrRejectValue& Value() const
+  {
+    // This method should only be called once the value has stabilized. As
+    // such, we don't need to acquire the lock here.
+    MOZ_DIAGNOSTIC_ASSERT(!IsPending());
+    return mValue;
+  }
+
   void DispatchAll()
   {
     mMutex.AssertCurrentThreadOwns();
     for (size_t i = 0; i < mThenValues.Length(); ++i) {
       mThenValues[i]->Dispatch(this);
     }
     mThenValues.Clear();
 
@@ -585,40 +665,43 @@ protected:
 
 template<typename ResolveValueT, typename RejectValueT, bool IsExclusive>
 class MediaPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
   : public MediaPromise<ResolveValueT, RejectValueT, IsExclusive>
 {
 public:
   explicit Private(const char* aCreationSite) : MediaPromise(aCreationSite) {}
 
-  void Resolve(ResolveValueT aResolveValue, const char* aResolveSite)
+  template<typename ResolveValueT_>
+  void Resolve(ResolveValueT_&& aResolveValue, const char* aResolveSite)
   {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(IsPending());
     PROMISE_LOG("%s resolving MediaPromise (%p created at %s)", aResolveSite, this, mCreationSite);
-    mValue.SetResolve(aResolveValue);
+    mValue.SetResolve(Forward<ResolveValueT_>(aResolveValue));
     DispatchAll();
   }
 
-  void Reject(RejectValueT aRejectValue, const char* aRejectSite)
+  template<typename RejectValueT_>
+  void Reject(RejectValueT_&& aRejectValue, const char* aRejectSite)
   {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(IsPending());
     PROMISE_LOG("%s rejecting MediaPromise (%p created at %s)", aRejectSite, this, mCreationSite);
-    mValue.SetReject(aRejectValue);
+    mValue.SetReject(Forward<RejectValueT_>(aRejectValue));
     DispatchAll();
   }
 
-  void ResolveOrReject(ResolveOrRejectValue aValue, const char* aSite)
+  template<typename ResolveOrRejectValue_>
+  void ResolveOrReject(ResolveOrRejectValue_&& aValue, const char* aSite)
   {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(IsPending());
     PROMISE_LOG("%s resolveOrRejecting MediaPromise (%p created at %s)", aSite, this, mCreationSite);
-    mValue = aValue;
+    mValue = Forward<ResolveOrRejectValue_>(aValue);
     DispatchAll();
   }
 };
 
 /*
  * Class to encapsulate a promise for a particular role. Use this as the member
  * variable for a class whose method returns a promise.
  */
@@ -847,17 +930,17 @@ private:
 template<typename PromiseType>
 static nsRefPtr<PromiseType>
 ProxyInternal(AbstractThread* aTarget, MethodCallBase<PromiseType>* aMethodCall, const char* aCallerName)
 {
   nsRefPtr<typename PromiseType::Private> p = new (typename PromiseType::Private)(aCallerName);
   nsRefPtr<ProxyRunnable<PromiseType>> r = new ProxyRunnable<PromiseType>(p, aMethodCall);
   MOZ_ASSERT(aTarget->IsDispatchReliable());
   aTarget->Dispatch(r.forget());
-  return Move(p);
+  return p.forget();
 }
 
 } // namespace detail
 
 template<typename PromiseType, typename ThisType>
 static nsRefPtr<PromiseType>
 ProxyMediaCall(AbstractThread* aTarget, ThisType* aThisVal, const char* aCallerName,
                nsRefPtr<PromiseType>(ThisType::*aMethod)())
--- a/dom/media/gtest/TestMediaPromise.cpp
+++ b/dom/media/gtest/TestMediaPromise.cpp
@@ -168,9 +168,54 @@ TEST(MediaPromise, CompletionPromises)
       DO_FAIL)
     ->CompletionPromise()
     ->Then(queue, __func__,
       DO_FAIL,
       [queue, &invokedPass] (double aVal) -> void { EXPECT_EQ(aVal, 42.0); EXPECT_TRUE(invokedPass); queue->BeginShutdown(); });
   });
 }
 
+TEST(MediaPromise, PromiseAllResolve)
+{
+  AutoTaskQueue atq;
+  nsRefPtr<MediaTaskQueue> queue = atq.TaskQueue();
+  RunOnTaskQueue(queue, [queue] () -> void {
+
+    nsTArray<nsRefPtr<TestPromise>> promises;
+    promises.AppendElement(TestPromise::CreateAndResolve(22, __func__));
+    promises.AppendElement(TestPromise::CreateAndResolve(32, __func__));
+    promises.AppendElement(TestPromise::CreateAndResolve(42, __func__));
+
+    TestPromise::All(queue, promises)->Then(queue, __func__,
+      [queue] (const nsTArray<int>& aResolveValues) -> void {
+        EXPECT_EQ(aResolveValues.Length(), 3UL);
+        EXPECT_EQ(aResolveValues[0], 22);
+        EXPECT_EQ(aResolveValues[1], 32);
+        EXPECT_EQ(aResolveValues[2], 42);
+        queue->BeginShutdown();
+      },
+      DO_FAIL
+    );
+  });
+}
+
+TEST(MediaPromise, PromiseAllReject)
+{
+  AutoTaskQueue atq;
+  nsRefPtr<MediaTaskQueue> queue = atq.TaskQueue();
+  RunOnTaskQueue(queue, [queue] () -> void {
+
+    nsTArray<nsRefPtr<TestPromise>> promises;
+    promises.AppendElement(TestPromise::CreateAndResolve(22, __func__));
+    promises.AppendElement(TestPromise::CreateAndReject(32.0, __func__));
+    promises.AppendElement(TestPromise::CreateAndResolve(42, __func__));
+
+    TestPromise::All(queue, promises)->Then(queue, __func__,
+      DO_FAIL,
+      [queue] (float aRejectValue) -> void {
+        EXPECT_EQ(aRejectValue, 32.0);
+        queue->BeginShutdown();
+      }
+    );
+  });
+}
+
 #undef DO_FAIL
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -1,14 +1,12 @@
 [DEFAULT]
 skip-if = e10s # Bug ?????? - most of these tests fail for currently unknown reasons.
 support-files =
   browser_frame_elements.html
-  browser_geolocation_privatebrowsing_page.html
-  network_geolocation.sjs
   page_privatestorageevent.html
   position.html
   test-console-api.html
   test_bug1004814.html
   worker_bug1004814.js
 
 [browser_bug1008941_dismissGeolocationHanger.js]
 skip-if = buildapp == 'mulet'
@@ -18,17 +16,16 @@ skip-if = buildapp == 'mulet'
 [browser_ConsoleStoragePBTest_perwindowpb.js]
 [browser_autofocus_background.js]
 skip-if= buildapp == 'mulet'
 [browser_autofocus_preference.js]
 [browser_bug396843.js]
 [browser_focus_steal_from_chrome.js]
 [browser_focus_steal_from_chrome_during_mousedown.js]
 [browser_frame_elements.js]
-[browser_geolocation_privatebrowsing_perwindowpb.js]
 [browser_localStorage_privatestorageevent.js]
 [browser_test_new_window_from_content.js]
 skip-if = (toolkit == 'android' || buildapp == 'b2g' || buildapp == 'mulet')
 support-files =
   test_new_window_from_content_child.html
   test_new_window_from_content_child.js
 [browser_webapps_permissions.js]
 # TODO: Re-enable permissions tests on Mac, bug 795334
deleted file mode 100644
--- a/dom/tests/browser/browser_geolocation_privatebrowsing_page.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-<body>
-<script>
-  navigator.geolocation.getCurrentPosition(function(pos) {
-    var evt = document.createEvent('CustomEvent');
-    evt.initCustomEvent('georesult', true, false, pos.coords.latitude);
-    document.dispatchEvent(evt);
-  });
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/browser/browser_geolocation_privatebrowsing_perwindowpb.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
-  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-  let baseProvider = "http://mochi.test:8888/browser/dom/tests/browser/network_geolocation.sjs";
-  prefs.setCharPref("geo.wifi.uri", baseProvider + "?desired_access_token=fff");
-
-  prefs.setBoolPref("geo.prompt.testing", true);
-  prefs.setBoolPref("geo.prompt.testing.allow", true);
-  var origScanValue = true; // same default in NetworkGeolocationProvider.js.
-  try {
-    origScanValue = prefs.getBoolPref("geo.wifi.scan");
-  } catch(ex) {}
-  prefs.setBoolPref("geo.wifi.scan", false);
-
-  const testPageURL = "http://mochi.test:8888/browser/" +
-    "dom/tests/browser/browser_geolocation_privatebrowsing_page.html";
-  waitForExplicitFinish();
-
-  var windowsToClose = [];
-  function testOnWindow(aIsPrivate, aCallback) {
-    let win = OpenBrowserWindow({private: aIsPrivate});
-    let gotLoad = false;
-    let gotActivate = Services.focus.activeWindow == win;
-
-    function maybeRunCallback() {
-      if (gotLoad && gotActivate) {
-        windowsToClose.push(win);
-        executeSoon(function() { aCallback(win); });
-      }
-    }
-
-    if (!gotActivate) {
-      win.addEventListener("activate", function onActivate() {
-        info("got activate");
-        win.removeEventListener("activate", onActivate, true);
-        gotActivate = true;
-        maybeRunCallback();
-      }, true);
-    } else {
-      info("Was activated");
-    }
-
-    Services.obs.addObserver(function observer(aSubject, aTopic) {
-      if (win == aSubject) {
-        info("Delayed startup finished");
-        Services.obs.removeObserver(observer, aTopic);
-        gotLoad = true;
-        maybeRunCallback();
-      }
-    }, "browser-delayed-startup-finished", false);
-
-  }
-
-  testOnWindow(false, function(aNormalWindow) {
-    aNormalWindow.gBrowser.selectedBrowser.addEventListener("georesult", function load(ev) {
-      aNormalWindow.gBrowser.selectedBrowser.removeEventListener("georesult", load, false);
-      is(ev.detail, 200, "unexpected access token");
-
-      prefs.setCharPref("geo.wifi.uri", baseProvider + "?desired_access_token=ggg");
-
-      testOnWindow(true, function(aPrivateWindow) {
-        aPrivateWindow.gBrowser.selectedBrowser.addEventListener("georesult", function load2(ev) {
-          aPrivateWindow.gBrowser.selectedBrowser.removeEventListener("georesult", load2, false);
-          is(ev.detail, 200, "unexpected access token");
-
-          prefs.setCharPref("geo.wifi.uri", baseProvider + "?expected_access_token=fff");
-
-          testOnWindow(false, function(aAnotherNormalWindow) {
-            aAnotherNormalWindow.gBrowser.selectedBrowser.addEventListener("georesult", function load3(ev) {
-              aAnotherNormalWindow.gBrowser.selectedBrowser.removeEventListener("georesult", load3, false);
-              is(ev.detail, 200, "unexpected access token");
-              prefs.setBoolPref("geo.prompt.testing", false);
-              prefs.setBoolPref("geo.prompt.testing.allow", false);
-              prefs.setBoolPref("geo.wifi.scan", origScanValue);
-              windowsToClose.forEach(function(win) {
-                                       win.close();
-                                     });
-              finish();
-            }, false, true);
-            aAnotherNormalWindow.content.location = testPageURL;
-          });
-        }, false, true);
-        aPrivateWindow.content.location = testPageURL;
-      });
-    }, false, true);
-    aNormalWindow.content.location = testPageURL;
-  });
-}
deleted file mode 100644
--- a/dom/tests/browser/network_geolocation.sjs
+++ /dev/null
@@ -1,45 +0,0 @@
-function parseQueryString(str)
-{
-  if (str == "")
-    return {};
-
-  var paramArray = str.split("&");
-  var regex = /^([^=]+)=(.*)$/;
-  var params = {};
-  for (var i = 0, sz = paramArray.length; i < sz; i++)
-  {
-    var match = regex.exec(paramArray[i]);
-    if (!match)
-      throw "Bad parameter in queryString!  '" + paramArray[i] + "'";
-    params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
-  }
-
-  return params;
-}
-
-function getPosition(expectedAccessToken, providedAccessToken, desiredAccessToken)
-{  
-  var response = {
-    status: "OK",
-    location: {
-      lat: providedAccessToken ?
-             (expectedAccessToken == providedAccessToken ? 200 : 404) : 200,
-      lng: -122.08769,
-    },
-    accuracy: 100,
-    access_token: desiredAccessToken
-  };
-  
-  return JSON.stringify(response);
-}
-
-function handleRequest(request, response)
-{
-  var params = parseQueryString(request.queryString);
-
-  response.setStatusLine("1.0", 200, "OK");
-  response.setHeader("Cache-Control", "no-cache", false);
-  response.setHeader("Content-Type", "aplication/x-javascript", false);
-  response.write(getPosition(params.expected_access_token, params.access_token,
-                             params.desired_access_token));
-}
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/force_refresh_worker.js
@@ -0,0 +1,25 @@
+var name = 'refresherCache';
+
+self.addEventListener('install', function(event) {
+  event.waitUntil(
+    Promise.all([caches.open(name),
+                 fetch('./sw_clients/refresher_cached.html'),
+                 fetch('./sw_clients/refresher_cached_compressed.html')]).then(function(results) {
+      var cache = results[0];
+      var response = results[1];
+      var compressed = results[2];
+      return Promise.all([cache.put('./sw_clients/refresher.html', response),
+                          cache.put('./sw_clients/refresher_compressed.html', compressed)]);
+    })
+  );
+});
+
+self.addEventListener('fetch', function (event) {
+  event.respondWith(
+    caches.open(name).then(function(cache) {
+      return cache.match(event.request);
+    }).then(function(response) {
+      return response || fetch(event.request);
+    })
+  );
+});
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -94,16 +94,23 @@ support-files =
   swa/worker_scope_too_narrow.js
   swa/worker_scope_too_narrow.js^headers^
   claim_oninstall_worker.js
   claim_worker_1.js
   claim_worker_2.js
   claim_clients/client.html
   claim_fetch_worker.js
   app-protocol/*
+  force_refresh_worker.js
+  sw_clients/refresher.html
+  sw_clients/refresher_compressed.html
+  sw_clients/refresher_compressed.html^headers^
+  sw_clients/refresher_cached.html
+  sw_clients/refresher_cached_compressed.html
+  sw_clients/refresher_cached_compressed.html^headers^
 
 [test_unregister.html]
 [test_installation_simple.html]
 [test_fetch_event.html]
 [test_https_fetch.html]
 [test_https_fetch_cloned_response.html]
 [test_https_synth_fetch_from_cached_sw.html]
 [test_match_all.html]
@@ -133,8 +140,9 @@ support-files =
 [test_claim_oninstall.html]
 [test_claim.html]
 [test_periodic_https_update.html]
 [test_sanitize.html]
 [test_sanitize_domain.html]
 [test_service_worker_allowed.html]
 [test_app_protocol.html]
 [test_claim_fetch.html]
+[test_force_refresh.html]
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/sw_clients/refresher.html
@@ -0,0 +1,38 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 982726 - test match_all not crashing</title>
+  <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="display: none"></div>
+<pre id="test"></pre>
+<script class="testbody" type="text/javascript">
+
+  if (!parent) {
+    info("sw_clients/simple.html shouldn't be launched directly!");
+  }
+
+  window.addEventListener("message", function(event) {
+    if (event.data === "REFRESH") {
+      window.location.reload();
+    } else if (event.data === "FORCE_REFRESH") {
+      window.location.reload(true);
+    }
+  });
+
+  navigator.serviceWorker.ready.then(function() {
+    parent.postMessage("READY", "*");
+  });
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/sw_clients/refresher_cached.html
@@ -0,0 +1,38 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 982726 - test match_all not crashing</title>
+  <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="display: none"></div>
+<pre id="test"></pre>
+<script class="testbody" type="text/javascript">
+
+  if (!parent) {
+    info("sw_clients/simple.html shouldn't be launched directly!");
+  }
+
+  window.addEventListener("message", function(event) {
+    if (event.data === "REFRESH") {
+      window.location.reload();
+    } else if (event.data === "FORCE_REFRESH") {
+      window.location.reload(true);
+    }
+  });
+
+  navigator.serviceWorker.ready.then(function() {
+    parent.postMessage("READY_CACHED", "*");
+  });
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..55e97ac24766f5162f483e0bf707a7ca86db7a8c
GIT binary patch
literal 559
zc$@(*0?_>*iwFQ|+h|n)1C3KnPa821z2{d<eCbj(>y|@5Xf_f}f;fOcfK+jcj6KO3
z9D8L?mTs&5_l|c7<v^vL?0x&@J-_jII-X2M0LQ)q9hxrMO-*1E7&KNZLIV_lYJ|((
zowFJiVXLe!xuhm)j-=EP71<Vb*lvSQWr!Qu^jy<Z<xh-3ekk9|(PT0kO~;Fi`OWR+
z5>9W<&-lBht;-84Gh@{$S#mi0w%fp$&xfB5Kf(kE6Tw!Iu2;%A@PR-_m1^rZQ#tT+
zWzx|$1k^QH3Bn&F?^UY?R6vTl5;99Ad2P3i!yDee*p~N6%%*bS_kzy)2Z-n@k*IT+
zYD5-#p|4XCP)A(9rksJYXGqQ`hk(<&U^-qJu%;5mrpBo*+cpdu+xD;yp3vtrXWM7m
z5hwSU$xO@|5qo+z>LnugVc!MqR7%6YY$^WHmf47d+BFp8Mn(2KfL{zS<kz7P>2al<
zWjM*y2P^Y!L8`;f8UKdh4#BCN*EP?Hu@N=7ZY&PIvc~VM{Aj%ikEJqZ*|N-;O&knk
zA-0&3+Msv`Yc3}ne1Yvte?C$Vltz()s;WR-El;kN*Qa97d6sv9CzT~izN?^2(fjiW
z0A0dYrA{uc=F8Q83sT(SUNlGJJuhChcB3f7GGT13#_u6MVB{iYx{}|FFP_8gEru?a
xO-OV;w4mTz$BWz5{CIx4TyR6g+ouL*m%sD4zhC(@L2`IFqd(F8Fo(ed002Hz5xD>W
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/sw_clients/refresher_cached_compressed.html^headers^
@@ -0,0 +1,2 @@
+Content-Type: text/html
+Content-Encoding: gzip
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3cf1f6a4fbf4f39ded4568d475792bf44d4566f1
GIT binary patch
literal 553
zc$@(#0@nQ>iwFQ#+h|n)1C5hSPuwsNhVT0;W_@X>x^c^)A9S-4g+&}dparSogp57A
zF*tT)&xWQ||9i&?OF2-fCp(jOp7A>#&!@B51mMv3phMe7yQv9m0)xhCMQDHmP>pc8
zy>nK>acGqFC8yLx?SYg!q9WU&4owq$Dns1JcF>wZDt}@O@<aJvPG+;kWIjE<IJ&;M
zT*B$~`5AxL)VRE$G7F~8$&$mxx9tYLeBS@G{}E<Dm<Sq0y1rG;fe!>as#IIQnafe1
zGn0<CC7`~=N)Y}ad9OM(Mg^p(D<Lx~$t&Bm4zGFtVq4xPv6#zIKLDNe4-nB+B2n)!
z)rbsw!PhAXs3WdlBj-RlC?xxnqrv%IFg-6VSW^jOQ|nZp%eEXewj07actW4goXbAT
z4%oTJEM{S5L>%O~(13{Chg}!6Qz?!Aa!K)zwk#%W)UKhJwkmSXJ@~}|4*7K`M0&i{
z&T=@(G#D%MZ9%HT)*1hX;10p5t=BcriLntixqd44zB1!?CO=wl!egn7S$2#$vx$vi
zEJTATsSS#Eu;z5K!57%Qtj|Xp0;N%;psFemtL4dRd37pwnrFNVJgJN*`L2R8#ZaG5
z0O%6FiaNPi9W8JF8%S}BJ7~7XdtSWi>_$<DWy085jo(9jz{p9;^d-L;Up$-Jl^DBR
rwjt5^*n)z69Uk9sC&b&Q&Sm`HLEK%ed>S1&zL?1$UkUjix&r_J05%R(
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/sw_clients/refresher_compressed.html^headers^
@@ -0,0 +1,2 @@
+Content-Type: text/html
+Content-Encoding: gzip
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/test_force_refresh.html
@@ -0,0 +1,84 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 982726 - Test service worker post message </title>
+  <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="display: none"></div>
+<pre id="test"></pre>
+<script class="testbody" type="text/javascript">
+  var registration;
+  function start() {
+    return navigator.serviceWorker.register("force_refresh_worker.js",
+                                            { scope: "./sw_clients/" })
+      .then((swr) => registration = swr);
+  }
+
+  function unregister() {
+    return registration.unregister().then(function(result) {
+      ok(result, "Unregister should return true.");
+    }, function(e) {
+      dump("Unregistering the SW failed with " + e + "\n");
+    });
+  }
+
+
+  function testForceRefresh(swr) {
+    var p = new Promise(function(res, rej) {
+      var count = 0;
+      var cachedCount = 0;
+      window.onmessage = function(e) {
+        if (e.data === "READY") {
+          count += 1;
+          if (count == 2) {
+            is(cachedCount, 1, "should have received cached message before " +
+                               "second non-cached message");
+            res();
+          }
+          iframe.contentWindow.postMessage("REFRESH", "*");
+        } else if (e.data === "READY_CACHED") {
+          cachedCount += 1;
+          is(count, 1, "should have received non-cached message before " +
+                       "cached message");
+          iframe.contentWindow.postMessage("FORCE_REFRESH", "*");
+        }
+      }
+    });
+
+    var content = document.getElementById("content");
+    ok(content, "Parent exists.");
+
+    iframe = document.createElement("iframe");
+    iframe.setAttribute('src', "sw_clients/refresher_compressed.html");
+    content.appendChild(iframe);
+
+    return p.then(() => content.removeChild(iframe));
+  }
+
+  function runTest() {
+    start()
+      .then(testForceRefresh)
+      .then(unregister)
+      .catch(function(e) {
+        ok(false, "Some test failed with error " + e);
+      }).then(SimpleTest.finish);
+  }
+
+  SimpleTest.waitForExplicitFinish();
+  SpecialPowers.pushPrefEnv({"set": [
+    ["dom.serviceWorkers.exemptFromPerDomainMax", true],
+    ["dom.serviceWorkers.enabled", true],
+    ["dom.serviceWorkers.testing.enabled", true],
+    ["dom.caches.enabled", true],
+  ]}, runTest);
+</script>
+</pre>
+</body>
+</html>
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -200,17 +200,21 @@ DrawTargetD2D1::DrawSurfaceWithShadow(So
 
   if (!mat.IsIdentity()) {
     gfxDebug() << *this << ": At this point complex partial uploads are not supported for Shadow surfaces.";
     return;
   }
 
   // Step 1, create the shadow effect.
   RefPtr<ID2D1Effect> shadowEffect;
-  mDC->CreateEffect(CLSID_D2D1Shadow, byRef(shadowEffect));
+  HRESULT hr = mDC->CreateEffect(CLSID_D2D1Shadow, byRef(shadowEffect));
+  if (FAILED(hr) || !shadowEffect) {
+    gfxWarning() << "Failed to create shadow effect. Code: " << hexa(hr);
+    return;
+  }
   shadowEffect->SetInput(0, image);
   shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, aSigma);
   D2D1_VECTOR_4F color = { aColor.r, aColor.g, aColor.b, aColor.a };
   shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, color);
 
   D2D1_POINT_2F shadowPoint = D2DPoint(aDest + aOffset);
   mDC->DrawImage(shadowEffect, &shadowPoint, nullptr, D2D1_INTERPOLATION_MODE_LINEAR, D2DCompositionMode(aOperator));
 
@@ -1081,19 +1085,19 @@ DrawTargetD2D1::FinalizeDrawing(Composit
         mDC->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
         mDC->FillGeometry(inverseGeom, brush);
         mDC->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
       }
       return;
     }
 
     if (!mBlendEffect) {
-      mDC->CreateEffect(CLSID_D2D1Blend, byRef(mBlendEffect));
+      HRESULT hr = mDC->CreateEffect(CLSID_D2D1Blend, byRef(mBlendEffect));
 
-      if (!mBlendEffect) {
+      if (FAILED(hr) || !mBlendEffect) {
         gfxWarning() << "Failed to create blend effect!";
         return;
       }
     }
 
     RefPtr<ID2D1Bitmap> tmpBitmap;
     HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
     if (FAILED(hr)) {
@@ -1126,17 +1130,21 @@ DrawTargetD2D1::FinalizeDrawing(Composit
     // Draw nothing!
     return;
   }
 
   PushAllClips();
 
   RefPtr<ID2D1Effect> radialGradientEffect;
 
-  mDC->CreateEffect(CLSID_RadialGradientEffect, byRef(radialGradientEffect));
+  HRESULT hr = mDC->CreateEffect(CLSID_RadialGradientEffect, byRef(radialGradientEffect));
+  if (FAILED(hr) || !radialGradientEffect) {
+    gfxWarning() << "Failed to create radial gradient effect. Code: " << hexa(hr);
+    return;
+  }
 
   radialGradientEffect->SetValue(RADIAL_PROP_STOP_COLLECTION,
                                  static_cast<const GradientStopsD2D*>(pat->mStops.get())->mStopCollection);
   radialGradientEffect->SetValue(RADIAL_PROP_CENTER_1, D2D1::Vector2F(pat->mCenter1.x, pat->mCenter1.y));
   radialGradientEffect->SetValue(RADIAL_PROP_CENTER_2, D2D1::Vector2F(pat->mCenter2.x, pat->mCenter2.y));
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_1, pat->mRadius1);
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_2, pat->mRadius2);
   radialGradientEffect->SetValue(RADIAL_PROP_RADIUS_2, pat->mRadius2);
--- a/gfx/2d/FilterNodeD2D1.cpp
+++ b/gfx/2d/FilterNodeD2D1.cpp
@@ -854,33 +854,33 @@ FilterNodeConvolveD2D1::FilterNodeConvol
   // our custom ExtendInput effect to adjust the output rect of our input.
   // All of this is only necessary when our edge mode is not EDGE_MODE_NONE, so
   // we update the filter chain dynamically in UpdateChain().
 
   HRESULT hr;
   
   hr = aDC->CreateEffect(CLSID_D2D1ConvolveMatrix, byRef(mEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mEffect) {
     gfxWarning() << "Failed to create ConvolveMatrix filter!";
     return;
   }
 
   mEffect->SetValue(D2D1_CONVOLVEMATRIX_PROP_BORDER_MODE, D2D1_BORDER_MODE_SOFT);
 
   hr = aDC->CreateEffect(CLSID_ExtendInputEffect, byRef(mExtendInputEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mExtendInputEffect) {
     gfxWarning() << "Failed to create ConvolveMatrix filter!";
     return;
   }
 
   hr = aDC->CreateEffect(CLSID_D2D1Border, byRef(mBorderEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mBorderEffect) {
     gfxWarning() << "Failed to create ConvolveMatrix filter!";
     return;
   }
 
   mBorderEffect->SetInputEffect(0, mExtendInputEffect.get());
 
   UpdateChain();
   UpdateSourceRect();
@@ -1013,17 +1013,17 @@ FilterNodeExtendInputAdapterD2D1::Filter
   // want mEffect to regard its input as unbounded. So we take the input,
   // pipe it through an ExtendInput effect (which has an infinite output rect
   // by default), and feed the resulting unbounded composition into mEffect.
 
   HRESULT hr;
 
   hr = aDC->CreateEffect(CLSID_ExtendInputEffect, byRef(mExtendInputEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mExtendInputEffect) {
     gfxWarning() << "Failed to create extend input effect for filter: " << hexa(hr);
     return;
   }
 
   aFilterNode->InputEffect()->SetInputEffect(0, mExtendInputEffect.get());
 }
 
 FilterNodePremultiplyAdapterD2D1::FilterNodePremultiplyAdapterD2D1(ID2D1DeviceContext *aDC,
@@ -1057,24 +1057,24 @@ FilterNodePremultiplyAdapterD2D1::Filter
   // with the enabled channels.
   // We also add an unpremultiply effect that postprocesses the result of the
   // transfer effect because getting unpremultiplied results from the transfer
   // filters is part of the FilterNode API.
   HRESULT hr;
 
   hr = aDC->CreateEffect(CLSID_D2D1Premultiply, byRef(mPrePremultiplyEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mPrePremultiplyEffect) {
     gfxWarning() << "Failed to create ComponentTransfer filter!";
     return;
   }
 
   hr = aDC->CreateEffect(CLSID_D2D1UnPremultiply, byRef(mPostUnpremultiplyEffect));
 
-  if (FAILED(hr)) {
+  if (FAILED(hr) || !mPostUnpremultiplyEffect) {
     gfxWarning() << "Failed to create ComponentTransfer filter!";
     return;
   }
 
   aFilterNode->InputEffect()->SetInputEffect(0, mPrePremultiplyEffect.get());
   mPostUnpremultiplyEffect->SetInputEffect(0, aFilterNode->OutputEffect());
 }
 
--- a/gfx/doc/AsyncPanZoom.md
+++ b/gfx/doc/AsyncPanZoom.md
@@ -156,23 +156,26 @@ For instance, if the user is doing an as
 
 Another problem that we need to deal with is that web content is allowed to intercept touch events and prevent the "default behaviour" of scrolling.
 This ability is defined in web standards and is non-negotiable.
 Touch event listeners in web content are allowed call preventDefault() on the touchstart or first touchmove event for a touch point; doing this is supposed to "consume" the event and prevent touch-based panning.
 As we saw in a previous section, the input event needs to be untransformed by the APZ code before it can be delivered to content.
 But, because of the preventDefault problem, we cannot fully process the touch event in the APZ code until content has had a chance to handle it.
 Web browsers in general solve this problem by inserting a delay of up to 300ms before processing the input - that is, web content is allowed up to 300ms to process the event and call preventDefault on it.
 If web content takes longer than 300ms, or if it completes handling of the event without calling preventDefault, then the browser immediately starts processing the events.
-The touch-action CSS property from the pointer-events spec is intended to allow eliminating this 300ms delay, although for backwards compatibility it will still be needed for a while.
 
 The way the APZ implementation deals with this is that upon receiving a touch event, it immediately returns an untransformed version that can be dispatched to content.
 It also schedules a 300ms timeout during which content is allowed to prevent scrolling.
 There is an API that allows the main-thread event dispatching code to notify the APZ as to whether or not the default action should be prevented.
 If the APZ content response timeout expires, or if the main-thread event dispatching code notifies the APZ of the preventDefault status, then the APZ continues with the processing of the events (which may involve discarding the events).
 
+The touch-action CSS property from the pointer-events spec is intended to allow eliminating this 300ms delay in many cases (although for backwards compatibility it will still be needed for a while).
+Note that even with touch-action implemented, there may be cases where the APZ code does not know the touch-action behaviour of the point the user touched.
+In such cases, the APZ code will still wait up to 300ms for the main thread to provide it with the touch-action behaviour information.
+
 ## Technical details
 
 This section describes various pieces of the APZ code, and goes into more specific detail on APIs and code than the previous sections.
 The primary purpose of this section is to help people who plan on making changes to the code, while also not going into so much detail that it needs to be updated with every patch.
 
 ### Overall flow of input events
 
 This section describes how input events flow through the APZ code.
--- a/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
@@ -48,17 +48,17 @@ WrapTexCoord(GLfloat v)
         return 1.0f + fmodf(v, 1.0f);
     }
 
     return fmodf(v, 1.0f);
 }
 
 void
 DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
-                               const nsIntSize& aTexSize,
+                               const gfx::IntSize& aTexSize,
                                RectTriangles& aRects,
                                bool aFlipY /* = false */)
 {
     // normalize this
     gfx::IntRect tcr(aTexCoordRect);
     while (tcr.x >= aTexSize.width)
         tcr.x -= aTexSize.width;
     while (tcr.y >= aTexSize.height)
--- a/gfx/gl/DecomposeIntoNoRepeatTriangles.h
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h
@@ -62,16 +62,16 @@ private:
   * The resulting triangle vertex coordinates will be in the space of
   * (0.0, 0.0) to (1.0, 1.0) -- transform the coordinates appropriately
   * if you need a different space.
   *
   * The resulting vertex coordinates should be drawn using GL_TRIANGLES,
   * and rects.numRects * 3 * 6
   */
 void DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
-                                    const nsIntSize& aTexSize,
+                                    const gfx::IntSize& aTexSize,
                                     RectTriangles& aRects,
                                     bool aFlipY = false);
 
 }
 }
 
 #endif // DecomposeIntoNoRepeatTriangles_h_
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -104,20 +104,20 @@ public:
         return EGL_DISPLAY();
     }
 
     bool BindTex2DOffscreen(GLContext *aOffscreen);
     void UnbindTex2DOffscreen(GLContext *aOffscreen);
     void BindOffscreenFramebuffer();
 
     static already_AddRefed<GLContextEGL>
-    CreateEGLPixmapOffscreenContext(const gfxIntSize& size);
+    CreateEGLPixmapOffscreenContext(const gfx::IntSize& size);
 
     static already_AddRefed<GLContextEGL>
-    CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
+    CreateEGLPBufferOffscreenContext(const gfx::IntSize& size);
 
 protected:
     friend class GLContextProviderEGL;
 
     EGLConfig  mConfig;
     EGLSurface mSurface;
     EGLSurface mSurfaceOverride;
     EGLContext mContext;
@@ -130,15 +130,15 @@ protected:
     bool mShareWithEGLImage;
 #ifdef MOZ_WIDGET_GONK
     nsRefPtr<HwcComposer2D> mHwc;
 #endif
     bool mOwnsContext;
 
     static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
                                                            EGLenum bindToTextureFormat,
-                                                           gfxIntSize& pbsize);
+                                                           gfx::IntSize& pbsize);
 };
 
 }
 }
 
 #endif // GLCONTEXTEGL_H_
--- a/gfx/gl/GLContextProvider.h
+++ b/gfx/gl/GLContextProvider.h
@@ -5,17 +5,17 @@
 
 #ifndef GLCONTEXTPROVIDER_H_
 #define GLCONTEXTPROVIDER_H_
 
 #include "GLContextTypes.h"
 #include "nsAutoPtr.h"
 #include "SurfaceTypes.h"
 
-#include "nsSize.h" // for gfxIntSize (needed by GLContextProviderImpl.h below)
+#include "nsSize.h" // for gfx::IntSize (needed by GLContextProviderImpl.h below)
 
 class nsIWidget;
 
 namespace mozilla {
 namespace gl {
 
 #define IN_GL_CONTEXT_PROVIDER_H
 
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -298,17 +298,17 @@ GLContextProviderCGL::CreateHeadless(boo
         NS_WARNING("Failed during Init.");
         return nullptr;
     }
 
     return gl.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
+GLContextProviderCGL::CreateOffscreen(const IntSize& size,
                                       const SurfaceCaps& caps,
                                       bool requireCompatProfile)
 {
     nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
     if (!glContext->InitOffscreen(size, caps)) {
         NS_WARNING("Failed during InitOffscreen.");
         return nullptr;
     }
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -544,17 +544,17 @@ GLContextEGL::CreateGLContext(const Surf
         return nullptr;
 
     return glContext.forget();
 }
 
 EGLSurface
 GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
                                                    EGLenum bindToTextureFormat,
-                                                   gfxIntSize& pbsize)
+                                                   mozilla::gfx::IntSize& pbsize)
 {
     nsTArray<EGLint> pbattrs(16);
     EGLSurface surface = nullptr;
 
 TRY_AGAIN_POWER_OF_TWO:
     pbattrs.Clear();
     pbattrs.AppendElement(LOCAL_EGL_WIDTH); pbattrs.AppendElement(pbsize.width);
     pbattrs.AppendElement(LOCAL_EGL_HEIGHT); pbattrs.AppendElement(pbsize.height);
@@ -833,17 +833,17 @@ GLContextProviderEGL::DestroyEGLSurface(
         MOZ_CRASH("Failed to load EGL library!\n");
     }
 
     sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
 }
 #endif // defined(ANDROID)
 
 already_AddRefed<GLContextEGL>
-GLContextEGL::CreateEGLPBufferOffscreenContext(const gfxIntSize& size)
+GLContextEGL::CreateEGLPBufferOffscreenContext(const mozilla::gfx::IntSize& size)
 {
     EGLConfig config;
     EGLSurface surface;
 
     const EGLint numConfigs = 1; // We only need one.
     EGLConfig configs[numConfigs];
     EGLint foundConfigs = 0;
     if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(),
@@ -856,17 +856,17 @@ GLContextEGL::CreateEGLPBufferOffscreenC
         return nullptr;
     }
 
     // We absolutely don't care, so just pick the first one.
     config = configs[0];
     if (GLContext::ShouldSpew())
         sEGLLibrary.DumpEGLConfig(config);
 
-    gfxIntSize pbSize(size);
+    mozilla::gfx::IntSize pbSize(size);
     surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
                                                                  LOCAL_EGL_NONE,
                                                                  pbSize);
     if (!surface) {
         NS_WARNING("Failed to create PBuffer for context!");
         return nullptr;
     }
 
@@ -886,17 +886,17 @@ GLContextEGL::CreateEGLPBufferOffscreenC
         // GLContextEGL::dtor will destroy |surface| for us.
         return nullptr;
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContextEGL>
-GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& size)
+GLContextEGL::CreateEGLPixmapOffscreenContext(const mozilla::gfx::IntSize& size)
 {
     gfxASurface *thebesSurface = nullptr;
     EGLNativePixmapType pixmap = 0;
 
     if (!pixmap) {
         return nullptr;
     }
 
@@ -932,29 +932,29 @@ GLContextEGL::CreateEGLPixmapOffscreenCo
 
 already_AddRefed<GLContext>
 GLContextProviderEGL::CreateHeadless(bool)
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
-    gfxIntSize dummySize = gfxIntSize(16, 16);
+    mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
     nsRefPtr<GLContext> glContext;
     glContext = GLContextEGL::CreateEGLPBufferOffscreenContext(dummySize);
     if (!glContext)
         return nullptr;
 
     return glContext.forget();
 }
 
 // Under EGL, on Android, pbuffers are supported fine, though
 // often without the ability to texture from them directly.
 already_AddRefed<GLContext>
-GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size,
+GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
                                       const SurfaceCaps& caps,
                                       bool requireCompatProfile)
 {
     nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(size, caps))
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -1094,17 +1094,17 @@ GLContextProviderGLX::CreateForWindow(ns
                                                                      window,
                                                                      cfgs[matchIndex],
                                                                      false);
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextGLX>
-CreateOffscreenPixmapContext(const gfxIntSize& size)
+CreateOffscreenPixmapContext(const IntSize& size)
 {
     GLXLibrary& glx = sGLXLibrary;
     if (!glx.EnsureInitialized()) {
         return nullptr;
     }
 
     Display *display = DefaultXDisplay();
     int xscreen = DefaultScreen(display);
@@ -1157,17 +1157,17 @@ CreateOffscreenPixmapContext(const gfxIn
 
     Visual *visual;
     int depth;
     FindVisualAndDepth(display, visid, &visual, &depth);
     ScopedXErrorHandler xErrorHandler;
     GLXPixmap glxpixmap = 0;
     bool error = false;
 
-    gfxIntSize dummySize(16, 16);
+    IntSize dummySize(16, 16);
     nsRefPtr<gfxXlibSurface> xsurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
                                                                visual,
                                                                dummySize);
     if (xsurface->CairoStatus() != 0) {
         error = true;
         goto DONE_CREATING_PIXMAP;
     }
 
@@ -1212,26 +1212,26 @@ DONE_CREATING_PIXMAP:
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
 GLContextProviderGLX::CreateHeadless(bool)
 {
-    gfxIntSize dummySize = gfxIntSize(16, 16);
+    IntSize dummySize = IntSize(16, 16);
     nsRefPtr<GLContext> glContext = CreateOffscreenPixmapContext(dummySize);
     if (!glContext)
         return nullptr;
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
-GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
+GLContextProviderGLX::CreateOffscreen(const IntSize& size,
                                       const SurfaceCaps& caps,
                                       bool requireCompatProfile)
 {
     nsRefPtr<GLContext> glContext = CreateHeadless(requireCompatProfile);
     if (!glContext)
         return nullptr;
 
     if (!glContext->InitOffscreen(size, caps))
@@ -1255,17 +1255,17 @@ GLContextProviderGLX::GetGlobalContext()
     if (!useContextSharing) {
         return nullptr;
     }
 
     static bool triedToCreateContext = false;
     if (!triedToCreateContext && !gGlobalContext) {
         triedToCreateContext = true;
 
-        gfxIntSize dummySize = gfxIntSize(16, 16);
+        IntSize dummySize = IntSize(16, 16);
         // StaticPtr doesn't support assignments from already_AddRefed,
         // so use a temporary nsRefPtr to make the reference counting
         // fall out correctly.
         nsRefPtr<GLContext> holder = CreateOffscreenPixmapContext(dummySize);
         gGlobalContext = holder;
     }
 
     return gGlobalContext;
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -55,17 +55,17 @@ public:
      * be, in order to isolate the offscreen context.
      *
      * @param aSize The initial size of this offscreen context.
      * @param aFormat The ContextFormat for this offscreen context.
      *
      * @return Context to use for offscreen rendering
      */
     static already_AddRefed<GLContext>
-    CreateOffscreen(const gfxIntSize& size,
+    CreateOffscreen(const mozilla::gfx::IntSize& size,
                     const SurfaceCaps& caps,
                     bool requireCompatProfile);
 
     // Just create a context. We'll add offscreen stuff ourselves.
     static already_AddRefed<GLContext>
     CreateHeadless(bool requireCompatProfile);
 
     /**
--- a/gfx/gl/GLContextProviderNull.cpp
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -16,17 +16,17 @@ GLContextProviderNull::CreateForWindow(n
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
-GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
+GLContextProviderNull::CreateOffscreen(const gfx::IntSize&,
                                        const SurfaceCaps&,
                                        bool)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateHeadless(bool)
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -357,35 +357,35 @@ GLContextWGL::SetupLookupFunction()
     MOZ_ASSERT(mLibrary == nullptr);
 
     mLibrary = sWGLLib.GetOGLLibrary();
     mLookupFunc = (PlatformLookupFunction)sWGLLib.fGetProcAddress;
     return true;
 }
 
 static bool
-GetMaxSize(HDC hDC, int format, gfxIntSize& size)
+GetMaxSize(HDC hDC, int format, IntSize& size)
 {
     int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB, LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
     int result[2];
 
     // (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues)
     if (!sWGLLib.fGetPixelFormatAttribiv(hDC, format, 0, 2, query, result))
         return false;
 
     size.width = result[0];
     size.height = result[1];
     return true;
 }
 
 static bool
 IsValidSizeForFormat(HDC hDC, int format,
-                     const gfxIntSize& requested)
+                     const IntSize& requested)
 {
-    gfxIntSize max;
+    IntSize max;
     if (!GetMaxSize(hDC, format, max))
         return true;
 
     if (requested.width > max.width)
         return false;
     if (requested.height > max.height)
         return false;
 
@@ -461,17 +461,17 @@ GLContextProviderWGL::CreateForWindow(ns
     }
 
     glContext->SetIsDoubleBuffered(true);
 
     return glContext.forget();
 }
 
 static already_AddRefed<GLContextWGL>
-CreatePBufferOffscreenContext(const gfxIntSize& aSize,
+CreatePBufferOffscreenContext(const IntSize& aSize,
                               GLContextWGL *aShareContext)
 {
     WGLLibrary& wgl = sWGLLib;
 
 #define A1(_a,_x)  do { _a.AppendElement(_x); } while(0)
 #define A2(_a,_x,_y)  do { _a.AppendElement(_x); _a.AppendElement(_y); } while(0)
 
     nsTArray<int> attrs;
@@ -615,17 +615,17 @@ GLContextProviderWGL::CreateHeadless(boo
 
     nsRefPtr<GLContextWGL> glContext;
 
     // Always try to create a pbuffer context first, because we
     // want the context isolation.
     if (sWGLLib.fCreatePbuffer &&
         sWGLLib.fChoosePixelFormat)
     {
-        gfxIntSize dummySize = gfxIntSize(16, 16);
+        IntSize dummySize = IntSize(16, 16);
         glContext = CreatePBufferOffscreenContext(dummySize, GetGlobalContextWGL());
     }
 
     // If it failed, then create a window context and use a FBO.
     if (!glContext) {
         glContext = CreateWindowOffscreenContext();
     }
 
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -41,17 +41,17 @@ CreateTextureImage(GLContext* gl,
         default:
             return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat);
     }
 }
 
 
 static already_AddRefed<TextureImage>
 TileGenFunc(GLContext* gl,
-            const nsIntSize& aSize,
+            const IntSize& aSize,
             TextureImage::ContentType aContentType,
             TextureImage::Flags aFlags,
             TextureImage::ImageFormat aImageFormat)
 {
     switch (gl->GetContextType()) {
 #ifdef XP_MACOSX
         case GLContextType::CGL:
             return TileGenFuncCGL(gl, aSize, aContentType, aFlags, aImageFormat);
@@ -628,17 +628,17 @@ void TiledTextureImage::Resize(const gfx
         // This will cause the pruning of columns not to work, but we don't need
         // to worry about that, as no more tiles will be reused past this point
         // anyway.
         if ((row == (int)mRows - 1) && (aSize.height != mSize.height))
             mColumns = 0;
 
         int col;
         for (col = 0; col < (int)columns; col++) {
-            nsIntSize size( // use tilesize first, then the remainder
+            IntSize size( // use tilesize first, then the remainder
                     (col+1) * mTileSize > (unsigned int)aSize.width  ? aSize.width  % mTileSize : mTileSize,
                     (row+1) * mTileSize > (unsigned int)aSize.height ? aSize.height % mTileSize : mTileSize);
 
             bool replace = false;
 
             // Check if we can re-use old tiles.
             if (col < (int)mColumns) {
                 // Reuse an existing tile. If the tile is an end-tile and the
--- a/gfx/gl/TextureImageCGL.h
+++ b/gfx/gl/TextureImageCGL.h
@@ -14,17 +14,17 @@
 namespace mozilla {
 namespace gl {
 
 class TextureImageCGL : public BasicTextureImage
 {
 public:
 
     TextureImageCGL(GLuint aTexture,
-                    const nsIntSize& aSize,
+                    const gfx::IntSize& aSize,
                     GLenum aWrapMode,
                     ContentType aContentType,
                     GLContext* aContext,
                     TextureImage::Flags aFlags = TextureImage::NoFlags,
                     TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
 
     ~TextureImageCGL();
 
@@ -44,17 +44,17 @@ CreateTextureImageCGL(GLContext *gl,
                       const gfx::IntSize& aSize,
                       TextureImage::ContentType aContentType,
                       GLenum aWrapMode,
                       TextureImage::Flags aFlags,
                       TextureImage::ImageFormat aImageFormat);
 
 already_AddRefed<TextureImage>
 TileGenFuncCGL(GLContext *gl,
-               const nsIntSize& aSize,
+               const gfx::IntSize& aSize,
                TextureImage::ContentType aContentType,
                TextureImage::Flags aFlags,
                TextureImage::ImageFormat aImageFormat);
 
 }
 }
 
 #endif
--- a/gfx/gl/TextureImageCGL.mm
+++ b/gfx/gl/TextureImageCGL.mm
@@ -12,17 +12,17 @@
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace gl {
 
 TextureImageCGL::TextureImageCGL(GLuint aTexture,
-                const nsIntSize& aSize,
+                const IntSize& aSize,
                 GLenum aWrapMode,
                 ContentType aContentType,
                 GLContext* aContext,
                 TextureImage::Flags aFlags,
                 TextureImage::ImageFormat aImageFormat)
     : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType,
                         aContext, aFlags, aImageFormat)
     , mPixelBuffer(0)
@@ -76,17 +76,17 @@ CreateTextureImageCGL(GLContext* gl,
     }
 
     return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode,
                                    aFlags, aImageFormat);
 }
 
 already_AddRefed<TextureImage>
 TileGenFuncCGL(GLContext *gl,
-               const nsIntSize& aSize,
+               const IntSize& aSize,
                TextureImage::ContentType aContentType,
                TextureImage::Flags aFlags,
                TextureImage::ImageFormat aImageFormat)
 {
     bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
     gl->MakeCurrent();
 
     GLuint texture;
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -43,17 +43,17 @@ GLTypeForImage(gfx::SurfaceFormat aForma
         return LOCAL_GL_UNSIGNED_SHORT_5_6_5;
     default:
         NS_WARNING("Unknown GL format for Surface format");
     }
     return 0;
 }
 
 TextureImageEGL::TextureImageEGL(GLuint aTexture,
-                                 const nsIntSize& aSize,
+                                 const gfx::IntSize& aSize,
                                  GLenum aWrapMode,
                                  ContentType aContentType,
                                  GLContext* aContext,
                                  Flags aFlags,
                                  TextureState aTextureState,
                                  TextureImage::ImageFormat aImageFormat)
     : TextureImage(aSize, aWrapMode, aContentType, aFlags)
     , mGLContext(aContext)
@@ -313,17 +313,17 @@ CreateTextureImageEGL(GLContext *gl,
                       TextureImage::ImageFormat aImageFormat)
 {
     nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat);
     return t.forget();
 }
 
 already_AddRefed<TextureImage>
 TileGenFuncEGL(GLContext *gl,
-               const nsIntSize& aSize,
+               const gfx::IntSize& aSize,
                TextureImage::ContentType aContentType,
                TextureImage::Flags aFlags,
                TextureImage::ImageFormat aImageFormat)
 {
   gl->MakeCurrent();
 
   GLuint texture;
   gl->fGenTextures(1, &texture);
--- a/gfx/gl/TextureImageEGL.h
+++ b/gfx/gl/TextureImageEGL.h
@@ -11,17 +11,17 @@
 namespace mozilla {
 namespace gl {
 
 class TextureImageEGL final
     : public TextureImage
 {
 public:
     TextureImageEGL(GLuint aTexture,
-                    const nsIntSize& aSize,
+                    const gfx::IntSize& aSize,
                     GLenum aWrapMode,
                     ContentType aContentType,
                     GLContext* aContext,
                     Flags aFlags = TextureImage::NoFlags,
                     TextureState aTextureState = Created,
                     TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
 
     virtual ~TextureImageEGL();
@@ -82,17 +82,17 @@ CreateTextureImageEGL(GLContext *gl,
                       const gfx::IntSize& aSize,
                       TextureImage::ContentType aContentType,
                       GLenum aWrapMode,
                       TextureImage::Flags aFlags,
                       TextureImage::ImageFormat aImageFormat);
 
 already_AddRefed<TextureImage>
 TileGenFuncEGL(GLContext *gl,
-               const nsIntSize& aSize,
+               const gfx::IntSize& aSize,
                TextureImage::ContentType aContentType,
                TextureImage::Flags aFlags,
                TextureImage::ImageFormat aImageFormat);
 
 }
 }
 
 #endif // TEXTUREIMAGEEGL_H_
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -421,19 +421,19 @@ struct RegionParamTraits
 };
 
 template<>
 struct ParamTraits<nsIntRegion>
   : RegionParamTraits<nsIntRegion, mozilla::gfx::IntRect, nsIntRegionRectIterator>
 {};
 
 template<>
-struct ParamTraits<nsIntSize>
+struct ParamTraits<mozilla::gfx::IntSize>
 {
-  typedef nsIntSize paramType;
+  typedef mozilla::gfx::IntSize paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
   static bool Read(const Message* msg, void** iter, paramType* result)
--- a/gfx/ipc/SharedDIBSurface.cpp
+++ b/gfx/ipc/SharedDIBSurface.cpp
@@ -42,17 +42,17 @@ void
 SharedDIBSurface::InitSurface(uint32_t aWidth, uint32_t aHeight,
                               bool aTransparent)
 {
   long stride = long(aWidth * kBytesPerPixel);
   unsigned char* data = reinterpret_cast<unsigned char*>(mSharedDIB.GetBits());
 
   gfxImageFormat format = aTransparent ? gfxImageFormat::ARGB32 : gfxImageFormat::RGB24;
 
-  gfxImageSurface::InitWithData(data, gfxIntSize(aWidth, aHeight),
+  gfxImageSurface::InitWithData(data, IntSize(aWidth, aHeight),
                                 stride, format);
 
   cairo_surface_set_user_data(mSurface, &SHAREDDIB_KEY, this, nullptr);
 }
 
 bool
 SharedDIBSurface::IsSharedDIBSurface(gfxASurface* aSurface)
 {
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -11,20 +11,20 @@
 #include "SharedSurfaceGL.h"              // for SharedSurface
 #include "gfxPattern.h"                 // for gfxPattern, etc
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils
 #include "gfx2DGlue.h"                  // for thebes --> moz2d transition
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Tools.h"
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING, etc
 #include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "nsSize.h"                     // for nsIntSize
 #include "gfxUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -18,17 +18,16 @@
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoArrayPtr, etc
 #include "nsAutoRef.h"                  // for nsCountedRef
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::Release, etc
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsTArray
 #include "mozilla/Atomics.h"
 #include "mozilla/WeakPtr.h"
 #include "nsThreadUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "nsDataHashtable.h"
 #include "mozilla/EnumeratedArray.h"
 
--- a/gfx/layers/ImageDataSerializer.cpp
+++ b/gfx/layers/ImageDataSerializer.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */
 
 #include "ImageDataSerializer.h"
 #include "gfx2DGlue.h"                  // for SurfaceFormatToImageFormat
-#include "gfxPoint.h"                   // for gfxIntSize
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/gfx/2D.h"             // for DataSourceSurface, Factory
 #include "mozilla/gfx/Logging.h"        // for gfxDebug
 #include "mozilla/gfx/Tools.h"          // for GetAlignedStride, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 
 namespace mozilla {
 namespace layers {
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -34,17 +34,16 @@
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsAutoPtr, nsRefPtr, etc
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsCSSProperty.h"              // for nsCSSProperty
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Layer::Release, etc
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
-#include "nsSize.h"                     // for nsIntSize
 #include "nsString.h"                   // for nsCString
 #include "nsTArray.h"                   // for nsTArray
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
 #include "nscore.h"                     // for nsACString, nsAString
 #include "mozilla/Logging.h"                      // for PRLogModuleInfo
 #include "nsIWidget.h"                  // For plugin window configuration information structs
 #include "gfxVR.h"
 
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -4,20 +4,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "LayersLogging.h"
 #include <stdint.h>                     // for uint8_t
 #include "gfxColor.h"                   // for gfxRGBA
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4, Matrix
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "nsDebug.h"                    // for NS_ERROR
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "nsSize.h"                     // for nsIntSize
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 void
 AppendToString(std::stringstream& aStream, const void* p,
--- a/gfx/layers/ReadbackProcessor.cpp
+++ b/gfx/layers/ReadbackProcessor.cpp
@@ -11,22 +11,22 @@
 #include "Units.h"                      // for ParentLayerIntRect
 #include "gfxColor.h"                   // for gfxRGBA
 #include "gfxContext.h"                 // for gfxContext
 #include "gfxUtils.h"
 #include "gfxRect.h"                    // for gfxRect
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
+#include "mozilla/gfx/Point.h"          // for Intsize
 #include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoPtr
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for gfxContext::Release, etc
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRegion.h"                   // for nsIntRegion
-#include "nsSize.h"                     // for nsIntSize
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 void
 ReadbackProcessor::BuildUpdates(ContainerLayer* aContainer)
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -19,17 +19,17 @@
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Matrix.h"         // for Matrix
 #include "mozilla/gfx/Point.h"          // for Point, IntPoint
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for ExtendMode::ExtendMode::CLAMP, etc
 #include "mozilla/layers/ShadowLayers.h"  // for ShadowableLayer
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
-#include "nsSize.h"                     // for nsIntSize
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "gfx2DGlue.h"
 #include "nsLayoutUtils.h"              // for invalidation debugging
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
--- a/gfx/layers/TextureDIB.cpp
+++ b/gfx/layers/TextureDIB.cpp
@@ -100,18 +100,17 @@ TextureClientMemoryDIB::ToSurfaceDescrip
 }
 
 bool
 TextureClientMemoryDIB::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
 {
   MOZ_ASSERT(!IsAllocated());
   mSize = aSize;
 
-  mSurface = new gfxWindowsSurface(gfxIntSize(aSize.width, aSize.height),
-                                   SurfaceFormatToImageFormat(mFormat));
+  mSurface = new gfxWindowsSurface(aSize, SurfaceFormatToImageFormat(mFormat));
   if (!mSurface || mSurface->CairoStatus())
   {
     NS_WARNING("Could not create surface");
     mSurface = nullptr;
     return false;
   }
 
   return true;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1910,16 +1910,23 @@ void AsyncPanZoomController::HandlePanni
       SetState(PANNING_LOCKED_Y);
       mPanDirRestricted = true;
     } else {
       SetState(NOTHING);
     }
   } else {
     SetState(NOTHING);
   }
+  if (!IsInPanningState()) {
+    // If we didn't enter a panning state because touch-action disallowed it,
+    // make sure to clear any leftover velocity from the pre-threshold
+    // touchmoves.
+    mX.SetVelocity(0);
+    mY.SetVelocity(0);
+  }
 }
 
 void AsyncPanZoomController::HandlePanning(double aAngle) {
   ReentrantMonitorAutoEnter lock(mMonitor);
   if (!gfxPrefs::APZCrossSlideEnabled() && (!mX.CanScrollNow() || !mY.CanScrollNow())) {
     SetState(PANNING);
   } else if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAxisLockAngle())) {
     mY.SetAxisLocked(true);
@@ -1969,21 +1976,16 @@ void AsyncPanZoomController::HandlePanni
 
 nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
   ReentrantMonitorAutoEnter lock(mMonitor);
 
   ParentLayerPoint point = GetFirstTouchPoint(aEvent);
   float dx = mX.PanDistance(point.x);
   float dy = mY.PanDistance(point.y);
 
-  // When the touch move breaks through the pan threshold, reposition the touch down origin
-  // so the page won't jump when we start panning.
-  mX.StartTouch(point.x, aEvent.mTime);
-  mY.StartTouch(point.y, aEvent.mTime);
-
   double angle = atan2(dy, dx); // range [-pi, pi]
   angle = fabs(angle); // range [0, pi]
 
   if (gfxPrefs::TouchActionEnabled()) {
     HandlePanningWithTouchAction(angle);
   } else {
     if (GetAxisLockMode() == FREE) {
       SetState(PANNING);
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -122,27 +122,34 @@ CancelableBlockState::TimeoutContentResp
   if (!mContentResponded) {
     mPreventDefault = false;
   }
   mContentResponseTimerExpired = true;
   return true;
 }
 
 bool
+CancelableBlockState::IsContentResponseTimerExpired() const
+{
+  return mContentResponseTimerExpired;
+}
+
+bool
 CancelableBlockState::IsDefaultPrevented() const
 {
   MOZ_ASSERT(mContentResponded || mContentResponseTimerExpired);
   return mPreventDefault;
 }
 
 bool
 CancelableBlockState::IsReadyForHandling() const
 {
-  if (!IsTargetConfirmed())
+  if (!IsTargetConfirmed()) {
     return false;
+  }
   return mContentResponded || mContentResponseTimerExpired;
 }
 
 void
 CancelableBlockState::DispatchImmediate(const InputData& aEvent) const
 {
   MOZ_ASSERT(!HasEvents());
   MOZ_ASSERT(GetTargetApzc());
@@ -442,34 +449,34 @@ TouchBlockState::GetAllowedTouchBehavior
   return true;
 }
 
 void
 TouchBlockState::CopyPropertiesFrom(const TouchBlockState& aOther)
 {
   TBS_LOG("%p copying properties from %p\n", this, &aOther);
   if (gfxPrefs::TouchActionEnabled()) {
-    MOZ_ASSERT(aOther.mAllowedTouchBehaviorSet);
+    MOZ_ASSERT(aOther.mAllowedTouchBehaviorSet || aOther.IsContentResponseTimerExpired());
     SetAllowedTouchBehaviors(aOther.mAllowedTouchBehaviors);
   }
   mTransformToApzc = aOther.mTransformToApzc;
 }
 
 bool
 TouchBlockState::IsReadyForHandling() const
 {
   if (!CancelableBlockState::IsReadyForHandling()) {
     return false;
   }
 
-  // TODO: for long-tap blocks we probably don't need the touch behaviour?
-  if (gfxPrefs::TouchActionEnabled() && !mAllowedTouchBehaviorSet) {
-    return false;
+  if (!gfxPrefs::TouchActionEnabled()) {
+    return true;
   }
-  return true;
+
+  return mAllowedTouchBehaviorSet || IsContentResponseTimerExpired();
 }
 
 void
 TouchBlockState::SetDuringFastMotion()
 {
   TBS_LOG("%p setting fast-motion flag\n", this);
   mDuringFastMotion = true;
 }
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -96,16 +96,21 @@ public:
 
   /**
    * Record that content didn't respond in time.
    * @return false if this block already timed out, true if not.
    */
   bool TimeoutContentResponse();
 
   /**
+   * Checks if the content response timer has already expired.
+   */
+  bool IsContentResponseTimerExpired() const;
+
+  /**
    * @return true iff web content cancelled this block of events.
    */
   bool IsDefaultPrevented() const;
 
   /**
    * Process the given event using this input block's target apzc.
    * This input block must not have pending events, and its apzc must not be
    * nullptr.
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -78,16 +78,21 @@ InputQueue::ReceiveTouchInput(const nsRe
   TouchBlockState* block = nullptr;
   if (aEvent.mType == MultiTouchInput::MULTITOUCH_START) {
     nsTArray<TouchBehaviorFlags> currentBehaviors;
     bool haveBehaviors = false;
     if (!gfxPrefs::TouchActionEnabled()) {
       haveBehaviors = true;
     } else if (!mInputBlockQueue.IsEmpty() && CurrentBlock()->AsTouchBlock()) {
       haveBehaviors = CurrentTouchBlock()->GetAllowedTouchBehaviors(currentBehaviors);
+      // If the behaviours aren't set, but the main-thread response timer on
+      // the block is expired we still treat it as though it has behaviors,
+      // because in that case we still want to interrupt the fast-fling and
+      // use the default behaviours.
+      haveBehaviors |= CurrentTouchBlock()->IsContentResponseTimerExpired();
     }
 
     block = StartNewTouchBlock(aTarget, aTargetConfirmed, false);
     INPQ_LOG("started new touch block %p for target %p\n", block, aTarget.get());
 
     // XXX using the chain from |block| here may be wrong in cases where the
     // target isn't confirmed and the real target turns out to be something
     // else. For now assume this is rare enough that it's not an issue.
@@ -216,29 +221,36 @@ InputQueue::CancelAnimationsForNewBlock(
     aBlock->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
   }
 }
 
 void
 InputQueue::MaybeRequestContentResponse(const nsRefPtr<AsyncPanZoomController>& aTarget,
                                         CancelableBlockState* aBlock)
 {
-  bool waitForMainThread = !aBlock->IsTargetConfirmed();
+  bool waitForMainThread = false;
+  if (aBlock->IsTargetConfirmed()) {
+    // Content won't prevent-default this, so we can just set the flag directly.
+    INPQ_LOG("not waiting for content response on block %p\n", aBlock);
+    aBlock->SetContentResponse(false);
+  } else {
+    waitForMainThread = true;
+  }
+  if (aBlock->AsTouchBlock() && gfxPrefs::TouchActionEnabled()) {
+    // TODO: once bug 1101628 is fixed, waitForMainThread should only be set
+    // to true if the APZCTM didn't know the touch-action behaviours for this
+    // block.
+    waitForMainThread = true;
+  }
   if (waitForMainThread) {
     // We either don't know for sure if aTarget is the right APZC, or we may
     // need to wait to give content the opportunity to prevent-default the
     // touch events. Either way we schedule a timeout so the main thread stuff
     // can run.
     ScheduleMainThreadTimeout(aTarget, aBlock->GetBlockId());
-  } else {
-    // Content won't prevent-default this, so we can just pretend like we scheduled
-    // a timeout and it expired. Note that we will still receive a ContentReceivedInputBlock
-    // callback for this block, and so we need to make sure we adjust the touch balance.
-    INPQ_LOG("not waiting for content response on block %p\n", aBlock);
-    aBlock->TimeoutContentResponse();
   }
 }
 
 uint64_t
 InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget)
 {
   TouchBlockState* block = StartNewTouchBlock(aTarget,
     /* aTargetConfirmed = */ true,
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -19,17 +19,17 @@
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
 #include "gfxASurface.h"                // for gfxASurface, etc
 #include "gfxColor.h"                   // for gfxRGBA
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxImageSurface.h"            // for gfxImageSurface
 #include "gfxMatrix.h"                  // for gfxMatrix
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"                   // for gfxPrefs
-#include "gfxPoint.h"                   // for gfxIntSize, gfxPoint
+#include "gfxPoint.h"                   // for IntSize, gfxPoint
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils
 #include "gfx2DGlue.h"                  // for thebes --> moz2d transition
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/WidgetUtils.h"        // for ScreenRotation
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
@@ -768,18 +768,18 @@ Transform3D(RefPtr<SourceSurface> aSourc
   // Intersect the transformed layer with the destination rectangle.
   // This is in device space since we have an identity transform set on aTarget.
   aDestRect = aDest->GetClipExtents();
   aDestRect.IntersectRect(aDestRect, offsetRect);
   aDestRect.RoundOut();
 
   // Create a surface the size of the transformed object.
   nsRefPtr<gfxASurface> dest = aDest->CurrentSurface();
-  nsRefPtr<gfxImageSurface> destImage = new gfxImageSurface(gfxIntSize(aDestRect.width,
-                                                                       aDestRect.height),
+  nsRefPtr<gfxImageSurface> destImage = new gfxImageSurface(IntSize(aDestRect.width,
+                                                                    aDestRect.height),
                                                             gfxImageFormat::ARGB32);
   gfxPoint offset = aDestRect.TopLeft();
 
   // Include a translation to the correct origin.
   gfx3DMatrix translation = gfx3DMatrix::Translation(aBounds.x, aBounds.y, 0);
 
   // Transform the content and offset it such that the content begins at the origin.
   Transform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/ContentClient.h"
 #include "BasicLayers.h"                // for BasicLayerManager
 #include "gfxColor.h"                   // for gfxRGBA
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPrefs.h"                   // for gfxPrefs
-#include "gfxPoint.h"                   // for gfxIntSize, gfxPoint
+#include "gfxPoint.h"                   // for IntSize, gfxPoint
 #include "gfxTeeSurface.h"              // for gfxTeeSurface
 #include "gfxUtils.h"                   // for gfxUtils
 #include "ipc/ShadowLayers.h"           // for ShadowLayerForwarder
 #include "mozilla/ArrayUtils.h"         // for ArrayLength
 #include "mozilla/gfx/2D.h"             // for DrawTarget, Factory
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Rect.h"           // for Rect
@@ -288,43 +288,43 @@ ContentClientRemoteBuffer::BuildTextureC
   MOZ_ASSERT(!mIsNewBuffer,
              "Bad! Did we create a buffer twice without painting?");
 
   mIsNewBuffer = true;
 
   DestroyBuffers();
 
   mSurfaceFormat = aFormat;
-  mSize = gfx::IntSize(aRect.width, aRect.height);
+  mSize = IntSize(aRect.width, aRect.height);
   mTextureFlags = TextureFlagsForRotatedContentBufferFlags(aFlags);
 
   if (aFlags & BUFFER_COMPONENT_ALPHA) {
     mTextureFlags |= TextureFlags::COMPONENT_ALPHA;
   }
 
   CreateBackBuffer(mBufferRect);
 }
 
 void
 ContentClientRemoteBuffer::CreateBackBuffer(const IntRect& aBufferRect)
 {
   // gfx::BackendType::NONE means fallback to the content backend
   mTextureClient = CreateTextureClientForDrawing(
     mSurfaceFormat, mSize, gfx::BackendType::NONE,
-    mTextureFlags,
+    mTextureFlags | ExtraTextureFlags(),
     TextureAllocationFlags::ALLOC_CLEAR_BUFFER
   );
   if (!mTextureClient || !AddTextureClient(mTextureClient)) {
     AbortTextureClientCreation();
     return;
   }
 
   if (mTextureFlags & TextureFlags::COMPONENT_ALPHA) {
     mTextureClientOnWhite = mTextureClient->CreateSimilar(
-      mTextureFlags,
+      mTextureFlags | ExtraTextureFlags(),
       TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE
     );
     if (!mTextureClientOnWhite || !AddTextureClient(mTextureClientOnWhite)) {
       AbortTextureClientCreation();
       return;
     }
   }
 }
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -254,16 +254,21 @@ public:
   virtual const nsIntPoint& BufferRotation() const
   {
     return RotatedContentBuffer::BufferRotation();
   }
 
   virtual void CreateBuffer(ContentType aType, const gfx::IntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) override;
 
+  virtual TextureFlags ExtraTextureFlags() const
+  {
+    return TextureFlags::NO_FLAGS;
+  }
+
 protected:
   void DestroyBuffers();
 
   virtual nsIntRegion GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                        const nsIntRegion& aVisibleRegion,
                                        bool aDidSelfCopy);
 
   void BuildTextureClients(gfx::SurfaceFormat aFormat,
@@ -385,16 +390,21 @@ public:
   {
   }
   virtual ~ContentClientSingleBuffered() {}
 
   virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw) override;
 
   virtual TextureInfo GetTextureInfo() const override
   {
-    return TextureInfo(CompositableType::CONTENT_SINGLE, mTextureFlags);
+    return TextureInfo(CompositableType::CONTENT_SINGLE, mTextureFlags | ExtraTextureFlags());
+  }
+
+  virtual TextureFlags ExtraTextureFlags() const override
+  {
+    return TextureFlags::IMMEDIATE_UPLOAD;
   }
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -19,17 +19,16 @@
 #include "mozilla/gfx/Tools.h"          // for BytesPerPixel
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/CompositorChild.h" // for CompositorChild
 #include "mozilla/layers/LayerMetricsWrapper.h"
 #include "mozilla/layers/ShadowLayers.h"  // for ShadowLayerForwarder
 #include "TextureClientPool.h"
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
-#include "nsSize.h"                     // for nsIntSize
 #include "gfxReusableSharedImageSurfaceWrapper.h"
 #include "nsExpirationTracker.h"        // for nsExpirationTracker
 #include "nsMathUtils.h"               // for NS_lroundf
 #include "gfx2DGlue.h"
 #include "LayersLogging.h"
 #include "UnitTransforms.h"             // for TransformTo
 #include "mozilla/UniquePtr.h"
 
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -2,26 +2,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TiledContentHost.h"
 #include "PaintedLayerComposite.h"      // for PaintedLayerComposite
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/Effects.h"     // for TexturedEffect, Effect, etc
 #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
 #include "nsAString.h"
 #include "nsDebug.h"                    // for NS_WARNING
 #include "nsPoint.h"                    // for IntPoint
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "nsRect.h"                     // for IntRect
-#include "nsSize.h"                     // for nsIntSize
 #include "mozilla/layers/TiledContentClient.h"
 
 class gfxReusableSurfaceWrapper;
 
 namespace mozilla {
 using namespace gfx;
 namespace layers {
 
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -20,25 +20,25 @@
 #include "base/basictypes.h"            // for DISALLOW_EVIL_CONSTRUCTORS
 #include "base/platform_thread.h"       // for PlatformThreadId
 #include "base/thread.h"                // for Thread
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/Monitor.h"            // for Monitor
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/TimeStamp.h"          // for TimeStamp
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/layers/GeckoContentController.h"
 #include "mozilla/layers/LayersMessages.h"  // for TargetConfig
 #include "mozilla/layers/PCompositorParent.h"
 #include "mozilla/layers/ShadowLayersManager.h" // for ShadowLayersManager
 #include "mozilla/layers/APZTestData.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"
-#include "nsSize.h"                     // for nsIntSize
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "mozilla/VsyncDispatcher.h"
 
 class CancelableTask;
 class MessageLoop;
 class nsIWidget;
 
 namespace mozilla {
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -23,17 +23,16 @@
 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "ShadowLayerUtils.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
-#include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
 namespace ipc {
 class Shmem;
 }
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -2,28 +2,28 @@
  * 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 "SharedRGBImage.h"
 #include "ImageTypes.h"                 // for ImageFormat::SHARED_RGB, etc
 #include "Shmem.h"                      // for Shmem
 #include "gfx2DGlue.h"                  // for ImageFormatToSurfaceFormat, etc
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
+#include "mozilla/gfx/Point.h"          // for IntSIze
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator, etc
 #include "mozilla/layers/ImageClient.h"  // for ImageClient
 #include "mozilla/layers/ImageDataSerializer.h"  // for ImageDataSerializer
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/TextureClient.h"  // for BufferTextureClient, etc
 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::AddRef, etc
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "nsSize.h"                     // for nsIntSize
 
 // Just big enough for a 1080p RGBA32 frame
 #define MAX_FRAME_SIZE (16 * 1024 * 1024)
 
 namespace mozilla {
 namespace layers {
 
 already_AddRefed<Image>
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -121,18 +121,17 @@ CompositorOGL::CreateContext()
 
   // Allow to create offscreen GL context for main Layer Manager
   if (!context && PR_GetEnv("MOZ_LAYERS_PREFER_OFFSCREEN")) {
     SurfaceCaps caps = SurfaceCaps::ForRGB();
     caps.preserve = false;
     caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565;
 
     bool requireCompatProfile = true;
-    context = GLContextProvider::CreateOffscreen(gfxIntSize(mSurfaceSize.width,
-                                                            mSurfaceSize.height),
+    context = GLContextProvider::CreateOffscreen(mSurfaceSize,
                                                  caps, requireCompatProfile);
   }
 
   if (!context) {
     context = gl::GLContextProvider::CreateForWindow(mWidget);
   }
 
   if (!context) {
@@ -1337,17 +1336,17 @@ CompositorOGL::EndFrameForExternalCompos
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
   }
   if (mTexturePool) {
     mTexturePool->EndFrame();
   }
 }
 
 void
-CompositorOGL::SetDestinationSurfaceSize(const gfx::IntSize& aSize)
+CompositorOGL::SetDestinationSurfaceSize(const IntSize& aSize)
 {
   mSurfaceSize.width = aSize.width;
   mSurfaceSize.height = aSize.height;
 }
 
 void
 CompositorOGL::CopyToTarget(DrawTarget* aTarget, const nsIntPoint& aTopLeft, const gfx::Matrix& aTransform)
 {
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -22,17 +22,16 @@
 #include "mozilla/gfx/Types.h"          // for Float, SurfaceFormat, etc
 #include "mozilla/layers/Compositor.h"  // for SurfaceInitMode, Compositor, etc
 #include "mozilla/layers/CompositorTypes.h"  // for MaskType::MaskType::NumMaskTypes, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
-#include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
 #include "nsThreadUtils.h"              // for nsRunnable
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType
 #include "nscore.h"                     // for NS_IMETHOD
 #include "gfxVR.h"
 
 class nsIWidget;
 
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -2,17 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLContext.h"                  // for GLContext, etc
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/TextureClientOGL.h"
-#include "nsSize.h"                     // for nsIntSize
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "GLLibraryEGL.h"
 
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 class CompositableForwarder;
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -12,17 +12,17 @@
 #include <algorithm>                    // for min/max
 #include "nsDebug.h"                    // for NS_WARNING
 #include "gfxCore.h"                    // for NS_GFX
 #include "mozilla/Likely.h"             // for MOZ_UNLIKELY
 #include "mozilla/gfx/Rect.h"
 #include "nsCoord.h"                    // for nscoord, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsPoint.h"                    // for nsIntPoint, nsPoint
-#include "nsSize.h"                     // for nsIntSize, nsSize
+#include "nsSize.h"                     // for IntSize, nsSize
 #include "nscore.h"                     // for NS_BUILD_REFCNT_LOGGING
 
 struct nsMargin;
 struct nsIntMargin;
 
 typedef mozilla::gfx::IntRect nsIntRect;
 
 struct NS_GFX nsRect :
--- a/gfx/src/nsSize.h
+++ b/gfx/src/nsSize.h
@@ -17,39 +17,39 @@ typedef mozilla::gfx::IntSize nsIntSize;
 typedef nsIntSize gfxIntSize;
 
 struct nsSize : public mozilla::gfx::BaseSize<nscoord, nsSize> {
   typedef mozilla::gfx::BaseSize<nscoord, nsSize> Super;
 
   nsSize() : Super() {}
   nsSize(nscoord aWidth, nscoord aHeight) : Super(aWidth, aHeight) {}
 
-  inline nsIntSize ScaleToNearestPixels(float aXScale, float aYScale,
+  inline mozilla::gfx::IntSize ScaleToNearestPixels(float aXScale, float aYScale,
                                         nscoord aAppUnitsPerPixel) const;
-  inline nsIntSize ToNearestPixels(nscoord aAppUnitsPerPixel) const;
+  inline mozilla::gfx::IntSize ToNearestPixels(nscoord aAppUnitsPerPixel) const;
 
   /**
    * Return this size scaled to a different appunits per pixel (APP) ratio.
    * @param aFromAPP the APP to scale from
    * @param aToAPP the APP to scale to
    */
   MOZ_WARN_UNUSED_RESULT inline nsSize
     ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const;
 };
 
-inline nsIntSize
+inline mozilla::gfx::IntSize
 nsSize::ScaleToNearestPixels(float aXScale, float aYScale,
                              nscoord aAppUnitsPerPixel) const
 {
-  return nsIntSize(
+  return mozilla::gfx::IntSize(
       NSToIntRoundUp(NSAppUnitsToDoublePixels(width, aAppUnitsPerPixel) * aXScale),
       NSToIntRoundUp(NSAppUnitsToDoublePixels(height, aAppUnitsPerPixel) * aYScale));
 }
 
-inline nsIntSize
+inline mozilla::gfx::IntSize
 nsSize::ToNearestPixels(nscoord aAppUnitsPerPixel) const
 {
   return ScaleToNearestPixels(1.0f, 1.0f, aAppUnitsPerPixel);
 }
 
 inline nsSize
 nsSize::ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const {
   if (aFromAPP != aToAPP) {
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -70,86 +70,105 @@ public:
   MOCK_METHOD3(SendAsyncScrollDOMEvent, void(bool aIsRoot, const CSSRect &aContentRect, const CSSSize &aScrollableSize));
   MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs));
   MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg));
 };
 
 class MockContentControllerDelayed : public MockContentController {
 public:
   MockContentControllerDelayed()
+    : mTime(TimeStamp::Now())
   {
   }
 
+  const TimeStamp& Time() {
+    return mTime;
+  }
+
+  void AdvanceByMillis(int aMillis) {
+    AdvanceBy(TimeDuration::FromMilliseconds(aMillis));
+  }
+
+  void AdvanceBy(const TimeDuration& aIncrement) {
+    TimeStamp target = mTime + aIncrement;
+    while (mTaskQueue.Length() > 0 && mTaskQueue[0].second <= target) {
+      RunNextDelayedTask();
+    }
+    mTime = target;
+  }
+
   void PostDelayedTask(Task* aTask, int aDelayMs) {
-    mTaskQueue.AppendElement(aTask);
-  }
-
-  void CheckHasDelayedTask() {
-    EXPECT_TRUE(mTaskQueue.Length() > 0);
-  }
-
-  void ClearDelayedTask() {
-    mTaskQueue.RemoveElementAt(0);
-  }
-
-  void DestroyOldestTask() {
-    delete mTaskQueue[0];
-    mTaskQueue.RemoveElementAt(0);
-  }
-
-  // Note that deleting mCurrentTask is important in order to
-  // release the reference to the callee object. Without this
-  // that object might be leaked. This is also why we don't
-  // expose mTaskQueue to any users of MockContentControllerDelayed.
-  void RunDelayedTask() {
-    mTaskQueue[0]->Run();
-    delete mTaskQueue[0];
-    mTaskQueue.RemoveElementAt(0);
+    TimeStamp runAtTime = mTime + TimeDuration::FromMilliseconds(aDelayMs);
+    int insIndex = mTaskQueue.Length();
+    while (insIndex > 0) {
+      if (mTaskQueue[insIndex - 1].second <= runAtTime) {
+        break;
+      }
+      insIndex--;
+    }
+    mTaskQueue.InsertElementAt(insIndex, std::make_pair(aTask, runAtTime));
   }
 
   // Run all the tasks in the queue, returning the number of tasks
   // run. Note that if a task queues another task while running, that
   // new task will not be run. Therefore, there may be still be tasks
   // in the queue after this function is called. Only when the return
   // value is 0 is the queue guaranteed to be empty.
   int RunThroughDelayedTasks() {
-    int numTasks = mTaskQueue.Length();
+    nsTArray<std::pair<Task*, TimeStamp>> runQueue;
+    runQueue.SwapElements(mTaskQueue);
+    int numTasks = runQueue.Length();
     for (int i = 0; i < numTasks; i++) {
-      RunDelayedTask();
+      mTime = runQueue[i].second;
+      runQueue[i].first->Run();
+
+      // Deleting the task is important in order to release the reference to
+      // the callee object.
+      delete runQueue[i].first;
     }
     return numTasks;
   }
 
 private:
-  nsTArray<Task*> mTaskQueue;
+  void RunNextDelayedTask() {
+    std::pair<Task*, TimeStamp> next = mTaskQueue[0];
+    mTaskQueue.RemoveElementAt(0);
+    mTime = next.second;
+    next.first->Run();
+    // Deleting the task is important in order to release the reference to
+    // the callee object.
+    delete next.first;
+  }
+
+  // The following array is sorted by timestamp (tasks are inserted in order by
+  // timestamp).
+  nsTArray<std::pair<Task*, TimeStamp>> mTaskQueue;
+  TimeStamp mTime;
 };
 
 class TestAPZCTreeManager : public APZCTreeManager {
 public:
-  explicit TestAPZCTreeManager(TimeStamp& aTime) : mTime(aTime) {}
+  TestAPZCTreeManager() {}
 
   nsRefPtr<InputQueue> GetInputQueue() const {
     return mInputQueue;
   }
 
 protected:
   AsyncPanZoomController* MakeAPZCInstance(uint64_t aLayersId, GeckoContentController* aController) override;
-private:
-  TimeStamp& mTime;
 };
 
 class TestAsyncPanZoomController : public AsyncPanZoomController {
 public:
-  TestAsyncPanZoomController(uint64_t aLayersId, GeckoContentController* aMcc,
+  TestAsyncPanZoomController(uint64_t aLayersId, MockContentControllerDelayed* aMcc,
                              TestAPZCTreeManager* aTreeManager,
-                             TimeStamp& aTime,
                              GestureBehavior aBehavior = DEFAULT_GESTURES)
     : AsyncPanZoomController(aLayersId, aTreeManager, aTreeManager->GetInputQueue(), aMcc, aBehavior)
     , mWaitForMainThread(false)
-    , mTime(aTime)
+    , mcc(aMcc)
   {}
 
   nsEventStatus ReceiveInputEvent(const InputData& aEvent, ScrollableLayerGuid* aDummy, uint64_t* aOutInputBlockId) {
     // This is a function whose signature matches exactly the ReceiveInputEvent
     // on APZCTreeManager. This allows us to templates for functions like
     // TouchDown, TouchUp, etc so that we can reuse the code for dispatching
     // events into both APZC and APZCTM.
     return ReceiveInputEvent(aEvent, aOutInputBlockId);
@@ -192,55 +211,56 @@ public:
     EXPECT_EQ(NOTHING, mState);
   }
 
   void AssertStateIsFling() const {
     ReentrantMonitorAutoEnter lock(mMonitor);
     EXPECT_EQ(FLING, mState);
   }
 
-  void AdvanceAnimationsUntilEnd(TimeStamp& aSampleTime,
-                                 const TimeDuration& aIncrement = TimeDuration::FromMilliseconds(10)) {
-    while (AdvanceAnimations(aSampleTime)) {
-      aSampleTime += aIncrement;
+  void AdvanceAnimationsUntilEnd(const TimeDuration& aIncrement = TimeDuration::FromMilliseconds(10)) {
+    while (AdvanceAnimations(mcc->Time())) {
+      mcc->AdvanceBy(aIncrement);
     }
   }
 
-  bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
-                                      ViewTransform* aOutTransform,
-                                      ParentLayerPoint& aScrollOffset) {
-    bool ret = AdvanceAnimations(aSampleTime);
+  bool SampleContentTransformForFrame(ViewTransform* aOutTransform,
+                                      ParentLayerPoint& aScrollOffset,
+                                      const TimeDuration& aIncrement = TimeDuration::FromMilliseconds(0)) {
+    mcc->AdvanceBy(aIncrement);
+    bool ret = AdvanceAnimations(mcc->Time());
     AsyncPanZoomController::SampleContentTransformForFrame(
       aOutTransform, aScrollOffset);
     return ret;
   }
 
   void SetWaitForMainThread() {
     mWaitForMainThread = true;
   }
 
   TimeStamp GetFrameTime() const {
-    return mTime;
+    return mcc->Time();
   }
 
   static TimeStamp GetStartupTime() {
     static TimeStamp sStartupTime = TimeStamp::Now();
     return sStartupTime;
   }
 
 private:
   bool mWaitForMainThread;
-  TimeStamp& mTime;
+  MockContentControllerDelayed* mcc;
 };
 
 AsyncPanZoomController*
 TestAPZCTreeManager::MakeAPZCInstance(uint64_t aLayersId, GeckoContentController* aController)
 {
-  return new TestAsyncPanZoomController(aLayersId, aController, this,
-      mTime, AsyncPanZoomController::USE_GESTURE_DETECTOR);
+  MockContentControllerDelayed* mcc = static_cast<MockContentControllerDelayed*>(aController);
+  return new TestAsyncPanZoomController(aLayersId, mcc, this,
+      AsyncPanZoomController::USE_GESTURE_DETECTOR);
 }
 
 static FrameMetrics
 TestFrameMetrics()
 {
   FrameMetrics fm;
 
   fm.SetDisplayPort(CSSRect(0, 0, 10, 10));
@@ -260,37 +280,36 @@ public:
 
 protected:
   virtual void SetUp()
   {
     gfxPrefs::GetSingleton();
     APZThreadUtils::SetThreadAssertionsEnabled(false);
     APZThreadUtils::SetControllerThread(MessageLoop::current());
 
-    mTime = TimeStamp::Now();
-
     mcc = new NiceMock<MockContentControllerDelayed>();
-    tm = new TestAPZCTreeManager(mTime);
-    apzc = new TestAsyncPanZoomController(0, mcc, tm, mTime, mGestureBehavior);
+    tm = new TestAPZCTreeManager();
+    apzc = new TestAsyncPanZoomController(0, mcc, tm, mGestureBehavior);
     apzc->SetFrameMetrics(TestFrameMetrics());
   }
 
   /**
    * Get the APZC's scroll range in CSS pixels.
    */
   CSSRect GetScrollRange() const
   {
     const FrameMetrics& metrics = apzc->GetFrameMetrics();
     return CSSRect(
         metrics.GetScrollableRect().TopLeft(),
         metrics.GetScrollableRect().Size() - metrics.CalculateCompositedSizeInCssPixels());
   }
 
   virtual void TearDown()
   {
+    while (mcc->RunThroughDelayedTasks());
     apzc->Destroy();
   }
 
   void MakeApzcWaitForMainThread()
   {
     apzc->SetWaitForMainThread();
   }
 
@@ -309,53 +328,52 @@ protected:
   /**
    * Sample animations once, 1 ms later than the last sample.
    */
   void SampleAnimationOnce()
   {
     const TimeDuration increment = TimeDuration::FromMilliseconds(1);
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
-    mTime += increment;
-    apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+    mcc->AdvanceBy(increment);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   }
 
   /**
    * Sample animations until we recover from overscroll.
    * @param aExpectedScrollOffset the expected reported scroll offset
    *                              throughout the animation
    */
   void SampleAnimationUntilRecoveredFromOverscroll(const ParentLayerPoint& aExpectedScrollOffset)
   {
     const TimeDuration increment = TimeDuration::FromMilliseconds(1);
     bool recoveredFromOverscroll = false;
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
-    while (apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut)) {
+    while (apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut)) {
       // The reported scroll offset should be the same throughout.
       EXPECT_EQ(aExpectedScrollOffset, pointOut);
 
       // Trigger computation of the overscroll tranform, to make sure
       // no assetions fire during the calculation.
       apzc->GetOverscrollTransform();
 
       if (!apzc->IsOverscrolled()) {
         recoveredFromOverscroll = true;
       }
 
-      mTime += increment;
+      mcc->AdvanceBy(increment);
     }
     EXPECT_TRUE(recoveredFromOverscroll);
     apzc->AssertStateIsReset();
   }
 
   void TestOverscroll();
 
   AsyncPanZoomController::GestureBehavior mGestureBehavior;
-  TimeStamp mTime;
   nsRefPtr<MockContentControllerDelayed> mcc;
   nsRefPtr<TestAPZCTreeManager> tm;
   nsRefPtr<TestAsyncPanZoomController> apzc;
 };
 
 class APZCGestureDetectorTester : public APZCBasicTester {
 public:
   APZCGestureDetectorTester()
@@ -447,116 +465,116 @@ template<class InputReceiver> static nsE
 TouchUp(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, TimeStamp aTime)
 {
   MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, aTime);
   mti.mTouches.AppendElement(CreateSingleTouchData(0, aX, aY));
   return aTarget->ReceiveInputEvent(mti, nullptr, nullptr);
 }
 
 template<class InputReceiver> static void
-Tap(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, TimeStamp& aTime,
+Tap(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, MockContentControllerDelayed* aMcc,
     TimeDuration aTapLength,
     nsEventStatus (*aOutEventStatuses)[2] = nullptr,
     uint64_t* aOutInputBlockId = nullptr)
 {
   // Even if the caller doesn't care about the block id, we need it to set the
   // allowed touch behaviour below, so make sure aOutInputBlockId is non-null.
   uint64_t blockId;
   if (!aOutInputBlockId) {
     aOutInputBlockId = &blockId;
   }
 
-  nsEventStatus status = TouchDown(aTarget, aX, aY, aTime, aOutInputBlockId);
+  nsEventStatus status = TouchDown(aTarget, aX, aY, aMcc->Time(), aOutInputBlockId);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[0] = status;
   }
-  aTime += aTapLength;
+  aMcc->AdvanceBy(aTapLength);
 
   // If touch-action is enabled then simulate the allowed touch behaviour
   // notification that the main thread is supposed to deliver.
   if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) {
     SetDefaultAllowedTouchBehavior(aTarget, *aOutInputBlockId);
   }
 
-  status = TouchUp(aTarget, aX, aY, aTime);
+  status = TouchUp(aTarget, aX, aY, aMcc->Time());
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[1] = status;
   }
 }
 
 template<class InputReceiver> static void
 TapAndCheckStatus(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY,
-    TimeStamp& aTime, TimeDuration aTapLength)
+    MockContentControllerDelayed* aMcc, TimeDuration aTapLength)
 {
   nsEventStatus statuses[2];
-  Tap(aTarget, aX, aY, aTime, aTapLength, &statuses);
+  Tap(aTarget, aX, aY, aMcc, aTapLength, &statuses);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[0]);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[1]);
 }
 
 template<class InputReceiver> static void
 Pan(const nsRefPtr<InputReceiver>& aTarget,
-    TimeStamp& aTime,
+    MockContentControllerDelayed* aMcc,
     const ScreenPoint& aTouchStart,
     const ScreenPoint& aTouchEnd,
     bool aKeepFingerDown = false,
     nsTArray<uint32_t>* aAllowedTouchBehaviors = nullptr,
     nsEventStatus (*aOutEventStatuses)[4] = nullptr,
     uint64_t* aOutInputBlockId = nullptr)
 {
   // Reduce the touch start tolerance to a tiny value.
   // We can't use a scoped pref because this value might be read at some later
   // time when the events are actually processed, rather than when we deliver
   // them.
   gfxPrefs::SetAPZTouchStartTolerance(1.0f / 1000.0f);
   const int OVERCOME_TOUCH_TOLERANCE = 1;
 
-  const TimeDuration TIME_BETWEEN_TOUCH_EVENT = TimeDuration::FromMilliseconds(100);
+  const TimeDuration TIME_BETWEEN_TOUCH_EVENT = TimeDuration::FromMilliseconds(50);
 
   // Even if the caller doesn't care about the block id, we need it to set the
   // allowed touch behaviour below, so make sure aOutInputBlockId is non-null.
   uint64_t blockId;
   if (!aOutInputBlockId) {
     aOutInputBlockId = &blockId;
   }
 
   // Make sure the move is large enough to not be handled as a tap
-  nsEventStatus status = TouchDown(aTarget, aTouchStart.x, aTouchStart.y + OVERCOME_TOUCH_TOLERANCE, aTime, aOutInputBlockId);
+  nsEventStatus status = TouchDown(aTarget, aTouchStart.x, aTouchStart.y + OVERCOME_TOUCH_TOLERANCE, aMcc->Time(), aOutInputBlockId);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[0] = status;
   }
 
-  aTime += TIME_BETWEEN_TOUCH_EVENT;
+  aMcc->AdvanceBy(TIME_BETWEEN_TOUCH_EVENT);
 
   // Allowed touch behaviours must be set after sending touch-start.
   if (status != nsEventStatus_eConsumeNoDefault) {
     if (aAllowedTouchBehaviors) {
       EXPECT_EQ(1UL, aAllowedTouchBehaviors->Length());
       aTarget->SetAllowedTouchBehavior(*aOutInputBlockId, *aAllowedTouchBehaviors);
     } else if (gfxPrefs::TouchActionEnabled()) {
       SetDefaultAllowedTouchBehavior(aTarget, *aOutInputBlockId);
     }
   }
 
-  status = TouchMove(aTarget, aTouchStart.x, aTouchStart.y, aTime);
+  status = TouchMove(aTarget, aTouchStart.x, aTouchStart.y, aMcc->Time());
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[1] = status;
   }
 
-  aTime += TIME_BETWEEN_TOUCH_EVENT;
-
-  status = TouchMove(aTarget, aTouchEnd.x, aTouchEnd.y, aTime);
+  aMcc->AdvanceBy(TIME_BETWEEN_TOUCH_EVENT);
+
+  status = TouchMove(aTarget, aTouchEnd.x, aTouchEnd.y, aMcc->Time());
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[2] = status;
   }
 
-  aTime += TIME_BETWEEN_TOUCH_EVENT;
+  aMcc->AdvanceBy(TIME_BETWEEN_TOUCH_EVENT);
 
   if (!aKeepFingerDown) {
-    status = TouchUp(aTarget, aTouchEnd.x, aTouchEnd.y, aTime);
+    status = TouchUp(aTarget, aTouchEnd.x, aTouchEnd.y, aMcc->Time());
   } else {
     status = nsEventStatus_eIgnore;
   }
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[3] = status;
   }
 
   // Don't increment the time here. Animations started on touch-up, such as
@@ -564,64 +582,64 @@ Pan(const nsRefPtr<InputReceiver>& aTarg
   // them immediately after they start, without time having elapsed.
 }
 
 // A version of Pan() that only takes y coordinates rather than (x, y) points
 // for the touch start and end points, and uses 10 for the x coordinates.
 // This is for convenience, as most tests only need to pan in one direction.
 template<class InputReceiver> static void
 Pan(const nsRefPtr<InputReceiver>& aTarget,
-    TimeStamp& aTime,
+    MockContentControllerDelayed* aMcc,
     int aTouchStartY,
     int aTouchEndY,
     bool aKeepFingerDown = false,
     nsTArray<uint32_t>* aAllowedTouchBehaviors = nullptr,
     nsEventStatus (*aOutEventStatuses)[4] = nullptr,
     uint64_t* aOutInputBlockId = nullptr)
 {
-  ::Pan(aTarget, aTime, ScreenPoint(10, aTouchStartY), ScreenPoint(10, aTouchEndY),
+  ::Pan(aTarget, aMcc, ScreenPoint(10, aTouchStartY), ScreenPoint(10, aTouchEndY),
       aKeepFingerDown, aAllowedTouchBehaviors, aOutEventStatuses, aOutInputBlockId);
 }
 
 /*
  * Dispatches mock touch events to the apzc and checks whether apzc properly
  * consumed them and triggered scrolling behavior.
  */
 template<class InputReceiver> static void
 PanAndCheckStatus(const nsRefPtr<InputReceiver>& aTarget,
-                  TimeStamp& aTime,
+                  MockContentControllerDelayed* aMcc,
                   int aTouchStartY,
                   int aTouchEndY,
                   bool aExpectConsumed,
                   nsTArray<uint32_t>* aAllowedTouchBehaviors,
                   uint64_t* aOutInputBlockId = nullptr)
 {
   nsEventStatus statuses[4]; // down, move, move, up
-  Pan(aTarget, aTime, aTouchStartY, aTouchEndY, false, aAllowedTouchBehaviors, &statuses, aOutInputBlockId);
+  Pan(aTarget, aMcc, aTouchStartY, aTouchEndY, false, aAllowedTouchBehaviors, &statuses, aOutInputBlockId);
 
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[0]);
 
   nsEventStatus touchMoveStatus;
   if (aExpectConsumed) {
     touchMoveStatus = nsEventStatus_eConsumeDoDefault;
   } else {
     touchMoveStatus = nsEventStatus_eIgnore;
   }
   EXPECT_EQ(touchMoveStatus, statuses[1]);
   EXPECT_EQ(touchMoveStatus, statuses[2]);
 }
 
 static void
 ApzcPanNoFling(const nsRefPtr<TestAsyncPanZoomController>& aApzc,
-               TimeStamp& aTime,
+               MockContentControllerDelayed* aMcc,
                int aTouchStartY,
                int aTouchEndY,
                uint64_t* aOutInputBlockId = nullptr)
 {
-  Pan(aApzc, aTime, aTouchStartY, aTouchEndY, false, nullptr, nullptr, aOutInputBlockId);
+  Pan(aApzc, aMcc, aTouchStartY, aTouchEndY, false, nullptr, nullptr, aOutInputBlockId);
   aApzc->CancelAnimation();
 }
 
 template<class InputReceiver> static void
 PinchWithPinchInput(const nsRefPtr<InputReceiver>& aTarget,
                     int aFocusX, int aFocusY, float aScale,
                     nsEventStatus (*aOutEventStatuses)[3] = nullptr)
 {
@@ -880,20 +898,16 @@ TEST_F(APZCPinchGestureDetectorTester, P
 
   int touchInputId = 0;
   uint64_t blockId = 0;
   PinchWithTouchInput(apzc, 250, 300, 1.25, touchInputId, nullptr, nullptr, &blockId);
 
   // Send the prevent-default notification for the touch block
   apzc->ContentReceivedInputBlock(blockId, true);
 
-  // Run all pending tasks (this should include at least the
-  // prevent-default timer).
-  EXPECT_LE(1, mcc->RunThroughDelayedTasks());
-
   // verify the metrics didn't change (i.e. the pinch was ignored)
   FrameMetrics fm = apzc->GetFrameMetrics();
   EXPECT_EQ(originalMetrics.GetZoom(), fm.GetZoom());
   EXPECT_EQ(originalMetrics.GetScrollOffset().x, fm.GetScrollOffset().x);
   EXPECT_EQ(originalMetrics.GetScrollOffset().y, fm.GetScrollOffset().y);
 
   apzc->AssertStateIsReset();
 }
@@ -921,17 +935,17 @@ TEST_F(APZCBasicTester, Overzoom) {
   // use a fuzzy match instead
   EXPECT_LT(abs(fm.GetScrollOffset().x), 1e-5);
   EXPECT_LT(abs(fm.GetScrollOffset().y), 1e-5);
 }
 
 TEST_F(APZCBasicTester, SimpleTransform) {
   ParentLayerPoint pointOut;
   ViewTransform viewTransformOut;
-  apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
 
   EXPECT_EQ(ParentLayerPoint(), pointOut);
   EXPECT_EQ(ViewTransform(), viewTransformOut);
 }
 
 
 TEST_F(APZCBasicTester, ComplexTransform) {
   // This test assumes there is a page that gets rendered to
@@ -945,17 +959,17 @@ TEST_F(APZCBasicTester, ComplexTransform
   // CSS transforms, the two layers are the same size in screen
   // pixels.
   //
   // The screen itself is 24x24 in screen pixels (therefore 4x4 in
   // CSS pixels). The displayport is 1 extra CSS pixel on all
   // sides.
 
   nsRefPtr<TestAsyncPanZoomController> childApzc =
-      new TestAsyncPanZoomController(0, mcc, tm, mTime);
+      new TestAsyncPanZoomController(0, mcc, tm);
 
   const char* layerTreeSyntax = "c(c)";
   // LayerID                     0 1
   nsIntRegion layerVisibleRegion[] = {
     nsIntRegion(IntRect(0, 0, 300, 300)),
     nsIntRegion(IntRect(0, 0, 150, 300)),
   };
   Matrix4x4 transforms[] = {
@@ -990,49 +1004,49 @@ TEST_F(APZCBasicTester, ComplexTransform
   ViewTransform viewTransformOut;
 
   // Both the parent and child layer should behave exactly the same here, because
   // the CSS transform on the child layer does not affect the SampleContentTransformForFrame code
 
   // initial transform
   apzc->SetFrameMetrics(metrics);
   apzc->NotifyLayersUpdated(metrics, true);
-  apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   childApzc->SetFrameMetrics(childMetrics);
   childApzc->NotifyLayersUpdated(childMetrics, true);
-  childApzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   // do an async scroll by 5 pixels and check the transform
   metrics.ScrollBy(CSSPoint(5, 0));
   apzc->SetFrameMetrics(metrics);
-  apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
 
   childMetrics.ScrollBy(CSSPoint(5, 0));
   childApzc->SetFrameMetrics(childMetrics);
-  childApzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
 
   // do an async zoom of 1.5x and check the transform
   metrics.ZoomBy(1.5f);
   apzc->SetFrameMetrics(metrics);
-  apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
 
   childMetrics.ZoomBy(1.5f);
   childApzc->SetFrameMetrics(childMetrics);
-  childApzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+  childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
 
   childApzc->Destroy();
 }
 
 class APZCPanningTester : public APZCBasicTester {
 protected:
@@ -1050,34 +1064,34 @@ protected:
     int touchEnd = 10;
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
 
     nsTArray<uint32_t> allowedTouchBehaviors;
     allowedTouchBehaviors.AppendElement(aBehavior);
 
     // Pan down
-    PanAndCheckStatus(apzc, mTime, touchStart, touchEnd, aShouldBeConsumed, &allowedTouchBehaviors);
-    apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+    PanAndCheckStatus(apzc, mcc, touchStart, touchEnd, aShouldBeConsumed, &allowedTouchBehaviors);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
 
     if (aShouldTriggerScroll) {
       EXPECT_EQ(ParentLayerPoint(0, -(touchEnd-touchStart)), pointOut);
       EXPECT_NE(ViewTransform(), viewTransformOut);
     } else {
       EXPECT_EQ(ParentLayerPoint(), pointOut);
       EXPECT_EQ(ViewTransform(), viewTransformOut);
     }
 
     // Clear the fling from the previous pan, or stopping it will
     // consume the next touchstart
     apzc->CancelAnimation();
 
     // Pan back
-    PanAndCheckStatus(apzc, mTime, touchEnd, touchStart, aShouldBeConsumed, &allowedTouchBehaviors);
-    apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+    PanAndCheckStatus(apzc, mcc, touchEnd, touchStart, aShouldBeConsumed, &allowedTouchBehaviors);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
 
     EXPECT_EQ(ParentLayerPoint(), pointOut);
     EXPECT_EQ(ViewTransform(), viewTransformOut);
   }
 
   void DoPanWithPreventDefaultTest()
   {
     MakeApzcWaitForMainThread();
@@ -1086,26 +1100,23 @@ protected:
     int touchEnd = 10;
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
     uint64_t blockId = 0;
 
     // Pan down
     nsTArray<uint32_t> allowedTouchBehaviors;
     allowedTouchBehaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
-    PanAndCheckStatus(apzc, mTime, touchStart, touchEnd, true, &allowedTouchBehaviors, &blockId);
+    PanAndCheckStatus(apzc, mcc, touchStart, touchEnd, true, &allowedTouchBehaviors, &blockId);
 
     // Send the signal that content has handled and preventDefaulted the touch
     // events. This flushes the event queue.
     apzc->ContentReceivedInputBlock(blockId, true);
-    // Run all pending tasks (this should include at least the
-    // prevent-default timer).
-    EXPECT_LE(1, mcc->RunThroughDelayedTasks());
-
-    apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
     EXPECT_EQ(ParentLayerPoint(), pointOut);
     EXPECT_EQ(ViewTransform(), viewTransformOut);
 
     apzc->AssertStateIsReset();
   }
 };
 
 TEST_F(APZCPanningTester, Pan) {
@@ -1157,47 +1168,47 @@ TEST_F(APZCBasicTester, Fling) {
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
 
   int touchStart = 50;
   int touchEnd = 10;
   ParentLayerPoint pointOut;
   ViewTransform viewTransformOut;
 
   // Fling down. Each step scroll further down
-  Pan(apzc, mTime, touchStart, touchEnd);
+  Pan(apzc, mcc, touchStart, touchEnd);
   ParentLayerPoint lastPoint;
   for (int i = 1; i < 50; i+=1) {
-    apzc->SampleContentTransformForFrame(mTime+TimeDuration::FromMilliseconds(i), &viewTransformOut, pointOut);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut, TimeDuration::FromMilliseconds(1));
     EXPECT_GT(pointOut.y, lastPoint.y);
     lastPoint = pointOut;
   }
 }
 
 TEST_F(APZCBasicTester, FlingIntoOverscroll) {
   // Enable overscrolling.
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   // Scroll down by 25 px. Don't fling for simplicity.
-  ApzcPanNoFling(apzc, mTime, 50, 25);
+  ApzcPanNoFling(apzc, mcc, 50, 25);
 
   // Now scroll back up by 20px, this time flinging after.
   // The fling should cover the remaining 5 px of room to scroll, then
   // go into overscroll, and finally snap-back to recover from overscroll.
-  Pan(apzc, mTime, 25, 45);
+  Pan(apzc, mcc, 25, 45);
   const TimeDuration increment = TimeDuration::FromMilliseconds(1);
   bool reachedOverscroll = false;
   bool recoveredFromOverscroll = false;
-  while (apzc->AdvanceAnimations(mTime)) {
+  while (apzc->AdvanceAnimations(mcc->Time())) {
     if (!reachedOverscroll && apzc->IsOverscrolled()) {
       reachedOverscroll = true;
     }
     if (reachedOverscroll && !apzc->IsOverscrolled()) {
       recoveredFromOverscroll = true;
     }
-    mTime += increment;
+    mcc->AdvanceBy(increment);
   }
   EXPECT_TRUE(reachedOverscroll);
   EXPECT_TRUE(recoveredFromOverscroll);
 }
 
 TEST_F(APZCBasicTester, PanningTransformNotifications) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
@@ -1224,28 +1235,28 @@ TEST_F(APZCBasicTester, PanningTransform
     EXPECT_CALL(*mcc, NotifyAPZStateChange(_,GeckoContentController::APZStateChange::TransformBegin,_)).Times(1);
     EXPECT_CALL(*mcc, NotifyAPZStateChange(_,GeckoContentController::APZStateChange::StartPanning,_)).Times(1);
     EXPECT_CALL(*mcc, NotifyAPZStateChange(_,GeckoContentController::APZStateChange::EndTouch,_)).Times(1);
     EXPECT_CALL(*mcc, NotifyAPZStateChange(_,GeckoContentController::APZStateChange::TransformEnd,_)).Times(1);
     EXPECT_CALL(check, Call("Done"));
   }
 
   check.Call("Simple pan");
-  ApzcPanNoFling(apzc, mTime, 50, 25);
+  ApzcPanNoFling(apzc, mcc, 50, 25);
   check.Call("Complex pan");
-  Pan(apzc, mTime, 25, 45);
-  apzc->AdvanceAnimationsUntilEnd(mTime);
+  Pan(apzc, mcc, 25, 45);
+  apzc->AdvanceAnimationsUntilEnd();
   check.Call("Done");
 }
 
 void APZCBasicTester::PanIntoOverscroll()
 {
   int touchStart = 500;
   int touchEnd = 10;
-  Pan(apzc, mTime, touchStart, touchEnd);
+  Pan(apzc, mcc, touchStart, touchEnd);
   EXPECT_TRUE(apzc->IsOverscrolled());
 }
 
 void APZCBasicTester::TestOverscroll()
 {
   // Pan sufficiently to hit overscroll behavior
   PanIntoOverscroll();
 
@@ -1292,70 +1303,68 @@ TEST_F(APZCBasicTester, OverScroll_Bug11
   // Pan sufficiently to hit overscroll behavior
   PanIntoOverscroll();
 
   // Sample animations once, to give the fling animation started on touch-up
   // a chance to realize it's overscrolled, and schedule a call to
   // HandleFlingOverscroll().
   SampleAnimationOnce();
 
-  // Give the call to HandleFlingOverscroll() a chance to occur, creating
-  // an overscroll animation.
-  mcc->RunThroughDelayedTasks();
-
-  // Sample the overscroll animation once, to get it to initialize
-  // the first overscroll sample.
+  // This advances the time and runs the HandleFlingOverscroll task scheduled in
+  // the previous call, which starts an overscroll animation. It then samples
+  // the overscroll animation once, to get it to initialize the first overscroll
+  // sample.
   SampleAnimationOnce();
 
   // Do a touch-down to cancel the overscroll animation, and then a touch-up
   // to schedule a new one since we're still overscrolled. We don't pan because
   // panning can trigger functions that clear the overscroll animation state
   // in other ways.
-  TouchDown(apzc, 10, 10, mTime, nullptr);
-  TouchUp(apzc, 10, 10, mTime);
+  TouchDown(apzc, 10, 10, mcc->Time(), nullptr);
+  TouchUp(apzc, 10, 10, mcc->Time());
 
   // Sample the second overscroll animation to its end.
   // If the ending of the first overscroll animation fails to clear state
   // properly, this will assert.
   ParentLayerPoint expectedScrollOffset(0, GetScrollRange().YMost());
   SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
 }
 
 TEST_F(APZCBasicTester, OverScrollAbort) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   // Pan sufficiently to hit overscroll behavior
   int touchStart = 500;
   int touchEnd = 10;
-  Pan(apzc, mTime, touchStart, touchEnd);
+  Pan(apzc, mcc, touchStart, touchEnd);
   EXPECT_TRUE(apzc->IsOverscrolled());
 
   ParentLayerPoint pointOut;
   ViewTransform viewTransformOut;
 
   // This sample call will run to the end of the fling animation
   // and will schedule the overscroll animation.
-  apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(10000), &viewTransformOut, pointOut);
+  apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut, TimeDuration::FromMilliseconds(10000));
   EXPECT_TRUE(apzc->IsOverscrolled());
 
   // At this point, we have an active overscroll animation.
   // Check that cancelling the animation clears the overscroll.
   apzc->CancelAnimation();
   EXPECT_FALSE(apzc->IsOverscrolled());
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCBasicTester, OverScrollPanningAbort) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   // Pan sufficiently to hit overscroll behaviour. Keep the finger down so
   // the pan does not end.
   int touchStart = 500;
   int touchEnd = 10;
-  Pan(apzc, mTime, touchStart, touchEnd, true); // keep finger down
+  Pan(apzc, mcc, touchStart, touchEnd, true); // keep finger down
   EXPECT_TRUE(apzc->IsOverscrolled());
 
   // Check that calling CancelAnimation() while the user is still panning
   // (and thus no fling or snap-back animation has had a chance to start)
   // clears the overscroll.
   apzc->CancelAnimation();
   EXPECT_FALSE(apzc->IsOverscrolled());
   apzc->AssertStateIsReset();
@@ -1370,92 +1379,88 @@ protected:
   // to content. If aSlow is true, the tap will happen while the fling
   // is at a slow velocity, and we check that the tap does trigger sending
   // a tap to content. See bug 1022956.
   void DoFlingStopTest(bool aSlow) {
     int touchStart = 50;
     int touchEnd = 10;
 
     // Start the fling down.
-    Pan(apzc, mTime, touchStart, touchEnd);
+    Pan(apzc, mcc, touchStart, touchEnd);
     // The touchstart from the pan will leave some cancelled tasks in the queue, clear them out
-    while (mcc->RunThroughDelayedTasks());
 
     // If we want to tap while the fling is fast, let the fling advance for 10ms only. If we want
     // the fling to slow down more, advance to 2000ms. These numbers may need adjusting if our
     // friction and threshold values change, but they should be deterministic at least.
     int timeDelta = aSlow ? 2000 : 10;
     int tapCallsExpected = aSlow ? 2 : 1;
 
     // Advance the fling animation by timeDelta milliseconds.
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(timeDelta), &viewTransformOut, pointOut);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut, TimeDuration::FromMilliseconds(timeDelta));
 
     // Deliver a tap to abort the fling. Ensure that we get a HandleSingleTap
     // call out of it if and only if the fling is slow.
     EXPECT_CALL(*mcc, HandleSingleTap(_, 0, apzc->GetGuid())).Times(tapCallsExpected);
-    Tap(apzc, 10, 10, mTime, 0);
+    Tap(apzc, 10, 10, mcc, 0);
     while (mcc->RunThroughDelayedTasks());
 
     // Deliver another tap, to make sure that taps are flowing properly once
     // the fling is aborted.
-    mTime += TimeDuration::FromMilliseconds(500);
-    Tap(apzc, 100, 100, mTime, 0);
+    Tap(apzc, 100, 100, mcc, 0);
     while (mcc->RunThroughDelayedTasks());
 
     // Verify that we didn't advance any further after the fling was aborted, in either case.
     ParentLayerPoint finalPointOut;
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(timeDelta + 1000), &viewTransformOut, finalPointOut);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, finalPointOut);
     EXPECT_EQ(pointOut.x, finalPointOut.x);
     EXPECT_EQ(pointOut.y, finalPointOut.y);
 
     apzc->AssertStateIsReset();
   }
 
   void DoFlingStopWithSlowListener(bool aPreventDefault) {
     MakeApzcWaitForMainThread();
 
     int touchStart = 50;
     int touchEnd = 10;
     uint64_t blockId = 0;
 
     // Start the fling down.
-    Pan(apzc, mTime, touchStart, touchEnd, false, nullptr, nullptr, &blockId);
+    Pan(apzc, mcc, touchStart, touchEnd, false, nullptr, nullptr, &blockId);
+    apzc->ConfirmTarget(blockId);
     apzc->ContentReceivedInputBlock(blockId, false);
-    while (mcc->RunThroughDelayedTasks());
 
     // Sample the fling a couple of times to ensure it's going.
     ParentLayerPoint point, finalPoint;
     ViewTransform viewTransform;
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(10), &viewTransform, point);
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(20), &viewTransform, finalPoint);
+    apzc->SampleContentTransformForFrame(&viewTransform, point, TimeDuration::FromMilliseconds(10));
+    apzc->SampleContentTransformForFrame(&viewTransform, finalPoint, TimeDuration::FromMilliseconds(10));
     EXPECT_GT(finalPoint.y, point.y);
 
     // Now we put our finger down to stop the fling
-    TouchDown(apzc, 10, 10, mTime, &blockId);
+    TouchDown(apzc, 10, 10, mcc->Time(), &blockId);
 
     // Re-sample to make sure it hasn't moved
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(30), &viewTransform, point);
+    apzc->SampleContentTransformForFrame(&viewTransform, point, TimeDuration::FromMilliseconds(10));
     EXPECT_EQ(finalPoint.x, point.x);
     EXPECT_EQ(finalPoint.y, point.y);
 
     // respond to the touchdown that stopped the fling.
     // even if we do a prevent-default on it, the animation should remain stopped.
     apzc->ContentReceivedInputBlock(blockId, aPreventDefault);
-    while (mcc->RunThroughDelayedTasks());
 
     // Verify the page hasn't moved
-    apzc->SampleContentTransformForFrame(mTime + TimeDuration::FromMilliseconds(100), &viewTransform, point);
+    apzc->SampleContentTransformForFrame(&viewTransform, point, TimeDuration::FromMilliseconds(70));
     EXPECT_EQ(finalPoint.x, point.x);
     EXPECT_EQ(finalPoint.y, point.y);
 
     // clean up
-    TouchUp(apzc, 10, 10, mTime);
-    while (mcc->RunThroughDelayedTasks());
+    TouchUp(apzc, 10, 10, mcc->Time());
 
     apzc->AssertStateIsReset();
   }
 };
 
 TEST_F(APZCFlingStopTester, FlingStop) {
   DoFlingStopTest(false);
 }
@@ -1470,59 +1475,61 @@ TEST_F(APZCFlingStopTester, FlingStopSlo
 
 TEST_F(APZCFlingStopTester, FlingStopPreventDefault) {
   DoFlingStopWithSlowListener(true);
 }
 
 TEST_F(APZCGestureDetectorTester, ShortPress) {
   MakeApzcUnzoomable();
 
-  TapAndCheckStatus(apzc, 10, 10, mTime, TimeDuration::FromMilliseconds(100));
-  // There will be delayed tasks posted for the long-tap and MAX_TAP timeouts, but
-  // we want to clear those.
-  mcc->ClearDelayedTask();
-  mcc->ClearDelayedTask();
-
-  // This verifies that the single tap notification is sent after the
-  // touchdown is fully processed. The ordering here is important.
-  mcc->CheckHasDelayedTask();
-
-  EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
-  mcc->RunDelayedTask();
+  MockFunction<void(std::string checkPointName)> check;
+  {
+    InSequence s;
+    // This verifies that the single tap notification is sent after the
+    // touchup is fully processed. The ordering here is important.
+    EXPECT_CALL(check, Call("pre-tap"));
+    EXPECT_CALL(check, Call("post-tap"));
+    EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
+  }
+
+  check.Call("pre-tap");
+  TapAndCheckStatus(apzc, 10, 10, mcc, TimeDuration::FromMilliseconds(100));
+  check.Call("post-tap");
 
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCGestureDetectorTester, MediumPress) {
   MakeApzcUnzoomable();
 
-  TapAndCheckStatus(apzc, 10, 10, mTime, TimeDuration::FromMilliseconds(400));
-  // There will be delayed tasks posted for the long-tap and MAX_TAP timeouts, but
-  // we want to clear those.
-  mcc->ClearDelayedTask();
-  mcc->ClearDelayedTask();
-
-  // This verifies that the single tap notification is sent after the
-  // touchdown is fully processed. The ordering here is important.
-  mcc->CheckHasDelayedTask();
-
-  EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
-  mcc->RunDelayedTask();
+  MockFunction<void(std::string checkPointName)> check;
+  {
+    InSequence s;
+    // This verifies that the single tap notification is sent after the
+    // touchup is fully processed. The ordering here is important.
+    EXPECT_CALL(check, Call("pre-tap"));
+    EXPECT_CALL(check, Call("post-tap"));
+    EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
+  }
+
+  check.Call("pre-tap");
+  TapAndCheckStatus(apzc, 10, 10, mcc, TimeDuration::FromMilliseconds(400));
+  check.Call("post-tap");
 
   apzc->AssertStateIsReset();
 }
 
 class APZCLongPressTester : public APZCGestureDetectorTester {
 protected:
   void DoLongPressTest(uint32_t aBehavior) {
     MakeApzcUnzoomable();
 
     uint64_t blockId = 0;
 
-    nsEventStatus status = TouchDown(apzc, 10, 10, mTime, &blockId);
+    nsEventStatus status = TouchDown(apzc, 10, 10, mcc->Time(), &blockId);
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
 
     if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) {
       // SetAllowedTouchBehavior() must be called after sending touch-start.
       nsTArray<uint32_t> allowedTouchBehaviors;
       allowedTouchBehaviors.AppendElement(aBehavior);
       apzc->SetAllowedTouchBehavior(blockId, allowedTouchBehaviors);
     }
@@ -1539,43 +1546,34 @@ protected:
       EXPECT_CALL(*mcc, HandleLongTap(CSSPoint(10, 10), 0, apzc->GetGuid(), blockId)).Times(1);
       EXPECT_CALL(check, Call("postHandleLongTap"));
 
       EXPECT_CALL(check, Call("preHandleSingleTap"));
       EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
       EXPECT_CALL(check, Call("postHandleSingleTap"));
     }
 
-    // There is a longpress event scheduled on a timeout
-    mcc->CheckHasDelayedTask();
-
     // Manually invoke the longpress while the touch is currently down.
     check.Call("preHandleLongTap");
-    mcc->RunDelayedTask();
+    mcc->RunThroughDelayedTasks();
     check.Call("postHandleLongTap");
 
-    // Destroy pending MAX_TAP timeout task
-    mcc->DestroyOldestTask();
-
     // Dispatching the longpress event starts a new touch block, which
     // needs a new content response and also has a pending timeout task
     // in the queue. Deal with those here. We do the content response first
     // with preventDefault=false, and then we run the timeout task which
     // "loses the race" and does nothing.
     apzc->ContentReceivedInputBlock(blockId, false);
-    mcc->CheckHasDelayedTask();
-    mcc->RunDelayedTask();
-
-    mTime += TimeDuration::FromMilliseconds(1000);
+    mcc->AdvanceByMillis(1000);
 
     // Finally, simulate lifting the finger. Since the long-press wasn't
     // prevent-defaulted, we should get a long-tap-up event.
     check.Call("preHandleSingleTap");
-    status = TouchUp(apzc, 10, 10, mTime);
-    mcc->RunDelayedTask();
+    status = TouchUp(apzc, 10, 10, mcc->Time());
+    mcc->RunThroughDelayedTasks();
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
     check.Call("postHandleSingleTap");
 
     apzc->AssertStateIsReset();
   }
 
   void DoLongPressPreventDefaultTest(uint32_t aBehavior) {
     MakeApzcUnzoomable();
@@ -1583,17 +1581,17 @@ protected:
     EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(0);
     EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
 
     int touchX = 10,
         touchStartY = 10,
         touchEndY = 50;
 
     uint64_t blockId = 0;
-    nsEventStatus status = TouchDown(apzc, touchX, touchStartY, mTime, &blockId);
+    nsEventStatus status = TouchDown(apzc, touchX, touchStartY, mcc->Time(), &blockId);
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
 
     if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) {
       // SetAllowedTouchBehavior() must be called after sending touch-start.
       nsTArray<uint32_t> allowedTouchBehaviors;
       allowedTouchBehaviors.AppendElement(aBehavior);
       apzc->SetAllowedTouchBehavior(blockId, allowedTouchBehaviors);
     }
@@ -1606,49 +1604,41 @@ protected:
       InSequence s;
 
       EXPECT_CALL(check, Call("preHandleLongTap"));
       blockId++;
       EXPECT_CALL(*mcc, HandleLongTap(CSSPoint(touchX, touchStartY), 0, apzc->GetGuid(), blockId)).Times(1);
       EXPECT_CALL(check, Call("postHandleLongTap"));
     }
 
-    mcc->CheckHasDelayedTask();
-
     // Manually invoke the longpress while the touch is currently down.
     check.Call("preHandleLongTap");
-    mcc->RunDelayedTask();
+    mcc->RunThroughDelayedTasks();
     check.Call("postHandleLongTap");
 
-    // Destroy pending MAX_TAP timeout task
-    mcc->DestroyOldestTask();
-
     // There should be a TimeoutContentResponse task in the queue still,
     // waiting for the response from the longtap event dispatched above.
     // Send the signal that content has handled the long-tap, and then run
     // the timeout task (it will be a no-op because the content "wins" the
     // race. This takes the place of the "contextmenu" event.
     apzc->ContentReceivedInputBlock(blockId, true);
-    mcc->CheckHasDelayedTask();
-    mcc->RunDelayedTask();
-
-    mTime += TimeDuration::FromMilliseconds(1000);
-
-    MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, mTime);
+    mcc->AdvanceByMillis(1000);
+
+    MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, mcc->Time());
     mti.mTouches.AppendElement(SingleTouchData(0, ParentLayerPoint(touchX, touchEndY), ScreenSize(0, 0), 0, 0));
     status = apzc->ReceiveInputEvent(mti, nullptr);
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
 
     EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(touchX, touchEndY), 0, apzc->GetGuid())).Times(0);
-    status = TouchUp(apzc, touchX, touchEndY, mTime);
+    status = TouchUp(apzc, touchX, touchEndY, mcc->Time());
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
 
     ParentLayerPoint pointOut;
     ViewTransform viewTransformOut;
-    apzc->SampleContentTransformForFrame(mTime, &viewTransformOut, pointOut);
+    apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
 
     EXPECT_EQ(ParentLayerPoint(), pointOut);
     EXPECT_EQ(ViewTransform(), viewTransformOut);
 
     apzc->AssertStateIsReset();
   }
 };
 
@@ -1672,220 +1662,206 @@ TEST_F(APZCLongPressTester, LongPressPre
 TEST_F(APZCLongPressTester, LongPressPreventDefaultWithTouchAction) {
   SCOPED_GFX_PREF(TouchActionEnabled, bool, true);
   DoLongPressPreventDefaultTest(mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN
                                 | mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN
                                 | mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
 }
 
 template<class InputReceiver> static void
-DoubleTap(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, TimeStamp& aTime,
+DoubleTap(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, MockContentControllerDelayed* aMcc,
           nsEventStatus (*aOutEventStatuses)[4] = nullptr,
           uint64_t (*aOutInputBlockIds)[2] = nullptr)
 {
   uint64_t blockId;
-  nsEventStatus status = TouchDown(aTarget, aX, aY, aTime, &blockId);
+  nsEventStatus status = TouchDown(aTarget, aX, aY, aMcc->Time(), &blockId);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[0] = status;
   }
   if (aOutInputBlockIds) {
     (*aOutInputBlockIds)[0] = blockId;
   }
-  aTime += TimeDuration::FromMilliseconds(10);
+  aMcc->AdvanceByMillis(10);
 
   // If touch-action is enabled then simulate the allowed touch behaviour
   // notification that the main thread is supposed to deliver.
   if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) {
     SetDefaultAllowedTouchBehavior(aTarget, blockId);
   }
 
-  status = TouchUp(aTarget, aX, aY, aTime);
+  status = TouchUp(aTarget, aX, aY, aMcc->Time());
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[1] = status;
   }
-  aTime += TimeDuration::FromMilliseconds(10);
-  status = TouchDown(aTarget, aX, aY, aTime, &blockId);
+  aMcc->AdvanceByMillis(10);
+  status = TouchDown(aTarget, aX, aY, aMcc->Time(), &blockId);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[2] = status;
   }
   if (aOutInputBlockIds) {
     (*aOutInputBlockIds)[1] = blockId;
   }
-  aTime += TimeDuration::FromMilliseconds(10);
+  aMcc->AdvanceByMillis(10);
 
   if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) {
     SetDefaultAllowedTouchBehavior(aTarget, blockId);
   }
 
-  status = TouchUp(aTarget, aX, aY, aTime);
+  status = TouchUp(aTarget, aX, aY, aMcc->Time());
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[3] = status;
   }
 }
 
 template<class InputReceiver> static void
 DoubleTapAndCheckStatus(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY,
-    TimeStamp& aTime, uint64_t (*aOutInputBlockIds)[2] = nullptr)
+    MockContentControllerDelayed* aMcc, uint64_t (*aOutInputBlockIds)[2] = nullptr)
 {
   nsEventStatus statuses[4];
-  DoubleTap(aTarget, aX, aY, aTime, &statuses, aOutInputBlockIds);
+  DoubleTap(aTarget, aX, aY, aMcc, &statuses, aOutInputBlockIds);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[0]);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[1]);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[2]);
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, statuses[3]);
 }
 
 TEST_F(APZCGestureDetectorTester, DoubleTap) {
   MakeApzcWaitForMainThread();
   MakeApzcZoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(0);
   EXPECT_CALL(*mcc, HandleDoubleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
 
   uint64_t blockIds[2];
-  DoubleTapAndCheckStatus(apzc, 10, 10, mTime, &blockIds);
+  DoubleTapAndCheckStatus(apzc, 10, 10, mcc, &blockIds);
 
   // responses to the two touchstarts
   apzc->ContentReceivedInputBlock(blockIds[0], false);
   apzc->ContentReceivedInputBlock(blockIds[1], false);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCGestureDetectorTester, DoubleTapNotZoomable) {
   MakeApzcWaitForMainThread();
   MakeApzcUnzoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(2);
   EXPECT_CALL(*mcc, HandleDoubleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(0);
 
   uint64_t blockIds[2];
-  DoubleTapAndCheckStatus(apzc, 10, 10, mTime, &blockIds);
+  DoubleTapAndCheckStatus(apzc, 10, 10, mcc, &blockIds);
 
   // responses to the two touchstarts
   apzc->ContentReceivedInputBlock(blockIds[0], false);
   apzc->ContentReceivedInputBlock(blockIds[1], false);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCGestureDetectorTester, DoubleTapPreventDefaultFirstOnly) {
   MakeApzcWaitForMainThread();
   MakeApzcZoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
   EXPECT_CALL(*mcc, HandleDoubleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(0);
 
   uint64_t blockIds[2];
-  DoubleTapAndCheckStatus(apzc, 10, 10, mTime, &blockIds);
+  DoubleTapAndCheckStatus(apzc, 10, 10, mcc, &blockIds);
 
   // responses to the two touchstarts
   apzc->ContentReceivedInputBlock(blockIds[0], true);
   apzc->ContentReceivedInputBlock(blockIds[1], false);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCGestureDetectorTester, DoubleTapPreventDefaultBoth) {
   MakeApzcWaitForMainThread();
   MakeApzcZoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(0);
   EXPECT_CALL(*mcc, HandleDoubleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(0);
 
   uint64_t blockIds[2];
-  DoubleTapAndCheckStatus(apzc, 10, 10, mTime, &blockIds);
+  DoubleTapAndCheckStatus(apzc, 10, 10, mcc, &blockIds);
 
   // responses to the two touchstarts
   apzc->ContentReceivedInputBlock(blockIds[0], true);
   apzc->ContentReceivedInputBlock(blockIds[1], true);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 // Test for bug 947892
 // We test whether we dispatch tap event when the tap is followed by pinch.
 TEST_F(APZCGestureDetectorTester, TapFollowedByPinch) {
   MakeApzcZoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
 
-  Tap(apzc, 10, 10, mTime, TimeDuration::FromMilliseconds(100));
+  Tap(apzc, 10, 10, mcc, TimeDuration::FromMilliseconds(100));
 
   int inputId = 0;
   MultiTouchInput mti;
-  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mTime);
+  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
   mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
   apzc->ReceiveInputEvent(mti, nullptr);
 
-  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, mTime);
+  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
   mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
   apzc->ReceiveInputEvent(mti, nullptr);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 TEST_F(APZCGestureDetectorTester, TapFollowedByMultipleTouches) {
   MakeApzcZoomable();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
 
-  Tap(apzc, 10, 10, mTime, TimeDuration::FromMilliseconds(100));
+  Tap(apzc, 10, 10, mcc, TimeDuration::FromMilliseconds(100));
 
   int inputId = 0;
   MultiTouchInput mti;
-  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mTime);
+  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
   apzc->ReceiveInputEvent(mti, nullptr);
 
-  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mTime);
+  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
   mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
   apzc->ReceiveInputEvent(mti, nullptr);
 
-  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, mTime);
+  mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
   mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
   apzc->ReceiveInputEvent(mti, nullptr);
 
-  while (mcc->RunThroughDelayedTasks());
-
   apzc->AssertStateIsReset();
 }
 
 class APZCTreeManagerTester : public ::testing::Test {
 protected:
   virtual void SetUp() {
     gfxPrefs::GetSingleton();
     APZThreadUtils::SetThreadAssertionsEnabled(false);
     APZThreadUtils::SetControllerThread(MessageLoop::current());
 
-    mTime = TimeStamp::Now();
-
     mcc = new NiceMock<MockContentControllerDelayed>();
-    manager = new TestAPZCTreeManager(mTime);
+    manager = new TestAPZCTreeManager();
   }
 
   virtual void TearDown() {
+    while (mcc->RunThroughDelayedTasks());
     manager->ClearTree();
   }
 
-  TimeStamp mTime;
   nsRefPtr<MockContentControllerDelayed> mcc;
 
   nsTArray<nsRefPtr<Layer> > layers;
   nsRefPtr<LayerManager> lm;
   nsRefPtr<Layer> root;
 
   nsRefPtr<TestAPZCTreeManager> manager;
 
@@ -2174,17 +2150,17 @@ TEST_F(APZHitTestingTester, HitTesting2)
   // Pan the root layer upward by 50 pixels.
   // This causes layers[1] to scroll out of view, and an async transform
   // of -50 to be set on the root layer.
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
 
   // This first pan will move the APZC by 50 pixels, and dispatch a paint request.
   // Since this paint request is in the queue to Gecko, transformToGecko will
   // take it into account.
-  ApzcPanNoFling(apzcroot, mTime, 100, 50);
+  ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
   EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
   // and transformToGecko unapplies it and then reapplies it, because by the
   // time the event being transformed reaches Gecko the new paint request will
@@ -2200,17 +2176,17 @@ TEST_F(APZHitTestingTester, HitTesting2)
   // transformToGecko reapplies both the css transform and the async transform
   // because we have already issued a paint request with it.
   EXPECT_EQ(Point(25, 25), transformToGecko * Point(12.5, 75));
 
   // This second pan will move the APZC by another 50 pixels but since the paint
   // request dispatched above has not "completed", we will not dispatch another
   // one yet. Now we have an async transform on top of the pending paint request
   // transform.
-  ApzcPanNoFling(apzcroot, mTime, 100, 50);
+  ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
   EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
   // transformToGecko unapplies the full async transform of -100 pixels, and then
   // reapplies the "D" transform of -50 leading to an overall adjustment of +50
@@ -2384,118 +2360,115 @@ TEST_F(APZHitTestingTester, TestRepaintF
     EXPECT_CALL(check, Call("post-first-touch-start"));
     EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(AtLeast(1));
     EXPECT_CALL(check, Call("post-second-fling"));
     EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(AtLeast(1));
     EXPECT_CALL(check, Call("post-second-touch-start"));
   }
 
   // This first pan will move the APZC by 50 pixels, and dispatch a paint request.
-  ApzcPanNoFling(apzcroot, mTime, 100, 50);
+  ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Verify that a touch start doesn't get untransformed
   ScreenIntPoint touchPoint(50, 50);
-  MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mTime);
+  MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time());
   mti.mTouches.AppendElement(SingleTouchData(0, touchPoint, ScreenSize(0, 0), 0, 0));
 
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, manager->ReceiveInputEvent(mti, nullptr, nullptr));
   EXPECT_EQ(touchPoint, mti.mTouches[0].mScreenPoint);
   check.Call("post-first-touch-start");
 
   // Send a touchend to clear state
   mti.mType = MultiTouchInput::MULTITOUCH_END;
   manager->ReceiveInputEvent(mti, nullptr, nullptr);
 
-  mTime += TimeDuration::FromMilliseconds(1000);
+  mcc->AdvanceByMillis(1000);
 
   // Now do two pans. The first of these will dispatch a repaint request, as above.
   // The second will get stuck in the paint throttler because the first one doesn't
   // get marked as "completed", so this will result in a non-empty LD transform.
   // (Note that any outstanding repaint requests from the first half of this test
   // don't impact this half because we advance the time by 1 second, which will trigger
   // the max-wait-exceeded codepath in the paint throttler).
-  ApzcPanNoFling(apzcroot, mTime, 100, 50);
+  ApzcPanNoFling(apzcroot, mcc, 100, 50);
   check.Call("post-second-fling");
-  ApzcPanNoFling(apzcroot, mTime, 100, 50);
+  ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Ensure that a touch start again doesn't get untransformed by flushing
   // a repaint
   mti.mType = MultiTouchInput::MULTITOUCH_START;
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, manager->ReceiveInputEvent(mti, nullptr, nullptr));
   EXPECT_EQ(touchPoint, mti.mTouches[0].mScreenPoint);
   check.Call("post-second-touch-start");
 
   mti.mType = MultiTouchInput::MULTITOUCH_END;
   EXPECT_EQ(nsEventStatus_eConsumeDoDefault, manager->ReceiveInputEvent(mti, nullptr, nullptr));
   EXPECT_EQ(touchPoint, mti.mTouches[0].mScreenPoint);
-
-  mcc->RunThroughDelayedTasks();
 }
 
 TEST_F(APZHitTestingTester, TestRepaintFlushOnWheelEvents) {
   // The purpose of this test is to ensure that wheel events trigger a repaint
   // flush as per bug 1166871, and that the wheel event untransform is a no-op.
 
   CreateSimpleScrollingLayer();
   ScopedLayerTreeRegistration registration(0, root, mcc);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
   TestAsyncPanZoomController* apzcroot = ApzcOf(root);
 
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(AtLeast(3));
   ScreenPoint origin(100, 50);
   for (int i = 0; i < 3; i++) {
-    ScrollWheelInput swi(MillisecondsSinceStartup(mTime), mTime, 0,
+    ScrollWheelInput swi(MillisecondsSinceStartup(mcc->Time()), mcc->Time(), 0,
       ScrollWheelInput::SCROLLMODE_INSTANT, ScrollWheelInput::SCROLLDELTA_PIXEL,
       origin, 0, 10);
     EXPECT_EQ(nsEventStatus_eConsumeDoDefault, manager->ReceiveInputEvent(swi, nullptr, nullptr));
     EXPECT_EQ(origin, swi.mOrigin);
 
     ViewTransform viewTransform;
     ParentLayerPoint point;
-    apzcroot->SampleContentTransformForFrame(mTime, &viewTransform, point);
+    apzcroot->SampleContentTransformForFrame(&viewTransform, point);
     EXPECT_EQ(0, point.x);
     EXPECT_EQ((i + 1) * 10, point.y);
     EXPECT_EQ(0, viewTransform.mTranslation.x);
     EXPECT_EQ((i + 1) * -10, viewTransform.mTranslation.y);
 
-    mTime += TimeDuration::FromMilliseconds(5);
+    mcc->AdvanceByMillis(5);
   }
-  mcc->RunThroughDelayedTasks();
 }
 
 TEST_F(APZHitTestingTester, Bug1148350) {
   CreateBug1148350LayerTree();
   ScopedLayerTreeRegistration registration(0, root, mcc);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
   MockFunction<void(std::string checkPointName)> check;
   {
     InSequence s;
     EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(100, 100), 0, ApzcOf(layers[1])->GetGuid())).Times(1);
     EXPECT_CALL(check, Call("Tapped without transform"));
     EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(100, 100), 0, ApzcOf(layers[1])->GetGuid())).Times(1);
     EXPECT_CALL(check, Call("Tapped with interleaved transform"));
   }
 
-  Tap(manager, 100, 100, mTime, TimeDuration::FromMilliseconds(100));
+  Tap(manager, 100, 100, mcc, TimeDuration::FromMilliseconds(100));
   mcc->RunThroughDelayedTasks();
   check.Call("Tapped without transform");
 
   uint64_t blockId;
-  TouchDown(manager, 100, 100, mTime, &blockId);
+  TouchDown(manager, 100, 100, mcc->Time(), &blockId);
   if (gfxPrefs::TouchActionEnabled()) {
     SetDefaultAllowedTouchBehavior(manager, blockId);
   }
-  mTime += TimeDuration::FromMilliseconds(100);
+  mcc->AdvanceByMillis(100);
 
   layers[0]->SetVisibleRegion(nsIntRegion(IntRect(0,50,200,150)));
   layers[0]->SetBaseTransform(Matrix4x4::Translation(0, 50, 0));
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
-  TouchUp(manager, 100, 100, mTime);
+  TouchUp(manager, 100, 100, mcc->Time());
   mcc->RunThroughDelayedTasks();
   check.Call("Tapped with interleaved transform");
 }
 
 class APZOverscrollHandoffTester : public APZCTreeManagerTester {
 protected:
   UniquePtr<ScopedLayerTreeRegistration> registration;
   TestAsyncPanZoomController* rootApzc;
@@ -2582,17 +2555,17 @@ TEST_F(APZOverscrollHandoffTester, Defer
   TestAsyncPanZoomController* childApzc = ApzcOf(layers[1]);
 
   // Enable touch-listeners so that we can separate the queueing of input
   // events from them being processed.
   childApzc->SetWaitForMainThread();
 
   // Queue input events for a pan.
   uint64_t blockId = 0;
-  ApzcPanNoFling(childApzc, mTime, 90, 30, &blockId);
+  ApzcPanNoFling(childApzc, mcc, 90, 30, &blockId);
 
   // Allow the pan to be processed.
   childApzc->ContentReceivedInputBlock(blockId, false);
   childApzc->ConfirmTarget(blockId);
 
   // Make sure overscroll was handed off correctly.
   EXPECT_EQ(50, childApzc->GetFrameMetrics().GetScrollOffset().y);
   EXPECT_EQ(10, rootApzc->GetFrameMetrics().GetScrollOffset().y);
@@ -2610,28 +2583,28 @@ TEST_F(APZOverscrollHandoffTester, Layer
   TestAsyncPanZoomController* childApzc = ApzcOf(layers[1]);
 
   // Enable touch-listeners so that we can separate the queueing of input
   // events from them being processed.
   childApzc->SetWaitForMainThread();
 
   // Queue input events for a pan.
   uint64_t blockId = 0;
-  ApzcPanNoFling(childApzc, mTime, 90, 30, &blockId);
+  ApzcPanNoFling(childApzc, mcc, 90, 30, &blockId);
 
   // Modify the APZC tree to insert a new APZC 'middle' into the handoff chain
   // between the child and the root.
   CreateOverscrollHandoffLayerTree2();
   nsRefPtr<Layer> middle = layers[1];
   childApzc->SetWaitForMainThread();
   TestAsyncPanZoomController* middleApzc = ApzcOf(middle);
 
   // Queue input events for another pan.
   uint64_t secondBlockId = 0;
-  ApzcPanNoFling(childApzc, mTime, 30, 90, &secondBlockId);
+  ApzcPanNoFling(childApzc, mcc, 30, 90, &secondBlockId);
 
   // Allow the first pan to be processed.
   childApzc->ContentReceivedInputBlock(blockId, false);
   childApzc->ConfirmTarget(blockId);
 
   // Make sure things have scrolled according to the handoff chain in
   // place at the time the touch-start of the first pan was queued.
   EXPECT_EQ(50, childApzc->GetFrameMetrics().GetScrollOffset().y);
@@ -2655,60 +2628,60 @@ TEST_F(APZOverscrollHandoffTester, Stuck
   // Enable overscrolling.
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   CreateOverscrollHandoffLayerTree1();
 
   TestAsyncPanZoomController* child = ApzcOf(layers[1]);
 
   // Pan, causing the parent APZC to overscroll.
-  Pan(manager, mTime, 10, 40, true /* keep finger down */);
+  Pan(manager, mcc, 10, 40, true /* keep finger down */);
   EXPECT_FALSE(child->IsOverscrolled());
   EXPECT_TRUE(rootApzc->IsOverscrolled());
 
   // Put a second finger down.
   MultiTouchInput secondFingerDown(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0);
   // Use the same touch identifier for the first touch (0) as Pan(). (A bit hacky.)
   secondFingerDown.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, 40), ScreenSize(0, 0), 0, 0));
   secondFingerDown.mTouches.AppendElement(SingleTouchData(1, ScreenIntPoint(30, 20), ScreenSize(0, 0), 0, 0));
   manager->ReceiveInputEvent(secondFingerDown, nullptr, nullptr);
 
   // Release the fingers.
   MultiTouchInput fingersUp = secondFingerDown;
   fingersUp.mType = MultiTouchInput::MULTITOUCH_END;
   manager->ReceiveInputEvent(fingersUp, nullptr, nullptr);
 
   // Allow any animations to run their course.
-  child->AdvanceAnimationsUntilEnd(mTime);
-  rootApzc->AdvanceAnimationsUntilEnd(mTime);
+  child->AdvanceAnimationsUntilEnd();
+  rootApzc->AdvanceAnimationsUntilEnd();
 
   // Make sure nothing is overscrolled.
   EXPECT_FALSE(child->IsOverscrolled());
   EXPECT_FALSE(rootApzc->IsOverscrolled());
 }
 
 // Test that flinging in a direction where one component of the fling goes into
 // overscroll but the other doesn't, results in just the one component being
 // handed off to the parent, while the original APZC continues flinging in the
 // other direction.
 TEST_F(APZOverscrollHandoffTester, PartialFlingHandoff) {
   CreateOverscrollHandoffLayerTree1();
 
   // Fling up and to the left. The child APZC has room to scroll up, but not
   // to the left, so the horizontal component of the fling should be handed
   // off to the parent APZC.
-  Pan(manager, mTime, ScreenPoint(90, 90), ScreenPoint(55, 55));
+  Pan(manager, mcc, ScreenPoint(90, 90), ScreenPoint(55, 55));
 
   nsRefPtr<TestAsyncPanZoomController> parent = ApzcOf(root);
   nsRefPtr<TestAsyncPanZoomController> child = ApzcOf(layers[1]);
 
   // Advance the child's fling animation once to give the partial handoff
   // a chance to occur.
-  mTime += TimeDuration::FromMilliseconds(10);
-  child->AdvanceAnimations(mTime);
+  mcc->AdvanceByMillis(10);
+  child->AdvanceAnimations(mcc->Time());
 
   // Assert that partial handoff has occurred.
   child->AssertStateIsFling();
   parent->AssertStateIsFling();
 }
 
 // Here we test that if two flings are happening simultaneously, overscroll
 // is handed off correctly for each.
@@ -2717,60 +2690,59 @@ TEST_F(APZOverscrollHandoffTester, Simul
   CreateOverscrollHandoffLayerTree3();
 
   nsRefPtr<TestAsyncPanZoomController> parent1 = ApzcOf(layers[1]);
   nsRefPtr<TestAsyncPanZoomController> child1 = ApzcOf(layers[2]);
   nsRefPtr<TestAsyncPanZoomController> parent2 = ApzcOf(layers[3]);
   nsRefPtr<TestAsyncPanZoomController> child2 = ApzcOf(layers[4]);
 
   // Pan on the lower child.
-  Pan(child2, mTime, 45, 5);
+  Pan(child2, mcc, 45, 5);
 
   // Pan on the upper child.
-  Pan(child1, mTime, 95, 55);
+  Pan(child1, mcc, 95, 55);
 
   // Check that child1 and child2 are in a FLING state.
   child1->AssertStateIsFling();
   child2->AssertStateIsFling();
 
   // Advance the animations on child1 and child2 until their end.
-  TimeStamp timestamp = TimeStamp::Now();
-  child1->AdvanceAnimationsUntilEnd(timestamp);
-  child2->AdvanceAnimationsUntilEnd(timestamp);
+  child1->AdvanceAnimationsUntilEnd();
+  child2->AdvanceAnimationsUntilEnd();
 
   // Check that the flings have been handed off to the parents.
   child1->AssertStateIsReset();
   parent1->AssertStateIsFling();
   child2->AssertStateIsReset();
   parent2->AssertStateIsFling();
 }
 
 TEST_F(APZOverscrollHandoffTester, Scrollgrab) {
   // Set up the layer tree
   CreateScrollgrabLayerTree();
 
   nsRefPtr<TestAsyncPanZoomController> childApzc = ApzcOf(layers[1]);
 
   // Pan on the child, enough to fully scroll the scrollgrab parent (20 px)
   // and leave some more (another 15 px) for the child.
-  Pan(childApzc, mTime, 80, 45);
+  Pan(childApzc, mcc, 80, 45);
 
   // Check that the parent and child have scrolled as much as we expect.
   EXPECT_EQ(20, rootApzc->GetFrameMetrics().GetScrollOffset().y);
   EXPECT_EQ(15, childApzc->GetFrameMetrics().GetScrollOffset().y);
 }
 
 TEST_F(APZOverscrollHandoffTester, ScrollgrabFling) {
   // Set up the layer tree
   CreateScrollgrabLayerTree();
 
   nsRefPtr<TestAsyncPanZoomController> childApzc = ApzcOf(layers[1]);
 
   // Pan on the child, not enough to fully scroll the scrollgrab parent.
-  Pan(childApzc, mTime, 80, 70);
+  Pan(childApzc, mcc, 80, 70);
 
   // Check that it is the scrollgrab parent that's in a fling, not the child.
   rootApzc->AssertStateIsFling();
   childApzc->AssertStateIsReset();
 }
 
 class APZEventRegionsTester : public APZCTreeManagerTester {
 protected:
@@ -2945,65 +2917,64 @@ TEST_F(APZEventRegionsTester, HitRegionI
     EXPECT_CALL(*mcc, HandleSingleTap(_, _, left->GetGuid())).Times(1);
     EXPECT_CALL(check, Call("Tapped on left this time"));
   }
 
   TimeDuration tapDuration = TimeDuration::FromMilliseconds(100);
 
   // Tap in the exposed hit regions of each of the layers once and ensure
   // the clicks are dispatched right away
-  Tap(manager, 10, 10, mTime, tapDuration);
+  Tap(manager, 10, 10, mcc, tapDuration);
   mcc->RunThroughDelayedTasks();    // this runs the tap event
   check.Call("Tapped on left");
-  Tap(manager, 110, 110, mTime, tapDuration);
+  Tap(manager, 110, 110, mcc, tapDuration);
   mcc->RunThroughDelayedTasks();    // this runs the tap event
   check.Call("Tapped on bottom");
-  Tap(manager, 110, 10, mTime, tapDuration);
+  Tap(manager, 110, 10, mcc, tapDuration);
   mcc->RunThroughDelayedTasks();    // this runs the tap event
   check.Call("Tapped on root");
 
   // Now tap on the dispatch-to-content region where the layers overlap
-  Tap(manager, 10, 110, mTime, tapDuration);
+  Tap(manager, 10, 110, mcc, tapDuration);
   mcc->RunThroughDelayedTasks();    // this runs the main-thread timeout
   check.Call("Tap pending on d-t-c region");
   mcc->RunThroughDelayedTasks();    // this runs the tap event
   check.Call("Tapped on bottom again");
 
   // Now let's do that again, but simulate a main-thread response
   uint64_t inputBlockId = 0;
-  Tap(manager, 10, 110, mTime, tapDuration, nullptr, &inputBlockId);
+  Tap(manager, 10, 110, mcc, tapDuration, nullptr, &inputBlockId);
   nsTArray<ScrollableLayerGuid> targets;
   targets.AppendElement(left->GetGuid());
   manager->SetTargetAPZC(inputBlockId, targets);
   while (mcc->RunThroughDelayedTasks());    // this runs the tap event
   check.Call("Tapped on left this time");
 }
 
 TEST_F(APZEventRegionsTester, HitRegionAccumulatesChildren) {
   CreateEventRegionsLayerTree2();
 
   // Tap in the area of the child layer that's not directly included in the
   // parent layer's hit region. Verify that it comes out of the APZC's
   // content controller, which indicates the input events got routed correctly
   // to the APZC.
   EXPECT_CALL(*mcc, HandleSingleTap(_, _, rootApzc->GetGuid())).Times(1);
-  Tap(manager, 10, 160, mTime, TimeDuration::FromMilliseconds(100));
-  mcc->RunThroughDelayedTasks();    // this runs the tap event
+  Tap(manager, 10, 160, mcc, TimeDuration::FromMilliseconds(100));
 }
 
 TEST_F(APZEventRegionsTester, Obscuration) {
   CreateObscuringLayerTree();
   ScopedLayerTreeRegistration registration(0, root, mcc);
 
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
   TestAsyncPanZoomController* parent = ApzcOf(layers[1]);
   TestAsyncPanZoomController* child = ApzcOf(layers[2]);
 
-  ApzcPanNoFling(parent, mTime, 75, 25);
+  ApzcPanNoFling(parent, mcc, 75, 25);
 
   HitTestResult result;
   nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result);
   EXPECT_EQ(child, hit.get());
   EXPECT_EQ(HitTestResult::HitLayer, result);
 }
 
 TEST_F(APZEventRegionsTester, Bug1119497) {
@@ -3020,25 +2991,24 @@ TEST_F(APZEventRegionsTester, Bug1119497
 TEST_F(APZEventRegionsTester, Bug1117712) {
   CreateBug1117712LayerTree();
 
   TestAsyncPanZoomController* apzc2 = ApzcOf(layers[2]);
 
   // These touch events should hit the dispatch-to-content region of layers[3]
   // and so get queued with that APZC as the tentative target.
   uint64_t inputBlockId = 0;
-  Tap(manager, 55, 5, mTime, TimeDuration::FromMilliseconds(100), nullptr, &inputBlockId);
+  Tap(manager, 55, 5, mcc, TimeDuration::FromMilliseconds(100), nullptr, &inputBlockId);
   // But now we tell the APZ that really it hit layers[2], and expect the tap
   // to be delivered at the correct coordinates.
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(55, 5), 0, apzc2->GetGuid())).Times(1);
 
   nsTArray<ScrollableLayerGuid> targets;
   targets.AppendElement(apzc2->GetGuid());
   manager->SetTargetAPZC(inputBlockId, targets);
-  while (mcc->RunThroughDelayedTasks());    // this runs the tap event
 }
 
 class TaskRunMetrics {
 public:
   TaskRunMetrics()
     : mRunCount(0)
     , mCancelCount(0)
   {}
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -40,17 +40,17 @@ public:
   NS_IMETHOD              GetBounds(IntRect &aRect) override { return GetClientBounds(aRect); }
 
   void* GetNativeData(uint32_t aDataType) override {
     if (aDataType == NS_NATIVE_OPENGL_CONTEXT) {
       mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGB();
       caps.preserve = false;
       caps.bpp16 = false;
       nsRefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
-        gfxIntSize(gCompWidth, gCompHeight), caps, true);
+        IntSize(gCompWidth, gCompHeight), caps, true);
       return context.forget().take();
     }
     return nullptr;
   }
 
   NS_IMETHOD              Create(nsIWidget *aParent,
                                  nsNativeWidget aNativeParent,
                                  const IntRect &aRect,
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -264,36 +264,36 @@ TEST(Layers, TextureSerialization) {
   // the test is run on all the following image formats
   gfxImageFormat formats[3] = {
     gfxImageFormat::ARGB32,
     gfxImageFormat::RGB24,
     gfxImageFormat::A8,
   };
 
   for (int f = 0; f < 3; ++f) {
-    RefPtr<gfxImageSurface> surface = new gfxImageSurface(gfxIntSize(400,300), formats[f]);
+    RefPtr<gfxImageSurface> surface = new gfxImageSurface(IntSize(400,300), formats[f]);
     SetupSurface(surface.get());
     AssertSurfacesEqual(surface, surface);
 
     RefPtr<TextureClient> client
       = new MemoryTextureClient(nullptr,
                                 mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
                                 gfx::BackendType::CAIRO,
                                 TextureFlags::DEALLOCATE_CLIENT);
 
     TestTextureClientSurface(client, surface);
 
     // XXX - Test more texture client types.
   }
 }
 
 TEST(Layers, TextureYCbCrSerialization) {
-  RefPtr<gfxImageSurface> ySurface = new gfxImageSurface(gfxIntSize(400,300), gfxImageFormat::A8);
-  RefPtr<gfxImageSurface> cbSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8);
-  RefPtr<gfxImageSurface> crSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8);
+  RefPtr<gfxImageSurface> ySurface = new gfxImageSurface(IntSize(400,300), gfxImageFormat::A8);
+  RefPtr<gfxImageSurface> cbSurface = new gfxImageSurface(IntSize(200,150), gfxImageFormat::A8);
+  RefPtr<gfxImageSurface> crSurface = new gfxImageSurface(IntSize(200,150), gfxImageFormat::A8);
   SetupSurface(ySurface.get());
   SetupSurface(cbSurface.get());
   SetupSurface(crSurface.get());
 
   PlanarYCbCrData clientData;
   clientData.mYChannel = ySurface->Data();
   clientData.mCbChannel = cbSurface->Data();
   clientData.mCrChannel = crSurface->Data();
--- a/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp
+++ b/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp
@@ -39,17 +39,17 @@ SurfaceDestroyNotifier (void *data) {
     *(int *)data = 1;
 }
 
 int
 TestNewSurface () {
     int failures = 0;
     int destroyed = 0;
 
-    nsRefPtr<gfxASurface> s = new gfxImageSurface (gfxIntSize(10, 10), gfxImageFormat::ARGB32);
+    nsRefPtr<gfxASurface> s = new gfxImageSurface (mozilla::gfx::IntSize(10, 10), gfxImageFormat::ARGB32);
     cairo_surface_t *cs = s->CairoSurface();
 
     cairo_surface_set_user_data (cs, &destruction_key, &destroyed, SurfaceDestroyNotifier);
 
     failures += CheckInt (GetASurfaceRefCount(s.get()), 1);
     failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
     failures += CheckInt (destroyed, 0);
 
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -150,17 +150,17 @@ void
 gfxASurface::SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf)
 {
     if (!csurf)
         return;
     cairo_surface_set_user_data(csurf, &gfxasurface_pointer_key, asurf, SurfaceDestroyFunc);
 }
 
 already_AddRefed<gfxASurface>
-gfxASurface::Wrap (cairo_surface_t *csurf, const gfxIntSize& aSize)
+gfxASurface::Wrap (cairo_surface_t *csurf, const IntSize& aSize)
 {
     nsRefPtr<gfxASurface> result;
 
     /* Do we already have a wrapper for this surface? */
     result = GetSurfaceWrapper(csurf);
     if (result) {
         // fprintf(stderr, "Existing wrapper for %p -> %p\n", csurf, result);
         return result.forget();
@@ -318,17 +318,17 @@ void
 gfxASurface::Finish()
 {
     // null surfaces are allowed here
     cairo_surface_finish(mSurface);
 }
 
 already_AddRefed<gfxASurface>
 gfxASurface::CreateSimilarSurface(gfxContentType aContent,
-                                  const nsIntSize& aSize)
+                                  const IntSize& aSize)
 {
     if (!mSurface || !mSurfaceValid) {
       return nullptr;
     }
     
     cairo_surface_t *surface =
         cairo_surface_create_similar(mSurface, cairo_content_t(int(aContent)),
                                      aSize.width, aSize.height);
@@ -354,17 +354,17 @@ gfxASurface::GetAsReadableARGB32ImageSur
 
 already_AddRefed<gfxImageSurface>
 gfxASurface::CopyToARGB32ImageSurface()
 {
     if (!mSurface || !mSurfaceValid) {
       return nullptr;
     }
 
-    const nsIntSize size = GetSize();
+    const IntSize size = GetSize();
     nsRefPtr<gfxImageSurface> imgSurface =
         new gfxImageSurface(size, gfxImageFormat::ARGB32);
 
     RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(imgSurface, IntSize(size.width, size.height));
     RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, this);
 
     dt->CopySurface(source, IntRect(0, 0, size.width, size.height), IntPoint());
 
@@ -377,17 +377,17 @@ gfxASurface::CairoStatus()
     if (!mSurfaceValid)
         return -1;
 
     return cairo_surface_status(mSurface);
 }
 
 /* static */
 bool
-gfxASurface::CheckSurfaceSize(const nsIntSize& sz, int32_t limit)
+gfxASurface::CheckSurfaceSize(const IntSize& sz, int32_t limit)
 {
     if (sz.width < 0 || sz.height < 0) {
         NS_WARNING("Surface width or height < 0!");
         return false;
     }
 
     // reject images with sides bigger than limit
     if (limit && (sz.width > limit || sz.height > limit)) {
@@ -697,19 +697,19 @@ gfxASurface::SetOpaqueRect(const gfxRect
 
 /* static */const gfxRect&
 gfxASurface::GetEmptyOpaqueRect()
 {
   static const gfxRect empty(0, 0, 0, 0);
   return empty;
 }
 
-const nsIntSize
+const IntSize
 gfxASurface::GetSize() const
 {
-  return nsIntSize(-1, -1);
+  return IntSize(-1, -1);
 }
 
 already_AddRefed<gfxImageSurface>
 gfxASurface::GetAsImageSurface()
 {
   return nullptr;
 }
--- a/gfx/thebes/gfxASurface.h
+++ b/gfx/thebes/gfxASurface.h
@@ -45,17 +45,17 @@ public:
     virtual nsrefcnt Release(void);
 #endif
 
 public:
 
     /** Wrap the given cairo surface and return a gfxASurface for it.
      * This adds a reference to csurf (owned by the returned gfxASurface).
      */
-    static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const gfxIntSize& aSize = gfxIntSize(-1, -1));
+    static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const mozilla::gfx::IntSize& aSize = mozilla::gfx::IntSize(-1, -1));
 
     /*** this DOES NOT addref the surface */
     cairo_surface_t *CairoSurface() {
         return mSurface;
     }
 
     gfxSurfaceType GetType() const;
 
@@ -85,17 +85,17 @@ public:
     virtual void Finish();
 
     /**
      * Create an offscreen surface that can be efficiently copied into
      * this surface (at least if tiling is not involved).
      * Returns null on error.
      */
     virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
-                                                               const nsIntSize& aSize);
+                                                               const mozilla::gfx::IntSize& aSize);
 
     /**
      * Returns an image surface for this surface, or nullptr if not supported.
      * This will not copy image data, just wraps an image surface around
      * pixel data already available in memory.
      */
     virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
 
@@ -113,17 +113,17 @@ public:
     already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface();
 
     int CairoStatus();
 
     /* Make sure that the given dimensions don't overflow a 32-bit signed int
      * using 4 bytes per pixel; optionally, make sure that either dimension
      * doesn't exceed the given limit.
      */
-    static bool CheckSurfaceSize(const nsIntSize& sz, int32_t limit = 0);
+    static bool CheckSurfaceSize(const mozilla::gfx::IntSize& sz, int32_t limit = 0);
 
     /* Provide a stride value that will respect all alignment requirements of
      * the accelerated image-rendering code.
      */
     static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width);
 
     static gfxContentType ContentFromFormat(gfxImageFormat format);
 
@@ -162,17 +162,17 @@ public:
     /**
      * Where does this surface's memory live?  By default, we say it's in this
      * process's heap.
      */
     virtual gfxMemoryLocation GetMemoryLocation() const;
 
     static int32_t BytePerPixelFromFormat(gfxImageFormat format);
 
-    virtual const nsIntSize GetSize() const;
+    virtual const mozilla::gfx::IntSize GetSize() const;
 
     void SetOpaqueRect(const gfxRect& aRect);
 
     const gfxRect& GetOpaqueRect() {
         if (!!mOpaqueRect)
             return *mOpaqueRect;
         return GetEmptyOpaqueRect();
     }
@@ -216,22 +216,22 @@ protected:
     bool mAllowUseAsSource;
 };
 
 /**
  * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo
  */
 class gfxUnknownSurface : public gfxASurface {
 public:
-    gfxUnknownSurface(cairo_surface_t *surf, const gfxIntSize& aSize)
+    gfxUnknownSurface(cairo_surface_t *surf, const mozilla::gfx::IntSize& aSize)
         : mSize(aSize)
     {
         Init(surf, true);
     }
 
     virtual ~gfxUnknownSurface() { }
-    virtual const nsIntSize GetSize() const override { return mSize; }
+    virtual const mozilla::gfx::IntSize GetSize() const override { return mSize; }
 
 private:
-    nsIntSize mSize;
+    mozilla::gfx::IntSize mSize;
 };
 
 #endif /* GFX_ASURFACE_H */
--- a/gfx/thebes/gfxAlphaRecovery.cpp
+++ b/gfx/thebes/gfxAlphaRecovery.cpp
@@ -9,17 +9,17 @@
 
 #define MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE2
 #include "mozilla/SSE.h"
 
 /* static */ bool
 gfxAlphaRecovery::RecoverAlpha(gfxImageSurface* blackSurf,
                                const gfxImageSurface* whiteSurf)
 {
-    gfxIntSize size = blackSurf->GetSize();
+    mozilla::gfx::IntSize size = blackSurf->GetSize();
 
     if (size != whiteSurf->GetSize() ||
         (blackSurf->Format() != gfxImageFormat::ARGB32 &&
          blackSurf->Format() != gfxImageFormat::RGB24) ||
         (whiteSurf->Format() != gfxImageFormat::ARGB32 &&
          whiteSurf->Format() != gfxImageFormat::RGB24))
         return false;
 
--- a/gfx/thebes/gfxAlphaRecoverySSE2.cpp
+++ b/gfx/thebes/gfxAlphaRecoverySSE2.cpp
@@ -25,17 +25,17 @@ static uint32_t alphaMaski[] __attribute
 static uint32_t greenMaski[] = { 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00 };
 static uint32_t alphaMaski[] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000 };
 #endif
 
 bool
 gfxAlphaRecovery::RecoverAlphaSSE2(gfxImageSurface* blackSurf,
                                    const gfxImageSurface* whiteSurf)
 {
-    gfxIntSize size = blackSurf->GetSize();
+    mozilla::gfx::IntSize size = blackSurf->GetSize();
 
     if (size != whiteSurf->GetSize() ||
         (blackSurf->Format() != gfxImageFormat::ARGB32 &&
          blackSurf->Format() != gfxImageFormat::RGB24) ||
         (whiteSurf->Format() != gfxImageFormat::ARGB32 &&
          whiteSurf->Format() != gfxImageFormat::RGB24))
         return false;
 
@@ -182,17 +182,17 @@ gfxAlphaRecovery::AlignRectForSubimageRe
     // ALIGN/BPP constant by using SIMD-ized alpha recovery.  So as
     // w*h diverges from w+h, the win factor approaches ALIGN/BPP.  We
     // only really care about the w*h >> w+h case anyway; others
     // should be fast enough even with the overhead.  (Unless the cost
     // of repainting the expanded rect is high, but in that case
     // SIMD-ized alpha recovery won't make a difference so this code
     // shouldn't be called.)
     //
-    gfxIntSize surfaceSize = aSurface->GetSize();
+    mozilla::gfx::IntSize surfaceSize = aSurface->GetSize();
     const int32_t stride = bpp * surfaceSize.width;
     if (stride != aSurface->Stride()) {
         NS_WARNING("Unexpected stride, falling back on slow alpha recovery");
         return aRect;
     }
 
     const int32_t x = aRect.x, y = aRect.y, w = aRect.width, h = aRect.height;
     const int32_t r = x + w;
--- a/gfx/thebes/gfxBaseSharedMemorySurface.h
+++ b/gfx/thebes/gfxBaseSharedMemorySurface.h
@@ -52,34 +52,34 @@ public:
      * the surface failed.
      *
      * NB: the *caller* is responsible for freeing the Shmem allocated
      * by this function.
      */
     template<class ShmemAllocator>
     static already_AddRefed<Sub>
     Create(ShmemAllocator* aAllocator,
-           const gfxIntSize& aSize,
+           const mozilla::gfx::IntSize& aSize,
            gfxImageFormat aFormat,
            SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
     {
         return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
     }
 
     /**
      * Return a new gfxSharedImageSurface that wraps a shmem segment
      * already created by the Create() above.  Bad things will happen
      * if an attempt is made to wrap any other shmem segment.  Null is
      * returned if creating the surface failed.
      */
     static already_AddRefed<Sub>
     Open(const Shmem& aShmem)
     {
         SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
-        gfxIntSize size(shmInfo->width, shmInfo->height);
+        mozilla::gfx::IntSize size(shmInfo->width, shmInfo->height);
         if (!gfxASurface::CheckSurfaceSize(size))
             return nullptr;
        
         gfxImageFormat format = (gfxImageFormat)shmInfo->format;
         long stride = gfxImageSurface::ComputeStride(size, format);
 
         nsRefPtr<Sub> s =
             new Sub(size,
@@ -88,34 +88,34 @@ public:
                     aShmem);
         // We didn't create this Shmem and so don't free it on errors
         return (s->CairoStatus() != 0) ? nullptr : s.forget();
     }
 
     template<class ShmemAllocator>
     static already_AddRefed<Sub>
     CreateUnsafe(ShmemAllocator* aAllocator,
-                 const gfxIntSize& aSize,
+                 const mozilla::gfx::IntSize& aSize,
                  gfxImageFormat aFormat,
                  SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
     {
         return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
     }
 
     Shmem& GetShmem() { return mShmem; }
 
     static bool IsSharedImage(gfxASurface *aSurface)
     {
         return (aSurface
                 && aSurface->GetType() == gfxSurfaceType::Image
                 && aSurface->GetData(&SHM_KEY));
     }
 
 protected:
-    gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride, 
+    gfxBaseSharedMemorySurface(const mozilla::gfx::IntSize& aSize, long aStride, 
                                gfxImageFormat aFormat, 
                                const Shmem& aShmem)
       : Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
     {
         MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
 
         mShmem = aShmem;
         this->SetData(&SHM_KEY, this, nullptr);
@@ -147,26 +147,26 @@ private:
 
     int32_t
     GetReadCount()
     {
         SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
         return shmInfo->readCount;
     }
 
-    static size_t GetAlignedSize(const gfxIntSize& aSize, long aStride)
+    static size_t GetAlignedSize(const mozilla::gfx::IntSize& aSize, long aStride)
     {
         #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
         return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
     }
 
     template<class ShmemAllocator, bool Unsafe>
     static already_AddRefed<Sub>
     Create(ShmemAllocator* aAllocator,
-           const gfxIntSize& aSize,
+           const mozilla::gfx::IntSize& aSize,
            gfxImageFormat aFormat,
            SharedMemory::SharedMemoryType aShmType)
     {
         if (!gfxASurface::CheckSurfaceSize(aSize))
             return nullptr;
 
         Shmem shmem;
         long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
--- a/gfx/thebes/gfxBlur.cpp
+++ b/gfx/thebes/gfxBlur.cpp
@@ -24,18 +24,18 @@ gfxAlphaBoxBlur::gfxAlphaBoxBlur()
 
 gfxAlphaBoxBlur::~gfxAlphaBoxBlur()
 {
   mContext = nullptr;
 }
 
 gfxContext*
 gfxAlphaBoxBlur::Init(const gfxRect& aRect,
-                      const gfxIntSize& aSpreadRadius,
-                      const gfxIntSize& aBlurRadius,
+                      const IntSize& aSpreadRadius,
+                      const IntSize& aBlurRadius,
                       const gfxRect* aDirtyRect,
                       const gfxRect* aSkipRect)
 {
     mozilla::gfx::Rect rect(Float(aRect.x), Float(aRect.y),
                             Float(aRect.width), Float(aRect.height));
     IntSize spreadRadius(aSpreadRadius.width, aSpreadRadius.height);
     IntSize blurRadius(aBlurRadius.width, aBlurRadius.height);
     UniquePtr<Rect> dirtyRect;
@@ -147,34 +147,34 @@ gfxAlphaBoxBlur::Paint(gfxContext* aDest
     if (!mask) {
       NS_ERROR("Failed to create mask!");
       return;
     }
 
     DrawBlur(aDestinationCtx, mask, topLeft, dirtyRect);
 }
 
-gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
+IntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
 {
     mozilla::gfx::Point std(Float(aStd.x), Float(aStd.y));
     IntSize size = AlphaBoxBlur::CalculateBlurRadius(std);
-    return gfxIntSize(size.width, size.height);
+    return IntSize(size.width, size.height);
 }
 
 struct BlurCacheKey : public PLDHashEntryHdr {
   typedef const BlurCacheKey& KeyType;
   typedef const BlurCacheKey* KeyTypePointer;
   enum { ALLOW_MEMMOVE = true };
 
   gfxRect mRect;
-  gfxIntSize mBlurRadius;
+  IntSize mBlurRadius;
   gfxRect mSkipRect;
   BackendType mBackend;
 
-  BlurCacheKey(const gfxRect& aRect, const gfxIntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend)
+  BlurCacheKey(const gfxRect& aRect, const IntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend)
     : mRect(aRect)
     , mBlurRadius(aBlurRadius)
     , mSkipRect(aSkipRect)
     , mBackend(aBackend)
   { }
 
   explicit BlurCacheKey(const BlurCacheKey* aOther)
     : mRect(aOther->mRect)
@@ -255,17 +255,17 @@ class BlurCache final : public nsExpirat
 
     virtual void NotifyExpired(BlurCacheData* aObject)
     {
       RemoveObject(aObject);
       mHashEntries.Remove(aObject->mKey);
     }
 
     BlurCacheData* Lookup(const gfxRect& aRect,
-                          const gfxIntSize& aBlurRadius,
+                          const IntSize& aBlurRadius,
                           const gfxRect& aSkipRect,
                           BackendType aBackendType,
                           const gfxRect* aDirtyRect)
     {
       BlurCacheData* blur =
         mHashEntries.Get(BlurCacheKey(aRect, aBlurRadius, aSkipRect, aBackendType));
 
       if (blur) {
@@ -304,17 +304,17 @@ class BlurCache final : public nsExpirat
     nsClassHashtable<BlurCacheKey, BlurCacheData> mHashEntries;
 };
 
 static BlurCache* gBlurCache = nullptr;
 
 SourceSurface*
 GetCachedBlur(DrawTarget *aDT,
               const gfxRect& aRect,
-              const gfxIntSize& aBlurRadius,
+              const IntSize& aBlurRadius,
               const gfxRect& aSkipRect,
               const gfxRect& aDirtyRect,
               IntPoint* aTopLeft)
 {
   if (!gBlurCache) {
     gBlurCache = new BlurCache();
   }
   BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect,
@@ -325,17 +325,17 @@ GetCachedBlur(DrawTarget *aDT,
     return cached->mBlur;
   }
   return nullptr;
 }
 
 void
 CacheBlur(DrawTarget *aDT,
           const gfxRect& aRect,
-          const gfxIntSize& aBlurRadius,
+          const IntSize& aBlurRadius,
           const gfxRect& aSkipRect,
           SourceSurface* aBlur,
           const IntPoint& aTopLeft,
           const gfxRect& aDirtyRect)
 {
   // If we already had a cached value with this key, but an incorrect dirty region then just update
   // the existing entry
   if (BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect,
@@ -367,24 +367,24 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContex
                                RectCornerRadii* aCornerRadii,
                                const gfxPoint& aBlurStdDev,
                                const gfxRGBA& aShadowColor,
                                const gfxRect& aDirtyRect,
                                const gfxRect& aSkipRect)
 {
   DrawTarget& aDrawTarget = *aDestinationCtx->GetDrawTarget();
 
-  gfxIntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
+  IntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
 
   IntPoint topLeft;
   RefPtr<SourceSurface> surface = GetCachedBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, aDirtyRect, &topLeft);
   if (!surface) {
     // Create the temporary surface for blurring
     gfxAlphaBoxBlur blur;
-    gfxContext* blurCtx = blur.Init(aRect, gfxIntSize(), blurRadius, &aDirtyRect, &aSkipRect);
+    gfxContext* blurCtx = blur.Init(aRect, IntSize(), blurRadius, &aDirtyRect, &aSkipRect);
     if (!blurCtx) {
       return;
     }
     DrawTarget* blurDT = blurCtx->GetDrawTarget();
 
     Rect shadowGfxRect = ToRect(aRect);
     shadowGfxRect.Round();
 
--- a/gfx/thebes/gfxBlur.h
+++ b/gfx/thebes/gfxBlur.h
@@ -68,18 +68,18 @@ public:
      *  if available. This will be used for optimizing the blur operation. It
      *  is safe to pass nullptr here.
      *
      * @param aSkipRect A pointer to a rect, measured in device units, that
      *  represents an area where blurring is unnecessary and shouldn't be done
      *  for speed reasons. It is safe to pass nullptr here.
      */
     gfxContext* Init(const gfxRect& aRect,
-                     const gfxIntSize& aSpreadRadius,
-                     const gfxIntSize& aBlurRadius,
+                     const mozilla::gfx::IntSize& aSpreadRadius,
+                     const mozilla::gfx::IntSize& aBlurRadius,
                      const gfxRect* aDirtyRect,
                      const gfxRect* aSkipRect);
 
     /**
      * Returns the context that should be drawn to supply the alpha mask to be
      * blurred. If the returned surface is null, then there was an error in
      * its creation.
      */
@@ -101,17 +101,17 @@ public:
     void Paint(gfxContext* aDestinationCtx);
 
     /**
      * Calculates a blur radius that, when used with box blur, approximates
      * a Gaussian blur with the given standard deviation.  The result of
      * this function should be used as the aBlurRadius parameter to Init,
      * above.
      */
-    static gfxIntSize CalculateBlurRadius(const gfxPoint& aStandardDeviation);
+    static mozilla::gfx::IntSize CalculateBlurRadius(const gfxPoint& aStandardDeviation);
 
     /**
      * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent
      * to calling Init(), drawing a rectangle onto the returned surface
      * and then calling Paint, but may let us optimize better in the
      * backend.
      *
      * @param aDestinationCtx      The destination to blur to.
--- a/gfx/thebes/gfxD2DSurface.cpp
+++ b/gfx/thebes/gfxD2DSurface.cpp
@@ -32,17 +32,17 @@ gfxD2DSurface::gfxD2DSurface(ID3D10Textu
         (cairo_content_t)(int)aContent));
 }
 
 gfxD2DSurface::gfxD2DSurface(cairo_surface_t *csurf)
 {
     Init(csurf, true);
 }
 
-gfxD2DSurface::gfxD2DSurface(const gfxIntSize& size,
+gfxD2DSurface::gfxD2DSurface(const mozilla::gfx::IntSize& size,
                              gfxImageFormat imageFormat)
 {
     Init(cairo_d2d_surface_create(
         gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
         (cairo_format_t)(int)imageFormat,
         size.width, size.height));
 }
 
@@ -89,13 +89,13 @@ gfxD2DSurface::ReleaseDC(const mozilla::
     cairo_rectangle_int_t rect;
     rect.x = aUpdatedRect->x;
     rect.y = aUpdatedRect->y;
     rect.width = aUpdatedRect->width;
     rect.height = aUpdatedRect->height;
     cairo_d2d_release_dc(CairoSurface(), &rect);
 }
 
-const gfxIntSize gfxD2DSurface::GetSize() const
+const mozilla::gfx::IntSize gfxD2DSurface::GetSize() const
 { 
-    return gfxIntSize(cairo_d2d_surface_get_width(mSurface),
+    return mozilla::gfx::IntSize(cairo_d2d_surface_get_width(mSurface),
                       cairo_d2d_surface_get_height(mSurface));
 }
\ No newline at end of file
--- a/gfx/thebes/gfxD2DSurface.h
+++ b/gfx/thebes/gfxD2DSurface.h
@@ -14,17 +14,17 @@
 struct ID3D10Texture2D;
 
 class gfxD2DSurface : public gfxASurface {
 public:
 
     gfxD2DSurface(HWND wnd,
                   gfxContentType aContent);
 
-    gfxD2DSurface(const gfxIntSize& size,
+    gfxD2DSurface(const mozilla::gfx::IntSize& size,
                   gfxImageFormat imageFormat = gfxImageFormat::RGB24);
 
     gfxD2DSurface(HANDLE handle, gfxContentType aContent);
 
     gfxD2DSurface(ID3D10Texture2D *texture, gfxContentType aContent);
 
     gfxD2DSurface(cairo_surface_t *csurf);
 
--- a/gfx/thebes/gfxDrawable.cpp
+++ b/gfx/thebes/gfxDrawable.cpp
@@ -14,17 +14,17 @@
 #include "gfxXlibSurface.h"
 #endif
 #include "mozilla/gfx/Logging.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 gfxSurfaceDrawable::gfxSurfaceDrawable(SourceSurface* aSurface,
-                                       const gfxIntSize aSize,
+                                       const IntSize aSize,
                                        const gfxMatrix aTransform)
  : gfxDrawable(aSize)
  , mSourceSurface(aSurface)
  , mTransform(aTransform)
 {
   if (!mSourceSurface) {
     gfxWarning() << "Creating gfxSurfaceDrawable with null SourceSurface";
   }
@@ -106,17 +106,17 @@ gfxSurfaceDrawable::DrawInternal(gfxCont
         dt->FillRect(fillRect, pattern,
                      DrawOptions(aOpacity,
                                  CompositionOpForOp(aContext->CurrentOperator()),
                                  aContext->CurrentAntialiasMode()));
     }
 }
 
 gfxCallbackDrawable::gfxCallbackDrawable(gfxDrawingCallback* aCallback,
-                                         const gfxIntSize aSize)
+                                         const IntSize aSize)
  : gfxDrawable(aSize)
  , mCallback(aCallback)
 {
 }
 
 already_AddRefed<gfxSurfaceDrawable>
 gfxCallbackDrawable::MakeSurfaceDrawable(const GraphicsFilter aFilter)
 {
@@ -157,17 +157,17 @@ gfxCallbackDrawable::Draw(gfxContext* aC
 
     if (mCallback)
         return (*mCallback)(aContext, aFillRect, aFilter, aTransform);
 
     return false;
 }
 
 gfxPatternDrawable::gfxPatternDrawable(gfxPattern* aPattern,
-                                       const gfxIntSize aSize)
+                                       const IntSize aSize)
  : gfxDrawable(aSize)
  , mPattern(aPattern)
 {
 }
 
 gfxPatternDrawable::~gfxPatternDrawable()
 {
 }
--- a/gfx/thebes/gfxDrawable.h
+++ b/gfx/thebes/gfxDrawable.h
@@ -18,17 +18,17 @@ class gfxPattern;
 /**
  * gfxDrawable
  * An Interface representing something that has an intrinsic size and can draw
  * itself repeatedly.
  */
 class gfxDrawable {
     NS_INLINE_DECL_REFCOUNTING(gfxDrawable)
 public:
-    explicit gfxDrawable(const gfxIntSize aSize)
+    explicit gfxDrawable(const mozilla::gfx::IntSize aSize)
      : mSize(aSize) {}
 
     /**
      * Draw into aContext filling aFillRect, possibly repeating, using aFilter.
      * aTransform is a userspace to "image"space matrix. For example, if Draw
      * draws using a gfxPattern, this is the matrix that should be set on the
      * pattern prior to rendering it.
      *  @return whether drawing was successful
@@ -44,32 +44,32 @@ public:
                                       const gfxRect& aSamplingRect,
                                       bool aRepeat,
                                       const GraphicsFilter& aFilter,
                                       gfxFloat aOpacity = 1.0)
     {
         return false;
     }
 
-    virtual gfxIntSize Size() { return mSize; }
+    virtual mozilla::gfx::IntSize Size() { return mSize; }
 
 protected:
     // Protected destructor, to discourage deletion outside of Release():
     virtual ~gfxDrawable() {}
 
-    const gfxIntSize mSize;
+    const mozilla::gfx::IntSize mSize;
 };
 
 /**
  * gfxSurfaceDrawable
  * A convenience implementation of gfxDrawable for surfaces.
  */
 class gfxSurfaceDrawable : public gfxDrawable {
 public:
-    gfxSurfaceDrawable(mozilla::gfx::SourceSurface* aSurface, const gfxIntSize aSize,
+    gfxSurfaceDrawable(mozilla::gfx::SourceSurface* aSurface, const mozilla::gfx::IntSize aSize,
                        const gfxMatrix aTransform = gfxMatrix());
     virtual ~gfxSurfaceDrawable() {}
 
     virtual bool Draw(gfxContext* aContext,
                         const gfxRect& aFillRect,
                         bool aRepeat,
                         const GraphicsFilter& aFilter,
                         gfxFloat aOpacity = 1.0,
@@ -120,17 +120,17 @@ public:
 };
 
 /**
  * gfxCallbackDrawable
  * A convenience implementation of gfxDrawable for callbacks.
  */
 class gfxCallbackDrawable : public gfxDrawable {
 public:
-    gfxCallbackDrawable(gfxDrawingCallback* aCallback, const gfxIntSize aSize);
+    gfxCallbackDrawable(gfxDrawingCallback* aCallback, const mozilla::gfx::IntSize aSize);
     virtual ~gfxCallbackDrawable() {}
 
     virtual bool Draw(gfxContext* aContext,
                         const gfxRect& aFillRect,
                         bool aRepeat,
                         const GraphicsFilter& aFilter,
                         gfxFloat aOpacity = 1.0,
                         const gfxMatrix& aTransform = gfxMatrix());
@@ -144,17 +144,17 @@ protected:
 
 /**
  * gfxPatternDrawable
  * A convenience implementation of gfxDrawable for patterns.
  */
 class gfxPatternDrawable : public gfxDrawable {
 public:
     gfxPatternDrawable(gfxPattern* aPattern,
-                       const gfxIntSize aSize);
+                       const mozilla::gfx::IntSize aSize);
     virtual ~gfxPatternDrawable();
 
     virtual bool Draw(gfxContext* aContext,
                         const gfxRect& aFillRect,
                         bool aRepeat,
                         const GraphicsFilter& aFilter,
                         gfxFloat aOpacity = 1.0,
                         const gfxMatrix& aTransform = gfxMatrix());
--- a/gfx/thebes/gfxGdkNativeRenderer.cpp
+++ b/gfx/thebes/gfxGdkNativeRenderer.cpp
@@ -44,17 +44,17 @@ gfxGdkNativeRenderer::DrawWithXlib(cairo
         clipRect.height = clipRects[0].height;
     }
 
     return DrawWithGDK(drawable, offset.x, offset.y,
                        numClipRects ? &clipRect : nullptr, numClipRects);
 }
 
 void
-gfxGdkNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
+gfxGdkNativeRenderer::Draw(gfxContext* ctx, mozilla::gfx::IntSize size,
                            uint32_t flags, GdkColormap* colormap)
 {
     mColormap = colormap;
 
     Visual* visual =
         gdk_x11_visual_get_xvisual(gdk_colormap_get_visual(colormap));
     Screen* screen =
         gdk_x11_screen_get_xscreen(gdk_colormap_get_screen(colormap));
--- a/gfx/thebes/gfxGdkNativeRenderer.h
+++ b/gfx/thebes/gfxGdkNativeRenderer.h
@@ -63,17 +63,17 @@ public:
 
     /**
      * @param flags see above
      * @param bounds Draw()'s drawing is guaranteed to be restricted to
      * the rectangle (offset.x,offset.y,bounds.width,bounds.height)
      * @param dpy a display to use for the drawing if ctx doesn't have one
      */
 #if (MOZ_WIDGET_GTK == 2)
-    void Draw(gfxContext* ctx, nsIntSize size,
+    void Draw(gfxContext* ctx, mozilla::gfx::IntSize size,
               uint32_t flags, GdkColormap* colormap);
 #endif
 
 private:
 #ifdef MOZ_X11
     // for gfxXlibNativeRenderer:
     virtual nsresult DrawWithXlib(cairo_surface_t* surface,
                                   nsIntPoint offset,
--- a/gfx/thebes/gfxImageSurface.cpp
+++ b/gfx/thebes/gfxImageSurface.cpp
@@ -34,32 +34,32 @@ gfxImageSurface::InitFromSurface(cairo_s
     mData = cairo_image_surface_get_data(csurf);
     mFormat = (gfxImageFormat) cairo_image_surface_get_format(csurf);
     mOwnsData = false;
     mStride = cairo_image_surface_get_stride(csurf);
 
     Init(csurf, true);
 }
 
-gfxImageSurface::gfxImageSurface(unsigned char *aData, const gfxIntSize& aSize,
+gfxImageSurface::gfxImageSurface(unsigned char *aData, const IntSize& aSize,
                                  long aStride, gfxImageFormat aFormat)
 {
     InitWithData(aData, aSize, aStride, aFormat);
 }
 
 void
 gfxImageSurface::MakeInvalid()
 {
-    mSize = gfxIntSize(-1, -1);
+    mSize = IntSize(-1, -1);
     mData = nullptr;
     mStride = 0;
 }
 
 void
-gfxImageSurface::InitWithData(unsigned char *aData, const gfxIntSize& aSize,
+gfxImageSurface::InitWithData(unsigned char *aData, const IntSize& aSize,
                               long aStride, gfxImageFormat aFormat)
 {
     mSize = aSize;
     mOwnsData = false;
     mData = aData;
     mFormat = aFormat;
     mStride = aStride;
 
@@ -94,17 +94,17 @@ TryAllocAlignedBytes(size_t aSize)
                               aSize) ?
              nullptr : ptr;
 #else
     // Oh well, hope that luck is with us in the allocator
     return malloc(aSize);
 #endif
 }
 
-gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format, bool aClear)
+gfxImageSurface::gfxImageSurface(const IntSize& size, gfxImageFormat format, bool aClear)
  : mSize(size), mData(nullptr), mFormat(format)
 {
     AllocateAndInit(0, 0, aClear);
 }
 
 void 
 gfxImageSurface::AllocateAndInit(long aStride, int32_t aMinimalAllocation,
                                  bool aClear)
@@ -145,17 +145,17 @@ gfxImageSurface::AllocateAndInit(long aS
     Init(surface);
 
     if (mSurfaceValid) {
         RecordMemoryUsed(mSize.height * ComputeStride() +
                          sizeof(gfxImageSurface));
     }
 }
 
-gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format,
+gfxImageSurface::gfxImageSurface(const IntSize& size, gfxImageFormat format,
                                  long aStride, int32_t aExtraBytes, bool aClear)
  : mSize(size), mData(nullptr), mFormat(format)
 {
     AllocateAndInit(aStride, aExtraBytes, aClear);
 }
 
 gfxImageSurface::gfxImageSurface(cairo_surface_t *csurf)
 {
@@ -171,17 +171,17 @@ gfxImageSurface::gfxImageSurface(cairo_s
 
 gfxImageSurface::~gfxImageSurface()
 {
     if (mOwnsData)
         free(mData);
 }
 
 /*static*/ long
-gfxImageSurface::ComputeStride(const gfxIntSize& aSize, gfxImageFormat aFormat)
+gfxImageSurface::ComputeStride(const IntSize& aSize, gfxImageFormat aFormat)
 {
     long stride;
 
     if (aFormat == gfxImageFormat::ARGB32)
         stride = aSize.width * 4;
     else if (aFormat == gfxImageFormat::RGB24)
         stride = aSize.width * 4;
     else if (aFormat == gfxImageFormat::RGB16_565)
@@ -219,17 +219,17 @@ gfxImageSurface::SizeOfIncludingThis(moz
 bool
 gfxImageSurface::SizeOfIsMeasured() const
 {
     return true;
 }
 
 // helper function for the CopyFrom methods
 static void
-CopyForStride(unsigned char* aDest, unsigned char* aSrc, const gfxIntSize& aSize, long aDestStride, long aSrcStride)
+CopyForStride(unsigned char* aDest, unsigned char* aSrc, const IntSize& aSize, long aDestStride, long aSrcStride)
 {
     if (aDestStride == aSrcStride) {
         memcpy (aDest, aSrc, aSrcStride * aSize.height);
     } else {
         int lineSize = std::min(aDestStride, aSrcStride);
         for (int i = 0; i < aSize.height; i++) {
             unsigned char* src = aSrc + aSrcStride * i;
             unsigned char* dst = aDest + aDestStride * i;
@@ -258,17 +258,17 @@ bool
 gfxImageSurface::CopyFrom (SourceSurface *aSurface)
 {
     mozilla::RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
 
     if (!data) {
         return false;
     }
 
-    gfxIntSize size(data->GetSize().width, data->GetSize().height);
+    IntSize size(data->GetSize().width, data->GetSize().height);
     if (size != mSize) {
         return false;
     }
 
     if (!FormatsAreCompatible(SurfaceFormatToImageFormat(aSurface->GetFormat()),
                               mFormat)) {
         return false;
     }
@@ -298,17 +298,17 @@ gfxImageSurface::CopyFrom(gfxImageSurfac
 bool
 gfxImageSurface::CopyTo(SourceSurface *aSurface) {
     mozilla::RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
 
     if (!data) {
         return false;
     }
 
-    gfxIntSize size(data->GetSize().width, data->GetSize().height);
+    IntSize size(data->GetSize().width, data->GetSize().height);
     if (size != mSize) {
         return false;
     }
 
     if (!FormatsAreCompatible(SurfaceFormatToImageFormat(aSurface->GetFormat()),
                               mFormat)) {
         return false;
     }
@@ -345,25 +345,25 @@ gfxImageSurface::GetSubimage(const gfxRe
 
     if (format == gfxImageFormat::ARGB32 &&
         GetOpaqueRect().Contains(aRect)) {
         format = gfxImageFormat::RGB24;
     }
 
     nsRefPtr<gfxSubimageSurface> image =
         new gfxSubimageSurface(this, subData,
-                               gfxIntSize((int)r.Width(), (int)r.Height()),
+                               IntSize((int)r.Width(), (int)r.Height()),
                                format);
 
     return image.forget();
 }
 
 gfxSubimageSurface::gfxSubimageSurface(gfxImageSurface* aParent,
                                        unsigned char* aData,
-                                       const gfxIntSize& aSize,
+                                       const IntSize& aSize,
                                        gfxImageFormat aFormat)
   : gfxImageSurface(aData, aSize, aParent->Stride(), aFormat)
   , mParent(aParent)
 {
 }
 
 already_AddRefed<gfxImageSurface>
 gfxImageSurface::GetAsImageSurface()
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -34,54 +34,54 @@ public:
      * Construct an image surface around an existing buffer of image data.
      * @param aData A buffer containing the image data
      * @param aSize The size of the buffer
      * @param aStride The stride of the buffer
      * @param format Format of the data
      *
      * @see gfxImageFormat
      */
-    gfxImageSurface(unsigned char *aData, const gfxIntSize& aSize,
+    gfxImageSurface(unsigned char *aData, const mozilla::gfx::IntSize& aSize,
                     long aStride, gfxImageFormat aFormat);
 
     /**
      * Construct an image surface.
      * @param aSize The size of the buffer
      * @param format Format of the data
      *
      * @see gfxImageFormat
      */
-    gfxImageSurface(const gfxIntSize& size, gfxImageFormat format, bool aClear = true);
+    gfxImageSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format, bool aClear = true);
 
     /**
      * Construct an image surface, with a specified stride and allowing the
      * allocation of more memory than required for the storage of the surface
      * itself.  When aStride and aMinimalAllocation are <=0, this constructor
      * is the equivalent of the preceeding one.
      *
      * @param format Format of the data
      * @param aSize The size of the buffer
      * @param aStride The stride of the buffer - if <=0, use ComputeStride()
      * @param aMinimalAllocation Allocate at least this many bytes.  If smaller
      *        than width * stride, or width*stride <=0, this value is ignored.
      * @param aClear 
      *
      * @see gfxImageFormat
      */
-    gfxImageSurface(const gfxIntSize& aSize, gfxImageFormat aFormat,
+    gfxImageSurface(const mozilla::gfx::IntSize& aSize, gfxImageFormat aFormat,
                     long aStride, int32_t aMinimalAllocation, bool aClear);
 
     explicit gfxImageSurface(cairo_surface_t *csurf);
 
     virtual ~gfxImageSurface();
 
     // ImageSurface methods
     gfxImageFormat Format() const { return mFormat; }
 
-    virtual const gfxIntSize GetSize() const override { return mSize; }
+    virtual const mozilla::gfx::IntSize GetSize() const override { return mSize; }
     int32_t Width() const { return mSize.width; }
     int32_t Height() const { return mSize.height; }
 
     /**
      * Distance in bytes between the start of a line and the start of the
      * next line.
      */
     int32_t Stride() const { return mStride; }
@@ -119,52 +119,52 @@ public:
     /* return new Subimage with pointing to original image starting from aRect.pos
      * and size of aRect.size. New subimage keeping current image reference
      */
     already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
 
     virtual already_AddRefed<gfxImageSurface> GetAsImageSurface() override;
 
     /** See gfxASurface.h. */
-    static long ComputeStride(const gfxIntSize&, gfxImageFormat);
+    static long ComputeStride(const mozilla::gfx::IntSize&, gfxImageFormat);
 
     virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
         override;
     virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
         override;
     virtual bool SizeOfIsMeasured() const override;
 
 protected:
     gfxImageSurface();
-    void InitWithData(unsigned char *aData, const gfxIntSize& aSize,
+    void InitWithData(unsigned char *aData, const mozilla::gfx::IntSize& aSize,
                       long aStride, gfxImageFormat aFormat);
     /**
      * See the parameters to the matching constructor.  This should only
      * be called once, in the constructor, which has already set mSize
      * and mFormat.
      */
     void AllocateAndInit(long aStride, int32_t aMinimalAllocation, bool aClear);
     void InitFromSurface(cairo_surface_t *csurf);
 
     long ComputeStride() const { return ComputeStride(mSize, mFormat); }
 
 
     void MakeInvalid();
 
-    gfxIntSize mSize;
+    mozilla::gfx::IntSize mSize;
     bool mOwnsData;
     unsigned char *mData;
     gfxImageFormat mFormat;
     long mStride;
 };
 
 class gfxSubimageSurface : public gfxImageSurface {
 protected:
     friend class gfxImageSurface;
     gfxSubimageSurface(gfxImageSurface* aParent,
                        unsigned char* aData,
-                       const gfxIntSize& aSize,
+                       const mozilla::gfx::IntSize& aSize,
                        gfxImageFormat aFormat);
 private:
     nsRefPtr<gfxImageSurface> mParent;
 };
 
 #endif /* GFX_IMAGESURFACE_H */
--- a/gfx/thebes/gfxPDFSurface.h
+++ b/gfx/thebes/gfxPDFSurface.h
@@ -24,19 +24,19 @@ public:
     virtual nsresult BeginPage();
     virtual nsresult EndPage();
     virtual void Finish();
 
     void SetDPI(double x, double y);
     void GetDPI(double *xDPI, double *yDPI);
 
     // this is in points!
-    virtual const gfxIntSize GetSize() const
+    virtual const mozilla::gfx::IntSize GetSize() const
     {
-        return gfxIntSize(mSize.width, mSize.height);
+        return mozilla::gfx::IntSize(mSize.width, mSize.height);
     }
 
 private:
     nsCOMPtr<nsIOutputStream> mStream;
     double mXDPI;
     double mYDPI;
     gfxSize mSize;
 };
--- a/gfx/thebes/gfxPSSurface.cpp
+++ b/gfx/thebes/gfxPSSurface.cpp
@@ -20,28 +20,28 @@ write_func(void *closure, const unsigned
     } while (length > 0);
     NS_ASSERTION(length == 0, "not everything was written to the file");
     return CAIRO_STATUS_SUCCESS;
 }
 
 gfxPSSurface::gfxPSSurface(nsIOutputStream *aStream, const gfxSize& aSizeInPoints, PageOrientation aOrientation)
     : mStream(aStream), mXDPI(-1), mYDPI(-1), mOrientation(aOrientation)
 {
-    mSize = gfxIntSize(aSizeInPoints.width, aSizeInPoints.height);
+    mSize = mozilla::gfx::IntSize(aSizeInPoints.width, aSizeInPoints.height);
 
     // The PS output does not specify the page size so to print
     // landscape we need to rotate the drawing 90 degrees and print on
     // portrait paper. If printing landscape, swap the width/height
     // supplied to cairo to select a portrait print area. gfxContext
     // will perform the rotation when GetRotateForLandscape() is TRUE.
-    gfxIntSize cairoSize;
+    mozilla::gfx::IntSize cairoSize;
     if (mOrientation == PORTRAIT) {
         cairoSize = mSize;
     } else {
-        cairoSize = gfxIntSize(mSize.height, mSize.width);
+        cairoSize = mozilla::gfx::IntSize(mSize.height, mSize.width);
     }
     cairo_surface_t* ps_surface = cairo_ps_surface_create_for_stream(write_func, (void*)mStream, cairoSize.width, cairoSize.height);
     cairo_ps_surface_restrict_to_level(ps_surface, CAIRO_PS_LEVEL_2);
     Init(ps_surface);
 }
 
 gfxPSSurface::~gfxPSSurface()
 {
--- a/gfx/thebes/gfxPSSurface.h
+++ b/gfx/thebes/gfxPSSurface.h
@@ -31,22 +31,22 @@ public:
     virtual void Finish();
 
     void SetDPI(double x, double y);
     void GetDPI(double *xDPI, double *yDPI);
 
     virtual bool GetRotateForLandscape() { return (mOrientation == LANDSCAPE); }
 
     // this is in points!
-    virtual const gfxIntSize GetSize() const
+    virtual const mozilla::gfx::IntSize GetSize() const
     {
         return mSize;
     }
 
 private:
     nsCOMPtr<nsIOutputStream> mStream;
     double mXDPI;
     double mYDPI;
-    gfxIntSize mSize;
+    mozilla::gfx::IntSize mSize;
     PageOrientation mOrientation;
 };
 
 #endif /* GFX_PSSURFACE_H */
--- a/gfx/thebes/gfxPoint.h
+++ b/gfx/thebes/gfxPoint.h
@@ -14,17 +14,17 @@
 
 #include "gfxTypes.h"
 
 struct gfxSize : public mozilla::gfx::BaseSize<gfxFloat, gfxSize> {
     typedef mozilla::gfx::BaseSize<gfxFloat, gfxSize> Super;
 
     gfxSize() : Super() {}
     gfxSize(gfxFloat aWidth, gfxFloat aHeight) : Super(aWidth, aHeight) {}
-    MOZ_IMPLICIT gfxSize(const nsIntSize& aSize) : Super(aSize.width, aSize.height) {}
+    MOZ_IMPLICIT gfxSize(const mozilla::gfx::IntSize& aSize) : Super(aSize.width, aSize.height) {}
 };
 
 struct gfxPoint : public mozilla::gfx::BasePoint<gfxFloat, gfxPoint> {
     typedef mozilla::gfx::BasePoint<gfxFloat, gfxPoint> Super;
 
     gfxPoint() : Super() {}
     gfxPoint(gfxFloat aX, gfxFloat aY) : Super(aX, aY) {}
     MOZ_IMPLICIT gfxPoint(const nsIntPoint& aPoint) : Super(aPoint.x, aPoint.y) {}
--- a/gfx/thebes/gfxQPainterSurface.cpp
+++ b/gfx/thebes/gfxQPainterSurface.cpp
@@ -14,27 +14,27 @@ gfxQPainterSurface::gfxQPainterSurface(Q
 {
     cairo_surface_t *csurf = cairo_qt_surface_create (painter);
 
     mPainter = painter;
 
     Init (csurf);
 }
 
-gfxQPainterSurface::gfxQPainterSurface(const gfxIntSize& size, gfxImageFormat format)
+gfxQPainterSurface::gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format)
 {
     cairo_surface_t *csurf = cairo_qt_surface_create_with_qimage ((cairo_format_t) format,
                                                                         size.width,
                                                                         size.height);
     mPainter = cairo_qt_surface_get_qpainter (csurf);
 
     Init (csurf);
 }
 
-gfxQPainterSurface::gfxQPainterSurface(const gfxIntSize& size, gfxContentType content)
+gfxQPainterSurface::gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxContentType content)
 {
     cairo_surface_t *csurf = cairo_qt_surface_create_with_qpixmap ((cairo_content_t) content,
                                                                          size.width,
                                                                          size.height);
     mPainter = cairo_qt_surface_get_qpainter (csurf);
 
     Init (csurf);
 }
--- a/gfx/thebes/gfxQPainterSurface.h
+++ b/gfx/thebes/gfxQPainterSurface.h
@@ -13,18 +13,18 @@
 #ifdef CAIRO_HAS_QT_SURFACE
 
 class QPainter;
 class QImage;
 
 class gfxQPainterSurface : public gfxASurface {
 public:
     gfxQPainterSurface(QPainter *painter);
-    gfxQPainterSurface(const gfxIntSize& size, gfxImageFormat format);
-    gfxQPainterSurface(const gfxIntSize& size, gfxContentType content);
+    gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format);
+    gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxContentType content);
 
     gfxQPainterSurface(cairo_surface_t *csurf);
 
     virtual ~gfxQPainterSurface();
 
     QPainter *GetQPainter() { return mPainter; }
 
     QImage *GetQImage();
--- a/gfx/thebes/gfxQtNativeRenderer.cpp
+++ b/gfx/thebes/gfxQtNativeRenderer.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxQtNativeRenderer.h"
 #include "gfxContext.h"
 #include "gfxUtils.h"
 #include "gfxXlibSurface.h"
 
 nsresult
-gfxQtNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
+gfxQtNativeRenderer::Draw(gfxContext* ctx, mozilla::gfx::IntSize size,
                           uint32_t flags, Screen* screen, Visual* visual)
 {
     Display *dpy = DisplayOfScreen(screen);
     bool isOpaque = (flags & DRAW_IS_OPAQUE) ? true : false;
     int screenNumber = screen - ScreenOfDisplay(dpy, 0);
 
     if (!isOpaque) {
         int depth = 32;
@@ -25,17 +25,17 @@ gfxQtNativeRenderer::Draw(gfxContext* ct
         if (!foundVisual)
             return NS_ERROR_FAILURE;
 
         visual = vinfo.visual;
     }
 
     nsRefPtr<gfxXlibSurface> xsurf =
         gfxXlibSurface::Create(screen, visual,
-                               gfxIntSize(size.width, size.height));
+                               mozilla::gfx::IntSize(size.width, size.height));
 
     if (!isOpaque) {
         gfxUtils::ClearThebesSurface(xsurf);
     }
 
     nsresult rv = DrawWithXlib(xsurf->CairoSurface(), nsIntPoint(0, 0), nullptr, 0);
 
     if (NS_FAILED(rv))
--- a/gfx/thebes/gfxQtNativeRenderer.h
+++ b/gfx/thebes/gfxQtNativeRenderer.h
@@ -57,13 +57,13 @@ public:
      * @param size Draw()'s drawing is guaranteed to be restricted to
      * the rectangle (offset.x,offset.y,size.width,size.height)
      * @param dpy a display to use for the drawing if ctx doesn't have one
      * @param resultSurface if non-null, we will try to capture a copy of the
      * rendered image into a surface similar to the surface of ctx; if
      * successful, a pointer to the new gfxASurface is stored in *resultSurface,
      * otherwise *resultSurface is set to nullptr.
      */
-    nsresult Draw(gfxContext* ctx, nsIntSize size,
+    nsresult Draw(gfxContext* ctx, mozilla::gfx::IntSize size,
                   uint32_t flags, Screen* screen, Visual* visual);
 };
 
 #endif /*GFXQTNATIVERENDER_H_*/
--- a/gfx/thebes/gfxQtPlatform.cpp
+++ b/gfx/thebes/gfxQtPlatform.cpp
@@ -90,17 +90,17 @@ gfxQtPlatform::GetXScreen(QWindow* aWind
 
 already_AddRefed<gfxASurface>
 gfxQtPlatform::CreateOffscreenSurface(const IntSize& size,
                                       gfxContentType contentType)
 {
     gfxImageFormat imageFormat = OptimalFormatForContent(contentType);
 
     nsRefPtr<gfxASurface> newSurface =
-        new gfxImageSurface(gfxIntSize(size.width, size.height), imageFormat);
+        new gfxImageSurface(size, imageFormat);
 
     return newSurface.forget();
 }
 
 nsresult
 gfxQtPlatform::GetFontList(nsIAtom *aLangGroup,
                            const nsACString& aGenericFamily,
                            nsTArray<nsString>& aListOfFonts)
--- a/gfx/thebes/gfxQuartzImageSurface.cpp
+++ b/gfx/thebes/gfxQuartzImageSurface.cpp
@@ -23,30 +23,30 @@ gfxQuartzImageSurface::gfxQuartzImageSur
     Init (csurf, true);
     mSize = ComputeSize();
 }
 
 gfxQuartzImageSurface::~gfxQuartzImageSurface()
 {
 }
 
-gfxIntSize
+mozilla::gfx::IntSize
 gfxQuartzImageSurface::ComputeSize()
 {
   if (mSurfaceValid) {
     cairo_surface_t* isurf = cairo_quartz_image_surface_get_image(mSurface);
     if (isurf) {
-      return gfxIntSize(cairo_image_surface_get_width(isurf),
-                        cairo_image_surface_get_height(isurf));
+      return mozilla::gfx::IntSize(cairo_image_surface_get_width(isurf),
+                                   cairo_image_surface_get_height(isurf));
     }
   }
 
   // If we reach here then something went wrong. Just use the same default
   // value as gfxASurface::GetSize.
-  return gfxIntSize(-1, -1);
+  return mozilla::gfx::IntSize(-1, -1);
 }
 
 int32_t
 gfxQuartzImageSurface::KnownMemoryUsed()
 {
   // This surface doesn't own any memory itself, but we want to report here the
   // amount of memory that the surface it wraps uses.
   nsRefPtr<gfxImageSurface> imgSurface = GetAsImageSurface();
--- a/gfx/thebes/gfxQuartzImageSurface.h
+++ b/gfx/thebes/gfxQuartzImageSurface.h
@@ -15,18 +15,18 @@ class gfxQuartzImageSurface : public gfx
 public:
     explicit gfxQuartzImageSurface(gfxImageSurface *imageSurface);
     explicit gfxQuartzImageSurface(cairo_surface_t *csurf);
 
     virtual ~gfxQuartzImageSurface();
 
     already_AddRefed<gfxImageSurface> GetAsImageSurface();
     virtual int32_t KnownMemoryUsed();
-    virtual const gfxIntSize GetSize() const { return gfxIntSize(mSize.width, mSize.height); }
+    virtual const mozilla::gfx::IntSize GetSize() const { return mSize; }
 
 protected:
-    gfxIntSize mSize;
+    mozilla::gfx::IntSize mSize;
 
 private:
-    gfxIntSize ComputeSize();
+    mozilla::gfx::IntSize ComputeSize();
 };
 
 #endif /* GFX_QUARTZIMAGESURFACE_H */
--- a/gfx/thebes/gfxQuartzSurface.cpp
+++ b/gfx/thebes/gfxQuartzSurface.cpp
@@ -7,23 +7,23 @@
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 
 #include "cairo-quartz.h"
 
 void
 gfxQuartzSurface::MakeInvalid()
 {
-    mSize = gfxIntSize(-1, -1);    
+    mSize = mozilla::gfx::IntSize(-1, -1);
 }
 
 gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format)
     : mCGContext(nullptr), mSize(desiredSize)
 {
-    gfxIntSize size((unsigned int) floor(desiredSize.width),
+    mozilla::gfx::IntSize size((unsigned int) floor(desiredSize.width),
                     (unsigned int) floor(desiredSize.height));
     if (!CheckSurfaceSize(size))
         MakeInvalid();
 
     unsigned int width = static_cast<unsigned int>(mSize.width);
     unsigned int height = static_cast<unsigned int>(mSize.height);
 
     cairo_surface_t *surf = cairo_quartz_surface_create
@@ -38,17 +38,17 @@ gfxQuartzSurface::gfxQuartzSurface(const
       RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
     }
 }
 
 gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
                                    const gfxSize& desiredSize)
     : mCGContext(context), mSize(desiredSize)
 {
-    gfxIntSize size((unsigned int) floor(desiredSize.width),
+    mozilla::gfx::IntSize size((unsigned int) floor(desiredSize.width),
                     (unsigned int) floor(desiredSize.height));
     if (!CheckSurfaceSize(size))
         MakeInvalid();
 
     unsigned int width = static_cast<unsigned int>(mSize.width);
     unsigned int height = static_cast<unsigned int>(mSize.height);
 
     cairo_surface_t *surf =
@@ -59,17 +59,17 @@ gfxQuartzSurface::gfxQuartzSurface(CGCon
 
     Init(surf);
     if (mSurfaceValid) {
       RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
     }
 }
 
 gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
-                                   const gfxIntSize& size)
+                                   const mozilla::gfx::IntSize& size)
     : mCGContext(context), mSize(size)
 {
     if (!CheckSurfaceSize(size))
         MakeInvalid();
 
     unsigned int width = static_cast<unsigned int>(mSize.width);
     unsigned int height = static_cast<unsigned int>(mSize.height);
 
@@ -81,32 +81,32 @@ gfxQuartzSurface::gfxQuartzSurface(CGCon
 
     Init(surf);
     if (mSurfaceValid) {
       RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
     }
 }
 
 gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf,
-                                   const gfxIntSize& aSize) :
+                                   const mozilla::gfx::IntSize& aSize) :
     mSize(aSize)
 {
     mCGContext = cairo_quartz_surface_get_cg_context (csurf);
     CGContextRetain (mCGContext);
 
     Init(csurf, true);
 }
 
 gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
                                    const gfxSize& desiredSize,
                                    long stride,
                                    gfxImageFormat format)
     : mCGContext(nullptr), mSize(desiredSize)
 {
-    gfxIntSize size((unsigned int) floor(desiredSize.width),
+    mozilla::gfx::IntSize size((unsigned int) floor(desiredSize.width),
                     (unsigned int) floor(desiredSize.height));
     if (!CheckSurfaceSize(size))
         MakeInvalid();
 
     unsigned int width = static_cast<unsigned int>(mSize.width);
     unsigned int height = static_cast<unsigned int>(mSize.height);
 
     cairo_surface_t *surf = cairo_quartz_surface_create_for_data
@@ -118,17 +118,17 @@ gfxQuartzSurface::gfxQuartzSurface(unsig
 
     Init(surf);
     if (mSurfaceValid) {
       RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
     }
 }
 
 gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
-                                   const gfxIntSize& aSize,
+                                   const mozilla::gfx::IntSize& aSize,
                                    long stride,
                                    gfxImageFormat format)
     : mCGContext(nullptr), mSize(aSize.width, aSize.height)
 {
     if (!CheckSurfaceSize(aSize))
         MakeInvalid();
 
     cairo_surface_t *surf = cairo_quartz_surface_create_for_data
@@ -141,17 +141,17 @@ gfxQuartzSurface::gfxQuartzSurface(unsig
     Init(surf);
     if (mSurfaceValid) {
       RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
     }
 }
 
 already_AddRefed<gfxASurface>
 gfxQuartzSurface::CreateSimilarSurface(gfxContentType aType,
-                                       const gfxIntSize& aSize)
+                                       const mozilla::gfx::IntSize& aSize)
 {
     cairo_surface_t *surface =
         cairo_quartz_surface_create_cg_layer(mSurface, (cairo_content_t)aType,
                                              aSize.width, aSize.height);
     if (cairo_surface_status(surface)) {
         cairo_surface_destroy(surface);
         return nullptr;
     }
--- a/gfx/thebes/gfxQuartzSurface.h
+++ b/gfx/thebes/gfxQuartzSurface.h
@@ -14,27 +14,27 @@
 
 class gfxContext;
 class gfxImageSurface;
 
 class gfxQuartzSurface : public gfxASurface {
 public:
     gfxQuartzSurface(const gfxSize& size, gfxImageFormat format);
     gfxQuartzSurface(CGContextRef context, const gfxSize& size);
-    gfxQuartzSurface(CGContextRef context, const gfxIntSize& size);
-    gfxQuartzSurface(cairo_surface_t *csurf, const gfxIntSize& aSize);
+    gfxQuartzSurface(CGContextRef context, const mozilla::gfx::IntSize& size);
+    gfxQuartzSurface(cairo_surface_t *csurf, const mozilla::gfx::IntSize& aSize);
     gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format);
-    gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format);
+    gfxQuartzSurface(unsigned char *data, const mozilla::gfx::IntSize& size, long stride, gfxImageFormat format);
 
     virtual ~gfxQuartzSurface();
 
     virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
-                                                               const gfxIntSize& aSize);
+                                                               const mozilla::gfx::IntSize& aSize);
 
-    virtual const gfxIntSize GetSize() const { return gfxIntSize(mSize.width, mSize.height); }
+    virtual const mozilla::gfx::IntSize GetSize() const { return mozilla::gfx::IntSize(mSize.width, mSize.height); }
 
     CGContextRef GetCGContext() { return mCGContext; }
 
     CGContextRef GetCGContextWithClip(gfxContext *ctx);
 
     already_AddRefed<gfxImageSurface> GetAsImageSurface();
 
 protected:
--- a/gfx/thebes/gfxSharedImageSurface.h
+++ b/gfx/thebes/gfxSharedImageSurface.h
@@ -9,16 +9,16 @@
 
 #include "gfxBaseSharedMemorySurface.h"
 
 class gfxSharedImageSurface : public gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>
 {
   typedef gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface> Super;
   friend class gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>;
 private:
-    gfxSharedImageSurface(const gfxIntSize& aSize, long aStride, 
-                          gfxImageFormat aFormat, 
+    gfxSharedImageSurface(const mozilla::gfx::IntSize& aSize, long aStride,
+                          gfxImageFormat aFormat,
                           const mozilla::ipc::Shmem& aShmem)
       : Super(aSize, aStride, aFormat, aShmem)
     {}
 };
 
 #endif /* GFX_SHARED_IMAGESURFACE_H */
--- a/gfx/thebes/gfxSharedQuartzSurface.h
+++ b/gfx/thebes/gfxSharedQuartzSurface.h
@@ -10,16 +10,16 @@
 #include "gfxBaseSharedMemorySurface.h"
 #include "gfxQuartzSurface.h"
 
 class gfxSharedQuartzSurface : public gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface>
 {
   typedef gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface> Super;
   friend class gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface>;
 private:
-    gfxSharedQuartzSurface(const gfxIntSize& aSize, long aStride, 
-                           gfxImageFormat aFormat, 
+    gfxSharedQuartzSurface(const mozilla::gfx::IntSize& aSize, long aStride,
+                           gfxImageFormat aFormat,
                            const mozilla::ipc::Shmem& aShmem)
       : Super(aSize, aStride, aFormat, aShmem)
     {}
 };
 
 #endif /* GFX_SHARED_QUARTZSURFACE_H */
--- a/gfx/thebes/gfxTeeSurface.cpp
+++ b/gfx/thebes/gfxTeeSurface.cpp
@@ -20,17 +20,17 @@ gfxTeeSurface::gfxTeeSurface(gfxASurface
     cairo_surface_t *csurf = cairo_tee_surface_create(aSurfaces[0]->CairoSurface());
     Init(csurf, false);
 
     for (int32_t i = 1; i < aSurfaceCount; ++i) {
         cairo_tee_surface_add(csurf, aSurfaces[i]->CairoSurface());
     }
 }
 
-const gfxIntSize
+const mozilla::gfx::IntSize
 gfxTeeSurface::GetSize() const
 {
     nsRefPtr<gfxASurface> master = Wrap(cairo_tee_surface_index(mSurface, 0));
     return master->GetSize();
 }
 
 void
 gfxTeeSurface::GetSurfaces(nsTArray<nsRefPtr<gfxASurface> >* aSurfaces)
--- a/gfx/thebes/gfxTeeSurface.h
+++ b/gfx/thebes/gfxTeeSurface.h
@@ -21,17 +21,17 @@ template<class T> class nsRefPtr;
  * underlying surfaces --- which also applies the device transforms of the
  * underlying surfaces.
  */
 class gfxTeeSurface : public gfxASurface {
 public:
     explicit gfxTeeSurface(cairo_surface_t *csurf);
     gfxTeeSurface(gfxASurface **aSurfaces, int32_t aSurfaceCount);
 
-    virtual const gfxIntSize GetSize() const;
+    virtual const mozilla::gfx::IntSize GetSize() const;
 
     /**
      * Returns the list of underlying surfaces.
      */
     void GetSurfaces(nsTArray<nsRefPtr<gfxASurface> > *aSurfaces);
 };
 
 #endif /* GFX_TEESURFACE_H */
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -74,17 +74,17 @@ void mozilla_dump_image(void* bytes, int
     case 4:
     default:
         format = SurfaceFormat::R8G8B8A8;
         break;
     }
 
     RefPtr<DataSourceSurface> surf =
         Factory::CreateWrappingDataSourceSurface((uint8_t*)bytes, strideBytes,
-                                                 gfx::IntSize(width, height),
+                                                 IntSize(width, height),
                                                  format);
     gfxUtils::DumpAsDataURI(surf);
 }
 
 }
 
 static const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
     return gfxUtils::sPremultiplyTable[a*256+v];
@@ -435,17 +435,17 @@ CreateSamplingRestrictedDrawable(gfxDraw
 
     // if 'needed' is empty, nothing will be drawn since aFill
     // must be entirely outside the clip region, so it doesn't
     // matter what we do here, but we should avoid trying to
     // create a zero-size surface.
     if (needed.IsEmpty())
         return nullptr;
 
-    gfxIntSize size(int32_t(needed.Width()), int32_t(needed.Height()));
+    IntSize size(int32_t(needed.Width()), int32_t(needed.Height()));
 
     RefPtr<DrawTarget> target =
       gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(size, aFormat);
     if (!target) {
       return nullptr;
     }
 
     nsRefPtr<gfxContext> tmpCtx = new gfxContext(target);
@@ -853,17 +853,17 @@ gfxUtils::GfxRectToIntRect(const gfxRect
   *aOut = IntRect(int32_t(aIn.X()), int32_t(aIn.Y()),
   int32_t(aIn.Width()), int32_t(aIn.Height()));
   return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn);
 }
 
 void
 gfxUtils::GetYCbCrToRGBDestFormatAndSize(const PlanarYCbCrData& aData,
                                          gfxImageFormat& aSuggestedFormat,
-                                         gfxIntSize& aSuggestedSize)
+                                         IntSize& aSuggestedSize)
 {
   YUVType yuvtype =
     TypeFromSize(aData.mYSize.width,
                       aData.mYSize.height,
                       aData.mCbCrSize.width,
                       aData.mCbCrSize.height);
 
   // 'prescale' is true if the scaling is to be done as part of the
@@ -907,17 +907,17 @@ gfxUtils::GetYCbCrToRGBDestFormatAndSize
   if (!prescale) {
     aSuggestedSize = aData.mPicSize;
   }
 }
 
 void
 gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData,
                             const gfxImageFormat& aDestFormat,
-                            const gfxIntSize& aDestSize,
+                            const IntSize& aDestSize,
                             unsigned char* aDestBuffer,
                             int32_t aStride)
 {
   // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
   // luma plane is odd sized.
   MOZ_ASSERT((aData.mCbCrSize.width == aData.mYSize.width ||
               aData.mCbCrSize.width == (aData.mYSize.width + 1) >> 1) &&
              (aData.mCbCrSize.height == aData.mYSize.height ||
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -139,27 +139,27 @@ public:
      *   if the desired format is not supported.
      * @param aSuggestedSize will be set to the picture size from aData
      *   if either the suggested size was {0,0}
      *   or simultaneous scaling and conversion is not supported.
      */
     static void
     GetYCbCrToRGBDestFormatAndSize(const mozilla::layers::PlanarYCbCrData& aData,
                                    gfxImageFormat& aSuggestedFormat,
-                                   gfxIntSize& aSuggestedSize);
+                                   mozilla::gfx::IntSize& aSuggestedSize);
 
     /**
      * Convert YCbCrImage into RGB aDestBuffer
      * Format and Size parameters must have
      *   been passed to GetYCbCrToRGBDestFormatAndSize
      */
     static void
     ConvertYCbCrToRGB(const mozilla::layers::PlanarYCbCrData& aData,
                       const gfxImageFormat& aDestFormat,
-                      const gfxIntSize& aDestSize,
+                      const mozilla::gfx::IntSize& aDestSize,
                       unsigned char* aDestBuffer,
                       int32_t aStride);
 
     /**
      * Clears surface to aColor (which defaults to transparent black).
      */
     static void ClearThebesSurface(gfxASurface* aSurface,
                                    mozilla::gfx::IntRect* aRect = nullptr,
--- a/gfx/thebes/gfxWindowsNativeDrawing.cpp
+++ b/gfx/thebes/gfxWindowsNativeDrawing.cpp
@@ -112,32 +112,32 @@ gfxWindowsNativeDrawing::BeginNativeDraw
             if (mTransformType == TRANSLATION_ONLY || !(mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) {
                 mScale = gfxSize(1.0, 1.0);
 
                 // Add 1 to the surface size; it's guaranteed to not be incorrect,
                 // and it fixes bug 382458
                 // There's probably a better fix, but I haven't figured out
                 // the root cause of the problem.
                 mTempSurfaceSize =
-                    gfxIntSize((int32_t) ceil(mNativeRect.Width() + 1),
+                    IntSize((int32_t) ceil(mNativeRect.Width() + 1),
                                (int32_t) ceil(mNativeRect.Height() + 1));
             } else {
                 // figure out the scale factors
                 mScale = m.ScaleFactors(true);
 
                 mWorldTransform.eM11 = (FLOAT) mScale.width;
                 mWorldTransform.eM12 = 0.0f;
                 mWorldTransform.eM21 = 0.0f;
                 mWorldTransform.eM22 = (FLOAT) mScale.height;
                 mWorldTransform.eDx  = 0.0f;
                 mWorldTransform.eDy  = 0.0f;
 
                 // See comment above about "+1"
                 mTempSurfaceSize =
-                    gfxIntSize((int32_t) ceil(mNativeRect.Width() * mScale.width + 1),
+                    IntSize((int32_t) ceil(mNativeRect.Width() * mScale.width + 1),
                                (int32_t) ceil(mNativeRect.Height() * mScale.height + 1));
             }
         }
     }
 
     if (mRenderState == RENDER_STATE_NATIVE_DRAWING) {
         // we can just do native drawing directly to the context's surface
 
--- a/gfx/thebes/gfxWindowsNativeDrawing.h
+++ b/gfx/thebes/gfxWindowsNativeDrawing.h
@@ -108,12 +108,12 @@ private:
     gfxSize mScale;
     XFORM mWorldTransform;
 
     // saved state
     nsRefPtr<gfxWindowsSurface> mWinSurface, mBlackSurface, mWhiteSurface;
     HDC mDC;
     XFORM mOldWorldTransform;
     POINT mOrigViewportOrigin;
-    gfxIntSize mTempSurfaceSize;
+    mozilla::gfx::IntSize mTempSurfaceSize;
 };
 
 #endif
--- a/gfx/thebes/gfxWindowsSurface.cpp
+++ b/gfx/thebes/gfxWindowsSurface.cpp
@@ -38,45 +38,45 @@ gfxWindowsSurface::gfxWindowsSurface(IDi
     mOwnsDC(false), mForPrinting(false), mDC(0), mWnd(nullptr)
 {
     cairo_surface_t *surf = cairo_win32_surface_create_with_d3dsurface9(surface);
     Init(surf);
 }
 
 
 void
-gfxWindowsSurface::MakeInvalid(gfxIntSize& size)
+gfxWindowsSurface::MakeInvalid(mozilla::gfx::IntSize& size)
 {
-    size = gfxIntSize(-1, -1);
+    size = mozilla::gfx::IntSize(-1, -1);
 }
 
-gfxWindowsSurface::gfxWindowsSurface(const gfxIntSize& realSize, gfxImageFormat imageFormat) :
+gfxWindowsSurface::gfxWindowsSurface(const mozilla::gfx::IntSize& realSize, gfxImageFormat imageFormat) :
     mOwnsDC(false), mForPrinting(false), mWnd(nullptr)
 {
-    gfxIntSize size(realSize);
+    mozilla::gfx::IntSize size(realSize);
     if (!CheckSurfaceSize(size))
         MakeInvalid(size);
 
     cairo_surface_t *surf = cairo_win32_surface_create_with_dib((cairo_format_t)(int)imageFormat,
                                                                 size.width, size.height);
 
     Init(surf);
 
     if (CairoStatus() == CAIRO_STATUS_SUCCESS) {
         mDC = cairo_win32_surface_get_dc(CairoSurface());
         RecordMemoryUsed(size.width * size.height * 4 + sizeof(gfxWindowsSurface));
     } else {
         mDC = nullptr;
     }
 }
 
-gfxWindowsSurface::gfxWindowsSurface(HDC dc, const gfxIntSize& realSize, gfxImageFormat imageFormat) :
+gfxWindowsSurface::gfxWindowsSurface(HDC dc, const mozilla::gfx::IntSize& realSize, gfxImageFormat imageFormat) :
     mOwnsDC(false), mForPrinting(false), mWnd(nullptr)
 {
-    gfxIntSize size(realSize);
+    mozilla::gfx::IntSize size(realSize);
     if (!CheckSurfaceSize(size))
         MakeInvalid(size);
 
     cairo_surface_t *surf = cairo_win32_surface_create_with_ddb(dc, (cairo_format_t)(int)imageFormat,
                                                                 size.width, size.height);
 
     Init(surf);
 
@@ -113,17 +113,17 @@ gfxWindowsSurface::InitWithDC(uint32_t f
         Init(cairo_win32_surface_create_with_alpha(mDC));
     } else {
         Init(cairo_win32_surface_create(mDC));
     }
 }
 
 already_AddRefed<gfxASurface>
 gfxWindowsSurface::CreateSimilarSurface(gfxContentType aContent,
-                                        const gfxIntSize& aSize)
+                                        const mozilla::gfx::IntSize& aSize)
 {
     if (!mSurface || !mSurfaceValid) {
         return nullptr;
     }
 
     cairo_surface_t *surface;
     if (!mForPrinting && GetContentType() == gfxContentType::COLOR_ALPHA) {
         // When creating a similar surface to a transparent surface, ensure
@@ -278,27 +278,27 @@ gfxWindowsSurface::EndPage()
     if (result <= 0)
         return NS_ERROR_FAILURE;
     return NS_OK;
 #else
     return NS_ERROR_FAILURE;
 #endif
 }
 
-const gfxIntSize 
+const mozilla::gfx::IntSize
 gfxWindowsSurface::GetSize() const
 {
     if (!mSurfaceValid) {
         NS_WARNING ("GetImageSurface on an invalid (null) surface; who's calling this without checking for surface errors?");
-        return gfxIntSize(-1, -1);
+        return mozilla::gfx::IntSize(-1, -1);
     }
 
     NS_ASSERTION(mSurface != nullptr, "CairoSurface() shouldn't be nullptr when mSurfaceValid is TRUE!");
 
-    return gfxIntSize(cairo_win32_surface_get_width(mSurface),
+    return mozilla::gfx::IntSize(cairo_win32_surface_get_width(mSurface),
                       cairo_win32_surface_get_height(mSurface));
 }
 
 gfxMemoryLocation
 gfxWindowsSurface::GetMemoryLocation() const
 {
     return gfxMemoryLocation::IN_PROCESS_NONHEAP;
 }
--- a/gfx/thebes/gfxWindowsSurface.h
+++ b/gfx/thebes/gfxWindowsSurface.h
@@ -29,28 +29,28 @@ public:
 
     gfxWindowsSurface(HWND wnd, uint32_t flags = 0);
     gfxWindowsSurface(HDC dc, uint32_t flags = 0);
 
     // Create from a shared d3d9surface
     gfxWindowsSurface(IDirect3DSurface9 *surface, uint32_t flags = 0);
 
     // Create a DIB surface
-    gfxWindowsSurface(const gfxIntSize& size,
+    gfxWindowsSurface(const mozilla::gfx::IntSize& size,
                       gfxImageFormat imageFormat = gfxImageFormat::RGB24);
 
     // Create a DDB surface; dc may be nullptr to use the screen DC
     gfxWindowsSurface(HDC dc,
-                      const gfxIntSize& size,
+                      const mozilla::gfx::IntSize& size,
                       gfxImageFormat imageFormat = gfxImageFormat::RGB24);
 
     gfxWindowsSurface(cairo_surface_t *csurf);
 
     virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
-                                                               const gfxIntSize& aSize);
+                                                               const mozilla::gfx::IntSize& aSize);
 
     void InitWithDC(uint32_t flags);
 
     virtual ~gfxWindowsSurface();
 
     HDC GetDC();
 
     HDC GetDCWithClip(gfxContext *);
@@ -58,24 +58,24 @@ public:
     already_AddRefed<gfxImageSurface> GetAsImageSurface();
 
     nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName);
     nsresult EndPrinting();
     nsresult AbortPrinting();
     nsresult BeginPage();
     nsresult EndPage();
 
-    const gfxIntSize GetSize() const;
+    const mozilla::gfx::IntSize GetSize() const;
 
     // The memory used by this surface lives in this process's address space,
     // but not in the heap.
     virtual gfxMemoryLocation GetMemoryLocation() const;
 
 private:
-    void MakeInvalid(gfxIntSize& size);
+    void MakeInvalid(mozilla::gfx::IntSize& size);
 
     bool mOwnsDC;
     bool mForPrinting;
 
     HDC mDC;
     HWND mWnd;
 };
 
--- a/gfx/thebes/gfxXlibNativeRenderer.cpp
+++ b/gfx/thebes/gfxXlibNativeRenderer.cpp
@@ -131,17 +131,17 @@ FINISH:
 
 #define MAX_STATIC_CLIP_RECTANGLES 50
 
 /**
  * Try the direct path.
  * @return True if we took the direct path
  */
 bool
-gfxXlibNativeRenderer::DrawDirect(gfxContext *ctx, nsIntSize size,
+gfxXlibNativeRenderer::DrawDirect(gfxContext *ctx, IntSize size,
                                   uint32_t flags,
                                   Screen *screen, Visual *visual)
 {
     // We need to actually borrow the context because we want to read out the
     // clip rectangles.
     BorrowedCairoContext borrowed(ctx->GetDrawTarget());
     if (!borrowed.mCairo) {
       return false;
@@ -149,17 +149,17 @@ gfxXlibNativeRenderer::DrawDirect(gfxCon
 
     bool direct = DrawCairo(borrowed.mCairo, size, flags, screen, visual);
     borrowed.Finish();
 
     return direct;
 }
 
 bool
-gfxXlibNativeRenderer::DrawCairo(cairo_t* cr, nsIntSize size,
+gfxXlibNativeRenderer::DrawCairo(cairo_t* cr, IntSize size,
                                  uint32_t flags,
                                  Screen *screen, Visual *visual)
 {
     /* Check that the target surface is an xlib surface. */
     cairo_surface_t *target = cairo_get_group_target (cr);
     if (cairo_surface_get_type (target) != CAIRO_SURFACE_TYPE_XLIB) {
         NATIVE_DRAWING_NOTE("FALLBACK: non-X surface");
         return false;
@@ -303,17 +303,17 @@ enum DrawingMethod {
     eSimple,
     eCopyBackground,
     eAlphaExtraction
 };
 
 static cairo_surface_t*
 CreateTempXlibSurface (cairo_surface_t* cairoTarget,
                        DrawTarget* drawTarget,
-                       nsIntSize size,
+                       IntSize size,
                        bool canDrawOverBackground,
                        uint32_t flags, Screen *screen, Visual *visual,
                        DrawingMethod *method)
 {
     NS_ASSERTION(cairoTarget || drawTarget, "Must have some type");
 
     bool drawIsOpaque = (flags & gfxXlibNativeRenderer::DRAW_IS_OPAQUE) != 0;
     bool supportsAlternateVisual =
@@ -407,17 +407,17 @@ CreateTempXlibSurface (cairo_surface_t* 
     }
 
     Drawable drawable =
         (screen == target_screen && cairoTargetType == CAIRO_SURFACE_TYPE_XLIB) ?
         cairo_xlib_surface_get_drawable (cairoTarget) : RootWindowOfScreen(screen);
 
     cairo_surface_t *surface =
         gfxXlibSurface::CreateCairoSurface(screen, visual,
-                                           gfxIntSize(size.width, size.height),
+                                           IntSize(size.width, size.height),
                                            drawable);
     if (!surface) {
         return nullptr;
     }
 
     if (drawIsOpaque ||
         cairo_surface_get_content(surface) == CAIRO_CONTENT_COLOR_ALPHA) {
         NATIVE_DRAWING_NOTE(drawIsOpaque ?
@@ -443,32 +443,32 @@ gfxXlibNativeRenderer::DrawOntoTempSurfa
        surface anyway */
     nsresult rv = DrawWithXlib(tempXlibSurface, offset, nullptr, 0);
     cairo_surface_mark_dirty(tempXlibSurface);
     return NS_SUCCEEDED(rv);
 }
 
 static already_AddRefed<gfxImageSurface>
 CopyXlibSurfaceToImage(cairo_surface_t *tempXlibSurface,
-                       gfxIntSize size,
+                       IntSize size,
                        gfxImageFormat format)
 {
     nsRefPtr<gfxImageSurface> result = new gfxImageSurface(size, format);
 
     cairo_t* copyCtx = cairo_create(result->CairoSurface());
     cairo_set_source_surface(copyCtx, tempXlibSurface, 0, 0);
     cairo_set_operator(copyCtx, CAIRO_OPERATOR_SOURCE);
     cairo_paint(copyCtx);
     cairo_destroy(copyCtx);
 
     return result.forget();
 }
 
 void
-gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
+gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size,
                             uint32_t flags, Screen *screen, Visual *visual)
 {
     gfxMatrix matrix = ctx->CurrentMatrix();
 
     // We can only draw direct or onto a copied background if pixels align and
     // native drawing is compatible with the current operator.  (The matrix is
     // actually also pixel-exact for flips and right-angle rotations, which
     // would permit copying the background but not drawing direct.)
--- a/gfx/thebes/gfxXlibSurface.cpp
+++ b/gfx/thebes/gfxXlibSurface.cpp
@@ -22,36 +22,36 @@
 using namespace mozilla;
 
 gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual)
     : mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
 #if defined(GL_PROVIDER_GLX)
     , mGLXPixmap(None)
 #endif
 {
-    const gfxIntSize size = DoSizeQuery();
+    const gfx::IntSize size = DoSizeQuery();
     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, size.width, size.height);
     Init(surf);
 }
 
-gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size)
+gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfx::IntSize& size)
     : mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
 #if defined(GL_PROVIDER_GLX)
     , mGLXPixmap(None)
 #endif
 {
     NS_ASSERTION(CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
                  "Bad size");
 
     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, size.width, size.height);
     Init(surf);
 }
 
 gfxXlibSurface::gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFormat *format,
-                               const gfxIntSize& size)
+                               const gfx::IntSize& size)
     : mPixmapTaken(false), mDisplay(DisplayOfScreen(screen)),
       mDrawable(drawable)
 #if defined(GL_PROVIDER_GLX)
       , mGLXPixmap(None)
 #endif
 {
     NS_ASSERTION(CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
                  "Bad Size");
@@ -87,17 +87,17 @@ gfxXlibSurface::~gfxXlibSurface()
 #endif
     // gfxASurface's destructor calls RecordMemoryFreed().
     if (mPixmapTaken) {
         XFreePixmap (mDisplay, mDrawable);
     }
 }
 
 static Drawable
-CreatePixmap(Screen *screen, const gfxIntSize& size, unsigned int depth,
+CreatePixmap(Screen *screen, const gfx::IntSize& size, unsigned int depth,
              Drawable relatedDrawable)
 {
     if (!gfxASurface::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
         return None;
 
     if (relatedDrawable == None) {
         relatedDrawable = RootWindowOfScreen(screen);
     }
@@ -117,17 +117,17 @@ gfxXlibSurface::TakePixmap()
 
     // The bit depth returned from Cairo is technically int, but this is
     // the last place we'd be worried about that scenario.
     unsigned int bitDepth = cairo_xlib_surface_get_depth(CairoSurface());
     MOZ_ASSERT((bitDepth % 8) == 0, "Memory used not recorded correctly");    
 
     // Divide by 8 because surface_get_depth gives us the number of *bits* per
     // pixel.
-    gfxIntSize size = GetSize();
+    gfx::IntSize size = GetSize();
     CheckedInt32 totalBytes = CheckedInt32(size.width) * CheckedInt32(size.height) * (bitDepth/8);
 
     // Don't do anything in the "else" case.  We could add INT32_MAX, but that
     // would overflow the memory used counter.  It would also mean we tried for
     // a 2G image.  For now, we'll just assert,
     MOZ_ASSERT(totalBytes.isValid(),"Did not expect to exceed 2Gb image");
     if (totalBytes.isValid()) {
         RecordMemoryUsed(totalBytes.value());
@@ -156,17 +156,17 @@ DestroyPixmap(void *data)
     DestroyPixmapClosure *closure = static_cast<DestroyPixmapClosure*>(data);
     XFreePixmap(DisplayOfScreen(closure->mScreen), closure->mPixmap);
     delete closure;
 }
 
 /* static */
 cairo_surface_t *
 gfxXlibSurface::CreateCairoSurface(Screen *screen, Visual *visual,
-                                   const gfxIntSize& size, Drawable relatedDrawable)
+                                   const gfx::IntSize& size, Drawable relatedDrawable)
 {
     Drawable drawable =
         CreatePixmap(screen, size, DepthOfVisual(screen, visual),
                      relatedDrawable);
     if (!drawable)
         return nullptr;
 
     cairo_surface_t* surface =
@@ -182,17 +182,17 @@ gfxXlibSurface::CreateCairoSurface(Scree
     cairo_surface_set_user_data(surface, &gDestroyPixmapKey,
                                 closure, DestroyPixmap);
     return surface;
 }
 
 /* static */
 already_AddRefed<gfxXlibSurface>
 gfxXlibSurface::Create(Screen *screen, Visual *visual,
-                       const gfxIntSize& size, Drawable relatedDrawable)
+                       const gfx::IntSize& size, Drawable relatedDrawable)
 {
     Drawable drawable =
         CreatePixmap(screen, size, DepthOfVisual(screen, visual),
                      relatedDrawable);
     if (!drawable)
         return nullptr;
 
     nsRefPtr<gfxXlibSurface> result =
@@ -203,17 +203,17 @@ gfxXlibSurface::Create(Screen *screen, V
         return nullptr;
 
     return result.forget();
 }
 
 /* static */
 already_AddRefed<gfxXlibSurface>
 gfxXlibSurface::Create(Screen *screen, XRenderPictFormat *format,
-                       const gfxIntSize& size, Drawable relatedDrawable)
+                       const gfx::IntSize& size, Drawable relatedDrawable)
 {
     Drawable drawable =
         CreatePixmap(screen, size, format->depth, relatedDrawable);
     if (!drawable)
         return nullptr;
 
     nsRefPtr<gfxXlibSurface> result =
         new gfxXlibSurface(screen, drawable, format, size);
@@ -227,17 +227,17 @@ gfxXlibSurface::Create(Screen *screen, X
 
 static bool GetForce24bppPref()
 {
     return Preferences::GetBool("mozilla.widget.force-24bpp", false);
 }
 
 already_AddRefed<gfxASurface>
 gfxXlibSurface::CreateSimilarSurface(gfxContentType aContent,
-                                     const gfxIntSize& aSize)
+                                     const gfx::IntSize& aSize)
 {
     if (!mSurface || !mSurfaceValid) {
       return nullptr;
     }
 
     if (aContent == gfxContentType::COLOR) {
         // cairo_surface_create_similar will use a matching visual if it can.
         // However, systems with 16-bit or indexed default visuals may benefit
@@ -251,17 +251,17 @@ gfxXlibSurface::CreateSimilarSurface(gfx
                 // Cairo only performs simple self-copies as desired if it
                 // knows that this is a Pixmap surface.  It only knows that
                 // surfaces are pixmap surfaces if it creates the Pixmap
                 // itself, so we use cairo_surface_create_similar with a
                 // temporary reference surface to indicate the format.
                 Screen* screen = cairo_xlib_surface_get_screen(CairoSurface());
                 nsRefPtr<gfxXlibSurface> depth24reference =
                     gfxXlibSurface::Create(screen, format,
-                                           gfxIntSize(1, 1), mDrawable);
+                                           gfx::IntSize(1, 1), mDrawable);
                 if (depth24reference)
                     return depth24reference->
                         gfxASurface::CreateSimilarSurface(aContent, aSize);
             }
         }
     }
 
     return gfxASurface::CreateSimilarSurface(aContent, aSize);
@@ -274,41 +274,41 @@ gfxXlibSurface::Finish()
     if (mGLXPixmap) {
         gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
         mGLXPixmap = None;
     }
 #endif
     gfxASurface::Finish();
 }
 
-const gfxIntSize
+const gfx::IntSize
 gfxXlibSurface::GetSize() const
 {
     if (!mSurfaceValid)
-        return gfxIntSize(0,0);
+        return gfx::IntSize(0,0);
 
-    return gfxIntSize(cairo_xlib_surface_get_width(mSurface),
+    return gfx::IntSize(cairo_xlib_surface_get_width(mSurface),
                       cairo_xlib_surface_get_height(mSurface));
 }
 
-const gfxIntSize
+const gfx::IntSize
 gfxXlibSurface::DoSizeQuery()
 {
     // figure out width/height/depth
     Window root_ignore;
     int x_ignore, y_ignore;
     unsigned int bwidth_ignore, width, height, depth;
 
     XGetGeometry(mDisplay,
                  mDrawable,
                  &root_ignore, &x_ignore, &y_ignore,
                  &width, &height,
                  &bwidth_ignore, &depth);
 
-    return gfxIntSize(width, height);
+    return gfx::IntSize(width, height);
 }
 
 class DisplayTable {
 public:
     static bool GetColormapAndVisual(Screen* screen,
                                        XRenderPictFormat* format,
                                        Visual* visual, Colormap* colormap,
                                        Visual** visualForColormap);
--- a/gfx/thebes/gfxXlibSurface.h
+++ b/gfx/thebes/gfxXlibSurface.h
@@ -26,47 +26,47 @@
 class gfxXlibSurface final : public gfxASurface {
 public:
     // construct a wrapper around the specified drawable with dpy/visual.
     // Will use XGetGeometry to query the window/pixmap size.
     gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual);
 
     // construct a wrapper around the specified drawable with dpy/visual,
     // and known width/height.
-    gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size);
+    gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const mozilla::gfx::IntSize& size);
 
     // construct a wrapper around the specified drawable with dpy/format,
     // and known width/height.
     gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFormat *format,
-                   const gfxIntSize& size);
+                   const mozilla::gfx::IntSize& size);
 
     explicit gfxXlibSurface(cairo_surface_t *csurf);
 
     // create a new Pixmap and wrapper surface.
     // |relatedDrawable| provides a hint to the server for determining whether
     // the pixmap should be in video or system memory.  It must be on
     // |screen| (if specified).
     static already_AddRefed<gfxXlibSurface>
-    Create(Screen *screen, Visual *visual, const gfxIntSize& size,
+    Create(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
            Drawable relatedDrawable = None);
     static cairo_surface_t *
-    CreateCairoSurface(Screen *screen, Visual *visual, const gfxIntSize& size,
+    CreateCairoSurface(Screen *screen, Visual *visual, const mozilla::gfx::IntSize& size,
                        Drawable relatedDrawable = None);
     static already_AddRefed<gfxXlibSurface>
-    Create(Screen* screen, XRenderPictFormat *format, const gfxIntSize& size,
+    Create(Screen* screen, XRenderPictFormat *format, const mozilla::gfx::IntSize& size,
            Drawable relatedDrawable = None);
 
     virtual ~gfxXlibSurface();
 
     virtual already_AddRefed<gfxASurface>
     CreateSimilarSurface(gfxContentType aType,
-                         const gfxIntSize& aSize) override;
+                         const mozilla::gfx::IntSize& aSize) override;
     virtual void Finish() override;
 
-    virtual const gfxIntSize GetSize() const override;
+    virtual const mozilla::gfx::IntSize GetSize() const override;
 
     Display* XDisplay() { return mDisplay; }
     Screen* XScreen();
     Drawable XDrawable() { return mDrawable; }
     XRenderPictFormat* XRenderFormat();
 
     static int DepthOfVisual(const Screen* screen, const Visual* visual);
     static Visual* FindVisual(Screen* screen, gfxImageFormat format);
@@ -107,16 +107,16 @@ public:
 
 protected:
     // if TakePixmap() has been called on this
     bool mPixmapTaken;
     
     Display *mDisplay;
     Drawable mDrawable;
 
-    const gfxIntSize DoSizeQuery();
+    const mozilla::gfx::IntSize DoSizeQuery();
 
 #if defined(GL_PROVIDER_GLX)
     GLXPixmap mGLXPixmap;
 #endif
 };
 
 #endif /* GFX_XLIBSURFACE_H */
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -1693,16 +1693,17 @@ class ValueOperations
     double toNumber() const { return value()->toNumber(); }
     int32_t toInt32() const { return value()->toInt32(); }
     double toDouble() const { return value()->toDouble(); }
     JSString* toString() const { return value()->toString(); }
     JS::Symbol* toSymbol() const { return value()->toSymbol(); }
     JSObject& toObject() const { return value()->toObject(); }
     JSObject* toObjectOrNull() const { return value()->toObjectOrNull(); }
     gc::Cell* toGCThing() const { return value()->toGCThing(); }
+    JS::TraceKind traceKind() const { return value()->traceKind(); }
     uint64_t asRawBits() const { return value()->asRawBits(); }
 
     JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); }
     uint32_t toPrivateUint32() const { return value()->toPrivateUint32(); }
 
     JSWhyMagic whyMagic() const { return value()->whyMagic(); }
     uint32_t magicUint32() const { return value()->magicUint32(); }
 };
--- a/js/src/asmjs/AsmJSFrameIterator.cpp
+++ b/js/src/asmjs/AsmJSFrameIterator.cpp
@@ -17,16 +17,18 @@
  */
 
 #include "asmjs/AsmJSFrameIterator.h"
 
 #include "asmjs/AsmJSModule.h"
 #include "asmjs/AsmJSValidate.h"
 #include "jit/MacroAssembler.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 /*****************************************************************************/
 // AsmJSFrameIterator implementation
 
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -40,16 +40,17 @@
 #include "jit/IonCode.h"
 #include "js/Class.h"
 #include "js/Conversions.h"
 #include "js/MemoryMetrics.h"
 
 #include "jsobjinlines.h"
 
 #include "frontend/ParseNode-inl.h"
+#include "jit/MacroAssembler-inl.h"
 #include "vm/ArrayBufferObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace jit;
 using namespace frontend;
 using mozilla::BinarySearch;
 using mozilla::Compression::LZ4;
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -44,16 +44,17 @@
 #endif
 #include "vm/HelperThreads.h"
 #include "vm/Interpreter.h"
 
 #include "jsobjinlines.h"
 
 #include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
+#include "jit/MacroAssembler-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 using namespace js::jit;
 
 using mozilla::AddToHash;
 using mozilla::ArrayLength;
 using mozilla::CountLeadingZeroes32;
@@ -6917,160 +6918,16 @@ CheckLabel(FunctionCompiler& f, ParseNod
 
     if (!CheckStatement(f, stmt, &labels))
         return false;
 
     return f.bindLabeledBreaks(&labels, labeledStmt);
 }
 
 static bool
-CheckLeafCondition(FunctionCompiler& f, ParseNode* cond, ParseNode* thenStmt, ParseNode* elseOrJoinStmt,
-                   MBasicBlock** thenBlock, MBasicBlock** elseOrJoinBlock)
-{
-    MDefinition* condDef;
-    Type condType;
-    if (!CheckExpr(f, cond, &condDef, &condType))
-        return false;
-    if (!condType.isInt())
-        return f.failf(cond, "%s is not a subtype of int", condType.toChars());
-
-    if (!f.branchAndStartThen(condDef, thenBlock, elseOrJoinBlock, thenStmt, elseOrJoinStmt))
-        return false;
-    return true;
-}
-
-static bool
-CheckIfCondition(FunctionCompiler& f, ParseNode* cond, ParseNode* thenStmt, ParseNode* elseOrJoinStmt,
-                 MBasicBlock** thenBlock, MBasicBlock** elseOrJoinBlock);
-
-static bool
-CheckIfConditional(FunctionCompiler& f, ParseNode* conditional, ParseNode* thenStmt, ParseNode* elseOrJoinStmt,
-                   MBasicBlock** thenBlock, MBasicBlock** elseOrJoinBlock)
-{
-    MOZ_ASSERT(conditional->isKind(PNK_CONDITIONAL));
-
-    // a ? b : c <=> (a && b) || (!a && c)
-    // b is always referred to the AND condition, as we need A and B to reach this test,
-    // c is always referred as the OR condition, as we reach it if we don't have A.
-    ParseNode* cond = TernaryKid1(conditional);
-    ParseNode* lhs = TernaryKid2(conditional);
-    ParseNode* rhs = TernaryKid3(conditional);
-
-    MBasicBlock* maybeAndTest = nullptr;
-    MBasicBlock* maybeOrTest = nullptr;
-    MBasicBlock** ifTrueBlock = &maybeAndTest;
-    MBasicBlock** ifFalseBlock = &maybeOrTest;
-    ParseNode* ifTrueBlockNode = lhs;
-    ParseNode* ifFalseBlockNode = rhs;
-
-    // Try to spot opportunities for short-circuiting in the AND subpart
-    uint32_t andTestLiteral = 0;
-    bool skipAndTest = false;
-
-    if (IsLiteralInt(f.m(), lhs, &andTestLiteral)) {
-        skipAndTest = true;
-        if (andTestLiteral == 0) {
-            // (a ? 0 : b) is equivalent to !a && b
-            // If a is true, jump to the elseBlock directly
-            ifTrueBlock = elseOrJoinBlock;
-            ifTrueBlockNode = elseOrJoinStmt;
-        } else {
-            // (a ? 1 : b) is equivalent to a || b
-            // If a is true, jump to the thenBlock directly
-            ifTrueBlock = thenBlock;
-            ifTrueBlockNode = thenStmt;
-        }
-    }
-
-    // Try to spot opportunities for short-circuiting in the OR subpart
-    uint32_t orTestLiteral = 0;
-    bool skipOrTest = false;
-
-    if (IsLiteralInt(f.m(), rhs, &orTestLiteral)) {
-        skipOrTest = true;
-        if (orTestLiteral == 0) {
-            // (a ? b : 0) is equivalent to a && b
-            // If a is false, jump to the elseBlock directly
-            ifFalseBlock = elseOrJoinBlock;
-            ifFalseBlockNode = elseOrJoinStmt;
-        } else {
-            // (a ? b : 1) is equivalent to !a || b
-            // If a is false, jump to the thenBlock directly
-            ifFalseBlock = thenBlock;
-            ifFalseBlockNode = thenStmt;
-        }
-    }
-
-    // Pathological cases: a ? 0 : 0 (i.e. false) or a ? 1 : 1 (i.e. true)
-    // These cases can't be optimized properly at this point: one of the blocks might be
-    // created and won't ever be executed. Furthermore, it introduces inconsistencies in the
-    // MIR graph (even if we try to create a block by hand, it will have no predecessor, which
-    // breaks graph assumptions). The only way we could optimize it is to do it directly in
-    // CheckIf by removing the control flow entirely.
-    if (skipOrTest && skipAndTest && (!!orTestLiteral == !!andTestLiteral))
-        return CheckLeafCondition(f, conditional, thenStmt, elseOrJoinStmt, thenBlock, elseOrJoinBlock);
-
-    if (!CheckIfCondition(f, cond, ifTrueBlockNode, ifFalseBlockNode, ifTrueBlock, ifFalseBlock))
-        return false;
-    f.assertCurrentBlockIs(*ifTrueBlock);
-
-    // Add supplementary tests, if needed
-    if (!skipAndTest) {
-        if (!CheckIfCondition(f, lhs, thenStmt, elseOrJoinStmt, thenBlock, elseOrJoinBlock))
-            return false;
-        f.assertCurrentBlockIs(*thenBlock);
-    }
-
-    if (!skipOrTest) {
-        f.switchToElse(*ifFalseBlock);
-        if (!CheckIfCondition(f, rhs, thenStmt, elseOrJoinStmt, thenBlock, elseOrJoinBlock))
-            return false;
-        f.assertCurrentBlockIs(*thenBlock);
-    }
-
-    // We might not be on the thenBlock in one case
-    if (ifTrueBlock == elseOrJoinBlock) {
-        MOZ_ASSERT(skipAndTest && andTestLiteral == 0);
-        f.switchToElse(*thenBlock);
-    }
-
-    // Check post-conditions
-    f.assertCurrentBlockIs(*thenBlock);
-    MOZ_ASSERT_IF(!f.inDeadCode(), *thenBlock && *elseOrJoinBlock);
-    return true;
-}
-
-// Recursive function that checks for a complex condition (formed with ternary
-// conditionals) and creates the associated short-circuiting control flow graph.
-//
-// After a call to CheckCondition, the followings are true:
-// - if *thenBlock and *elseOrJoinBlock were non-null on entry, their value is
-//   not changed by this function.
-// - *thenBlock and *elseOrJoinBlock are non-null on exit.
-// - the current block on exit is the *thenBlock.
-static bool
-CheckIfCondition(FunctionCompiler& f, ParseNode* cond, ParseNode* thenStmt,
-                 ParseNode* elseOrJoinStmt, MBasicBlock** thenBlock, MBasicBlock** elseOrJoinBlock)
-{
-    JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
-
-    if (cond->isKind(PNK_CONDITIONAL))
-        return CheckIfConditional(f, cond, thenStmt, elseOrJoinStmt, thenBlock, elseOrJoinBlock);
-
-    // We've reached a leaf, i.e. an atomic condition
-    if (!CheckLeafCondition(f, cond, thenStmt, elseOrJoinStmt, thenBlock, elseOrJoinBlock))
-        return false;
-
-    // Check post-conditions
-    f.assertCurrentBlockIs(*thenBlock);
-    MOZ_ASSERT_IF(!f.inDeadCode(), *thenBlock && *elseOrJoinBlock);
-    return true;
-}
-
-static bool
 CheckIf(FunctionCompiler& f, ParseNode* ifStmt)
 {
     // Handle if/else-if chains using iteration instead of recursion. This
     // avoids blowing the C stack quota for long if/else-if chains and also
     // creates fewer MBasicBlocks at join points (by creating one join block
     // for the entire if/else-if chain).
     BlockVector thenBlocks(f.cx());
 
@@ -7080,17 +6937,24 @@ CheckIf(FunctionCompiler& f, ParseNode* 
     ParseNode* cond = TernaryKid1(ifStmt);
     ParseNode* thenStmt = TernaryKid2(ifStmt);
     ParseNode* elseStmt = TernaryKid3(ifStmt);
 
     MBasicBlock* thenBlock = nullptr;
     MBasicBlock* elseBlock = nullptr;
     ParseNode* elseOrJoinStmt = elseStmt ? elseStmt : nextStmt;
 
-    if (!CheckIfCondition(f, cond, thenStmt, elseOrJoinStmt, &thenBlock, &elseBlock))
+    MDefinition* condDef;
+    Type condType;
+    if (!CheckExpr(f, cond, &condDef, &condType))
+        return false;
+    if (!condType.isInt())
+        return f.failf(cond, "%s is not a subtype of int", condType.toChars());
+
+    if (!f.branchAndStartThen(condDef, &thenBlock, &elseBlock, thenStmt, elseOrJoinStmt))
         return false;
 
     if (!CheckStatement(f, thenStmt))
         return false;
 
     if (!f.appendThenBlock(&thenBlocks))
         return false;
 
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -798,177 +798,53 @@ NondeterministicGetWeakMapKeys(JSContext
                              "nondeterministicGetWeakMapKeys", "WeakMap",
                              args[0].toObject().getClass()->name);
         return false;
     }
     args.rval().setObject(*arr);
     return true;
 }
 
-struct JSCountHeapNode {
-    void*               thing;
-    JS::TraceKind       kind;
-    JSCountHeapNode*    next;
-};
-
-typedef HashSet<void*, PointerHasher<void*, 3>, SystemAllocPolicy> VisitedSet;
-
-class CountHeapTracer : public JS::CallbackTracer
-{
-  public:
-    CountHeapTracer(JSRuntime* rt, JSTraceCallback callback) : CallbackTracer(rt, callback) {}
-
-    VisitedSet          visited;
-    JSCountHeapNode*    traceList;
-    JSCountHeapNode*    recycleList;
-    bool                ok;
-};
-
-static void
-CountHeapNotify(JS::CallbackTracer* trc, void** thingp, JS::TraceKind kind)
+class HasChildTracer : public JS::CallbackTracer
 {
-    CountHeapTracer* countTracer = (CountHeapTracer*)trc;
-    void* thing = *thingp;
-
-    if (!countTracer->ok)
-        return;
-
-    VisitedSet::AddPtr p = countTracer->visited.lookupForAdd(thing);
-    if (p)
-        return;
-
-    if (!countTracer->visited.add(p, thing)) {
-        countTracer->ok = false;
-        return;
+    RootedValue child_;
+    bool found_;
+
+    void onEdge(void** thingp, JS::TraceKind kind) {
+        if (*thingp == child_.toGCThing())
+            found_ = true;
     }
 
-    JSCountHeapNode* node = countTracer->recycleList;
-    if (node) {
-        countTracer->recycleList = node->next;
-    } else {
-        node = js_pod_malloc<JSCountHeapNode>();
-        if (!node) {
-            countTracer->ok = false;
-            return;
-        }
+    static void trampoline(JS::CallbackTracer* trc, void** thingp, JS::TraceKind kind) {
+        static_cast<HasChildTracer*>(trc)->onEdge(thingp, kind);
     }
-    node->thing = thing;
-    node->kind = kind;
-    node->next = countTracer->traceList;
-    countTracer->traceList = node;
-}
-
-static const struct TraceKindPair {
-    const char*      name;
-    int32_t          kind;
-} traceKindNames[] = {
-    { "all",        -1                             },
-    { "object",     int32_t(JS::TraceKind::Object) },
-    { "string",     int32_t(JS::TraceKind::String) },
-    { "symbol",     int32_t(JS::TraceKind::Symbol) },
+
+  public:
+    HasChildTracer(JSRuntime* rt, HandleValue child)
+      : JS::CallbackTracer(rt, trampoline, TraceWeakMapKeysValues), child_(rt, child), found_(false)
+    {}
+
+    bool found() const { return found_; }
 };
 
 static bool
-CountHeap(JSContext* cx, unsigned argc, jsval* vp)
+HasChild(JSContext* cx, unsigned argc, jsval* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-
-    RootedValue startValue(cx, UndefinedValue());
-    if (args.length() > 0) {
-        jsval v = args[0];
-        if (v.isMarkable()) {
-            startValue = v;
-        } else if (!v.isNull()) {
-            JS_ReportError(cx,
-                           "the first argument is not null or a heap-allocated "
-                           "thing");
-            return false;
-        }
+    RootedValue parent(cx, args.get(0));
+    RootedValue child(cx, args.get(1));
+
+    if (!parent.isMarkable() || !child.isMarkable()) {
+        args.rval().setBoolean(false);
+        return true;
     }
 
-    RootedValue traceValue(cx);
-    int32_t traceKind = -1;
-    void* traceThing = nullptr;
-    if (args.length() > 1) {
-        JSString* str = ToString(cx, args[1]);
-        if (!str)
-            return false;
-        JSFlatString* flatStr = JS_FlattenString(cx, str);
-        if (!flatStr)
-            return false;
-        if (JS_FlatStringEqualsAscii(flatStr, "specific")) {
-            if (args.length() < 3) {
-                JS_ReportError(cx, "tracing of specific value requested "
-                               "but no value provided");
-                return false;
-            }
-            traceValue = args[2];
-            if (!traceValue.isMarkable()){
-                JS_ReportError(cx, "cannot trace this kind of value");
-                return false;
-            }
-            traceThing = traceValue.toGCThing();
-        } else {
-            for (size_t i = 0; ;) {
-                if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
-                    traceKind = traceKindNames[i].kind;
-                    break;
-                }
-                if (++i == ArrayLength(traceKindNames)) {
-                    JSAutoByteString bytes(cx, str);
-                    if (!!bytes)
-                        JS_ReportError(cx, "trace kind name '%s' is unknown", bytes.ptr());
-                    return false;
-                }
-            }
-        }
-    }
-
-    CountHeapTracer countTracer(JS_GetRuntime(cx), CountHeapNotify);
-    if (!countTracer.visited.init()) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-    countTracer.ok = true;
-    countTracer.traceList = nullptr;
-    countTracer.recycleList = nullptr;
-
-    if (startValue.isUndefined()) {
-        JS_TraceRuntime(&countTracer);
-    } else {
-        JS_CallUnbarrieredValueTracer(&countTracer, startValue.address(), "root");
-    }
-
-    JSCountHeapNode* node;
-    size_t counter = 0;
-    while ((node = countTracer.traceList) != nullptr) {
-        if (traceThing == nullptr) {
-            // We are looking for all nodes with a specific kind
-            if (traceKind == -1 || int32_t(node->kind) == traceKind)
-                counter++;
-        } else {
-            // We are looking for some specific thing
-            if (node->thing == traceThing)
-                counter++;
-        }
-        countTracer.traceList = node->next;
-        node->next = countTracer.recycleList;
-        countTracer.recycleList = node;
-        JS_TraceChildren(&countTracer, node->thing, node->kind);
-    }
-    while ((node = countTracer.recycleList) != nullptr) {
-        countTracer.recycleList = node->next;
-        js_free(node);
-    }
-    if (!countTracer.ok) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    args.rval().setNumber(double(counter));
+    HasChildTracer trc(cx->runtime(), child);
+    TraceChildren(&trc, parent.toGCThing(), parent.traceKind());
+    args.rval().setBoolean(trc.found());
     return true;
 }
 
 // Stolen from jsmath.cpp
 static const uint64_t RNG_MULTIPLIER = 0x5DEECE66DLL;
 static const uint64_t RNG_MASK = (1LL << 48) - 1;
 
 static bool
@@ -2640,24 +2516,20 @@ static const JSFunctionSpecWithHelp Test
 "  Perform a GC and allow relazification of functions. Accepts the same\n"
 "  arguments as gc()."),
 
     JS_FN_HELP("getBuildConfiguration", GetBuildConfiguration, 0, 0,
 "getBuildConfiguration()",
 "  Return an object describing some of the configuration options SpiderMonkey\n"
 "  was built with."),
 
-    JS_FN_HELP("countHeap", CountHeap, 0, 0,
-"countHeap([start[, kind[, thing]]])",
-"  Count the number of live GC things in the heap or things reachable from\n"
-"  start when it is given and is not null. kind is either 'all' (default) to\n"
-"  count all things or one of 'object', 'double', 'string', 'function'\n"
-"  to count only things of that kind. If kind is the string 'specific',\n"
-"  then you can provide an extra argument with some specific traceable\n"
-"  thing to count.\n"),
+    JS_FN_HELP("hasChild", HasChild, 0, 0,
+"hasChild(parent, child)",
+"  Return true if |child| is a child of |parent|, as determined by a call to\n"
+"  TraceChildren"),
 
     JS_FN_HELP("setSavedStacksRNGState", SetSavedStacksRNGState, 1, 0,
 "setSavedStacksRNGState(seed)",
 "  Set this compartment's SavedStacks' RNG state.\n"),
 
     JS_FN_HELP("getSavedFrameCount", GetSavedFrameCount, 0, 0,
 "getSavedFrameCount()",
 "  Return the number of SavedFrame instances stored in this compartment's\n"
--- a/js/src/frontend/ParseMaps-inl.h
+++ b/js/src/frontend/ParseMaps-inl.h
@@ -18,16 +18,18 @@ template <class Map>
 inline bool
 AtomThingMapPtr<Map>::ensureMap(ExclusiveContext* cx)
 {
     if (map_)
         return true;
 
     AutoLockForExclusiveAccess lock(cx);
     map_ = cx->parseMapPool().acquire<Map>();
+    if (!map_)
+        ReportOutOfMemory(cx);
     return !!map_;
 }
 
 template <class Map>
 inline void
 AtomThingMapPtr<Map>::releaseMap(ExclusiveContext* cx)
 {
     if (!map_)
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3659,17 +3659,17 @@ Parser<ParseHandler>::deprecatedLetBlock
     RootedStaticBlockObject blockObj(context, StaticBlockObject::create(context));
     if (!blockObj)
         return null();
 
     uint32_t begin = pos().begin;
 
     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_LET);
 
-    Node vars = variables(yieldHandling, PNK_LET, nullptr, blockObj, DontHoistVars);
+    Node vars = variables(yieldHandling, PNK_LET, NotInForInit, nullptr, blockObj, DontHoistVars);
     if (!vars)
         return null();
 
     MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_LET);
 
     StmtInfoPC stmtInfo(context);
     Node block = pushLetScope(blockObj, &stmtInfo);
     if (!block)
@@ -3755,18 +3755,19 @@ Parser<ParseHandler>::newBindingNode(Pro
 /*
  * The 'blockObj' parameter is non-null when parsing the 'vars' in a let
  * expression, block statement, non-top-level let declaration in statement
  * context, and the let-initializer of a for-statement.
  */
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::variables(YieldHandling yieldHandling,
-                                ParseNodeKind kind, bool* psimple,
-                                StaticBlockObject* blockObj, VarContext varContext)
+                                ParseNodeKind kind,
+                                ForInitLocation location,
+                                bool* psimple, StaticBlockObject* blockObj, VarContext varContext)
 {
     /*
      * The four options here are:
      * - PNK_VAR:   We're parsing var declarations.
      * - PNK_CONST: We're parsing const declarations.
      * - PNK_GLOBALCONST: We're parsing const declarations at toplevel (see bug 589119).
      * - PNK_LET:   We are parsing a let declaration.
      */
@@ -3818,17 +3819,17 @@ Parser<ParseHandler>::variables(YieldHan
 
                 pc->inDeclDestructuring = true;
                 pn2 = primaryExpr(yieldHandling, tt);
                 pc->inDeclDestructuring = false;
                 if (!pn2)
                     return null();
 
                 bool parsingForInOrOfInit = false;
-                if (pc->parsingForInit) {
+                if (location == InForInit) {
                     bool isForIn, isForOf;
                     if (!matchInOrOf(&isForIn, &isForOf))
                         return null();
                     parsingForInOrOfInit = isForIn || isForOf;
                 }
 
                 // See comment below for bindBeforeInitializer in the code that
                 // handles the non-destructuring case.
@@ -3840,23 +3841,24 @@ Parser<ParseHandler>::variables(YieldHan
                 if (parsingForInOrOfInit) {
                     tokenStream.ungetToken();
                     handler.addList(pn, pn2);
                     break;
                 }
 
                 MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL);
 
-                Node init = assignExpr(InAllowed, yieldHandling);
+                Node init = assignExpr(location == InForInit ? InProhibited : InAllowed,
+                                       yieldHandling);
                 if (!init)
                     return null();
 
                 // Ban the nonsensical |for (var V = E1 in E2);| where V is a
                 // destructuring pattern.  See bug 1164741 for background.
-                if (pc->parsingForInit && kind == PNK_VAR) {
+                if (location == InForInit && kind == PNK_VAR) {
                     TokenKind afterInit;
                     if (!tokenStream.peekToken(&afterInit))
                         return null();
                     if (afterInit == TOK_IN) {
                         report(ParseError, false, init, JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT,
                                "in");
                         return null();
                     }
@@ -3907,28 +3909,29 @@ Parser<ParseHandler>::variables(YieldHan
                 //
                 // If we are not parsing a let declaration, bind the name
                 // now. Otherwise we must wait until after parsing the initializing
                 // assignment.
                 bool bindBeforeInitializer = kind != PNK_LET && kind != PNK_CONST;
                 if (bindBeforeInitializer && !data.binder(&data, name, this))
                     return null();
 
-                Node init = assignExpr(InAllowed, yieldHandling);
+                Node init = assignExpr(location == InForInit ? InProhibited : InAllowed,
+                                       yieldHandling);
                 if (!init)
                     return null();
 
                 // Ignore an initializer if we have a for-in loop declaring a
                 // |var| with an initializer: |for (var v = ... in ...);|.
                 // Warn that this syntax is invalid so that developers looking
                 // in the console know to fix this.  ES<6 permitted the
                 // initializer while ES6 doesn't; ignoring it seems the best
                 // way to incrementally move to ES6 semantics.
                 bool performAssignment = true;
-                if (pc->parsingForInit && kind == PNK_VAR) {
+                if (location == InForInit && kind == PNK_VAR) {
                     TokenKind afterInit;
                     if (!tokenStream.peekToken(&afterInit))
                         return null();
                     if (afterInit == TOK_IN) {
                         performAssignment = false;
                         if (!report(ParseWarning, pc->sc->strict(), init,
                                     JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT, "in"))
                         {
@@ -3940,17 +3943,17 @@ Parser<ParseHandler>::variables(YieldHan
                 if (performAssignment) {
                     if (!bindBeforeInitializer && !data.binder(&data, name, this))
                         return null();
 
                     if (!handler.finishInitializerAssignment(pn2, init, data.op))
                         return null();
                 }
             } else {
-                if (data.isConst && !pc->parsingForInit) {
+                if (data.isConst && location == NotInForInit) {
                     report(ParseError, false, null(), JSMSG_BAD_CONST_DECL);
                     return null();
                 }
 
                 if (!data.binder(&data, name, this))
                     return null();
             }
 
@@ -4119,19 +4122,18 @@ Parser<FullParseHandler>::lexicalDeclara
      * other bugs are fixed.
      */
     ParseNodeKind kind = PNK_LET;
     if (pc->atGlobalLevel())
         kind = isConst ? PNK_GLOBALCONST : PNK_VAR;
     else if (isConst)
         kind = PNK_CONST;
 
-    ParseNode* pn = variables(yieldHandling, kind, nullptr,
-                              CurrentLexicalStaticBlock(pc),
-                              HoistVars);
+    ParseNode* pn = variables(yieldHandling, kind, NotInForInit,
+                              nullptr, CurrentLexicalStaticBlock(pc), HoistVars);
     if (!pn)
         return null();
     pn->pn_xflags = PNX_POPVAR;
     return MatchOrInsertSemicolon(tokenStream) ? pn : nullptr;
 }
 
 template <>
 SyntaxParseHandler::Node
@@ -4491,17 +4493,18 @@ Parser<FullParseHandler>::exportDeclarat
         break;
 
       case TOK_CLASS:
         kid = classDefinition(YieldIsKeyword, ClassStatement, NameRequired);
         if (!kid)
             return null();
         break;
 
-      case TOK_VAR: kid = variables(YieldIsName, PNK_VAR);
+      case TOK_VAR:
+        kid = variables(YieldIsName, PNK_VAR, NotInForInit);
         if (!kid)
             return null();
         kid->pn_xflags = PNX_POPVAR;
 
         kid = MatchOrInsertSemicolon(tokenStream) ? kid : nullptr;
         if (!kid)
             return null();
         break;
@@ -4748,49 +4751,46 @@ Parser<FullParseHandler>::forStatement(Y
 
     {
         TokenKind tt;
         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
             return null();
         if (tt == TOK_SEMI) {
             pn1 = nullptr;
         } else {
-            /*
-             * Set pn1 to a var list or an initializing expression.
-             *
-             * Set the parsingForInit flag during parsing of the first clause
-             * of the for statement.  This flag will be used by the RelExpr
-             * production; if it is set, then the 'in' keyword will not be
-             * recognized as an operator, leaving it available to be parsed as
-             * part of a for/in loop.
-             *
-             * A side effect of this restriction is that (unparenthesized)
-             * expressions involving an 'in' operator are illegal in the init
-             * clause of an ordinary for loop.
-             */
-            pc->parsingForInit = true;
+            // Set pn1 to a variable list or an initializing expression.
+            //
+            // Pass |InForInit| to Parser::variables when parsing declarations
+            // to trigger |for|-specific parsing for that one position.  In a
+            // normal variable declaration, any initializer may be an |in|
+            // expression.  But for declarations at the start of a for-loop
+            // head, initializers can't contain |in|.  (Such syntax conflicts
+            // with ES5's |for (var i = 0 in foo)| syntax, removed in ES6, that
+            // we "support" by ignoring the |= 0|.)
             if (tt == TOK_VAR) {
                 isForDecl = true;
                 tokenStream.consumeKnownToken(tt);
-                pn1 = variables(yieldHandling, PNK_VAR);
+                pn1 = variables(yieldHandling, PNK_VAR, InForInit);
             } else if (tt == TOK_LET || tt == TOK_CONST) {
                 handler.disableSyntaxParser();
                 bool constDecl = tt == TOK_CONST;
                 tokenStream.consumeKnownToken(tt);
                 isForDecl = true;
                 blockObj = StaticBlockObject::create(context);
                 if (!blockObj)
                     return null();
-                pn1 = variables(yieldHandling,
-                                constDecl ? PNK_CONST : PNK_LET, nullptr, blockObj,
-                                DontHoistVars);
+                pn1 = variables(yieldHandling, constDecl ? PNK_CONST : PNK_LET, InForInit,
+                                nullptr, blockObj, DontHoistVars);
             } else {
+                // Pass |InProhibited| when parsing an expression so that |in|
+                // isn't parsed in a RelationalExpression as a binary operator.
+                // In this context, |in| is part of a for-in loop -- *not* part
+                // of a binary expression.
                 pn1 = expr(InProhibited, yieldHandling);
             }
-            pc->parsingForInit = false;
             if (!pn1)
                 return null();
         }
     }
 
     MOZ_ASSERT_IF(isForDecl, pn1->isArity(PN_LIST));
     MOZ_ASSERT(!!blockObj == (isForDecl && pn1->isOp(JSOP_NOP)));
 
@@ -4837,22 +4837,18 @@ Parser<FullParseHandler>::forStatement(Y
     //
     //   * forLetImpliedBlock is the node for the implicit block scope.
     //   * forLetDecl is the node for the decl 'let/const <pattern>'.
     //
     // Otherwise both are null.
     ParseNode* forLetImpliedBlock = nullptr;
     ParseNode* forLetDecl = nullptr;
 
-    /*
-     * We can be sure that it's a for/in loop if there's still an 'in'
-     * keyword here, even if JavaScript recognizes 'in' as an operator,
-     * as we've excluded 'in' from being parsed in RelExpr by setting
-     * pc->parsingForInit.
-     */
+    // If there's an |in| keyword here, it's a for-in loop, by dint of careful
+    // parsing of |pn1|.
     StmtInfoPC letStmt(context); /* used if blockObj != nullptr. */
     ParseNode* pn2;      /* forHead->pn_kid2 */
     ParseNode* pn3;      /* forHead->pn_kid3 */
     ParseNodeKind headKind = PNK_FORHEAD;
     if (pn1) {
         bool isForIn, isForOf;
         if (!matchInOrOf(&isForIn, &isForOf))
             return null();
@@ -5102,41 +5098,35 @@ Parser<SyntaxParseHandler>::forStatement
     {
         TokenKind tt;
         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
             return null();
         if (tt == TOK_SEMI) {
             lhsNode = null();
         } else {
             /* Set lhsNode to a var list or an initializing expression. */
-            pc->parsingForInit = true;
             if (tt == TOK_VAR) {
                 isForDecl = true;
                 tokenStream.consumeKnownToken(tt);
-                lhsNode = variables(yieldHandling, PNK_VAR, &simpleForDecl);
+                lhsNode = variables(yieldHandling, PNK_VAR, InForInit, &simpleForDecl);
             }
             else if (tt == TOK_CONST || tt == TOK_LET) {
                 JS_ALWAYS_FALSE(abortIfSyntaxParser());
                 return null();
             }
             else {
                 lhsNode = expr(InProhibited, yieldHandling);
             }
             if (!lhsNode)
                 return null();
-            pc->parsingForInit = false;
-        }
-    }
-
-    /*
-     * We can be sure that it's a for/in loop if there's still an 'in'
-     * keyword here, even if JavaScript recognizes 'in' as an operator,
-     * as we've excluded 'in' from being parsed in RelExpr by setting
-     * pc->parsingForInit.
-     */
+        }
+    }
+
+    // If there's an |in| keyword here, it's a for-in loop, by dint of careful
+    // parsing of |pn1|.
     bool isForIn = false, isForOf = false;
     if (lhsNode) {
         if (!matchInOrOf(&isForIn, &isForOf))
             return null();
     }
     if (isForIn || isForOf) {
         /* Parse the rest of the for/in or for/of head. */
         forStmt.type = isForOf ? STMT_FOR_OF_LOOP : STMT_FOR_IN_LOOP;
@@ -6056,17 +6046,17 @@ Parser<ParseHandler>::statement(YieldHan
 
     switch (tt) {
       // BlockStatement[?Yield, ?Return]
       case TOK_LC:
         return blockStatement(yieldHandling);
 
       // VariableStatement[?Yield]
       case TOK_VAR: {
-        Node pn = variables(yieldHandling, PNK_VAR);
+        Node pn = variables(yieldHandling, PNK_VAR, NotInForInit);
         if (!pn)
             return null();
 
         // Tell js_EmitTree to generate a final POP.
         handler.setListFlag(pn, PNX_POPVAR);
 
         if (!MatchOrInsertSemicolon(tokenStream))
             return null();
@@ -6287,22 +6277,16 @@ static const JSOp ParseNodeKindToJSOp[] 
 static inline JSOp
 BinaryOpParseNodeKindToJSOp(ParseNodeKind pnk)
 {
     MOZ_ASSERT(pnk >= PNK_BINOP_FIRST);
     MOZ_ASSERT(pnk <= PNK_BINOP_LAST);
     return ParseNodeKindToJSOp[pnk - PNK_BINOP_FIRST];
 }
 
-static bool
-IsBinaryOpToken(TokenKind tok, bool parsingForInit)
-{
-    return tok == TOK_IN ? !parsingForInit : TokenKindIsBinaryOp(tok);
-}
-
 static ParseNodeKind
 BinaryOpTokenKindToParseNodeKind(TokenKind tok)
 {
     MOZ_ASSERT(TokenKindIsBinaryOp(tok));
     return ParseNodeKind(PNK_BINOP_FIRST + (tok - TOK_BINOP_FIRST));
 }
 
 static const int PrecedenceTable[] = {
@@ -6355,35 +6339,30 @@ Parser<ParseHandler>::orExpr1(InHandling
     // the JS syntax.
 
     // Conceptually there's just one stack, a stack of pairs (lhs, op).
     // It's implemented using two separate arrays, though.
     Node nodeStack[PRECEDENCE_CLASSES];
     ParseNodeKind kindStack[PRECEDENCE_CLASSES];
     int depth = 0;
 
-    bool oldParsingForInit = pc->parsingForInit;
-    pc->parsingForInit = false;
-
     Node pn;
     for (;;) {
         pn = unaryExpr(yieldHandling, invoked);
         if (!pn)
             return pn;
 
         // If a binary operator follows, consume it and compute the
         // corresponding operator.
         TokenKind tok;
         if (!tokenStream.getToken(&tok))
             return null();
 
-        // FIXME: Change this to use |inHandling == InAllowed|, not
-        // |pc->parsingForInit|.
         ParseNodeKind pnk;
-        if (IsBinaryOpToken(tok, oldParsingForInit)) {
+        if (tok == TOK_IN ? inHandling == InAllowed : TokenKindIsBinaryOp(tok)) {
             pnk = BinaryOpTokenKindToParseNodeKind(tok);
         } else {
             tok = TOK_EOF;
             pnk = PNK_LIMIT;
         }
 
         // If pnk has precedence less than or equal to another operator on the
         // stack, reduce. This combines nodes on the stack until we form the
@@ -6407,38 +6386,29 @@ Parser<ParseHandler>::orExpr1(InHandling
 
         nodeStack[depth] = pn;
         kindStack[depth] = pnk;
         depth++;
         MOZ_ASSERT(depth <= PRECEDENCE_CLASSES);
     }
 
     MOZ_ASSERT(depth == 0);
-    pc->parsingForInit = oldParsingForInit;
     return pn;
 }
 
 template <typename ParseHandler>
 MOZ_ALWAYS_INLINE typename ParseHandler::Node
 Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandling,
                                 InvokedPrediction invoked)
 {
     Node condition = orExpr1(inHandling, yieldHandling, invoked);
     if (!condition || !tokenStream.isCurrentTokenType(TOK_HOOK))
         return condition;
 
-    /*
-     * Always accept the 'in' operator in the middle clause of a ternary,
-     * where it's unambiguous, even if we might be parsing the init of a
-     * for statement.
-     */
-    bool oldParsingForInit = pc->parsingForInit;
-    pc->parsingForInit = false;
     Node thenExpr = assignExpr(InAllowed, yieldHandling);
-    pc->parsingForInit = oldParsingForInit;
     if (!thenExpr)
         return null();
 
     MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
 
     Node elseExpr = assignExpr(inHandling, yieldHandling);
     if (!elseExpr)
         return null();
@@ -8740,26 +8710,17 @@ Parser<ParseHandler>::parenExprOrGenerat
     uint32_t startYieldOffset = pc->lastYieldOffset;
 
     bool matched;
     if (!tokenStream.matchToken(&matched, TOK_FOR, TokenStream::Operand))
         return null();
     if (matched)
         return generatorComprehension(begin);
 
-    /*
-     * Always accept the 'in' operator in a parenthesized expression,
-     * where it's unambiguous, even if we might be parsing the init of a
-     * for statement.
-     */
-    bool oldParsingForInit = pc->parsingForInit;
-    pc->parsingForInit = false;
     Node pn = expr(InAllowed, yieldHandling, PredictInvoked);
-    pc->parsingForInit = oldParsingForInit;
-
     if (!pn)
         return null();
 
 #if JS_HAS_GENERATOR_EXPRS
     if (!tokenStream.matchToken(&matched, TOK_FOR))
         return null();
     if (matched) {
         if (pc->lastYieldOffset != startYieldOffset) {
@@ -8817,26 +8778,17 @@ Parser<ParseHandler>::parenExprOrGenerat
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP));
     uint32_t begin = pos().begin;
     uint32_t startYieldOffset = pc->lastYieldOffset;
 
-    /*
-     * Always accept the 'in' operator in a parenthesized expression,
-     * where it's unambiguous, even if we might be parsing the init of a
-     * for statement.
-     */
-    bool oldParsingForInit = pc->parsingForInit;
-    pc->parsingForInit = false;
     Node pn = expr(inHandling, yieldHandling, PredictInvoked);
-    pc->parsingForInit = oldParsingForInit;
-
     if (!pn)
         return null();
 
 #if JS_HAS_GENERATOR_EXPRS
     bool matched;
     if (!tokenStream.matchToken(&matched, TOK_FOR))
         return null();
     if (matched) {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -65,29 +65,25 @@ struct GenericParseContext
     bool funHasReturnExpr:1;
 
     // Function has 'return;'
     bool funHasReturnVoid:1;
 
     // The following flags are set when parsing enters a particular region of
     // source code, and cleared when that region is exited.
 
-    // true while parsing init expr of for; exclude 'in'
-    bool parsingForInit:1;
-
     // true while we are within a with-statement in the current ParseContext
     // chain (which stops at the top-level or an eval()
     bool parsingWith:1;
 
     GenericParseContext(GenericParseContext* parent, SharedContext* sc)
       : parent(parent),
         sc(sc),
         funHasReturnExpr(false),
         funHasReturnVoid(false),
-        parsingForInit(false),
         parsingWith(parent ? parent->parsingWith : false)
     {}
 };
 
 template <typename ParseHandler>
 bool
 GenerateBlockId(TokenStream& ts, ParseContext<ParseHandler>* pc, uint32_t& blockid);
 
@@ -521,16 +517,17 @@ class Parser : private JS::AutoGCRooter,
     }
 
     const ReadOnlyCompileOptions& options() const {
         return tokenStream.options();
     }
 
   private:
     enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
+    enum ForInitLocation { InForInit, NotInForInit };
 
   private:
     /*
      * JS parsers, from lowest to highest precedence.
      *
      * Each parser must be called during the dynamic scope of a ParseContext
      * object, pointed to by this->pc.
      *
@@ -565,18 +562,20 @@ class Parser : private JS::AutoGCRooter,
 
     Node lexicalDeclaration(YieldHandling yieldHandling, bool isConst);
     Node letDeclarationOrBlock(YieldHandling yieldHandling);
     Node importDeclaration();
     Node exportDeclaration();
     Node expressionStatement(YieldHandling yieldHandling,
                              InvokedPrediction invoked = PredictUninvoked);
     Node variables(YieldHandling yieldHandling,
-                   ParseNodeKind kind, bool* psimple = nullptr,
-                   StaticBlockObject* blockObj = nullptr, VarContext varContext = HoistVars);
+                   ParseNodeKind kind,
+                   ForInitLocation location,
+                   bool* psimple = nullptr, StaticBlockObject* blockObj = nullptr,
+                   VarContext varContext = HoistVars);
     Node expr(InHandling inHandling, YieldHandling yieldHandling,
               InvokedPrediction invoked = PredictUninvoked);
     Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
                     InvokedPrediction invoked = PredictUninvoked);
     Node assignExprWithoutYield(YieldHandling yieldHandling, unsigned err);
     Node yieldExpression(InHandling inHandling);
     Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
                    InvokedPrediction invoked = PredictUninvoked);
--- a/js/src/gc/Nursery-inl.h
+++ b/js/src/gc/Nursery-inl.h
@@ -37,17 +37,20 @@ namespace js {
 
 template <typename T>
 static inline T*
 AllocateObjectBuffer(ExclusiveContext* cx, uint32_t count)
 {
     if (cx->isJSContext()) {
         Nursery& nursery = cx->asJSContext()->runtime()->gc.nursery;
         size_t nbytes = JS_ROUNDUP(count * sizeof(T), sizeof(Value));
-        return static_cast<T*>(nursery.allocateBuffer(cx->zone(), nbytes));
+        T* buffer = static_cast<T*>(nursery.allocateBuffer(cx->zone(), nbytes));
+        if (!buffer)
+            ReportOutOfMemory(cx);
+        return buffer;
     }
     return cx->zone()->pod_malloc<T>(count);
 }
 
 template <typename T>
 static inline T*
 AllocateObjectBuffer(ExclusiveContext* cx, JSObject* obj, uint32_t count)
 {
@@ -65,18 +68,21 @@ AllocateObjectBuffer(ExclusiveContext* c
 // If this returns null then the old buffer will be left alone.
 template <typename T>
 static inline T*
 ReallocateObjectBuffer(ExclusiveContext* cx, JSObject* obj, T* oldBuffer,
                        uint32_t oldCount, uint32_t newCount)
 {
     if (cx->isJSContext()) {
         Nursery& nursery = cx->asJSContext()->runtime()->gc.nursery;
-        return static_cast<T*>(nursery.reallocateBuffer(obj, oldBuffer,
-                                                        oldCount * sizeof(T),
-                                                        newCount * sizeof(T)));
+        T* buffer =  static_cast<T*>(nursery.reallocateBuffer(obj, oldBuffer,
+                                                              oldCount * sizeof(T),
+                                                              newCount * sizeof(T)));
+        if (!buffer)
+            ReportOutOfMemory(cx);
+        return buffer;
     }
     return obj->zone()->pod_realloc<T>(oldBuffer, oldCount, newCount);
 }
 
 } // namespace js
 
 #endif /* gc_Nursery_inl_h */
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -620,27 +620,27 @@ Statistics::formatJsonDescription(uint64
     int64_t sccTotal, sccLongest;
     sccDurations(&sccTotal, &sccLongest);
 
     double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC);
     double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
 
     const char *format =
         "\"timestamp\":%llu,"
-        "\"max_pause\":%lu.%03lu,"
-        "\"total_time\":%lu.%03lu,"
+        "\"max_pause\":%llu.%03llu,"
+        "\"total_time\":%llu.%03llu,"
         "\"zones_collected\":%d,"
         "\"total_zones\":%d,"
         "\"total_compartments\":%d,"
         "\"minor_gcs\":%d,"
         "\"store_buffer_overflows\":%d,"
         "\"mmu_20ms\":%d,"
         "\"mmu_50ms\":%d,"
-        "\"scc_sweep_total\":%lu.%03lu,"
-        "\"scc_sweep_max_pause\":%lu.%03lu,"
+        "\"scc_sweep_total\":%llu.%03llu,"
+        "\"scc_sweep_max_pause\":%llu.%03llu,"
         "\"nonincremental_reason\":\"%s\","
         "\"allocated\":%u,"
         "\"added_chunks\":%d,"
         "\"removed_chunks\":%d,";
     char buffer[1024];
     memset(buffer, 0, sizeof(buffer));
     JS_snprintf(buffer, sizeof(buffer), format,
                 (unsigned long long)timestamp,
@@ -668,18 +668,18 @@ Statistics::formatJsonSliceDescription(u
     int64_t duration = slices[i].duration();
     int64_t when = slices[i].start - slices[0].start;
     char budgetDescription[200];
     slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
     int64_t pageFaults = slices[i].endFaults - slices[i].startFaults;
 
     const char* format =
         "\"slice\":%d,"
-        "\"pause\":%lu.%03lu,"
-        "\"when\":%lu.%03lu,"
+        "\"pause\":%llu.%03llu,"
+        "\"when\":%llu.%03llu,"
         "\"reason\":\"%s\","
         "\"budget\":\"%s\","
         "\"page_faults\":%llu,"
         "\"start_timestamp\":%llu,"
         "\"end_timestamp\":%llu,";
     char buffer[1024];
     memset(buffer, 0, sizeof(buffer));
     JS_snprintf(buffer, sizeof(buffer), format,
@@ -716,17 +716,17 @@ Statistics::formatJsonPhaseTimes(PhaseTi
     char buffer[128];
     for (AllPhaseIterator iter(phaseTimes); !iter.done(); iter.advance()) {
         Phase phase;
         size_t dagSlot;
         iter.get(&phase, &dagSlot);
 
         UniqueChars name = FilterJsonKey(phases[phase].name);
         int64_t ownTime = phaseTimes[dagSlot][phase];
-        JS_snprintf(buffer, sizeof(buffer), "\"%s\":%lu.%03lu",
+        JS_snprintf(buffer, sizeof(buffer), "\"%s\":%llu.%03llu",
                     name.get(), ownTime / 1000, ownTime % 1000);
 
         if (!fragments.append(make_string_copy(buffer)))
             return UniqueChars(nullptr);
     }
     return Join(fragments, ",");
 }
 
--- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp
+++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp
@@ -32,16 +32,18 @@
 
 #include "irregexp/RegExpStack.h"
 #include "jit/Linker.h"
 #ifdef JS_ION_PERF
 # include "jit/PerfSpewer.h"
 #endif
 #include "vm/MatchPairs.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace js::irregexp;
 using namespace js::jit;
 
 /*
  * This assembler uses the following register assignment convention:
  *
  * - current_character :
old mode 100644
new mode 100755
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug734196.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var x = new ArrayBuffer(2);
-gczeal(4);
-actual = [].concat(x).toString();
-var count2 = countHeap();
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug747926.js
+++ /dev/null
@@ -1,12 +0,0 @@
-a = 'a';
-b = [,];
-exhaustiveSliceTest("exhaustive slice test 1", a);
-print('---');
-exhaustiveSliceTest("exhaustive slice test 2", b);
-function exhaustiveSliceTest(testname, a){
-  x = 0
-  var y = 0;
-  countHeap();
-    for (y=a.length; y + a.length; y--) { print(y);
-					  var b  = a.slice(x,y); }
-}
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug821340.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var g = newGlobal();
-var dbg = Debugger(g);
-function test(code, expected) {
-    var actual = '';
-    g.h = function () { actual += dbg.getNewestFrame().environment.type; }
-    g.eval(code);
-}
-test("h();", 'object');
-gczeal(4);
-var count2 = countHeap();
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -7581,37 +7581,29 @@ ComputeGetPropResult(JSContext* cx, Base
         if (op == JSOP_LENGTH) {
             res.setInt32(frame->numActualArgs());
         } else {
             MOZ_ASSERT(name == cx->names().callee);
             MOZ_ASSERT(!frame->script()->strict());
             res.setObject(*frame->callee());
         }
     } else {
-        // Handle when val is an object.
-        RootedObject obj(cx, ToObjectFromStack(cx, val));
-        if (!obj)
-            return false;
-
-        RootedId id(cx, NameToId(name));
-        if (op == JSOP_GETXPROP) {
-            if (!GetPropertyForNameLookup(cx, obj, id, res))
+        if (op == JSOP_GETPROP || op == JSOP_LENGTH) {
+            if (!GetProperty(cx, val, name, res))
+                return false;
+        } else if (op == JSOP_CALLPROP) {
+            if (!CallProperty(cx, val, name, res))
                 return false;
         } else {
-            if (!GetProperty(cx, obj, obj, id, res))
+            MOZ_ASSERT(op == JSOP_GETXPROP);
+            RootedObject obj(cx, &val.toObject());
+            RootedId id(cx, NameToId(name));
+            if (!GetPropertyForNameLookup(cx, obj, id, res))
                 return false;
         }
-
-#if JS_HAS_NO_SUCH_METHOD
-        // Handle objects with __noSuchMethod__.
-        if (op == JSOP_CALLPROP && MOZ_UNLIKELY(res.isUndefined()) && val.isObject()) {
-            if (!OnUnknownMethod(cx, obj, IdToValue(id), res))
-                return false;
-        }
-#endif
     }
 
     return true;
 }
 
 static bool
 DoGetPropFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_,
                   MutableHandleValue val, MutableHandleValue res)
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -34,16 +34,17 @@
 #include "jit/MoveEmitter.h"
 #include "jit/RangeAnalysis.h"
 #include "vm/MatchPairs.h"
 #include "vm/RegExpStatics.h"
 #include "vm/TraceLogging.h"
 
 #include "jsboolinlines.h"
 
+#include "jit/MacroAssembler-inl.h"
 #include "jit/shared/CodeGenerator-shared-inl.h"
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 using mozilla::FloatingPoint;
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1274,17 +1274,17 @@ OptimizeMIR(MIRGenerator* mir)
     }
 
     gs.spewPass("BuildSSA");
     AssertBasicGraphCoherency(graph);
 
     if (mir->shouldCancel("Start"))
         return false;
 
-    if (!mir->compilingAsmJS()) {
+    {
         AutoTraceLog log(logger, TraceLogger_FoldTests);
         FoldTests(graph);
         gs.spewPass("Fold Tests");
         AssertBasicGraphCoherency(graph);
 
         if (mir->shouldCancel("Fold Tests"))
             return false;
     }
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3495,29 +3495,34 @@ jit::AnalyzeArgumentsUsage(JSContext* cx
     TempAllocator temp(&alloc);
     JitContext jctx(cx, &temp);
 
     if (!cx->compartment()->ensureJitCompartmentExists(cx))
         return false;
 
     MIRGraph graph(&temp);
     InlineScriptTree* inlineScriptTree = InlineScriptTree::New(&temp, nullptr, nullptr, script);
-    if (!inlineScriptTree)
+    if (!inlineScriptTree) {
+        ReportOutOfMemory(cx);
         return false;
+    }
+
     CompileInfo info(script, script->functionNonDelazifying(),
                      /* osrPc = */ nullptr, /* constructing = */ false,
                      Analysis_ArgumentsUsage,
                      /* needsArgsObj = */ true,
                      inlineScriptTree);
 
     const OptimizationInfo* optimizationInfo = js_IonOptimizations.get(Optimization_Normal);
 
     CompilerConstraintList* constraints = NewCompilerConstraintList(temp);
-    if (!constraints)
+    if (!constraints) {
+        ReportOutOfMemory(cx);
         return false;
+    }
 
     BaselineInspector inspector(script);
     const JitCompileOptions options(cx);
 
     IonBuilder builder(nullptr, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
                        &inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
 
     if (!builder.build()) {
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -21,16 +21,17 @@
 #ifdef JS_ION_PERF
 # include "jit/PerfSpewer.h"
 #endif
 #include "jit/VMFunctions.h"
 #include "js/Proxy.h"
 #include "vm/Shape.h"
 
 #include "jit/JitFrames-inl.h"
+#include "jit/MacroAssembler-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/Shape-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::tl::FloorLog2;
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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_inl_h
+#define jit_MacroAssembler_inl_h
+
+#include "jit/MacroAssembler.h"
+
+namespace js {
+namespace jit {
+
+// ===============================================================
+// Frame manipulation functions.
+
+uint32_t
+MacroAssembler::framePushed() const
+{
+    return framePushed_;
+}
+
+void
+MacroAssembler::setFramePushed(uint32_t framePushed)
+{
+    framePushed_ = framePushed;
+}
+
+void
+MacroAssembler::adjustFrame(int value)
+{
+    setFramePushed(framePushed_ + value);
+}
+
+void
+MacroAssembler::implicitPop(uint32_t bytes)
+{
+    MOZ_ASSERT(bytes % sizeof(intptr_t) == 0);
+    adjustFrame(-bytes);
+}
+
+// ===============================================================
+// Stack manipulation functions.
+
+CodeOffsetLabel
+MacroAssembler::PushWithPatch(ImmWord word)
+{
+    framePushed_ += sizeof(word.value);
+    return pushWithPatch(word);
+}
+
+CodeOffsetLabel
+MacroAssembler::PushWithPatch(ImmPtr imm)
+{
+    return PushWithPatch(ImmWord(uintptr_t(imm.value)));
+}
+
+// ===============================================================
+// Call functions.
+
+void
+MacroAssembler::call(const CallSiteDesc& desc, const Register reg)
+{
+    call(reg);
+    append(desc, currentOffset(), framePushed());
+}
+
+void
+MacroAssembler::call(const CallSiteDesc& desc, Label* label)
+{
+    call(label);
+    append(desc, currentOffset(), framePushed());
+}
+
+// ===============================================================
+
+void
+MacroAssembler::PushStubCode()
+{
+    exitCodePatch_ = PushWithPatch(ImmWord(-1));
+}
+
+void
+MacroAssembler::enterExitFrame(const VMFunction* f)
+{
+    linkExitFrame();
+    // Push the ioncode. (Bailout or VM wrapper)
+    PushStubCode();
+    // Push VMFunction pointer, to mark arguments.
+    Push(ImmPtr(f));
+}
+
+void
+MacroAssembler::enterFakeExitFrame(JitCode* codeVal)
+{
+    linkExitFrame();
+    Push(ImmPtr(codeVal));
+    Push(ImmPtr(nullptr));
+}
+
+void
+MacroAssembler::leaveExitFrame(size_t extraFrame)
+{
+    freeStack(ExitFooterFrame::Size() + extraFrame);
+}
+
+bool
+MacroAssembler::hasEnteredExitFrame() const
+{
+    return exitCodePatch_.offset() != 0;
+}
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_MacroAssembler_inl_h */
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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/. */
 
-#include "jit/MacroAssembler.h"
+#include "jit/MacroAssembler-inl.h"
 
 #include "jsprf.h"
 
 #include "builtin/TypedObject.h"
 #include "gc/GCTrace.h"
 #include "jit/AtomicOp.h"
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
@@ -2473,16 +2473,69 @@ MacroAssembler::alignJitStackBasedOnNArg
         bind(&end);
         assertStackAlignment(JitStackAlignment, sizeof(Value));
     } else {
         andToStackPtr(Imm32(~(JitStackAlignment - 1)));
     }
 }
 
 // ===============================================================
+
+MacroAssembler::MacroAssembler(JSContext* cx, IonScript* ion,
+                               JSScript* script, jsbytecode* pc)
+  : emitProfilingInstrumentation_(false),
+    framePushed_(0)
+{
+    constructRoot(cx);
+    jitContext_.emplace(cx, (js::jit::TempAllocator*)nullptr);
+    alloc_.emplace(cx);
+    moveResolver_.setAllocator(*jitContext_->temp);
+#ifdef JS_CODEGEN_ARM
+    initWithAllocator();
+    m_buffer.id = GetJitContext()->getNextAssemblerId();
+#endif
+    if (ion) {
+        setFramePushed(ion->frameSize());
+        if (pc && cx->runtime()->spsProfiler.enabled())
+            emitProfilingInstrumentation_ = true;
+    }
+}
+
+void
+MacroAssembler::resetForNewCodeGenerator(TempAllocator& alloc)
+{
+    setFramePushed(0);
+    moveResolver_.clearTempObjectPool();
+    moveResolver_.setAllocator(alloc);
+}
+
+MacroAssembler::AfterICSaveLive
+MacroAssembler::icSaveLive(LiveRegisterSet& liveRegs)
+{
+    PushRegsInMask(liveRegs);
+    AfterICSaveLive aic(framePushed());
+    alignFrameForICArguments(aic);
+    return aic;
+}
+
+bool
+MacroAssembler::icBuildOOLFakeExitFrame(void* fakeReturnAddr, AfterICSaveLive& aic)
+{
+    return buildOOLFakeExitFrame(fakeReturnAddr);
+}
+
+void
+MacroAssembler::icRestoreLive(LiveRegisterSet& liveRegs, AfterICSaveLive& aic)
+{
+    restoreFrameAlignmentForICArguments(aic);
+    MOZ_ASSERT(framePushed() == aic.initialStack);
+    PopRegsInMask(liveRegs);
+}
+
+// ===============================================================
 // Stack manipulation functions.
 
 void
 MacroAssembler::PushRegsInMask(LiveGeneralRegisterSet set)
 {
     PushRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet()));
 }
 
@@ -2621,8 +2674,23 @@ MacroAssembler::popRooted(VMFunction::Ro
 void
 MacroAssembler::adjustStack(int amount)
 {
     if (amount > 0)
         freeStack(amount);
     else if (amount < 0)
         reserveStack(-amount);
 }
+
+void
+MacroAssembler::freeStack(uint32_t amount)
+{
+    MOZ_ASSERT(amount <= framePushed_);
+    if (amount)
+        addPtr(Imm32(amount), StackPointer);
+    framePushed_ -= amount;
+}
+
+void
+MacroAssembler::freeStack(Register amount)
+{
+    addPtr(amount, StackPointer);
+}
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -214,17 +214,18 @@ class MacroAssembler : public MacroAssem
     // sites.
     bool emitProfilingInstrumentation_;
 
     // Labels for handling exceptions and failures.
     NonAssertingLabel failureLabel_;
 
   public:
     MacroAssembler()
-      : emitProfilingInstrumentation_(false)
+      : emitProfilingInstrumentation_(false),
+        framePushed_(0)
     {
         JitContext* jcx = GetJitContext();
         JSContext* cx = jcx->cx;
         if (cx)
             constructRoot(cx);
 
         if (!jcx->temp) {
             MOZ_ASSERT(cx);
@@ -236,69 +237,70 @@ class MacroAssembler : public MacroAssem
         initWithAllocator();
         m_buffer.id = jcx->getNextAssemblerId();
 #endif
     }
 
     // This constructor should only be used when there is no JitContext active
     // (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp).
     explicit MacroAssembler(JSContext* cx, IonScript* ion = nullptr,
-                            JSScript* script = nullptr, jsbytecode* pc = nullptr)
-      : emitProfilingInstrumentation_(false)
-    {
-        constructRoot(cx);
-        jitContext_.emplace(cx, (js::jit::TempAllocator*)nullptr);
-        alloc_.emplace(cx);
-        moveResolver_.setAllocator(*jitContext_->temp);
-#ifdef JS_CODEGEN_ARM
-        initWithAllocator();
-        m_buffer.id = GetJitContext()->getNextAssemblerId();
-#endif
-        if (ion) {
-            setFramePushed(ion->frameSize());
-            if (pc && cx->runtime()->spsProfiler.enabled())
-                emitProfilingInstrumentation_ = true;
-        }
-    }
+                            JSScript* script = nullptr, jsbytecode* pc = nullptr);
 
     // asm.js compilation handles its own JitContext-pushing
     struct AsmJSToken {};
     explicit MacroAssembler(AsmJSToken)
-      : emitProfilingInstrumentation_(false)
+      : emitProfilingInstrumentation_(false),
+        framePushed_(0)
     {
 #ifdef JS_CODEGEN_ARM
         initWithAllocator();
         m_buffer.id = 0;
 #endif
     }
 
     void enableProfilingInstrumentation() {
         emitProfilingInstrumentation_ = true;
     }
 
-    void resetForNewCodeGenerator(TempAllocator& alloc) {
-        setFramePushed(0);
-        moveResolver_.clearTempObjectPool();
-        moveResolver_.setAllocator(alloc);
-    }
+    void resetForNewCodeGenerator(TempAllocator& alloc);
 
     void constructRoot(JSContext* cx) {
         autoRooter_.emplace(cx, this);
     }
 
     MoveResolver& moveResolver() {
         return moveResolver_;
     }
 
     size_t instructionsSize() const {
         return size();
     }
 
   public:
     // ===============================================================
+    // Frame manipulation functions.
+
+    inline uint32_t framePushed() const;
+    inline void setFramePushed(uint32_t framePushed);
+    inline void adjustFrame(int value);
+
+    // Adjust the frame, to account for implicit modification of the stack
+    // pointer, such that callee can remove arguments on the behalf of the
+    // caller.
+    inline void implicitPop(uint32_t bytes);
+
+  private:
+    // This field is used to statically (at compilation time) emulate a frame
+    // pointer by keeping track of stack manipulations.
+    //
+    // It is maintained by all stack manipulation functions below.
+    uint32_t framePushed_;
+
+  public:
+    // ===============================================================
     // Stack manipulation functions.
 
     void PushRegsInMask(LiveRegisterSet set) PER_ARCH;
     void PushRegsInMask(LiveGeneralRegisterSet set);
 
     void PopRegsInMask(LiveRegisterSet set);
     void PopRegsInMask(LiveGeneralRegisterSet set);
     void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) PER_ARCH;
@@ -313,24 +315,41 @@ class MacroAssembler : public MacroAssem
     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 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:
+    // ===============================================================
+    // Call functions.
+
+    using MacroAssemblerSpecific::call; // legacy
+
+    inline void call(const CallSiteDesc& desc, const Register reg);
+    inline void call(const CallSiteDesc& desc, Label* label);
 
   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);
 
@@ -750,17 +769,17 @@ class MacroAssembler : public MacroAssem
         if (reg.hasValue())
             return extractObject(reg.valueReg(), scratch);
         MOZ_ASSERT(reg.type() == MIRType_Object);
         return reg.typedReg().gpr();
     }
 
     // Inline version of js_TypedArray_uint8_clamp_double.
     // This function clobbers the input register.
-    void clampDoubleToUint8(FloatRegister input, Register output);
+    void clampDoubleToUint8(FloatRegister input, Register output) PER_ARCH;
 
     using MacroAssemblerSpecific::ensureDouble;
 
     template <typename S>
     void ensureDouble(const S& source, FloatRegister dest, Label* failure) {
         Label isDouble, done;
         branchTestDouble(Assembler::Equal, source, &isDouble);
         branchTestInt32(Assembler::NotEqual, source, failure);
@@ -821,43 +840,29 @@ class MacroAssembler : public MacroAssem
     // This is a reference to a patch location where the JitCode* will be written.
   private:
     CodeOffsetLabel exitCodePatch_;
 
   private:
     void linkExitFrame();
 
   public:
-    void PushStubCode() {
-        exitCodePatch_ = PushWithPatch(ImmWord(-1));
-    }
+    inline void PushStubCode();
 
-    void enterExitFrame(const VMFunction* f = nullptr) {
-        linkExitFrame();
-        // Push the ioncode. (Bailout or VM wrapper)
-        PushStubCode();
-        // Push VMFunction pointer, to mark arguments.
-        Push(ImmPtr(f));
-    }
+    // Push stub code, and the VMFunction pointer.
+    inline void enterExitFrame(const VMFunction* f = nullptr);
 
     // The JitCode * argument here is one of the tokens defined in the various
     // exit frame layout classes, e.g. NativeExitFrameLayout::Token().
-    void enterFakeExitFrame(JitCode* codeVal) {
-        linkExitFrame();
-        Push(ImmPtr(codeVal));
-        Push(ImmPtr(nullptr));
-    }
+    inline void enterFakeExitFrame(JitCode* codeVal);
 
-    void leaveExitFrame(size_t extraFrame = 0) {
-        freeStack(ExitFooterFrame::Size() + extraFrame);
-    }
+    // Pop ExitFrame footer in addition to the extra frame.
+    inline void leaveExitFrame(size_t extraFrame = 0);
 
-    bool hasEnteredExitFrame() const {
-        return exitCodePatch_.offset() != 0;
-    }
+    inline bool hasEnteredExitFrame() const;
 
     // Generates code used to complete a bailout.
     void generateBailoutTail(Register scratch, Register bailoutInfo);
 
     // These functions exist as small wrappers around sites where execution can
     // leave the currently running stream of instructions. They exist so that
     // instrumentation may be put in place around them if necessary and the
     // instrumentation is enabled. For the functions that return a uint32_t,
@@ -1265,35 +1270,22 @@ class MacroAssembler : public MacroAssem
 
       public:
 #ifdef JS_DEBUG
         uint32_t initialStack;
 #endif
         uint32_t alignmentPadding;
     };
 
-    void alignFrameForICArguments(AfterICSaveLive& aic);
-    void restoreFrameAlignmentForICArguments(AfterICSaveLive& aic);
-
-    AfterICSaveLive icSaveLive(LiveRegisterSet& liveRegs) {
-        PushRegsInMask(liveRegs);
-        AfterICSaveLive aic(framePushed());
-        alignFrameForICArguments(aic);
-        return aic;
-    }
+    void alignFrameForICArguments(AfterICSaveLive& aic) PER_ARCH;
+    void restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) PER_ARCH;
 
-    bool icBuildOOLFakeExitFrame(void* fakeReturnAddr, AfterICSaveLive& aic) {
-        return buildOOLFakeExitFrame(fakeReturnAddr);
-    }
-
-    void icRestoreLive(LiveRegisterSet& liveRegs, AfterICSaveLive& aic) {
-        restoreFrameAlignmentForICArguments(aic);
-        MOZ_ASSERT(framePushed() == aic.initialStack);
-        PopRegsInMask(liveRegs);
-    }
+    AfterICSaveLive icSaveLive(LiveRegisterSet& liveRegs);
+    bool icBuildOOLFakeExitFrame(void* fakeReturnAddr, AfterICSaveLive& aic);
+    void icRestoreLive(LiveRegisterSet& liveRegs, AfterICSaveLive& aic);
 
     // Align the stack pointer based on the number of arguments which are pushed
     // on the stack, such that the JitFrameLayout would be correctly aligned on
     // the JitStackAlignment.
     void alignJitStackBasedOnNArgs(Register nargs);
     void alignJitStackBasedOnNArgs(uint32_t nargs);
 
     void assertStackAlignment(uint32_t alignment, int32_t offset = 0) {
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -18,16 +18,17 @@
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "js/Conversions.h"
 #include "vm/Shape.h"
 #include "vm/TraceLogging.h"
 
 #include "jsscriptinlines.h"
 
+#include "jit/MacroAssembler-inl.h"
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::FloorLog2;
 using mozilla::NegativeInfinity;
 using JS::GenericNaN;
--- a/js/src/jit/arm/CodeGenerator-arm.h
+++ b/js/src/jit/arm/CodeGenerator-arm.h
@@ -21,32 +21,16 @@ class CodeGeneratorARM : public CodeGene
     friend class MoveResolverARM;
 
     CodeGeneratorARM* thisFromCtor() {return this;}
 
   protected:
     // Label for the common return path.
     NonAssertingLabel returnLabel_;
     NonAssertingLabel deoptLabel_;
-    // Ugh. This is not going to be pretty to move over. Stack slotted variables
-    // are not useful on arm. It looks like this will need to return one of two
-    // types.
-    inline Operand ToOperand(const LAllocation& a) {
-        if (a.isGeneralReg())
-            return Operand(a.toGeneralReg()->reg());
-        if (a.isFloatReg())
-            return Operand(a.toFloatReg()->reg());
-        return Operand(StackPointer, ToStackOffset(&a));
-    }
-    inline Operand ToOperand(const LAllocation* a) {
-        return ToOperand(*a);
-    }
-    inline Operand ToOperand(const LDefinition* def) {
-        return ToOperand(def->output());
-    }
 
     MoveOperand toMoveOperand(LAllocation a) const;
 
     void bailoutIf(Assembler::Condition condition, LSnapshot* snapshot);
     void bailoutFrom(Label* label, LSnapshot* snapshot);
     void bailout(LSnapshot* snapshot);
 
     template <typename T1, typename T2>
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -12,16 +12,18 @@
 
 #include "jit/arm/Simulator-arm.h"
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
 #include "jit/JitFrames.h"
 #include "jit/MacroAssembler.h"
 #include "jit/MoveEmitter.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace jit;
 
 using mozilla::Abs;
 using mozilla::BitwiseCast;
 
 bool
 isValueDTRDCandidate(ValueOperand& val)
@@ -1798,80 +1800,80 @@ MacroAssemblerARM::ma_vstr(VFPRegister s
 {
     as_add(ScratchRegister, base, lsl(index, shift), LeaveCC, cc);
     return ma_vstr(src, Address(ScratchRegister, offset), cc);
 }
 
 void
 MacroAssemblerARMCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
 {
-    DebugOnly<uint32_t> initialDepth = framePushed();
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
 
     asMasm().Push(Imm32(descriptor)); // descriptor_
 
     enterNoPool(2);
     DebugOnly<uint32_t> offsetBeforePush = currentOffset();
     asMasm().Push(pc); // actually pushes $pc + 8.
 
     // Consume an additional 4 bytes. The start of the next instruction will
     // then be 8 bytes after the instruction for Push(pc); this offset can
     // therefore be fed to the safepoint.
     ma_nop();
     uint32_t pseudoReturnOffset = currentOffset();
     leaveNoPool();
 
-    MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
+    MOZ_ASSERT(asMasm().framePushed() == initialDepth + ExitFrameLayout::Size());
     MOZ_ASSERT(pseudoReturnOffset - offsetBeforePush == 8);
 
     *offset = pseudoReturnOffset;
 }
 
 bool
 MacroAssemblerARMCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
 {
-    DebugOnly<uint32_t> initialDepth = framePushed();
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
 
     asMasm().Push(Imm32(descriptor)); // descriptor_
     asMasm().Push(ImmPtr(fakeReturnAddr));
 
     return true;
 }
 
 void
 MacroAssemblerARMCompat::callWithExitFrame(Label* target)
 {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor)); // descriptor
 
     ma_callJitHalfPush(target);
 }
 
 void
 MacroAssemblerARMCompat::callWithExitFrame(JitCode* target)
 {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor)); // descriptor
 
     addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
     RelocStyle rs;
     if (HasMOVWT())
         rs = L_MOVWT;
     else
         rs = L_LDR;
 
     ma_movPatchable(ImmPtr(target->raw()), ScratchRegister, Always, rs);
     ma_callJitHalfPush(ScratchRegister);
 }
 
 void
 MacroAssemblerARMCompat::callWithExitFrame(JitCode* target, Register dynStack)
 {
-    ma_add(Imm32(framePushed()), dynStack);
+    ma_add(Imm32(asMasm().framePushed()), dynStack);
     makeFrameDescriptor(dynStack, JitFrame_IonJS);
     asMasm().Push(dynStack); // descriptor
 
     addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
     RelocStyle rs;
     if (HasMOVWT())
         rs = L_MOVWT;
     else
@@ -1879,21 +1881,21 @@ MacroAssemblerARMCompat::callWithExitFra
 
     ma_movPatchable(ImmPtr(target->raw()), ScratchRegister, Always, rs);
     ma_callJitHalfPush(ScratchRegister);
 }
 
 void
 MacroAssemblerARMCompat::callJit(Register callee)
 {
-    MOZ_ASSERT((framePushed() & 3) == 0);
-    if ((framePushed() & 7) == 4) {
+    MOZ_ASSERT((asMasm().framePushed() & 3) == 0);
+    if ((asMasm().framePushed() & 7) == 4) {
         ma_callJitHalfPush(callee);
     } else {
-        adjustFrame(sizeof(void*));
+        asMasm().adjustFrame(sizeof(void*));
         ma_callJit(callee);
     }
 }
 
 void
 MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic)
 {
     // Exists for MIPS compatibility.
@@ -1901,37 +1903,16 @@ MacroAssembler::alignFrameForICArguments
 
 void
 MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic)
 {
     // Exists for MIPS compatibility.
 }
 
 void
-MacroAssemblerARMCompat::reserveStack(uint32_t amount)
-{
-    if (amount)
-        ma_sub(Imm32(amount), sp);
-    adjustFrame(amount);
-}
-void
-MacroAssemblerARMCompat::freeStack(uint32_t amount)
-{
-    MOZ_ASSERT(amount <= framePushed_);
-    if (amount)
-        ma_add(Imm32(amount), sp);
-    adjustFrame(-amount);
-}
-void
-MacroAssemblerARMCompat::freeStack(Register amount)
-{
-    ma_add(amount, sp);
-}
-
-void
 MacroAssemblerARMCompat::add32(Register src, Register dest)
 {
     ma_add(src, dest, SetCC);
 }
 
 void
 MacroAssemblerARMCompat::add32(Imm32 imm, Register dest)
 {
@@ -3975,25 +3956,25 @@ MacroAssemblerARMCompat::callWithABIPre(
     *stackAdjust = ((usedIntSlots_ > NumIntArgRegs) ? usedIntSlots_ - NumIntArgRegs : 0) * sizeof(intptr_t);
 #if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR)
     if (UseHardFpABI())
         *stackAdjust += 2*((usedFloatSlots_ > NumFloatArgRegs) ? usedFloatSlots_ - NumFloatArgRegs : 0) * sizeof(intptr_t);
 #endif
     uint32_t alignmentAtPrologue = callFromAsmJS ? sizeof(AsmJSFrame) : 0;
 
     if (!dynamicAlignment_) {
-        *stackAdjust += ComputeByteAlignment(framePushed_ + *stackAdjust + alignmentAtPrologue,
+        *stackAdjust += ComputeByteAlignment(asMasm().framePushed() + *stackAdjust + alignmentAtPrologue,
                                              ABIStackAlignment);
     } else {
         // sizeof(intptr_t) accounts for the saved stack pointer pushed by
         // setupUnalignedABICall.
         *stackAdjust += ComputeByteAlignment(*stackAdjust + sizeof(intptr_t), ABIStackAlignment);
     }
 
-    reserveStack(*stackAdjust);
+    asMasm().reserveStack(*stackAdjust);
 
     // Position all arguments.
     {
         enoughMemory_ = enoughMemory_ && moveResolver_.resolve();
         if (!enoughMemory_)
             return;
 
         MoveEmitter emitter(asMasm());
@@ -4061,17 +4042,17 @@ MacroAssemblerARMCompat::callWithABIPost
         }
       case MoveOp::GENERAL:
         break;
 
       default:
         MOZ_CRASH("unexpected callWithABI result");
     }
 
-    freeStack(stackAdjust);
+    asMasm().freeStack(stackAdjust);
 
     if (dynamicAlignment_) {
         // While the x86 supports pop esp, on ARM that isn't well defined, so
         // just do it manually.
         as_dtr(IsLoad, 32, Offset, sp, DTRAddr(sp, DtrOffImm(0)));
     }
 
     MOZ_ASSERT(inCall_);
@@ -5243,10 +5224,18 @@ MacroAssembler::Pop(Register reg)
     ma_pop(reg);
     adjustFrame(-sizeof(intptr_t));
 }
 
 void
 MacroAssembler::Pop(const ValueOperand& val)
 {
     popValue(val);
-    framePushed_ -= sizeof(Value);
-}
+    adjustFrame(-sizeof(Value));
+}
+
+void
+MacroAssembler::reserveStack(uint32_t amount)
+{
+    if (amount)
+        ma_sub(Imm32(amount), sp);
+    adjustFrame(amount);
+}
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -527,29 +527,19 @@ class MacroAssemblerARMCompat : public M
     // function.
     //
     // arg            Number of arguments of the function.
     void setupABICall(uint32_t arg);
 
   protected:
     MoveResolver moveResolver_;
 
-    // Extra bytes currently pushed onto the frame beyond frameDepth_. This is
-    // needed to compute offsets to stack slots while temporary space has been
-    // reserved for unexpected spills or C++ function calls. It is maintained by
-    // functions which track stack alignment, which for clear distinction use
-    // StudlyCaps (for example, Push, Pop).
-    uint32_t framePushed_;
-    void adjustFrame(int value) {
-        setFramePushed(framePushed_ + value);
-    }
   public:
     MacroAssemblerARMCompat()
-      : inCall_(false),
-        framePushed_(0)
+      : inCall_(false)
     { }
 
   public:
     using MacroAssemblerARM::call;
 
     // Jumps + other functions that should be called from non-arm specific
     // code. Basically, an x86 front end on top of the ARM code.
     void j(Condition code , Label* dest)
@@ -603,24 +593,16 @@ class MacroAssemblerARMCompat : public M
         if (HasMOVWT())
             rs = L_MOVWT;
         else
             rs = L_LDR;
 
         ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
         ma_callJitHalfPush(ScratchRegister);
     }
-    void call(const CallSiteDesc& desc, const Register reg) {
-        call(reg);
-        append(desc, currentOffset(), framePushed_);
-    }
-    void call(const CallSiteDesc& desc, Label* label) {
-        call(label);
-        append(desc, currentOffset(), framePushed_);
-    }
     void callAndPushReturnAddress(Label* label) {
         AutoForbidPools afp(this, 2);
         ma_push(pc);
         call(label);
     }
 
     void branch(JitCode* c) {
         BufferOffset bo = m_buffer.nextOffset();
@@ -1256,63 +1238,29 @@ class MacroAssemblerARMCompat : public M
     }
 
     void handleFailureWithHandlerTail(void* handler);
 
     /////////////////////////////////////////////////////////////////
     // Common interface.
     /////////////////////////////////////////////////////////////////
   public:
-    // The following functions are exposed for use in platform-shared code.
-
-    CodeOffsetLabel PushWithPatch(ImmWord word) {
-        framePushed_ += sizeof(word.value);
-        return pushWithPatch(word);
-    }
-    CodeOffsetLabel PushWithPatch(ImmPtr imm) {
-        return PushWithPatch(ImmWord(uintptr_t(imm.value)));
-    }
-
-    void PushWithPadding(Register reg, const Imm32 extraSpace) {
-        pushWithPadding(reg, extraSpace);
-        adjustFrame(sizeof(intptr_t) + extraSpace.value);
-    }
-    void PushWithPadding(const Imm32 imm, const Imm32 extraSpace) {
-        pushWithPadding(imm, extraSpace);
-        adjustFrame(sizeof(intptr_t) + extraSpace.value);
-    }
-
-    void implicitPop(uint32_t args) {
-        MOZ_ASSERT(args % sizeof(intptr_t) == 0);
-        adjustFrame(-args);
-    }
-    uint32_t framePushed() const {
-        return framePushed_;
-    }
-    void setFramePushed(uint32_t framePushed) {
-        framePushed_ = framePushed;
-    }
-
     // Builds an exit frame on the stack, with a return address to an internal
     // non-function. Returns offset to be passed to markSafepointAt().
     void buildFakeExitFrame(Register scratch, uint32_t* offset);
 
     void callWithExitFrame(Label* target);
     void callWithExitFrame(JitCode* target);
     void callWithExitFrame(JitCode* target, Register dynStack);
 
     // Makes a call using the only two methods that it is sane for
     // independent code to make a call.
     void callJit(Register callee);
     void callJitFromAsmJS(Register callee) { as_blx(callee); }
 
-    void reserveStack(uint32_t amount);
-    void freeStack(uint32_t amount);
-    void freeStack(Register amount);
-
     void add32(Register src, Register dest);
     void add32(Imm32 imm, Register dest);
     void add32(Imm32 imm, const Address& dest);
     void sub32(Imm32 imm, Register dest);
     void sub32(Register src, Register dest);
     template <typename T>
     void branchAdd32(Condition cond, T src, Register dest, Label* label) {
         add32(src, dest);
--- a/js/src/jit/arm/MoveEmitter-arm.cpp
+++ b/js/src/jit/arm/MoveEmitter-arm.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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/. */
 
 #include "jit/arm/MoveEmitter-arm.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace js::jit;
 
 MoveEmitterARM::MoveEmitterARM(MacroAssembler& masm)
   : inCycle_(0),
     masm(masm),
     pushedAtCycle_(-1),
     pushedAtSpill_(-1),
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -12,16 +12,18 @@
 #include "jit/JitFrames.h"
 #include "jit/JitSpewer.h"
 #include "jit/Linker.h"
 #ifdef JS_ION_PERF
 # include "jit/PerfSpewer.h"
 #endif
 #include "jit/VMFunctions.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace js::jit;
 
 static const FloatRegisterSet NonVolatileFloatRegs =
     FloatRegisterSet((1ULL << FloatRegisters::d8) |
                      (1ULL << FloatRegisters::d9) |
                      (1ULL << FloatRegisters::d10) |
                      (1ULL << FloatRegisters::d11) |
--- a/js/src/jit/mips/CodeGenerator-mips.cpp
+++ b/js/src/jit/mips/CodeGenerator-mips.cpp
@@ -18,26 +18,45 @@
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "js/Conversions.h"
 #include "vm/Shape.h"
 #include "vm/TraceLogging.h"
 
 #include "jsscriptinlines.h"
 
+#include "jit/MacroAssembler-inl.h"
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::FloorLog2;
 using mozilla::NegativeInfinity;
 using JS::GenericNaN;
 using JS::ToInt32;
 
+// inline
+Address
+CodeGeneratorMIPS::ToAddress(const LAllocation& a)
+{
+    MOZ_ASSERT(a.isMemory());
+    int32_t offset = ToStackOffset(&a);
+
+    return Address(StackPointer, offset);
+}
+
+// inline
+Address
+CodeGeneratorMIPS::ToAddress(const LAllocation* a)
+{
+    return ToAddress(*a);
+}
+
+
 // shared
 CodeGeneratorMIPS::CodeGeneratorMIPS(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm)
   : CodeGeneratorShared(gen, graph, masm)
 {
 }
 
 bool
 CodeGeneratorMIPS::generatePrologue()
--- a/js/src/jit/mips/CodeGenerator-mips.h
+++ b/js/src/jit/mips/CodeGenerator-mips.h
@@ -24,44 +24,18 @@ class CodeGeneratorMIPS : public CodeGen
         return this;
     }
 
   protected:
     // Label for the common return path.
     NonAssertingLabel returnLabel_;
     NonAssertingLabel deoptLabel_;
 
-    inline Address ToAddress(const LAllocation& a) {
-        MOZ_ASSERT(a.isMemory());
-        int32_t offset = ToStackOffset(&a);
-
-        return Address(StackPointer, offset);
-    }
-
-    inline Address ToAddress(const LAllocation* a) {
-        return ToAddress(*a);
-    }
-
-    inline Operand ToOperand(const LAllocation& a) {
-        if (a.isGeneralReg())
-            return Operand(a.toGeneralReg()->reg());
-        if (a.isFloatReg())
-            return Operand(a.toFloatReg()->reg());
-
-        MOZ_ASSERT(a.isMemory());
-        int32_t offset = ToStackOffset(&a);
-
-        return Operand(StackPointer, offset);
-    }
-    inline Operand ToOperand(const LAllocation* a) {
-        return ToOperand(*a);
-    }
-    inline Operand ToOperand(const LDefinition* def) {
-        return ToOperand(def->output());
-    }
+    inline Address ToAddress(const LAllocation& a);
+    inline Address ToAddress(const LAllocation* a);
 
     MoveOperand toMoveOperand(LAllocation a) const;
 
     template <typename T1, typename T2>
     void bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot* snapshot) {
         Label skip;
         masm.ma_b(lhs, rhs, &skip, Assembler::InvertCondition(c), ShortJump);
         bailout(snapshot);
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -12,16 +12,18 @@
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineRegisters.h"
 #include "jit/JitFrames.h"
 #include "jit/MacroAssembler.h"
 #include "jit/mips/Simulator-mips.h"
 #include "jit/MoveEmitter.h"
 
+#include "jit/MacroAssembler-inl.h"
+
 using namespace js;
 using namespace jit;
 
 using mozilla::Abs;
 
 static const int32_t PAYLOAD_OFFSET = NUNBOX32_PAYLOAD_OFFSET;
 static const int32_t TAG_OFFSET = NUNBOX32_TYPE_OFFSET;
 
@@ -1494,111 +1496,88 @@ MacroAssemblerMIPS::ma_bc1d(FloatRegiste
     FloatTestKind testKind;
     compareFloatingPoint(DoubleFloat, lhs, rhs, c, &testKind, fcc);
     branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
 }
 
 void
 MacroAssemblerMIPSCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
 {
-    mozilla::DebugOnly<uint32_t> initialDepth = framePushed();
+    mozilla::DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
 
     CodeLabel cl;
     ma_li(scratch, cl.dest());
 
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor));
     asMasm().Push(scratch);
 
     bind(cl.src());
     *offset = currentOffset();
 
-    MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
+    MOZ_ASSERT(asMasm().framePushed() == initialDepth + ExitFrameLayout::Size());
     addCodeLabel(cl);
 }
 
 bool
 MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
 {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
 
     asMasm().Push(Imm32(descriptor)); // descriptor_
     asMasm().Push(ImmPtr(fakeReturnAddr));
 
     return true;
 }
 
 void
 MacroAssemblerMIPSCompat::callWithExitFrame(Label* target)
 {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor)); // descriptor
 
     ma_callJitHalfPush(target);
 }
 
 void
 MacroAssemblerMIPSCompat::callWithExitFrame(JitCode* target)
 {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor)); // descriptor
 
     addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
     ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
     ma_callJitHalfPush(ScratchRegister);
 }
 
 void
 MacroAssemblerMIPSCompat::callWithExitFrame(JitCode* target, Register dynStack)
 {
-    ma_addu(dynStack, dynStack, Imm32(framePushed()));
+    ma_addu(dynStack, dynStack, Imm32(asMasm().framePushed()));
     makeFrameDescriptor(dynStack, JitFrame_IonJS);
     asMasm().Push(dynStack); // descriptor
 
     addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
     ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
     ma_callJitHalfPush(ScratchRegister);
 }
 
 void
 MacroAssemblerMIPSCompat::callJit(Register callee)
 {
-    MOZ_ASSERT((framePushed() & 3) == 0);
-    if ((framePushed() & 7) == 4) {
+    MOZ_ASSERT((asMasm().framePushed() & 3) == 0);
+    if ((asMasm().framePushed() & 7) == 4) {
         ma_callJitHalfPush(callee);
     } else {
-        adjustFrame(sizeof(uint32_t));
+        asMasm().adjustFrame(sizeof(uint32_t));
         ma_callJit(callee);
     }
 }
 
 void
-MacroAssemblerMIPSCompat::reserveStack(uint32_t amount)
-{
-    if (amount)
-        ma_subu(StackPointer, StackPointer, Imm32(amount));
-    adjustFrame(amount);
-}
-
-void
-MacroAssemblerMIPSCompat::freeStack(uint32_t amount)
-{
-    MOZ_ASSERT(amount <= framePushed_);
-    if (amount)
-        ma_addu(StackPointer, StackPointer, Imm32(amount));
-    adjustFrame(-amount);
-}
-
-void
-MacroAssemblerMIPSCompat::freeStack(Register amount)
-{
-    as_addu(StackPointer, StackPointer, amount);
-}
-
-void
 MacroAssemblerMIPSCompat::add32(Register src, Register dest)
 {
     as_addu(dest, dest, src);
 }
 
 void
 MacroAssemblerMIPSCompat::add32(Imm32 imm, Register dest)
 {
@@ -3354,21 +3333,21 @@ MacroAssemblerMIPSCompat::callWithABIPre
                     usedArgSlots_ * sizeof(intptr_t) :
                     NumIntArgRegs * sizeof(intptr_t);
 
     uint32_t alignmentAtPrologue = callFromAsmJS ? sizeof(AsmJSFrame) : 0;
 
     if (dynamicAlignment_) {
         *stackAdjust += ComputeByteAlignment(*stackAdjust, ABIStackAlignment);
     } else {
-        *stackAdjust += ComputeByteAlignment(framePushed_ + alignmentAtPrologue + *stackAdjust,
+        *stackAdjust += ComputeByteAlignment(asMasm().framePushed() + alignmentAtPrologue + *stackAdjust,
                                              ABIStackAlignment);
     }
 
-    reserveStack(*stackAdjust);
+    asMasm().reserveStack(*stackAdjust);
 
     // Save $ra because call is going to clobber it. Restore it in
     // callWithABIPost. NOTE: This is needed for calls from BaselineIC.
     // Maybe we can do this differently.
     ma_sw(ra, Address(StackPointer, *stackAdjust - sizeof(intptr_t)));
 
     // Position all arguments.
     {
@@ -3389,19 +3368,19 @@ MacroAssemblerMIPSCompat::callWithABIPos
 {
     // Restore ra value (as stored in callWithABIPre()).
     ma_lw(ra, Address(StackPointer, stackAdjust - sizeof(intptr_t)));
 
     if (dynamicAlignment_) {
         // Restore sp value from stack (as stored in setupUnalignedABICall()).
         ma_lw(StackPointer, Address(StackPointer, stackAdjust));
         // Use adjustFrame instead of freeStack because we already restored sp.
-        adjustFrame(-stackAdjust);
+        asMasm().adjustFrame(-stackAdjust