Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 21 Feb 2014 13:18:38 +0100
changeset 170381 cd5862484910bd9ba9962721a4de17ec433ff0c8
parent 170380 7c7963536edbde5b19b5dc7e486e778122410c02 (current diff)
parent 170236 04bdb7369ba40e78b4ec2b5bfe2a17c1bc05bc8e (diff)
child 170382 bfecd06b79f20521dc59eda5686b15e084384cdc
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
milestone30.0a1
Merge mozilla-central to fx-team
dom/system/unix/Makefile.in
dom/system/unix/QTMLocationProvider.cpp
dom/system/unix/QTMLocationProvider.h
dom/system/unix/moz.build
dom/system/unix/nsHapticFeedback.cpp
dom/system/unix/nsHapticFeedback.h
gfx/gl/GLContextSkia.cpp
widget/qt/faststartupqt/Makefile.in
widget/qt/faststartupqt/moz.build
widget/qt/faststartupqt/mozqwidgetfast.cpp
widget/qt/faststartupqt/mozqwidgetfast.h
widget/qt/faststartupqt/nsFastStartupQt.cpp
widget/qt/faststartupqt/nsFastStartupQt.h
widget/qt/mozSwipeGesture.cpp
widget/qt/mozSwipeGesture.h
widget/qt/moziqwidget.h
widget/qt/mozqglwidgetwrapper.cpp
widget/qt/mozqglwidgetwrapper.h
widget/qt/mozqorientationsensorfilter.cpp
widget/qt/mozqorientationsensorfilter.h
widget/qt/nsCommonWidget.cpp
widget/qt/nsCommonWidget.h
widget/qt/nsDragService.cpp
widget/qt/nsDragService.h
widget/qt/nsFilePicker.cpp
widget/qt/nsFilePicker.h
widget/qt/nsMFilePicker.cpp
widget/qt/nsMFilePicker.h
widget/qt/nsNativeThemeQt.cpp
widget/qt/nsNativeThemeQt.h
widget/qt/nsSound.cpp
widget/qt/nsSound.h
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -113,18 +113,18 @@ this.AccessFu = {
     this._notifyOutputPref =
       new PrefCache('accessibility.accessfu.notify_output');
 
 
     this.Input.start();
     Output.start();
     TouchAdapter.start();
 
-    Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
-    Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
+    Services.obs.addObserver(this, 'remote-browser-shown', false);
+    Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'Accessibility:NextObject', false);
     Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
     Services.obs.addObserver(this, 'Accessibility:Focus', false);
     Services.obs.addObserver(this, 'Accessibility:ActivateObject', false);
     Services.obs.addObserver(this, 'Accessibility:LongPress', false);
     Services.obs.addObserver(this, 'Accessibility:MoveByGranularity', false);
     Utils.win.addEventListener('TabOpen', this);
     Utils.win.addEventListener('TabClose', this);
@@ -157,18 +157,18 @@ this.AccessFu = {
     this.Input.stop();
     Output.stop();
     TouchAdapter.stop();
 
     Utils.win.removeEventListener('TabOpen', this);
     Utils.win.removeEventListener('TabClose', this);
     Utils.win.removeEventListener('TabSelect', this);
 
-    Services.obs.removeObserver(this, 'remote-browser-frame-shown');
-    Services.obs.removeObserver(this, 'in-process-browser-or-app-frame-shown');
+    Services.obs.removeObserver(this, 'remote-browser-shown');
+    Services.obs.removeObserver(this, 'inprocess-browser-shown');
     Services.obs.removeObserver(this, 'Accessibility:NextObject');
     Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
     Services.obs.removeObserver(this, 'Accessibility:Focus');
     Services.obs.removeObserver(this, 'Accessibility:ActivateObject');
     Services.obs.removeObserver(this, 'Accessibility:LongPress');
     Services.obs.removeObserver(this, 'Accessibility:MoveByGranularity');
 
     delete this._quicknavModesPref;
@@ -299,21 +299,25 @@ this.AccessFu = {
         this._focused = JSON.parse(aData);
         if (this._focused) {
           this.showCurrent(true);
         }
         break;
       case 'Accessibility:MoveByGranularity':
         this.Input.moveByGranularity(JSON.parse(aData));
         break;
-      case 'remote-browser-frame-shown':
-      case 'in-process-browser-or-app-frame-shown':
+      case 'remote-browser-shown':
+      case 'inprocess-browser-shown':
       {
-        let mm = aSubject.QueryInterface(Ci.nsIFrameLoader).messageManager;
-        this._handleMessageManager(mm);
+        // Ignore notifications that aren't from a BrowserOrApp
+        let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
+        if (!frameLoader.ownerIsBrowserOrAppFrame) {
+          return;
+        }
+        this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
       case 'TabOpen':
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -751,16 +751,19 @@ pref("font.size.inflation.disabledInMast
 
 // Enable freeing dirty pages when minimizing memory; this reduces memory
 // consumption when applications are sent to the background.
 pref("memory.free_dirty_pages", true);
 
 // Enable the Linux-specific, system-wide memory reporter.
 pref("memory.system_memory_reporter", true);
 
+// Don't dump memory reports on OOM, by default.
+pref("memory.dump_reports_on_oom", false);
+
 pref("layout.imagevisibility.enabled", true);
 pref("layout.imagevisibility.numscrollportwidths", 1);
 pref("layout.imagevisibility.numscrollportheights", 1);
 
 // Enable native identity (persona/browserid)
 pref("dom.identity.enabled", true);
 
 // Wait up to this much milliseconds when orientation changed
--- a/b2g/chrome/content/devtools.js
+++ b/b2g/chrome/content/devtools.js
@@ -60,18 +60,18 @@ let devtoolsWidgetPanel = {
         this._webappsActor = res.webappsActor;
 
         for (let w of this._watchers) {
           if (w.init) {
             w.init(this._client);
           }
         }
 
-        Services.obs.addObserver(this, 'remote-browser-frame-pending', false);
-        Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
+        Services.obs.addObserver(this, 'remote-browser-pending', false);
+        Services.obs.addObserver(this, 'inprocess-browser-shown', false);
         Services.obs.addObserver(this, 'message-manager-disconnect', false);
 
         let systemapp = document.querySelector('#systemapp');
         let manifestURL = systemapp.getAttribute("mozapp");
         this.trackApp(manifestURL);
 
         let frames =
           systemapp.contentWindow.document.querySelectorAll('iframe[mozapp]');
@@ -86,18 +86,18 @@ let devtoolsWidgetPanel = {
   uninit: function dwp_uninit() {
     if (!this._client)
       return;
 
     for (let manifest of this._apps.keys()) {
       this.untrackApp(manifest);
     }
 
-    Services.obs.removeObserver(this, 'remote-browser-frame-pending');
-    Services.obs.removeObserver(this, 'in-process-browser-or-app-frame-shown');
+    Services.obs.removeObserver(this, 'remote-browser-pending');
+    Services.obs.removeObserver(this, 'inprocess-browser-shown');
     Services.obs.removeObserver(this, 'message-manager-disconnect');
 
     this._client.close();
     delete this._client;
   },
 
   /**
    * This method will ask all registered watchers to track and update metrics
@@ -145,21 +145,25 @@ let devtoolsWidgetPanel = {
     if (!this._client)
       return;
 
     let manifestURL;
 
     switch(topic) {
 
       // listen for frame creation in OOP (device) as well as in parent process (b2g desktop)
-      case 'remote-browser-frame-pending':
-      case 'in-process-browser-or-app-frame-shown':
+      case 'remote-browser-pending':
+      case 'inprocess-browser-shown':
         let frameLoader = subject;
         // get a ref to the app <iframe>
         frameLoader.QueryInterface(Ci.nsIFrameLoader);
+        // Ignore notifications that aren't from a BrowserOrApp
+        if (!frameLoader.ownerIsBrowserOrAppFrame) {
+          return;
+        }
         manifestURL = frameLoader.ownerElement.appManifestURL;
         if (!manifestURL) // Ignore all frames but apps
           return;
         this.trackApp(manifestURL);
         this._urls.set(frameLoader.messageManager, manifestURL);
         break;
 
       // Every time an iframe is destroyed, its message manager also is
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -165,19 +165,23 @@ let ErrorPage = {
 
     frameElement.addEventListener('mozbrowsererror',
                                   injectErrorPageScript,
                                   true // use capture
                                  );
   },
 
   init: function errorPageInit() {
-    Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
-    Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
+    Services.obs.addObserver(this, 'inprocess-browser-shown', false);
+    Services.obs.addObserver(this, 'remote-browser-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
+    // Ignore notifications that aren't from a BrowserOrApp
+    if (!frameLoader.ownerIsBrowserOrAppFrame) {
+      return;
+    }
     this._listenError(frameLoader);
   }
 };
 
 ErrorPage.init();
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="022eadd5917615ff00c47eaaafa792b45e9c8a28"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="97a5b461686757dbb8ecab2aac5903e41d2e1afe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="022eadd5917615ff00c47eaaafa792b45e9c8a28"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "14b730ec837b7c98864f06422a1556c90b9ab9cf", 
+    "revision": "5ef18673926479e25a67e4133256f11dea0cf88e", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -5,17 +5,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="97a5b461686757dbb8ecab2aac5903e41d2e1afe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="35365feace970bfc51276428f40a477c9c86b7bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b88eb63c3950ecaa88d00399735e52d83ab6e307"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -972,21 +972,21 @@ pref("toolbar.customization.usesheet", f
 #ifdef XP_MACOSX
 // On mac, the default pref is per-architecture
 pref("dom.ipc.plugins.enabled.i386", true);
 pref("dom.ipc.plugins.enabled.x86_64", true);
 #else
 pref("dom.ipc.plugins.enabled", true);
 #endif
 
-#if defined(NIGHTLY_BUILD) && defined(XP_MACOSX)
-// In Nightly, browser.tabs.remote is enabled on platforms that
-// support OMTC. However, users won't actually get remote tabs unless
-// they enable browser.tabs.remote.autostart or they use the "New OOP
-// Window" menu option.
+#if defined(NIGHTLY_BUILD)
+// browser.tabs.remote is enabled on nightly. However, users won't
+// actually get remote tabs unless they enable
+// browser.tabs.remote.autostart or they use the "New OOP Window" menu
+// option.
 pref("browser.tabs.remote", true);
 #else
 pref("browser.tabs.remote", false);
 #endif
 pref("browser.tabs.remote.autostart", false);
 
 // This pref governs whether we attempt to work around problems caused by
 // plugins using OS calls to manipulate the cursor while running out-of-
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3192,17 +3192,22 @@ function OpenBrowserWindow(options)
       // Force the new window to load about:privatebrowsing instead of the default home page
       defaultArgs = "about:privatebrowsing";
     }
   } else {
     extraFeatures = ",non-private";
   }
 
   if (options && options.remote) {
-    extraFeatures += ",remote";
+    let omtcEnabled = gPrefService.getBoolPref("layers.offmainthreadcomposition.enabled");
+    if (!omtcEnabled) {
+      alert("To use out-of-process tabs, you must set the layers.offmainthreadcomposition.enabled preference and restart. Opening a normal window instead.");
+    } else {
+      extraFeatures += ",remote";
+    }
   } else if (options && options.remote === false) {
     extraFeatures += ",non-remote";
   }
 
   // if and only if the current window is a browser window and it has a document with a character
   // set, then extract the current charset menu setting from the current document and use it to
   // initialize the new browser window...
   var win;
--- a/build/application.ini
+++ b/build/application.ini
@@ -13,16 +13,19 @@
 ; 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/.
 #endif
 #filter substitution
 [App]
 Vendor=@MOZ_APP_VENDOR@
 Name=@MOZ_APP_BASENAME@
+#ifdef MOZ_APP_DISPLAYNAME
+CodeName=@MOZ_APP_DISPLAYNAME@
+#endif
 Version=@MOZ_APP_VERSION@
 #ifdef MOZ_APP_PROFILE
 Profile=@MOZ_APP_PROFILE@
 #endif
 BuildID=@APP_BUILDID@
 #ifdef MOZ_SOURCE_REPO
 SourceRepository=@MOZ_SOURCE_REPO@
 #endif
--- a/build/moz.build
+++ b/build/moz.build
@@ -25,16 +25,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
         'mobile/robocop',
     ]
 
 for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
             'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
             'ACCEPTED_MAR_CHANNEL_IDS'):
     DEFINES[var] = CONFIG[var]
 
+if CONFIG['MOZ_APP_DISPLAYNAME'] != CONFIG['MOZ_APP_BASENAME']:
+    DEFINES['MOZ_APP_DISPLAYNAME'] = CONFIG['MOZ_APP_DISPLAYNAME']
+
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     DEFINES['MOZ_BUILD_APP_IS_BROWSER'] = True
 
 if CONFIG['MOZ_APP_PROFILE']:
     DEFINES['MOZ_APP_PROFILE'] = CONFIG['MOZ_APP_PROFILE']
 
 for var in ('MOZ_CRASHREPORTER', 'MOZ_PROFILE_MIGRATOR',
             'MOZ_EXTENSION_MANAGER', 'MOZ_APP_STATIC_INI'):
--- a/build/valgrind/mach_commands.py
+++ b/build/valgrind/mach_commands.py
@@ -84,17 +84,17 @@ class MachCommands(MachCommandBase):
                                      preferences=prefs,
                                      addons=[quitter],
                                      locations=locations)
 
             firefox_args = [httpd.get_url()]
 
             env = os.environ.copy()
             env['G_SLICE'] = 'always-malloc'
-            env['XPCOM_CC_RUN_DURING_SHUTDOWN'] = '1'
+            env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1'
             env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
             env['XPCOM_DEBUG_BREAK'] = 'warn'
 
             outputHandler = OutputHandler()
             kp_kwargs = {'processOutputLine': [outputHandler]}
 
             valgrind = 'valgrind'
             if not os.path.exists(valgrind):
--- a/configure.in
+++ b/configure.in
@@ -4394,16 +4394,29 @@ then
 
     TK_LIBS="$TK_LIBS $MOZ_STARTUP_NOTIFICATION_LIBS"
 fi
 AC_SUBST(MOZ_ENABLE_STARTUP_NOTIFICATION)
 AC_SUBST(MOZ_STARTUP_NOTIFICATION_CFLAGS)
 AC_SUBST(MOZ_STARTUP_NOTIFICATION_LIBS)
 
 dnl ========================================================
+dnl Disable printing
+dnl ========================================================
+MOZ_ARG_DISABLE_BOOL(printing,
+[  --disable-printing      Disable printing support],
+    NS_PRINTING=,
+    NS_PRINTING=1)
+
+if test "$NS_PRINTING"; then
+    AC_DEFINE(NS_PRINTING)
+    AC_DEFINE(NS_PRINT_PREVIEW)
+fi
+
+dnl ========================================================
 dnl = QT support
 dnl ========================================================
 if test "$MOZ_ENABLE_QT"
 then
     MOZ_ARG_WITH_STRING(qtdir,
     [  --with-qtdir=\$dir       Specify Qt directory ],
     [ QTDIR=$withval])
 
@@ -4413,75 +4426,69 @@ then
         HOST_QMAKE="$QTDIR/bin/qmake"
     fi
     QT_VERSION=`$HOST_QMAKE -v | grep 'Using Qt version' | egrep -o '[[0-9]]+\.[[0-9]]+\.[[0-9]]+'`
 
     if test -z "$QTDIR"; then
         case $QT_VERSION in
         5.*)
             AC_MSG_RESULT("Using qt5: $QT_VERSION")
-            PKG_CHECK_MODULES(MOZ_QT, Qt5Gui Qt5Network Qt5Core Qt5OpenGL Qt5Widgets Qt5PrintSupport, ,
+            PKG_CHECK_MODULES(MOZ_QT, Qt5Gui Qt5Network Qt5Core Qt5Quick, ,
             [
               AC_MSG_ERROR([$MOZ_QT_PKG_ERRORS Need qtbase development packages, (On Ubuntu, you might try installing the packages qtbase5-dev libqt5opengl5-dev.)])
             ])
             QT5INCDIR=`pkg-config --variable=includedir Qt5Gui`
             MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QT5INCDIR/QtGui/$QT_VERSION/QtGui"
-            ;;
-        4.*)
-            AC_MSG_RESULT("Using qt4: $QT_VERSION")
-            PKG_CHECK_MODULES(MOZ_QT, QtGui QtNetwork QtCore QtOpenGL, ,
-            [
-              AC_MSG_ERROR([$MOZ_QT_PKG_ERRORS Need qt4 development package, (On Ubuntu, you might try installing the packages libqt4-dev libqt4-opengl-dev.)])
-            ])
+            if test "$NS_PRINTING"; then
+                PKG_CHECK_MODULES(MOZ_QT_WIDGETS, Qt5PrintSupport, ,
+                [
+                  AC_MSG_ERROR([$MOZ_QT_PKG_ERRORS Need qtbase widgets development package])
+                ])
+                MOZ_QT_LIBS="$MOZ_QT_LIBS $MOZ_QT_WIDGETS_LIBS"
+                MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $MOZ_QT_WIDGETS_CFLAGS"
+            fi
             ;;
         *)
             AC_MSG_ERROR([* * * Unsupported Qt Version: $QT_VERSION])
             ;;
         esac
 
         AC_CHECK_PROGS(HOST_MOC, $MOC moc, "")
         AC_CHECK_PROGS(HOST_RCC, $RCC rcc, "")
     else
         MOZ_QT_CFLAGS="-DQT_SHARED"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtCore"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtNetwork"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtXml"
         MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtDeclarative"
-
         case $QT_VERSION in
         5.*)
             AC_MSG_RESULT("Using qt5: $QT_VERSION")
-            MOZ_QT_LIBS="-L$QTDIR/lib/ -lQt5Gui -lQt5Network -lQt5Core -lQt5Xml -lQt5OpenGL"
+            MOZ_QT_LIBS="$MOZ_QT_LIBS -L$QTDIR/lib/ -lQt5Gui -lQt5Network -lQt5Core -lQt5Xml"
             MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui/$QT_VERSION/QtGui"
-            MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtWidgets"
-            MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtPrintSupport"
-            MOZ_QT_LIBS="$MOZ_QT_LIBS -lQt5Widgets -lQt5PrintSupport"
-            ;;
-        4.*)
-            AC_MSG_RESULT("Using qt4: $QT_VERSION")
-            MOZ_QT_LIBS="-L$QTDIR/lib/ -lQtGui -lQtNetwork -lQtCore -lQtXml -lQtOpenGL"
-            MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/Qt"
+            if test "$NS_PRINTING"; then
+                MOZ_QT_LIBS="$MOZ_QT_LIBS -lQt5Widgets -lQt5PrintSupport"
+                MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtPrintSupport"
+            fi
             ;;
         *)
             AC_MSG_ERROR([* * * Unsupported Qt Version: $QT_VERSION])
             ;;
         esac
 
         HOST_MOC="$QTDIR/bin/moc"
         HOST_RCC="$QTDIR/bin/rcc"
     fi
     if test -z "$HOST_MOC"; then
-        AC_MSG_ERROR([No acceptable moc preprocessor found. Qt SDK is not installed or --with-qt is
-incorrect])
+        AC_MSG_ERROR([No acceptable moc preprocessor found. Qt SDK is not installed or --with-qt is incorrect])
     fi
     if test -z "$HOST_RCC"; then
-        AC_MSG_ERROR([No acceptable rcc preprocessor found. Qt SDK is not installed or --with-qt is
-incorrect])
+        AC_MSG_ERROR([No acceptable rcc preprocessor found. Qt SDK is not installed or --with-qt is incorrect])
     fi
 
     MOC=$HOST_MOC
     RCC=$HOST_RCC
 
     MOZ_ENABLE_QMSYSTEM2=
     PKG_CHECK_MODULES(_QMSYSTEM2, qmsystem2,
                       MOZ_ENABLE_QMSYSTEM2=1,
@@ -4520,16 +4527,40 @@ incorrect])
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtMobility"
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtSensors"
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtFeedback"
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtLocation"
           MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback -lQtLocation"
        ])
     fi
 
+    MOZ_ENABLE_QT5FEEDBACK=
+    PKG_CHECK_MODULES(_QT5FEEDBACK, Qt0Feedback,
+                      MOZ_ENABLE_QT5FEEDBACK=1,
+                      MOZ_ENABLE_QT5FEEDBACK=)
+    if test "$MOZ_ENABLE_QT5FEEDBACK"; then
+       MOZ_ENABLE_QT5FEEDBACK=1
+       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QT5FEEDBACK_CFLAGS"
+       MOZ_QT_LIBS="$MOZ_QT_LIBS $_QT5FEEDBACK_LIBS"
+       AC_DEFINE(MOZ_ENABLE_QT5FEEDBACK)
+       AC_SUBST(MOZ_ENABLE_QT5FEEDBACK)
+    fi
+
+    MOZ_ENABLE_QT5GEOPOSITION=
+    PKG_CHECK_MODULES(_QT5GEOPOSITION, Qt5Positioning,
+                      MOZ_ENABLE_QT5GEOPOSITION=1,
+                      MOZ_ENABLE_QT5GEOPOSITION=)
+    if test "$MOZ_ENABLE_QT5GEOPOSITION"; then
+       MOZ_ENABLE_QT5GEOPOSITION=1
+       MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QT5GEOPOSITION_CFLAGS"
+       MOZ_QT_LIBS="$MOZ_QT_LIBS $_QT5GEOPOSITION_LIBS"
+       AC_DEFINE(MOZ_ENABLE_QT5GEOPOSITION)
+       AC_SUBST(MOZ_ENABLE_QT5GEOPOSITION)
+    fi
+
     if test "$MOZ_ENABLE_CONTENTACTION"; then
       MOZ_ENABLE_CONTENTACTION=1
       AC_DEFINE(MOZ_ENABLE_CONTENTACTION)
     fi
 
     MOZ_ENABLE_CONTENTACTION=
     PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
     if test "$MOZ_ENABLE_CONTENTACTION"; then
@@ -4955,29 +4986,16 @@ fi
 dnl ========================================================
 dnl Accessibility is required for the linuxgl widget
 dnl backend
 dnl ========================================================
 if test "${MOZ_WIDGET_TOOLKIT}" = "linuxgl" -a "$ACCESSIBILITY" != "1"; then
     AC_MSG_ERROR(["Accessibility is required for the linuxgl widget backend"])
 fi
 
-dnl ========================================================
-dnl Disable printing
-dnl ========================================================
-MOZ_ARG_DISABLE_BOOL(printing,
-[  --disable-printing      Disable printing support],
-    NS_PRINTING=,
-    NS_PRINTING=1)
-
-if test "$NS_PRINTING"; then
-    AC_DEFINE(NS_PRINTING)
-    AC_DEFINE(NS_PRINT_PREVIEW)
-fi
-
 dnl Turn off webrtc for OS's we don't handle yet, but allow 
 dnl --enable-webrtc to override.  Can disable for everything in
 dnl the master list above.
 if test -n "$MOZ_WEBRTC"; then
     case "$target" in
     *-linux*|*-mingw*|*-darwin*|*-android*|*-linuxandroid*|*-dragonfly*|*-freebsd*|*-netbsd*|*-openbsd*)
         dnl Leave enabled
         ;;
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -107,17 +107,17 @@ interface nsIContentViewManager : nsISup
                          [retval, array, size_is(aLength)] out nsIContentView aResult);
 
   /**
    * The root content view.
    */
   readonly attribute nsIContentView rootContentView;
 };
 
-[scriptable, builtinclass, uuid(4c9f91c0-7a5d-11e3-981f-0800200c9a66)]
+[scriptable, builtinclass, uuid(a723673b-a26e-4cc6-ae23-ec70df9d97c9)]
 interface nsIFrameLoader : nsISupports
 {
   /**
    * Get the docshell from the frame loader.
    */
   readonly attribute nsIDocShell docShell;
 
   /**
@@ -275,16 +275,21 @@ interface nsIFrameLoader : nsISupports
   /**
    * Get or set this frame loader's visibility.
    *
    * The notion of "visibility" here is separate from the notion of a
    * window/docshell's visibility.  This field is mostly here so that we can
    * have a notion of visibility in the parent process when frames are OOP.
    */
   [infallible] attribute boolean visible;
+
+  /**
+   * Find out whether the owner content really is a browser or app frame
+   */
+  readonly attribute boolean ownerIsBrowserOrAppFrame;
 };
 
 %{C++
 class nsFrameLoader;
 %}
 
 native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5837,19 +5837,17 @@ nsContentUtils::IsUserFocusIgnored(nsINo
   while (aNode) {
     nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aNode);
     if (browserFrame &&
         aNode->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::ignoreuserfocus) &&
         browserFrame->GetReallyIsBrowserOrApp()) {
       return true;
     }
     nsPIDOMWindow* win = aNode->OwnerDoc()->GetWindow();
-    if (win) {
-      aNode = win->GetFrameElementInternal();
-    }
+    aNode = win ? win->GetFrameElementInternal() : nullptr;
   }
 
   return false;
 }
 
 bool
 nsContentUtils::HasScrollgrab(nsIContent* aContent)
 {
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -457,19 +457,19 @@ nsFrameLoader::ReallyStartLoadingInterna
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (mRemoteFrame) {
     if (!mRemoteBrowser) {
       if (!mPendingFrameSent) {
         nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-        if (OwnerIsBrowserOrAppFrame() && os && !mRemoteBrowserInitialized) {
+        if (os && !mRemoteBrowserInitialized) {
           os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                              "remote-browser-frame-pending", nullptr);
+                              "remote-browser-pending", nullptr);
           mPendingFrameSent = true;
         }
       }
       if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false) &&
           !ContentParent::PreallocatedProcessReady()) {
 
         ContentParent::RunAfterPreallocatedProcessReady(
             new DelayedStartLoadingRunnable(this));
@@ -990,24 +990,24 @@ nsFrameLoader::ShowRemoteFrame(const nsI
     }
 
     mRemoteBrowser->Show(size);
     mRemoteBrowserShown = true;
 
     EnsureMessageManager();
 
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (OwnerIsBrowserOrAppFrame() && os && !mRemoteBrowserInitialized) {
+    if (os && !mRemoteBrowserInitialized) {
       if (!mPendingFrameSent) {
         os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                            "remote-browser-frame-pending", nullptr);
+                            "remote-browser-pending", nullptr);
         mPendingFrameSent = true;
       }
       os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                          "remote-browser-frame-shown", nullptr);
+                          "remote-browser-shown", nullptr);
       mRemoteBrowserInitialized = true;
     }
   } else {
     nsRect dimensions;
     NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
 
     // Don't show remote iframe if we are waiting for the completion of reflow.
     if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
@@ -1444,16 +1444,24 @@ nsFrameLoader::SetOwnerContent(Element* 
 
 bool
 nsFrameLoader::OwnerIsBrowserOrAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
 }
 
+// The xpcom getter version
+NS_IMETHODIMP
+nsFrameLoader::GetOwnerIsBrowserOrAppFrame(bool* aResult)
+{
+  *aResult = OwnerIsBrowserOrAppFrame();
+  return NS_OK;
+}
+
 bool
 nsFrameLoader::OwnerIsAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsApp() : false;
 }
 
 bool
@@ -1710,29 +1718,27 @@ nsFrameLoader::MaybeCreateDocShell()
     uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (containingApp) {
       NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
                         NS_ERROR_FAILURE);
     }
     mDocShell->SetIsBrowserInsideApp(containingAppId);
   }
 
-  if (OwnerIsBrowserOrAppFrame()) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (os) {
-      os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                          "in-process-browser-or-app-frame-shown", nullptr);
-    }
-
-    if (mMessageManager) {
-      mMessageManager->LoadFrameScript(
-        NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
-        /* allowDelayedLoad = */ true,
-        /* aRunInGlobalScope */ true);
-    }
+  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+  if (os) {
+    os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
+                        "inprocess-browser-shown", nullptr);
+  }
+
+  if (OwnerIsBrowserOrAppFrame() && mMessageManager) {
+    mMessageManager->LoadFrameScript(
+      NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
+      /* allowDelayedLoad = */ true,
+      /* aRunInGlobalScope */ true);
   }
 
   return NS_OK;
 }
 
 void
 nsFrameLoader::GetURL(nsString& aURI)
 {
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -455,13 +455,13 @@ private:
   // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
   // favor of what content tells.
   uint32_t mRenderMode;
 
   // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
   // forwards some input events to out-of-process content.
   uint32_t mEventMode;
 
-  // Indicate if we have sent 'remote-browser-frame-pending'.
+  // Indicate if we have sent 'remote-browser-pending'.
   bool mPendingFrameSent;
 };
 
 #endif
old mode 100644
new mode 100755
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -1215,20 +1215,18 @@ WebGLContext::PresentScreenBuffer()
 
     return true;
 }
 
 void
 WebGLContext::DummyFramebufferOperation(const char *info)
 {
     GLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-    if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
-        return;
-    else
-        return ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
+    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
+        ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
 }
 
 // We use this timer for many things. Here are the things that it is activated for:
 // 1) If a script is using the MOZ_WEBGL_lose_context extension.
 // 2) If we are using EGL and _NOT ANGLE_, we query periodically to see if the
 //    CONTEXT_LOST_WEBGL error has been triggered.
 // 3) If we are using ANGLE, or anything that supports ARB_robustness, query the
 //    GPU periodically to see if the reset status bit has been set.
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -939,38 +939,63 @@ protected:
 
     virtual bool IsWebGL2() const = 0;
 
     bool InitWebGL2();
 
 
     // -------------------------------------------------------------------------
     // Validation functions (implemented in WebGLContextValidate.cpp)
+    GLenum BaseTexFormat(GLenum internalFormat) const;
+
     bool InitAndValidateGL();
     bool ValidateBlendEquationEnum(GLenum cap, const char *info);
     bool ValidateBlendFuncDstEnum(GLenum mode, const char *info);
     bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info);
     bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info);
     bool ValidateTextureTargetEnum(GLenum target, const char *info);
     bool ValidateComparisonEnum(GLenum target, const char *info);
     bool ValidateStencilOpEnum(GLenum action, const char *info);
     bool ValidateFaceEnum(GLenum face, const char *info);
-    bool ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType,
-                                      uint32_t *texelSize, const char *info);
+    bool ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFunc func);
     bool ValidateDrawModeEnum(GLenum mode, const char *info);
     bool ValidateAttribIndex(GLuint index, const char *info);
     bool ValidateStencilParamsForDrawCall();
 
     bool ValidateGLSLVariableName(const nsAString& name, const char *info);
     bool ValidateGLSLCharacter(char16_t c);
     bool ValidateGLSLString(const nsAString& string, const char *info);
-    bool ValidateTexImage2DFormat(GLenum format, const char* info);
-    bool ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info);
-    bool ValidateCompressedTextureSize(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, uint32_t byteLength, const char* info);
-    bool ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, GLsizei height, const char* info);
+
+    bool ValidateTexImage(GLuint dims, GLenum target,
+                          GLint level, GLint internalFormat,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLint width, GLint height, GLint depth,
+                          GLint border, GLenum format, GLenum type,
+                          WebGLTexImageFunc func);
+    bool ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func);
+    bool ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func);
+    bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func);
+    bool ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func);
+    bool ValidateTexImageSize(GLenum target, GLint level,
+                              GLint width, GLint height, GLint depth,
+                              WebGLTexImageFunc func);
+    bool ValidateTexSubImageSize(GLint x, GLint y, GLint z,
+                                 GLsizei width, GLsizei height, GLsizei depth,
+                                 GLsizei baseWidth, GLsizei baseHeight, GLsizei baseDepth,
+                                 WebGLTexImageFunc func);
+
+    bool ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
+                                  GLint xoffset, GLint yoffset,
+                                  GLsizei width, GLsizei height,
+                                  GLsizei levelWidth, GLsizei levelHeight,
+                                  WebGLTexImageFunc func);
+    bool ValidateCompTexImageDataSize(GLint level, GLenum format,
+                                      GLsizei width, GLsizei height,
+                                      uint32_t byteLength, WebGLTexImageFunc func);
+
 
     static uint32_t GetBitsPerTexel(GLenum format, GLenum type);
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
     void MakeContextCurrent() const;
 
@@ -1047,17 +1072,21 @@ protected:
 private:
     // Like ValidateObject, but only for cases when aObject is known
     // to not be null already.
     template<class ObjectType>
     bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
 
 protected:
     int32_t MaxTextureSizeForTarget(GLenum target) const {
-        return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
+        MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
+                   (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+                    target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z),
+                   "Invalid target enum");
+        return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
     }
 
     /** like glBufferData but if the call may change the buffer size, checks any GL error generated
      * by this glBufferData call and returns it */
     GLenum CheckedBufferData(GLenum target,
                              GLsizeiptr size,
                              const GLvoid *data,
                              GLenum usage);
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -384,19 +384,27 @@ WebGLContext::CopyTexSubImage2D_base(GLe
                                      GLsizei width,
                                      GLsizei height,
                                      bool sub)
 {
     const WebGLRectangleObject* framebufferRect = CurValidFBRectObject();
     GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
-    const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
-
-    if (!ValidateLevelWidthHeightForTarget(target, level, width, height, info)) {
+    const char* info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
+    WebGLTexImageFunc func = sub ? WebGLTexImageFunc::CopyTexSubImage : WebGLTexImageFunc::CopyTexImage;
+
+    // TODO: This changes with color_buffer_float. Reassess when the
+    // patch lands.
+    if (!ValidateTexImage(2, target, level, internalformat,
+                          xoffset, yoffset, 0,
+                          width, height, 0,
+                          0, internalformat, LOCAL_GL_UNSIGNED_BYTE,
+                          func))
+    {
         return;
     }
 
     MakeContextCurrent();
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
 
     if (!tex)
@@ -410,34 +418,35 @@ WebGLContext::CopyTexSubImage2D_base(GLe
     } else {
 
         // the rect doesn't fit in the framebuffer
 
         /*** first, we initialize the texture as black ***/
 
         // first, compute the size of the buffer we should allocate to initialize the texture as black
 
-        uint32_t texelSize = 0;
-        if (!ValidateTexFormatAndType(internalformat, LOCAL_GL_UNSIGNED_BYTE, -1, &texelSize, info))
+        if (!ValidateTexInputData(LOCAL_GL_UNSIGNED_BYTE, -1, func))
             return;
 
+        uint32_t texelSize = GetBitsPerTexel(internalformat, LOCAL_GL_UNSIGNED_BYTE) / 8;
+
         CheckedUint32 checked_neededByteLength =
             GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
 
         if (!checked_neededByteLength.isValid())
             return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
 
         uint32_t bytesNeeded = checked_neededByteLength.value();
 
         // now that the size is known, create the buffer
 
         // We need some zero pages, because GL doesn't guarantee the
         // contents of a texture allocated with nullptr data.
         // Hopefully calloc will just mmap zero pages here.
-        void *tempZeroData = calloc(1, bytesNeeded);
+        void* tempZeroData = calloc(1, bytesNeeded);
         if (!tempZeroData)
             return ErrorOutOfMemory("%s: could not allocate %d bytes (for zero fill)", info, bytesNeeded);
 
         // now initialize the texture as black
 
         if (sub)
             gl->fTexSubImage2D(target, level, 0, 0, width, height,
                                internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
@@ -481,106 +490,65 @@ WebGLContext::CopyTexImage2D(GLenum targ
                              GLint y,
                              GLsizei width,
                              GLsizei height,
                              GLint border)
 {
     if (IsContextLost())
         return;
 
-    switch (target) {
-        case LOCAL_GL_TEXTURE_2D:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            break;
-        default:
-            return ErrorInvalidEnumInfo("copyTexImage2D: target", target);
-    }
-
-
-    switch (internalformat) {
-        case LOCAL_GL_RGB:
-        case LOCAL_GL_LUMINANCE:
-        case LOCAL_GL_RGBA:
-        case LOCAL_GL_ALPHA:
-        case LOCAL_GL_LUMINANCE_ALPHA:
-            break;
-        default:
-            return ErrorInvalidEnumInfo("copyTexImage2D: internal format", internalformat);
+    // copyTexImage2D only generates textures with type = UNSIGNED_BYTE
+    const WebGLTexImageFunc func = WebGLTexImageFunc::CopyTexImage;
+    GLenum type = LOCAL_GL_UNSIGNED_BYTE;
+
+    if (!ValidateTexImage(2, target, level, internalformat,
+                          0, 0, 0,
+                          width, height, 0,
+                          border, internalformat, type,
+                          func))
+    {
+        return;
     }
 
-    if (border != 0)
-        return ErrorInvalidValue("copyTexImage2D: border must be 0");
-
-    if (width < 0 || height < 0)
-        return ErrorInvalidValue("copyTexImage2D: width and height may not be negative");
-
-    if (level < 0)
-        return ErrorInvalidValue("copyTexImage2D: level may not be negative");
-
-    GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
-    if (!(maxTextureSize >> level))
-        return ErrorInvalidValue("copyTexImage2D: 2^level exceeds maximum texture size");
-
-    if (level >= 1) {
-        if (!(is_pot_assuming_nonnegative(width) &&
-              is_pot_assuming_nonnegative(height)))
-            return ErrorInvalidValue("copyTexImage2D: with level > 0, width and height must be powers of two");
-    }
-
-    if (internalformat == LOCAL_GL_DEPTH_COMPONENT ||
-        internalformat == LOCAL_GL_DEPTH_STENCIL)
-        return ErrorInvalidOperation("copyTexImage2D: a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
-
-    WebGLTexture *tex = activeBoundTextureForTarget(target);
-    if (!tex)
-        return ErrorInvalidOperation("copyTexImage2D: no texture bound to this target");
-    
-    if (mBoundFramebuffer)
-        if (!mBoundFramebuffer->CheckAndInitializeAttachments())
-            return ErrorInvalidFramebufferOperation("copyTexImage2D: incomplete framebuffer");
+    if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeAttachments())
+        return ErrorInvalidFramebufferOperation("copyTexImage2D: incomplete framebuffer");
 
     bool texFormatRequiresAlpha = internalformat == LOCAL_GL_RGBA ||
-                                    internalformat == LOCAL_GL_ALPHA ||
-                                    internalformat == LOCAL_GL_LUMINANCE_ALPHA;
+                                  internalformat == LOCAL_GL_ALPHA ||
+                                  internalformat == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment(0).HasAlpha()
                                                : bool(gl->GetPixelFormat().alpha > 0);
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
-    // copyTexImage2D only generates textures with type = UNSIGNED_BYTE
-    GLenum type = LOCAL_GL_UNSIGNED_BYTE;
-
     // check if the memory size of this texture may change with this call
     bool sizeMayChange = true;
+    WebGLTexture* tex = activeBoundTextureForTarget(target);
     if (tex->HasImageInfoAt(target, level)) {
         const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
 
         sizeMayChange = width != imageInfo.Width() ||
                         height != imageInfo.Height() ||
                         internalformat != imageInfo.InternalFormat() ||
                         type != imageInfo.Type();
     }
 
-    if (sizeMayChange) {
+    if (sizeMayChange)
         UpdateWebGLErrorAndClearGLError();
-        CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
+
+    CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
+
+    if (sizeMayChange) {
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError(&error);
         if (error) {
             GenerateWarning("copyTexImage2D generated error %s", ErrorName(error));
             return;
         }
-    } else {
-        CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
     }
 
     tex->SetImageInfo(target, level, width, height, internalformat, type,
                       WebGLImageDataStatus::InitializedImageData);
 }
 
 void
 WebGLContext::CopyTexSubImage2D(GLenum target,
@@ -3351,154 +3319,86 @@ WebGLContext::CompileShader(WebGLShader 
     }
 }
 
 void
 WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
                                    GLsizei width, GLsizei height, GLint border,
                                    const ArrayBufferView& view)
 {
-    if (IsContextLost()) {
-        return;
-    }
-
-    if (!ValidateTexImage2DTarget(target, width, height, "compressedTexImage2D")) {
+    if (IsContextLost())
         return;
-    }
-
-    WebGLTexture *tex = activeBoundTextureForTarget(target);
-    if (!tex) {
-        ErrorInvalidOperation("compressedTexImage2D: no texture is bound to this target");
-        return;
-    }
-
-    if (!mCompressedTextureFormats.Contains(internalformat)) {
-        ErrorInvalidEnum("compressedTexImage2D: compressed texture format 0x%x is not supported", internalformat);
-        return;
-    }
-
-    if (border) {
-        ErrorInvalidValue("compressedTexImage2D: border is not 0");
+
+    const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexImage;
+
+    if (!ValidateTexImage(2, target, level, internalformat,
+                          0, 0, 0, width, height, 0,
+                          border, internalformat, LOCAL_GL_UNSIGNED_BYTE,
+                          func))
+    {
         return;
     }
 
     uint32_t byteLength = view.Length();
-    if (!ValidateCompressedTextureSize(target, level, internalformat, width, height, byteLength, "compressedTexImage2D")) {
+    if (!ValidateCompTexImageDataSize(target, internalformat, width, height, byteLength, func)) {
         return;
     }
 
     MakeContextCurrent();
     gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
+    WebGLTexture* tex = activeBoundTextureForTarget(target);
+    MOZ_ASSERT(tex);
     tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE,
                       WebGLImageDataStatus::InitializedImageData);
 
     ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
 }
 
 void
 WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
                                       GLint yoffset, GLsizei width, GLsizei height,
                                       GLenum format, const ArrayBufferView& view)
 {
-    if (IsContextLost()) {
+    if (IsContextLost())
         return;
-    }
-
-    switch (target) {
-        case LOCAL_GL_TEXTURE_2D:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            break;
-        default:
-            return ErrorInvalidEnumInfo("texSubImage2D: target", target);
+
+    const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexSubImage;
+
+    if (!ValidateTexImage(2, target,
+                          level, format,
+                          xoffset, yoffset, 0,
+                          width, height, 0,
+                          0, format, LOCAL_GL_UNSIGNED_BYTE,
+                          func))
+    {
+        return;
     }
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
-    if (!tex) {
-        ErrorInvalidOperation("compressedTexSubImage2D: no texture is bound to this target");
-        return;
-    }
-
-    if (!mCompressedTextureFormats.Contains(format)) {
-        ErrorInvalidEnum("compressedTexSubImage2D: compressed texture format 0x%x is not supported", format);
-        return;
-    }
-
-    if (!ValidateLevelWidthHeightForTarget(target, level, width, height, "compressedTexSubImage2D")) {
+    MOZ_ASSERT(tex);
+    WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(target, level);
+
+    if (!ValidateCompTexImageSize(target, level, format,
+                                  xoffset, yoffset,
+                                  width, height,
+                                  levelInfo.Width(), levelInfo.Height(),
+                                  func))
+    {
         return;
     }
 
     uint32_t byteLength = view.Length();
-    if (!ValidateCompressedTextureSize(target, level, format, width, height, byteLength, "compressedTexSubImage2D")) {
-        return;
-    }
-
-    if (!tex->HasImageInfoAt(target, level)) {
-        ErrorInvalidOperation("compressedTexSubImage2D: no texture image previously defined for this level and face");
-        return;
-    }
-
-    const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(target, level);
-
-    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.Width(), imageInfo.Height())) {
-        ErrorInvalidValue("compressedTexSubImage2D: subtexture rectangle out of bounds");
+    if (!ValidateCompTexImageDataSize(target, format, width, height, byteLength, func))
         return;
-    }
-
-    switch (format) {
-        case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-        {
-            if (xoffset < 0 || xoffset % 4 != 0) {
-                ErrorInvalidOperation("compressedTexSubImage2D: xoffset is not a multiple of 4");
-                return;
-            }
-            if (yoffset < 0 || yoffset % 4 != 0) {
-                ErrorInvalidOperation("compressedTexSubImage2D: yoffset is not a multiple of 4");
-                return;
-            }
-            if (width % 4 != 0 && width != imageInfo.Width()) {
-                ErrorInvalidOperation("compressedTexSubImage2D: width is not a multiple of 4 or equal to texture width");
-                return;
-            }
-            if (height % 4 != 0 && height != imageInfo.Height()) {
-                ErrorInvalidOperation("compressedTexSubImage2D: height is not a multiple of 4 or equal to texture height");
-                return;
-            }
-            break;
-        }
-        case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
-        case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
-        case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
-        case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
-        {
-            if (xoffset || yoffset ||
-                width != imageInfo.Width() ||
-                height != imageInfo.Height())
-            {
-                ErrorInvalidValue("compressedTexSubImage2D: the update rectangle doesn't match the existing image");
-                return;
-            }
-        }
-    }
-
-    if (imageInfo.HasUninitializedImageData()) {
+
+    if (levelInfo.HasUninitializedImageData())
         tex->DoDeferredImageInitialization(target, level);
-    }
 
     MakeContextCurrent();
     gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.Data());
-
-    return;
 }
 
 JS::Value
 WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname)
 {
     if (IsContextLost())
         return JS::NullValue();
 
@@ -3728,58 +3628,38 @@ void
 WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
                               GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
                               GLint border,
                               GLenum format, GLenum type,
                               void *data, uint32_t byteLength,
                               int jsArrayType, // a TypedArray format enum, or -1 if not relevant
                               WebGLTexelFormat srcFormat, bool srcPremultiplied)
 {
-    if (!ValidateTexImage2DTarget(target, width, height, "texImage2D")) {
+    const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
+
+    if (!ValidateTexImage(2, target, level, internalformat,
+                          0, 0, 0,
+                          width, height, 0,
+                          border, format, type, func))
+    {
         return;
     }
 
-    if (!ValidateTexImage2DFormat(format, "texImage2D: format"))
-        return;
-
-    if (format != internalformat)
-        return ErrorInvalidOperation("texImage2D: format does not match internalformat");
-
-    if (!ValidateLevelWidthHeightForTarget(target, level, width, height, "texImage2D")) {
-        return;
-    }
-
-    if (level >= 1) {
-        if (!(is_pot_assuming_nonnegative(width) &&
-              is_pot_assuming_nonnegative(height)))
-            return ErrorInvalidValue("texImage2D: with level > 0, width and height must be powers of two");
-    }
-
-    if (border != 0)
-        return ErrorInvalidValue("texImage2D: border must be 0");
-
     const bool isDepthTexture = format == LOCAL_GL_DEPTH_COMPONENT ||
                                 format == LOCAL_GL_DEPTH_STENCIL;
 
     if (isDepthTexture) {
-        if (IsExtensionEnabled(WEBGL_depth_texture)) {
-            if (target != LOCAL_GL_TEXTURE_2D || data != nullptr || level != 0)
-                return ErrorInvalidOperation("texImage2D: "
-                                             "with format of DEPTH_COMPONENT or DEPTH_STENCIL, "
-                                             "target must be TEXTURE_2D, "
-                                             "data must be nullptr, "
-                                             "level must be zero"); // Haiku by unknown Zen master
-        } else {
-            return ErrorInvalidEnum("texImage2D: attempt to create a depth texture "
-                                    "without having enabled the WEBGL_depth_texture extension.");
-        }
+        if (data != nullptr || level != 0)
+            return ErrorInvalidOperation("texImage2D: "
+                                         "with format of DEPTH_COMPONENT or DEPTH_STENCIL, "
+                                         "data must be nullptr, "
+                                         "level must be zero");
     }
 
-    uint32_t dstTexelSize = 0;
-    if (!ValidateTexFormatAndType(format, type, jsArrayType, &dstTexelSize, "texImage2D"))
+    if (!ValidateTexInputData(type, jsArrayType, func))
         return;
 
     WebGLTexelFormat dstFormat = GetWebGLTexelFormat(format, type);
     WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
 
     uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
 
     CheckedUint32 checked_neededByteLength =
@@ -3829,16 +3709,17 @@ WebGLContext::TexImage2D_base(GLenum tar
 
     GLenum error = LOCAL_GL_NO_ERROR;
 
     WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::NoImageData;
 
     if (byteLength) {
         size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
+        uint32_t dstTexelSize = GetBitsPerTexel(format, type) / 8;
         size_t dstPlainRowSize = dstTexelSize * width;
         size_t unpackAlignment = mPixelStoreUnpackAlignment;
         size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
 
         if (actualSrcFormat == dstFormat &&
             srcPremultiplied == mPixelStorePremultiplyAlpha &&
             srcStride == dstStride &&
             !mPixelStoreFlipY)
@@ -3921,46 +3802,27 @@ void
 WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
                                  GLint xoffset, GLint yoffset,
                                  GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
                                  GLenum format, GLenum type,
                                  void *pixels, uint32_t byteLength,
                                  int jsArrayType,
                                  WebGLTexelFormat srcFormat, bool srcPremultiplied)
 {
-    switch (target) {
-        case LOCAL_GL_TEXTURE_2D:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            break;
-        default:
-            return ErrorInvalidEnumInfo("texSubImage2D: target", target);
-    }
-
-    if (!ValidateLevelWidthHeightForTarget(target, level, width, height, "texSubImage2D")) {
+    const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
+
+    if (!ValidateTexImage(2, target, level, format,
+                          xoffset, yoffset, 0,
+                          width, height, 0,
+                          0, format, type, func))
+    {
         return;
     }
 
-    if (level >= 1) {
-        if (!(is_pot_assuming_nonnegative(width) &&
-              is_pot_assuming_nonnegative(height)))
-            return ErrorInvalidValue("texSubImage2D: with level > 0, width and height must be powers of two");
-    }
-
-    if (IsExtensionEnabled(WEBGL_depth_texture) &&
-        (format == LOCAL_GL_DEPTH_COMPONENT || format == LOCAL_GL_DEPTH_STENCIL)) {
-        return ErrorInvalidOperation("texSubImage2D: format");
-    }
-
-    uint32_t dstTexelSize = 0;
-    if (!ValidateTexFormatAndType(format, type, jsArrayType, &dstTexelSize, "texSubImage2D"))
+    if (!ValidateTexInputData(type, jsArrayType, func))
         return;
 
     WebGLTexelFormat dstFormat = GetWebGLTexelFormat(format, type);
     WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
 
     uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
 
     if (width == 0 || height == 0)
@@ -3978,48 +3840,34 @@ WebGLContext::TexSubImage2D_base(GLenum 
         return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
 
     uint32_t bytesNeeded = checked_neededByteLength.value();
 
     if (byteLength < bytesNeeded)
         return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
-
-    if (!tex)
-        return ErrorInvalidOperation("texSubImage2D: no texture is bound to this target");
-
-    if (!tex->HasImageInfoAt(target, level))
-        return ErrorInvalidOperation("texSubImage2D: no texture image previously defined for this level and face");
-
     const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(target, level);
-    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.Width(), imageInfo.Height()))
-        return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
-
-    // Require the format and type in texSubImage2D to match that of the existing texture as created by texImage2D
-    if (imageInfo.InternalFormat() != format || imageInfo.Type() != type)
-        return ErrorInvalidOperation("texSubImage2D: format or type doesn't match the existing texture");
-
-    if (imageInfo.HasUninitializedImageData()) {
+
+    if (imageInfo.HasUninitializedImageData())
         tex->DoDeferredImageInitialization(target, level);
-    }
 
     MakeContextCurrent();
 
     size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
+    uint32_t dstTexelSize = GetBitsPerTexel(format, type) / 8;
     size_t dstPlainRowSize = dstTexelSize * width;
     // There are checks above to ensure that this won't overflow.
     size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
 
     // convert type for half float if not on GLES2
     GLenum realType = type;
-    if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2()) {
+    if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2())
         realType = LOCAL_GL_HALF_FLOAT;
-    }
 
     if (actualSrcFormat == dstFormat &&
         srcPremultiplied == mPixelStorePremultiplyAlpha &&
         srcStride == dstStride &&
         !mPixelStoreFlipY)
     {
         // no conversion, no flipping, so we avoid copying anything and just pass the source pointer
         gl->fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, realType, pixels);
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -9,32 +9,213 @@
 #include "WebGLShader.h"
 #include "WebGLProgram.h"
 #include "WebGLUniformLocation.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 #include "WebGLVertexArray.h"
 #include "GLContext.h"
+#include "CanvasUtils.h"
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 
 #include "jsfriendapi.h"
 
 #include "angle/ShaderLang.h"
 
 #include <algorithm>
 
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 
 using namespace mozilla;
 
+/**
+ * Return the block size for format.
+ */
+static void
+BlockSizeFor(GLenum format, GLint* blockWidth, GLint* blockHeight)
+{
+    MOZ_ASSERT(blockWidth && blockHeight);
+
+    switch (format) {
+    case LOCAL_GL_ATC_RGB:
+    case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
+    case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
+    case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+        if (blockWidth)
+            *blockWidth = 4;
+        if (blockHeight)
+            *blockHeight = 4;
+        break;
+    default:
+        break;
+    }
+}
+
+/**
+ * Return the displayable name for the texture function that is the
+ * source for validation.
+ */
+static const char*
+InfoFrom(WebGLTexImageFunc func)
+{
+    // TODO: Account for dimensions (WebGL 2)
+    switch (func) {
+    case WebGLTexImageFunc::TexImage:        return "texImage2D";
+    case WebGLTexImageFunc::TexSubImage:     return "texSubImage2D";
+    case WebGLTexImageFunc::CopyTexImage:    return "copyTexImage2D";
+    case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage2D";
+    case WebGLTexImageFunc::CompTexImage:    return "compressedTexImage2D";
+    case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage2D";
+    default:
+        MOZ_ASSERT(false, "Missing case for WebGLTexImageSource");
+        return "(error)";
+    }
+}
+
+/**
+ * Return displayable name for GLenum.
+ * This version is like gl::GLenumToStr but with out the GL_ prefix to
+ * keep consistency with how errors are reported from WebGL.
+ */
+static const char*
+NameFrom(GLenum glenum)
+{
+    switch (glenum) {
+#define XX(x) case LOCAL_GL_##x: return #x
+        XX(ALPHA);
+        XX(ATC_RGB);
+        XX(ATC_RGBA_EXPLICIT_ALPHA);
+        XX(ATC_RGBA_INTERPOLATED_ALPHA);
+        XX(COMPRESSED_RGBA_PVRTC_2BPPV1);
+        XX(COMPRESSED_RGBA_PVRTC_4BPPV1);
+        XX(COMPRESSED_RGBA_S3TC_DXT1_EXT);
+        XX(COMPRESSED_RGBA_S3TC_DXT3_EXT);
+        XX(COMPRESSED_RGBA_S3TC_DXT5_EXT);
+        XX(COMPRESSED_RGB_PVRTC_2BPPV1);
+        XX(COMPRESSED_RGB_PVRTC_4BPPV1);
+        XX(COMPRESSED_RGB_S3TC_DXT1_EXT);
+        XX(DEPTH_COMPONENT);
+        XX(DEPTH_COMPONENT16);
+        XX(DEPTH_COMPONENT32);
+        XX(DEPTH_STENCIL);
+        XX(DEPTH24_STENCIL8);
+        XX(FLOAT);
+        XX(HALF_FLOAT);
+        XX(LUMINANCE);
+        XX(LUMINANCE_ALPHA);
+        XX(RGB);
+        XX(RGB16F);
+        XX(RGB32F);
+        XX(RGBA);
+        XX(RGBA16F);
+        XX(RGBA32F);
+        XX(SRGB);
+        XX(SRGB_ALPHA);
+        XX(TEXTURE_2D);
+        XX(TEXTURE_3D);
+        XX(TEXTURE_CUBE_MAP);
+        XX(TEXTURE_CUBE_MAP_NEGATIVE_X);
+        XX(TEXTURE_CUBE_MAP_NEGATIVE_Y);
+        XX(TEXTURE_CUBE_MAP_NEGATIVE_Z);
+        XX(TEXTURE_CUBE_MAP_POSITIVE_X);
+        XX(TEXTURE_CUBE_MAP_POSITIVE_Y);
+        XX(TEXTURE_CUBE_MAP_POSITIVE_Z);
+        XX(UNSIGNED_BYTE);
+        XX(UNSIGNED_INT);
+        XX(UNSIGNED_INT_24_8);
+        XX(UNSIGNED_SHORT);
+        XX(UNSIGNED_SHORT_4_4_4_4);
+        XX(UNSIGNED_SHORT_5_5_5_1);
+        XX(UNSIGNED_SHORT_5_6_5);
+#undef XX
+    }
+
+    return nullptr;
+}
+
+/**
+ * Same as ErrorInvalidEnum but uses NameFrom to print displayable
+ * name for \a glenum.
+ */
+static void
+ErrorInvalidEnumWithName(WebGLContext* ctx, const char* msg, GLenum glenum, WebGLTexImageFunc func)
+{
+    const char* name = NameFrom(glenum);
+    if (name)
+        ctx->ErrorInvalidEnum("%s: %s %s", InfoFrom(func), msg, name);
+    else
+        ctx->ErrorInvalidEnum("%s: %s 0x%04X", InfoFrom(func), msg, glenum);
+}
+
+/**
+ * Return true if the format is valid for source calls.
+ */
+static bool
+IsAllowedFromSource(GLenum format, WebGLTexImageFunc func)
+{
+    switch (format) {
+    case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
+        return (func == WebGLTexImageFunc::CompTexImage ||
+                func == WebGLTexImageFunc::CompTexSubImage);
+
+    case LOCAL_GL_ATC_RGB:
+    case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
+    case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
+        return func == WebGLTexImageFunc::CompTexImage;
+    }
+
+    return true;
+}
+
+/**
+ * Returns true if func is a CopyTexImage variant.
+ */
+static bool
+IsCopyFunc(WebGLTexImageFunc func)
+{
+    return (func == WebGLTexImageFunc::CopyTexImage ||
+            func == WebGLTexImageFunc::CopyTexSubImage);
+}
+
+/**
+ * Returns true if func is a SubImage variant.
+ */
+static bool
+IsSubFunc(WebGLTexImageFunc func)
+{
+    return (func == WebGLTexImageFunc::TexSubImage ||
+            func == WebGLTexImageFunc::CopyTexSubImage ||
+            func == WebGLTexImageFunc::CompTexSubImage);
+}
+
+/**
+ * returns true is target is a texture cube map target.
+ */
+static bool
+IsTexImageCubemapTarget(GLenum target)
+{
+    return (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+            target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+}
+
 /*
  * Pull data out of the program, post-linking
  */
 bool
 WebGLProgram::UpdateInfo()
 {
     mIdentifierMap = nullptr;
     mIdentifierReverseMap = nullptr;
@@ -74,19 +255,19 @@ WebGLProgram::UpdateInfo()
             }
         }
     }
 
     if (!mUniformInfoMap) {
         mUniformInfoMap = new CStringToUniformInfoMap;
         for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
             for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
-	        const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
-	        const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
-	        mUniformInfoMap->Put(uniform.mapped, info);
+                const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
+                const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
+                mUniformInfoMap->Put(uniform.mapped, info);
             }
         }
     }
 
     mActiveAttribMap.clear();
 
     GLint numActiveAttrs = 0;
     mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &numActiveAttrs);
@@ -103,16 +284,98 @@ WebGLProgram::UpdateInfo()
         GLint attrLoc = mContext->gl->fGetAttribLocation(mGLName, attrName);
         MOZ_ASSERT(attrLoc >= 0);
         mActiveAttribMap.insert(std::make_pair(attrLoc, nsCString(attrName)));
     }
 
     return true;
 }
 
+/**
+ * Return the simple base format for a given internal format.
+ *
+ * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA), or GL_NONE if invalid enum.
+ */
+GLenum
+WebGLContext::BaseTexFormat(GLenum internalFormat) const
+{
+    if (internalFormat == LOCAL_GL_ALPHA ||
+        internalFormat == LOCAL_GL_LUMINANCE ||
+        internalFormat == LOCAL_GL_LUMINANCE_ALPHA ||
+        internalFormat == LOCAL_GL_RGB ||
+        internalFormat == LOCAL_GL_RGBA)
+    {
+        return internalFormat;
+    }
+
+    if (IsExtensionEnabled(EXT_sRGB)) {
+        if (internalFormat == LOCAL_GL_SRGB)
+            return LOCAL_GL_RGB;
+
+        if (internalFormat == LOCAL_GL_SRGB_ALPHA)
+            return LOCAL_GL_RGBA;
+    }
+
+    if (IsExtensionEnabled(WEBGL_compressed_texture_atc)) {
+        if (internalFormat == LOCAL_GL_ATC_RGB)
+            return LOCAL_GL_RGB;
+
+        if (internalFormat == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
+            internalFormat == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
+        {
+            return LOCAL_GL_RGBA;
+        }
+    }
+
+    if (IsExtensionEnabled(WEBGL_compressed_texture_pvrtc)) {
+        if (internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
+            internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1)
+        {
+            return LOCAL_GL_RGB;
+        }
+
+        if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
+            internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
+        {
+            return LOCAL_GL_RGBA;
+        }
+    }
+
+    if (IsExtensionEnabled(WEBGL_compressed_texture_s3tc)) {
+        if (internalFormat == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
+            return LOCAL_GL_RGB;
+
+        if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+            internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+            internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+        {
+            return LOCAL_GL_RGBA;
+        }
+    }
+
+    if (IsExtensionEnabled(WEBGL_depth_texture)) {
+        if (internalFormat == LOCAL_GL_DEPTH_COMPONENT ||
+            internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
+            internalFormat == LOCAL_GL_DEPTH_COMPONENT32)
+        {
+            return LOCAL_GL_DEPTH_COMPONENT;
+        }
+
+        if (internalFormat == LOCAL_GL_DEPTH_STENCIL ||
+            internalFormat == LOCAL_GL_DEPTH24_STENCIL8)
+        {
+            return LOCAL_GL_DEPTH_STENCIL;
+        }
+    }
+
+    MOZ_ASSERT(false, "Unhandled internalFormat");
+    return LOCAL_GL_NONE;
+}
+
 bool WebGLContext::ValidateBlendEquationEnum(GLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_FUNC_ADD:
         case LOCAL_GL_FUNC_SUBTRACT:
         case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
             return true;
         case LOCAL_GL_MIN:
@@ -295,75 +558,278 @@ bool WebGLContext::ValidateGLSLString(co
              ErrorInvalidValue("%s: string contains the illegal character '%d'", info, string.CharAt(i));
              return false;
         }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateTexImage2DFormat(GLenum format, const char* info)
+/**
+ * Return true if format is a valid texture image format for source,
+ * taking into account enabled WebGL extensions.
+ */
+bool
+WebGLContext::ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func)
+{
+    /* Core WebGL texture formats */
+    if (format == LOCAL_GL_ALPHA ||
+        format == LOCAL_GL_RGB ||
+        format == LOCAL_GL_RGBA ||
+        format == LOCAL_GL_LUMINANCE ||
+        format == LOCAL_GL_LUMINANCE_ALPHA)
+    {
+        return true;
+    }
+
+    /* Only core formats are valid for CopyTex(Sub)?Image */
+    // TODO: Revisit this once color_buffer_(half_)?float lands
+    if (IsCopyFunc(func)) {
+        ErrorInvalidEnumWithName(this, "invalid format", format, func);
+        return false;
+    }
+
+    /* WEBGL_depth_texture added formats */
+    if (format == LOCAL_GL_DEPTH_COMPONENT ||
+        format == LOCAL_GL_DEPTH_STENCIL)
+    {
+        bool validFormat = IsExtensionEnabled(WEBGL_depth_texture);
+        if (!validFormat)
+            ErrorInvalidEnum("%s: invalid format %s: need WEBGL_depth_texture enabled",
+                             InfoFrom(func), NameFrom(format));
+        return validFormat;
+    }
+
+    /* EXT_sRGB added formats */
+    if (format == LOCAL_GL_SRGB ||
+        format == LOCAL_GL_SRGB_ALPHA)
+    {
+        bool validFormat = IsExtensionEnabled(EXT_sRGB);
+        if (!validFormat)
+            ErrorInvalidEnum("%s: invalid format %s: need EXT_sRGB enabled",
+                             InfoFrom(func), NameFrom(format));
+        return validFormat;
+    }
+
+    /* WEBGL_compressed_texture_atc added formats */
+    if (format == LOCAL_GL_ATC_RGB ||
+        format == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
+        format == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
+    {
+        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_atc);
+        if (!validFormat)
+            ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_atc enabled",
+                             InfoFrom(func), NameFrom(format));
+        return validFormat;
+    }
+
+
+    if (format == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
+        format == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1 ||
+        format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
+        format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
+    {
+        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_pvrtc);
+        if (!validFormat)
+            ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_pvrtc enabled",
+                             InfoFrom(func), NameFrom(format));
+        return validFormat;
+    }
+
+
+    if (format == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+        format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+        format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+        format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+    {
+        bool validFormat = IsExtensionEnabled(WEBGL_compressed_texture_s3tc);
+        if (!validFormat)
+            ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_s3tc enabled",
+                             InfoFrom(func), NameFrom(format));
+        return validFormat;
+    }
+
+    ErrorInvalidEnumWithName(this, "invalid format", format, func);
+
+    return false;
+}
+
+/**
+ * Check if the given texture target is valid for TexImage.
+ */
+bool
+WebGLContext::ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func)
 {
-    if (IsExtensionEnabled(EXT_sRGB)) {
-        switch (format) {
-            case LOCAL_GL_SRGB_EXT:
-            case LOCAL_GL_SRGB_ALPHA_EXT:
-                return true;
+    switch (dims) {
+    case 2:
+        if (target == LOCAL_GL_TEXTURE_2D ||
+            IsTexImageCubemapTarget(target))
+        {
+            return true;
+        }
+
+        ErrorInvalidEnumWithName(this, "invalid target", target, func);
+        return false;
+
+    default:
+        MOZ_ASSERT(false, "ValidateTexImageTarget: Invalid dims");
+    }
+
+    return false;
+}
+
+/**
+ * Return true if type is a valid texture image type for source,
+ * taking into account enabled WebGL extensions.
+ */
+bool
+WebGLContext::ValidateTexImageType(GLenum type, WebGLTexImageFunc func)
+{
+    /* Core WebGL texture types */
+    if (type == LOCAL_GL_UNSIGNED_BYTE ||
+        type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
+        type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+        type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1)
+    {
+        return true;
+    }
+
+    /* OES_texture_float added types */
+    if (type == LOCAL_GL_FLOAT) {
+        bool validType = IsExtensionEnabled(OES_texture_float);
+        if (!validType)
+            ErrorInvalidEnum("%s: invalid type %s: need OES_texture_float enabled",
+                             InfoFrom(func), NameFrom(type));
+        return validType;
+    }
+
+    /* OES_texture_half_float add types */
+    if (type == LOCAL_GL_HALF_FLOAT_OES) {
+        bool validType = IsExtensionEnabled(OES_texture_half_float);
+        if (!validType)
+            ErrorInvalidEnum("%s: invalid type %s: need OES_texture_half_float enabled",
+                             InfoFrom(func), NameFrom(type));
+        return validType;
+    }
+
+    /* WEBGL_depth_texture added types */
+    if (type == LOCAL_GL_UNSIGNED_SHORT ||
+        type == LOCAL_GL_UNSIGNED_INT ||
+        type == LOCAL_GL_UNSIGNED_INT_24_8)
+    {
+        bool validType = IsExtensionEnabled(WEBGL_depth_texture);
+        if (!validType)
+            ErrorInvalidEnum("%s: invalid type %s: need WEBGL_depth_texture enabled",
+                             InfoFrom(func), NameFrom(type));
+        return validType;
+    }
+
+    ErrorInvalidEnumWithName(this, "invalid type", type, func);
+    return false;
+}
+
+/**
+ * Validate texture image sizing extra constraints for
+ * CompressedTex(Sub)?Image.
+ */
+// TODO: WebGL 2
+bool
+WebGLContext::ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
+                                       GLint xoffset, GLint yoffset,
+                                       GLsizei width, GLsizei height,
+                                       GLsizei levelWidth, GLsizei levelHeight,
+                                       WebGLTexImageFunc func)
+{
+    // Negative parameters must already have been handled above
+    MOZ_ASSERT(xoffset >= 0 && yoffset >= 0 &&
+               width >= 0 && height >= 0);
+
+    if (xoffset + width > (GLint) levelWidth) {
+        ErrorInvalidValue("%s: xoffset + width must be <= levelWidth", InfoFrom(func));
+        return false;
+    }
+
+    if (yoffset + height > (GLint) levelHeight) {
+        ErrorInvalidValue("%s: yoffset + height must be <= levelHeight", InfoFrom(func));
+        return false;
+    }
+
+    GLint blockWidth = 1;
+    GLint blockHeight = 1;
+    BlockSizeFor(format, &blockWidth, &blockHeight);
+
+    /* If blockWidth || blockHeight != 1, then the compressed format
+     * had block-based constraints to be checked. (For example, PVRTC is compressed but
+     * isn't a block-based format)
+     */
+    if (blockWidth != 1 || blockHeight != 1) {
+        /* offsets must be multiple of block size */
+        if (xoffset % blockWidth != 0) {
+            ErrorInvalidOperation("%s: xoffset must be multiple of %d",
+                                  InfoFrom(func), blockWidth);
+            return false;
+        }
+
+        if (yoffset % blockHeight != 0) {
+            ErrorInvalidOperation("%s: yoffset must be multiple of %d",
+                                  InfoFrom(func), blockHeight);
+            return false;
+        }
+
+        /* The size must be a multiple of blockWidth and blockHeight,
+         * or must be using offset+size that exactly hits the edge.
+         * Important for small mipmap levels. (s3tc extension appears
+         * to have changed and old code that checks 1x1, 2x2 doesn't
+         * appear necessary anymore)
+         */
+        if ((width % blockWidth != 0) &&
+            (xoffset + width != (GLint) levelWidth))
+        {
+            ErrorInvalidOperation("%s: width must be multiple of %d or "
+                                  "xoffset + width must be %d",
+                                  InfoFrom(func), blockWidth, levelWidth);
+            return false;
+        }
+
+        if ((height % blockHeight != 0) &&
+            (yoffset + height != (GLint) levelHeight))
+        {
+            ErrorInvalidOperation("%s: height must be multiple of %d or "
+                                  "yoffset + height must be %d",
+                                  InfoFrom(func), blockHeight, levelHeight);
+            return false;
         }
     }
 
     switch (format) {
-        case LOCAL_GL_RGB:
-        case LOCAL_GL_RGBA:
-        case LOCAL_GL_ALPHA:
-        case LOCAL_GL_LUMINANCE:
-        case LOCAL_GL_LUMINANCE_ALPHA:
-        case LOCAL_GL_DEPTH_COMPONENT:
-        case LOCAL_GL_DEPTH_STENCIL:
-            return true;
-            break;
-    }
-
-    ErrorInvalidEnumInfo(info, format);
-    return false;
-}
-
-bool WebGLContext::ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height,
-                                            const char* info)
-{
-    switch (target) {
-        case LOCAL_GL_TEXTURE_2D:
-            break;
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            if (width != height) {
-                ErrorInvalidValue("%s: with cube map targets, width and height must be equal", info);
-                return false;
-            }
-            break;
-        default:
-            ErrorInvalidEnum("%s: invalid target enum 0x%x", info, target);
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
+        if (!is_pot_assuming_nonnegative(width) ||
+            !is_pot_assuming_nonnegative(height))
+        {
+            ErrorInvalidValue("%s: width and height must be powers of two",
+                              InfoFrom(func));
             return false;
+        }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateCompressedTextureSize(GLenum target, GLint level,
-                                                 GLenum format,
-                                                 GLsizei width, GLsizei height, uint32_t byteLength, const char* info)
+/**
+ * Return true if the enough data is present to satisfy compressed
+ * texture format constraints.
+ */
+bool
+WebGLContext::ValidateCompTexImageDataSize(GLint level, GLenum format,
+                                           GLsizei width, GLsizei height,
+                                           uint32_t byteLength, WebGLTexImageFunc func)
 {
-    if (!ValidateLevelWidthHeightForTarget(target, level, width, height, info)) {
-        return false;
-    }
-
     // negative width and height must already have been handled above
     MOZ_ASSERT(width >= 0 && height >= 0);
 
     CheckedUint32 required_byteLength = 0;
 
     switch (format) {
         case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
         case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
@@ -390,287 +856,486 @@ bool WebGLContext::ValidateCompressedTex
         case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
         {
             required_byteLength = CheckedUint32(std::max(width, 16)) * CheckedUint32(std::max(height, 8)) / 4;
             break;
         }
     }
 
     if (!required_byteLength.isValid() || required_byteLength.value() != byteLength) {
-        ErrorInvalidValue("%s: data size does not match dimensions", info);
+        ErrorInvalidValue("%s: data size does not match dimensions", InfoFrom(func));
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Validate the width, height, and depth of a texture image, \return
+ * true is valid, false otherwise.
+ * Used by all the (Compressed|Copy)?Tex(Sub)?Image functions.
+ * Target and level must have been validated before calling.
+ */
+bool
+WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
+                                   GLint width, GLint height, GLint depth,
+                                   WebGLTexImageFunc func)
+{
+    MOZ_ASSERT(level >= 0, "level should already be validated");
+
+    const GLuint maxTexImageSize = MaxTextureSizeForTarget(target) >> level;
+    const bool isCubemapTarget = IsTexImageCubemapTarget(target);
+
+    if (isCubemapTarget && width != height) {
+        /* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
+         *   "When the target parameter to TexImage2D is one of the
+         *   six cube map two-dimensional image targets, the error
+         *   INVALID_VALUE is generated if the width and height
+         *   parameters are not equal."
+         */
+        ErrorInvalidValue("%s: for cube map, width must equal height", InfoFrom(func));
         return false;
     }
 
-    switch (format) {
-        case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-        case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-        {
-            if (level == 0 && width % 4 == 0 && height % 4 == 0) {
-                break;
-            }
-            if (level > 0
-                && (width == 0 || width == 1 || width == 2 || width % 4 == 0)
-                && (height == 0 || height == 1 || height == 2 || height % 4 == 0))
-            {
-                break;
-            }
-            ErrorInvalidOperation("%s: level parameter does not match width and height", info);
+    if (target == LOCAL_GL_TEXTURE_2D || isCubemapTarget)
+    {
+        /* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
+         *   "If wt and ht are the specified image width and height,
+         *   and if either wt or ht are less than zero, then the error
+         *   INVALID_VALUE is generated."
+         */
+        if (width < 0) {
+            ErrorInvalidValue("%s: width must be >= 0", InfoFrom(func));
+            return false;
+        }
+
+        if (height < 0) {
+            ErrorInvalidValue("%s: height must be >= 0", InfoFrom(func));
+            return false;
+        }
+
+        /* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
+         *   "The maximum allowable width and height of a
+         *   two-dimensional texture image must be at least 2**(k−lod)
+         *   for image arrays of level zero through k, where k is the
+         *   log base 2 of MAX_TEXTURE_SIZE. and lod is the
+         *   level-of-detail of the image array. It may be zero for
+         *   image arrays of any level-of-detail greater than k. The
+         *   error INVALID_VALUE is generated if the specified image
+         *   is too large to be stored under any conditions.
+         */
+        if (width > (int) maxTexImageSize) {
+            ErrorInvalidValue("%s: the maximum width for level %d is %u",
+                              InfoFrom(func), level, maxTexImageSize);
             return false;
         }
-        case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
-        case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
-        case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
-        case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
-        {
-            if (!is_pot_assuming_nonnegative(width) ||
-                !is_pot_assuming_nonnegative(height))
-            {
-                ErrorInvalidValue("%s: width and height must be powers of two", info);
+
+        if (height > (int) maxTexImageSize) {
+            ErrorInvalidValue("%s: tex maximum height for level %d is %u",
+                              InfoFrom(func), level, maxTexImageSize);
+            return false;
+        }
+
+        /* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
+         *   "If level is greater than zero, and either width or
+         *   height is not a power-of-two, the error INVALID_VALUE is
+         *   generated."
+         */
+        if (level > 0) {
+            if (!is_pot_assuming_nonnegative(width)) {
+                ErrorInvalidValue("%s: level >= 0, width of %d must be a power of two.",
+                                  InfoFrom(func), width);
                 return false;
             }
+
+            if (!is_pot_assuming_nonnegative(height)) {
+                ErrorInvalidValue("%s: level >= 0, height of %d must be a power of two.",
+                                  InfoFrom(func), height);
+                return false;
+            }
+        }
+    }
+
+    // TODO: WebGL 2
+    if (target == LOCAL_GL_TEXTURE_3D) {
+        if (depth < 0) {
+            ErrorInvalidValue("%s: depth must be >= 0", InfoFrom(func));
+            return false;
+        }
+
+        if (!is_pot_assuming_nonnegative(depth)) {
+            ErrorInvalidValue("%s: level >= 0, depth of %d must be a power of two.",
+                              InfoFrom(func), depth);
+            return false;
         }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width,
-                                                     GLsizei height, const char* info)
+/**
+ * Validate texture image sizing for Tex(Sub)?Image variants.
+ */
+// TODO: WebGL 2. Update this to handle 3D textures.
+bool
+WebGLContext::ValidateTexSubImageSize(GLint xoffset, GLint yoffset, GLint /*zoffset*/,
+                                      GLsizei width, GLsizei height, GLsizei /*depth*/,
+                                      GLsizei baseWidth, GLsizei baseHeight, GLsizei /*baseDepth*/,
+                                      WebGLTexImageFunc func)
 {
-    GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
+    /* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
+     *   "Taking wt and ht to be the specified width and height of the
+     *   texture array, and taking x, y, w, and h to be the xoffset,
+     *   yoffset, width, and height argument values, any of the
+     *   following relationships generates the error INVALID_VALUE:
+     *       x < 0
+     *       x + w > wt
+     *       y < 0
+     *       y + h > ht"
+     */
 
-    if (level < 0) {
-        ErrorInvalidValue("%s: level must be >= 0", info);
+    if (xoffset < 0) {
+        ErrorInvalidValue("%s: xoffset must be >= 0", InfoFrom(func));
         return false;
     }
 
-    GLsizei maxAllowedSize = maxTextureSize >> level;
-
-    if (!maxAllowedSize) {
-        ErrorInvalidValue("%s: 2^level exceeds maximum texture size", info);
+    if (yoffset < 0) {
+        ErrorInvalidValue("%s: yoffset must be >= 0", InfoFrom(func));
         return false;
     }
 
-    if (width < 0 || height < 0) {
-        ErrorInvalidValue("%s: width and height must be >= 0", info);
-        return false;
-    }
-
-    if (width > maxAllowedSize || height > maxAllowedSize) {
-        ErrorInvalidValue("%s: the maximum texture size for level %d is %d", info, level, maxAllowedSize);
+    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, baseWidth, baseHeight)) {
+        ErrorInvalidValue("%s: subtexture rectangle out-of-bounds", InfoFrom(func));
         return false;
     }
 
     return true;
 }
 
-uint32_t WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
+/**
+ * Return the bits per texel for format & type combination.
+ * Assumes that format & type are a valid combination as checked with
+ * ValidateTexImageFormatAndType().
+ */
+uint32_t
+WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
 {
     // If there is no defined format or type, we're not taking up any memory
     if (!format || !type) {
         return 0;
     }
 
-    if (format == LOCAL_GL_DEPTH_COMPONENT) {
-        if (type == LOCAL_GL_UNSIGNED_SHORT)
-            return 2;
-        else if (type == LOCAL_GL_UNSIGNED_INT)
-            return 4;
-    } else if (format == LOCAL_GL_DEPTH_STENCIL) {
-        if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
-            return 4;
+    /* Known fixed-sized types */
+    if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+        type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+        type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
+    {
+        return 16;
+    }
+
+    if (type == LOCAL_GL_UNSIGNED_INT_24_8)
+        return 32;
+
+    int bitsPerComponent = 0;
+    switch (type) {
+    case LOCAL_GL_UNSIGNED_BYTE:
+        bitsPerComponent = 8;
+        break;
+
+    case LOCAL_GL_HALF_FLOAT:
+    case LOCAL_GL_HALF_FLOAT_OES:
+    case LOCAL_GL_UNSIGNED_SHORT:
+        bitsPerComponent = 16;
+        break;
+
+    case LOCAL_GL_FLOAT:
+    case LOCAL_GL_UNSIGNED_INT:
+        bitsPerComponent = 32;
+        break;
+
+    default:
+        MOZ_ASSERT(false, "Unhandled type.");
+        break;
     }
 
-    if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
-        int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
-        switch (format) {
-            case LOCAL_GL_ALPHA:
-            case LOCAL_GL_LUMINANCE:
-                return 1 * multiplier;
-            case LOCAL_GL_LUMINANCE_ALPHA:
-                return 2 * multiplier;
-            case LOCAL_GL_RGB:
-            case LOCAL_GL_RGB32F:
-            case LOCAL_GL_SRGB_EXT:
-                return 3 * multiplier;
-            case LOCAL_GL_RGBA:
-            case LOCAL_GL_RGBA32F:
-            case LOCAL_GL_SRGB_ALPHA_EXT:
-                return 4 * multiplier;
-            case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
-            case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
-                return 2;
-            case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-            case LOCAL_GL_ATC_RGB:
-            case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
-            case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
-                return 4;
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-            case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
-            case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
-                return 8;
-            default:
-                break;
-        }
-    } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
-               type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
-               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
-    {
-        return 16;
+    switch (format) {
+        // Uncompressed formats
+    case LOCAL_GL_ALPHA:
+    case LOCAL_GL_LUMINANCE:
+    case LOCAL_GL_DEPTH_COMPONENT:
+    case LOCAL_GL_DEPTH_STENCIL:
+        return 1 * bitsPerComponent;
+
+    case LOCAL_GL_LUMINANCE_ALPHA:
+        return 2 * bitsPerComponent;
+
+    case LOCAL_GL_RGB:
+    case LOCAL_GL_RGB32F:
+    case LOCAL_GL_SRGB_EXT:
+        return 3 * bitsPerComponent;
+
+    case LOCAL_GL_RGBA:
+    case LOCAL_GL_RGBA32F:
+    case LOCAL_GL_SRGB_ALPHA_EXT:
+        return 4 * bitsPerComponent;
+
+        // Compressed formats
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
+        return 2;
+
+    case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    case LOCAL_GL_ATC_RGB:
+    case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
+    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
+        return 4;
+
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+    case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
+    case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
+        return 8;
+
+    default:
+        break;
     }
 
     MOZ_ASSERT(false, "Unhandled format+type combo.");
     return 0;
 }
 
-bool WebGLContext::ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType,
-                                              uint32_t *texelSize, const char *info)
+/**
+ * Perform validation of format/type combinations for TexImage variants.
+ * Returns true if the format/type is a valid combination, false otherwise.
+ */
+bool
+WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func)
 {
-    if (IsExtensionEnabled(WEBGL_depth_texture)) {
-        if (format == LOCAL_GL_DEPTH_COMPONENT) {
-            if (jsArrayType != -1) {
-                if ((type == LOCAL_GL_UNSIGNED_SHORT && jsArrayType != js::ArrayBufferView::TYPE_UINT16) ||
-                    (type == LOCAL_GL_UNSIGNED_INT && jsArrayType != js::ArrayBufferView::TYPE_UINT32)) {
-                    ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
-                    return false;
-                }
-            }
-
-            switch(type) {
-                case LOCAL_GL_UNSIGNED_SHORT:
-                    *texelSize = 2;
-                    break;
-                case LOCAL_GL_UNSIGNED_INT:
-                    *texelSize = 4;
-                    break;
-                default:
-                    ErrorInvalidOperation("%s: invalid type 0x%x", info, type);
-                    return false;
-            }
-
-            return true;
-
-        } else if (format == LOCAL_GL_DEPTH_STENCIL) {
-            if (type != LOCAL_GL_UNSIGNED_INT_24_8_EXT) {
-                ErrorInvalidOperation("%s: invalid format 0x%x", info, format);
-                return false;
-            }
-            if (jsArrayType != -1) {
-                if (jsArrayType != js::ArrayBufferView::TYPE_UINT32) {
-                    ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
-                    return false;
-                }
-            }
-
-            *texelSize = 4;
-            return true;
-        }
+    if (!ValidateTexImageFormat(format, func) ||
+        !ValidateTexImageType(type, func))
+    {
+        return false;
     }
 
+    bool validCombo = false;
+
+    switch (format) {
+    case LOCAL_GL_ALPHA:
+    case LOCAL_GL_LUMINANCE:
+    case LOCAL_GL_LUMINANCE_ALPHA:
+        validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
+                      type == LOCAL_GL_HALF_FLOAT ||
+                      type == LOCAL_GL_FLOAT);
+        break;
+
+    case LOCAL_GL_RGB:
+    case LOCAL_GL_SRGB:
+        validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
+                      type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
+                      type == LOCAL_GL_HALF_FLOAT ||
+                      type == LOCAL_GL_FLOAT);
+        break;
+
+    case LOCAL_GL_RGBA:
+    case LOCAL_GL_SRGB_ALPHA:
+        validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
+                      type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+                      type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+                      type == LOCAL_GL_HALF_FLOAT ||
+                      type == LOCAL_GL_FLOAT);
+        break;
+
+    case LOCAL_GL_DEPTH_COMPONENT:
+        validCombo = (type == LOCAL_GL_UNSIGNED_SHORT ||
+                      type == LOCAL_GL_UNSIGNED_INT);
+        break;
+
+    case LOCAL_GL_DEPTH_STENCIL:
+        validCombo = (type == LOCAL_GL_UNSIGNED_INT_24_8);
+        break;
+
+    default:
+        // Only valid formats should be passed to the switch stmt.
+        MOZ_ASSERT("Invalid format");
+        return false;
+    }
+
+    if (!validCombo)
+        ErrorInvalidOperation("%s: invalid combination of format %s and type %s",
+                              InfoFrom(func), NameFrom(format), NameFrom(type));
+
+    return validCombo;
+}
+
+/**
+ * Return true if format, type and jsArrayType are a valid combination.
+ * Also returns the size for texel of format and type (in bytes) via
+ * \a texelSize.
+ *
+ * It is assumed that type has previously been validated.
+ */
+bool
+WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFunc func)
+{
+    bool validInput = false;
     const char invalidTypedArray[] = "%s: invalid typed array type for given texture data type";
 
     // First, we check for packed types
     switch (type) {
-        case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
-        case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
-            if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_UINT16) {
-                ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
-                return false;
-            }
+    case LOCAL_GL_UNSIGNED_BYTE:
+        validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT8);
+        break;
+
+        // TODO: WebGL spec doesn't allow half floats to specified as UInt16.
+    // case LOCAL_GL_HALF_FLOAT:
+    // case LOCAL_GL_HALF_FLOAT_OES:
+    case LOCAL_GL_UNSIGNED_SHORT:
+    case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
+    case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
+    case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
+        validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT16);
+        break;
+
+    case LOCAL_GL_UNSIGNED_INT:
+    case LOCAL_GL_UNSIGNED_INT_24_8:
+        validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT32);
+        break;
+
+    case LOCAL_GL_FLOAT:
+        validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_FLOAT32);
+        break;
 
-            if (format == LOCAL_GL_RGBA) {
-                *texelSize = 2;
-                return true;
-            }
-            ErrorInvalidOperation("%s: mutually incompatible format and type", info);
-            return false;
+    default:
+        break;
+    }
+
+    if (!validInput)
+        ErrorInvalidOperation(invalidTypedArray, InfoFrom(func));
+
+    return validInput;
+}
 
-        case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
-            if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_UINT16) {
-                ErrorInvalidOperation("%s: invalid typed array type for given texture data type", info);
-                return false;
-            }
+/**
+ * Test the gl(Copy|Compressed)?Tex[Sub]?Image[23]() parameters for errors.
+ * Verifies each of the parameters against the WebGL standard and enabled extensions.
+ */
+// TODO: Texture dims is here for future expansion in WebGL 2.0
+bool
+WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
+                               GLint level, GLint internalFormat,
+                               GLint xoffset, GLint yoffset, GLint zoffset,
+                               GLint width, GLint height, GLint depth,
+                               GLint border, GLenum format, GLenum type,
+                               WebGLTexImageFunc func)
+{
+    const char* info = InfoFrom(func);
+
+    /* Check target */
+    if (!ValidateTexImageTarget(dims, target, func))
+        return false;
 
-            if (format == LOCAL_GL_RGB) {
-                *texelSize = 2;
-                return true;
-            }
-            ErrorInvalidOperation("%s: mutually incompatible format and type", info);
-            return false;
+    /* Check level */
+    if (level < 0) {
+        ErrorInvalidValue("%s: level must be >= 0", info);
+        return false;
+    }
+
+    /* Check border */
+    if (border != 0) {
+        ErrorInvalidValue("%s: border must be 0", info);
+        return false;
+    }
 
-        default:
-            break;
-        }
+    /* Check incoming image format and type */
+    if (!ValidateTexImageFormatAndType(format, type, func))
+        return false;
+
+    /* WebGL and OpenGL ES 2.0 impose additional restrictions on the
+     * combinations of format, internalFormat, and type that can be
+     * used.  Formats and types that require additional extensions
+     * (e.g., GL_FLOAT requires GL_OES_texture_float) are filtered
+     * elsewhere.
+     */
+    if ((GLint) format != internalFormat) {
+        ErrorInvalidOperation("%s: format does not match internalformat", info);
+        return false;
+    }
 
-    int texMultiplier = 1;
+    /* check internalFormat */
+    // TODO: Not sure if this is a bit of over kill.
+    if (BaseTexFormat(internalFormat) == LOCAL_GL_NONE) {
+        MOZ_ASSERT(false);
+        ErrorInvalidValue("%s:", info);
+        return false;
+    }
+
+    /* Check texture image size */
+    if (!ValidateTexImageSize(target, level, width, height, 0, func))
+        return false;
 
-    // If not a packed types, then it's might be a standard type.
-    if (type == LOCAL_GL_UNSIGNED_BYTE) {
-        if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_UINT8) {
-            ErrorInvalidEnum(invalidTypedArray, info);
-            return false;
-        }
-    } else if (type == LOCAL_GL_FLOAT) {
-        if (!IsExtensionEnabled(OES_texture_float)) {
-            ErrorInvalidEnum("%s: invalid format FLOAT: need OES_texture_float enabled", info);
+    /* 5.14.8 Texture objects - WebGL Spec.
+     *   "If an attempt is made to call these functions with no
+     *    WebGLTexture bound (see above), an INVALID_OPERATION error
+     *    is generated."
+     */
+    WebGLTexture* tex = activeBoundTextureForTarget(target);
+    if (!tex) {
+        ErrorInvalidOperation("%s: no texture is bound to target %s",
+                              info, NameFrom(target));
+        return false;
+    }
+
+    if (IsSubFunc(func)) {
+        if (!tex->HasImageInfoAt(target, level)) {
+            ErrorInvalidOperation("%s: no texture image previously defined for target %s at level %d",
+                                  info, NameFrom(target), level);
             return false;
         }
 
-        if (jsArrayType != -1 && jsArrayType != js::ArrayBufferView::TYPE_FLOAT32) {
-            ErrorInvalidOperation(invalidTypedArray, info);
-            return false;
-        }
-
-        texMultiplier = 4;
-    } else if (type == LOCAL_GL_HALF_FLOAT_OES) {
-        if (!IsExtensionEnabled(OES_texture_half_float)) {
-            ErrorInvalidEnum("%s: invalid format HALF_FLOAT_OES: need OES_texture_half_float enabled", info);
-            return false;
-        }
-
-        if (jsArrayType != -1)
+        const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
+        if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
+                                     width, height, depth,
+                                     imageInfo.Width(), imageInfo.Height(), 0,
+                                     func))
         {
-            ErrorInvalidOperation(invalidTypedArray, info);
             return false;
         }
 
-        texMultiplier = 2;
-    } else {
-        // We don't know the type
-        ErrorInvalidEnum("%s: invalid type 0x%x", info, type);
+        /* Require the format and type to match that of the existing
+         * texture as created
+         */
+        if (imageInfo.InternalFormat() != format ||
+            imageInfo.Type() != type)
+        {
+            ErrorInvalidOperation("%s: format or type doesn't match the existing texture",
+                                  info);
+            return false;
+        }
+    }
+
+    /* Additional checks for depth textures */
+    if (target != LOCAL_GL_TEXTURE_2D &&
+        (format == LOCAL_GL_DEPTH_COMPONENT ||
+         format == LOCAL_GL_DEPTH_STENCIL))
+    {
+        ErrorInvalidOperation("%s: with format of %s target must be TEXTURE_2D",
+                              info, NameFrom(format));
         return false;
     }
 
-    // Ok we know that is a standard type.
-    switch (format) {
-        case LOCAL_GL_ALPHA:
-        case LOCAL_GL_LUMINANCE:
-            *texelSize = 1 * texMultiplier;
-            return true;
-        case LOCAL_GL_LUMINANCE_ALPHA:
-            *texelSize = 2 * texMultiplier;
-            return true;
-        case LOCAL_GL_RGB:
-        case LOCAL_GL_SRGB_EXT:
-            *texelSize = 3 * texMultiplier;
-            return true;
-        case LOCAL_GL_RGBA:
-        case LOCAL_GL_SRGB_ALPHA_EXT:
-            *texelSize = 4 * texMultiplier;
-            return true;
-        default:
-            break;
+    /* Additional checks for compressed textures */
+    if (!IsAllowedFromSource(format, func)) {
+        ErrorInvalidOperation("%s: Invalid format %s for this operation",
+                              info, NameFrom(format));
+        return false;
     }
 
-    ErrorInvalidEnum("%s: invalid format 0x%x", info, format);
-    return false;
+    /* Parameters are OK */
+    return true;
 }
 
 bool
 WebGLContext::ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object)
 {
     if (!ValidateObjectAllowNull(info, location_object))
         return false;
     if (!location_object)
--- a/content/canvas/src/WebGLTypes.h
+++ b/content/canvas/src/WebGLTypes.h
@@ -129,11 +129,20 @@ MOZ_BEGIN_ENUM_CLASS(WebGLTexelFormat, i
     RGBA8,
     BGRA8, // used for DOM elements
     RGBA5551,
     RGBA4444,
     RGBA16F, // OES_texture_half_float
     RGBA32F // OES_texture_float
 MOZ_END_ENUM_CLASS(WebGLTexelFormat)
 
+MOZ_BEGIN_ENUM_CLASS(WebGLTexImageFunc, int)
+    TexImage,
+    TexSubImage,
+    CopyTexImage,
+    CopyTexSubImage,
+    CompTexImage,
+    CompTexSubImage,
+MOZ_END_ENUM_CLASS(WebGLTexImageFunc)
+
 } // namespace mozilla
 
 #endif
--- a/content/canvas/test/webgl/conformance/more/functions/texImage2DBadArgs.html
+++ b/content/canvas/test/webgl/conformance/more/functions/texImage2DBadArgs.html
@@ -1,11 +1,12 @@
 <!DOCTYPE html>
-<html><head>
-<meta charset="utf-8">
+<html>
+<head>
+<meta charset="utf-8"/>
 <!--
 Tests for the OpenGL ES 2.0 HTML Canvas context
 
 Copyright (C) 2011  Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation
 files (the "Software"), to deal in the Software without
@@ -23,84 +24,93 @@ EXPRESS OR IMPLIED, INCLUDING BUT NOT LI
 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 
 -->
-<link rel="stylesheet" type="text/css" href="../unit.css" />
-<script type="application/x-javascript" src="../unit.js"></script>
-<script type="application/x-javascript" src="../util.js"></script>
-<script type="application/x-javascript">
+<link rel="stylesheet" type="text/css" href="../../../resources/js-test-style.css" />
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../resources/webgl-test.js"></script>
+<script src="../../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
+<div id="console"></div>
 
-Tests.startUnit = function () {
-    var canvas = document.getElementById('gl');
-    var gl = wrapGLContext(canvas.getContext(GL_CONTEXT_ID));
-    return [gl];
+<script>
+var wtu = WebGLTestUtils;
+
+description("Test bad arguments to texImage2D");
+
+var canvas = document.getElementById('canvas');
+var gl = wtu.create3DContext(canvas);
+
+function setup(gl) {
+    var tex = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, tex);
+    return tex;
 }
 
-Tests.setup = function(gl) {
-    var tex = gl.createTexture();
-    gl.bindTexture(gl.TEXTURE_2D, tex);
-    return [gl]
-}
-
-Tests.teardown = function(gl,tex) {
+function teardown(gl, tex) {
     gl.bindTexture(gl.TEXTURE_2D, null);
     gl.deleteTexture(tex);
 }
 
-Tests.testTexImage2D = function(gl) {
-    var data = new Uint8Array(4);
-    assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,1,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
-    });
-    assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,2,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
-    });
-    assertGLError(gl, gl.INVALID_ENUM, "bad target", function(){
-        gl.texImage2D(gl.FLOAT, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_ENUM, "bad internal format/format", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.FLOAT, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_VALUE, "border > 0", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,48,gl.RGBA,gl.UNSIGNED_BYTE, null);
-    });
-    // The spec says zero size is OK. If you disagree please list the section
-    // in the spec that details this issue.
-    assertOk("zero size", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_VALUE, "negative width", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, -1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_VALUE, "negative height", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,-1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_ENUM, "bad format", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
-    });
-    assertGLError(gl, gl.INVALID_ENUM, "bad type", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.TEXTURE_2D, null);
-    });
-    assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array(3));
-    });
-    assertGLError(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_SHORT_5_6_5, null);
-    });
-    assertGLError(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
-        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1,1,0,gl.RGB,gl.UNSIGNED_SHORT_4_4_4_4, null);
-    });
+function testrunner(gl, expected, desc, fn) {
+   var tex = setup(gl);
+   fn();
+   glErrorShouldBe(gl, expected, desc);
+   teardown(gl, tex);
 }
 
+ var data = new Uint8Array(4);
+ testrunner(gl, gl.INVALID_OPERATION, "not enough data", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,1,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
+ });
+ testrunner(gl, gl.INVALID_OPERATION, "not enough data", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,2,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
+ });
+ testrunner(gl, gl.INVALID_ENUM, "bad target", function(){
+     gl.texImage2D(gl.FLOAT, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_ENUM, "bad internal format/format", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.FLOAT, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_VALUE, "border > 0", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,48,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ // The spec says zero size is OK. If you disagree please list the section
+ // in the spec that details this issue.
+ testrunner(gl, gl.NO_ERROR, "zero size", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_VALUE, "negative width", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, -1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_VALUE, "negative height", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,-1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_ENUM, "bad format", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
+ });
+ testrunner(gl, gl.INVALID_ENUM, "bad type", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.TEXTURE_2D, null);
+ });
+ testrunner(gl, gl.INVALID_OPERATION, "not enough data", function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array(3));
+ });
+ testrunner(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_SHORT_5_6_5, null);
+ });
+ testrunner(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
+     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1,1,0,gl.RGB,gl.UNSIGNED_SHORT_4_4_4_4, null);
+ });
 
-Tests.endUnit = function(gl) {
-}
-
+debug("");
+var successfullyParsed = true;
 </script>
-<style>canvas{ position:absolute; }</style>
-</head><body>
-<canvas id="gl" width="16" height="16"></canvas>
-</body></html>
+<script>finishTest();</script>
+</body>
+</html>
--- a/content/html/content/src/nsTextEditorState.h
+++ b/content/html/content/src/nsTextEditorState.h
@@ -115,16 +115,17 @@ class nsITextControlElement;
  *     transferred to the mValue member variable, and will be managed there until a new
  *     frame is bound to the text editor state object.
  */
 
 class RestoreSelectionState;
 
 class nsTextEditorState : public mozilla::SupportsWeakPtr<nsTextEditorState> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(nsTextEditorState)
   explicit nsTextEditorState(nsITextControlElement* aOwningElement);
   ~nsTextEditorState();
 
   void Traverse(nsCycleCollectionTraversalCallback& cb);
   void Unlink();
 
   nsIEditor* GetEditor();
   nsISelectionController* GetSelectionController() const;
--- a/content/media/MediaTaskQueue.h
+++ b/content/media/MediaTaskQueue.h
@@ -20,16 +20,17 @@ class SharedThreadPool;
 
 // Abstracts executing runnables in order in a thread pool. The runnables
 // dispatched to the MediaTaskQueue will be executed in the order in which
 // they're received, and are guaranteed to not be executed concurrently.
 // They may be executed on different threads, and a memory barrier is used
 // to make this threadsafe for objects that aren't already threadsafe.
 class MediaTaskQueue : public AtomicRefCounted<MediaTaskQueue> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaTaskQueue)
   MediaTaskQueue(TemporaryRef<SharedThreadPool> aPool);
   ~MediaTaskQueue();
 
   nsresult Dispatch(nsIRunnable* aRunnable);
 
   // Removes all pending tasks from the task queue, and blocks until
   // the currently running task (if any) finishes.
   void Flush();
--- a/content/media/ogg/OggReader.cpp
+++ b/content/media/ogg/OggReader.cpp
@@ -1085,18 +1085,18 @@ nsresult OggReader::GetSeekRanges(nsTArr
       return NS_ERROR_FAILURE;
     }
     int64_t startOffset = range.mStart;
     int64_t endOffset = range.mEnd;
     startTime = RangeStartTime(startOffset);
     if (startTime != -1 &&
         ((endTime = RangeEndTime(endOffset)) != -1))
     {
-      NS_ASSERTION(startTime < endTime,
-                   "Start time must be before end time");
+      NS_WARN_IF_FALSE(startTime < endTime,
+                       "Start time must be before end time");
       aRanges.AppendElement(SeekRange(startOffset,
                                       endOffset,
                                       startTime,
                                       endTime));
      }
   }
   if (NS_FAILED(ResetDecode())) {
     return NS_ERROR_FAILURE;
--- a/content/media/webaudio/PannerNode.h
+++ b/content/media/webaudio/PannerNode.h
@@ -20,16 +20,17 @@ namespace dom {
 
 class AudioContext;
 class AudioBufferSourceNode;
 
 class PannerNode : public AudioNode,
                    public SupportsWeakPtr<PannerNode>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(PannerNode)
   explicit PannerNode(AudioContext* aContext);
   virtual ~PannerNode();
 
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   virtual void DestroyMediaStream() MOZ_OVERRIDE;
--- a/content/media/webrtc/LoadMonitor.cpp
+++ b/content/media/webrtc/LoadMonitor.cpp
@@ -151,16 +151,17 @@ public:
   uint64_t mPrevTotalTimes;
   uint64_t mPrevCpuTimes;
   float mPrevLoad;               // Previous load value.
 };
 
 class LoadInfo : public mozilla::RefCounted<LoadInfo>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(LoadInfo)
   double GetSystemLoad() { return mSystemLoad.GetLoad(); };
   double GetProcessLoad() { return mProcessLoad.GetLoad(); };
   nsresult UpdateSystemLoad();
   nsresult UpdateProcessLoad();
 
 private:
   void UpdateCpuLoad(uint64_t current_total_times,
                      uint64_t current_cpu_times,
--- a/content/media/webrtc/MediaEngine.h
+++ b/content/media/webrtc/MediaEngine.h
@@ -34,16 +34,17 @@ enum MediaEngineState {
 enum {
   kVideoTrack = 1,
   kAudioTrack = 2
 };
 
 class MediaEngine : public RefCounted<MediaEngine>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaEngine)
   virtual ~MediaEngine() {}
 
   static const int DEFAULT_VIDEO_FPS = 30;
   static const int DEFAULT_VIDEO_MIN_FPS = 10;
   static const int DEFAULT_VIDEO_WIDTH = 640;
   static const int DEFAULT_VIDEO_HEIGHT = 480;
   static const int DEFAULT_AUDIO_TIMER_MS = 10;
   static const bool DEFAULT_LOAD_ADAPT = false;
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -280,16 +280,17 @@ MediaEngineDefaultVideoSource::NotifyPul
     }
   }
 }
 
 // generate 1k sine wave per second
 class SineWaveGenerator : public RefCounted<SineWaveGenerator>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(SineWaveGenerator)
   static const int bytesPerSample = 2;
   static const int millisecondsPerSecond = 1000;
   static const int frequency = 1000;
 
   SineWaveGenerator(int aSampleRate) :
     mTotalLength(aSampleRate / frequency),
     mReadLength(0) {
     MOZ_ASSERT(mTotalLength * frequency == aSampleRate);
--- a/content/media/webspeech/recognition/SpeechRecognition.h
+++ b/content/media/webspeech/recognition/SpeechRecognition.h
@@ -53,16 +53,17 @@ PRLogModuleInfo* GetSpeechRecognitionLog
 #define SR_LOG(...)
 #endif
 
 class SpeechRecognition MOZ_FINAL : public nsDOMEventTargetHelper,
                                     public nsIObserver,
                                     public SupportsWeakPtr<SpeechRecognition>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(SpeechRecognition)
   SpeechRecognition(nsPIDOMWindow* aOwnerWindow);
   virtual ~SpeechRecognition() {};
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIOBSERVER
 
   nsISupports* GetParentObject() const;
--- a/content/xul/content/src/nsXULPopupListener.cpp
+++ b/content/xul/content/src/nsXULPopupListener.cpp
@@ -101,17 +101,17 @@ nsXULPopupListener::HandleEvent(nsIDOMEv
 {
   nsAutoString eventType;
   aEvent->GetType(eventType);
 
   if(!((eventType.EqualsLiteral("mousedown") && !mIsContext) ||
        (eventType.EqualsLiteral("contextmenu") && mIsContext)))
     return NS_OK;
 
-  uint16_t button;
+  int16_t button;
 
   nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
   if (!mouseEvent) {
     //non-ui event passed in.  bad things.
     return NS_OK;
   }
 
   // Get the node that was clicked on.
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -138,16 +138,17 @@ class nsDocShell : public nsDocLoader,
                    public nsILinkHandler,
                    public nsIClipboardCommands,
                    public nsIDOMStorageManager,
                    public mozilla::SupportsWeakPtr<nsDocShell>
 {
     friend class nsDSURIContentListener;
 
 public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(nsDocShell)
     // Object Management
     nsDocShell();
 
     NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
     virtual nsresult Init();
 
     NS_DECL_ISUPPORTS_INHERITED
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1078,16 +1078,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
     mShowAccelerators(false),
     mShowFocusRings(false),
 #else
     mShowAccelerators(true),
     mShowFocusRings(true),
 #endif
     mShowFocusRingForContent(false),
     mFocusByKeyOccurred(false),
+    mInnerObjectsFreed(false),
     mHasGamepad(false),
 #ifdef MOZ_GAMEPAD
     mHasSeenGamepadInput(false),
 #endif
     mNotifiedIDDestroyed(false),
     mAllowScriptsToClose(false),
     mTimeoutInsertionPoint(nullptr),
     mTimeoutPublicIdCounter(1),
@@ -1515,16 +1516,18 @@ nsGlobalWindow::FreeInnerObjects()
 {
   NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
 
   // Make sure that this is called before we null out the document and
   // other members that the window destroyed observers could
   // re-create.
   NotifyDOMWindowDestroyed(this);
 
+  mInnerObjectsFreed = true;
+
   // Kill all of the workers for this window.
   mozilla::dom::workers::CancelWorkersForWindow(this);
 
   // Close all offline storages for this window.
   quota::QuotaManager* quotaManager = quota::QuotaManager::Get();
   if (quotaManager) {
     quotaManager->AbortCloseStoragesForWindow(this);
   }
@@ -1801,16 +1804,24 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
+#ifdef DEBUG
+void
+nsGlobalWindow::RiskyUnlink()
+{
+  NS_CYCLE_COLLECTION_INNERNAME.Unlink(this);
+}
+#endif
+
 struct TraceData
 {
   const TraceCallbacks& callbacks;
   void* closure;
 };
 
 static PLDHashOperator
 TraceXBLHandlers(nsXBLPrototypeHandler* aKey, JS::Heap<JSObject*>& aData, void* aClosure)
@@ -12556,17 +12567,17 @@ nsGlobalWindow::SuspendTimeouts(uint32_t
 
 nsresult
 nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
 {
   FORWARD_TO_INNER(ResumeTimeouts, (), NS_ERROR_NOT_INITIALIZED);
 
   NS_ASSERTION(mTimeoutsSuspendDepth, "Mismatched calls to ResumeTimeouts!");
   --mTimeoutsSuspendDepth;
-  bool shouldResume = (mTimeoutsSuspendDepth == 0);
+  bool shouldResume = (mTimeoutsSuspendDepth == 0) && !mInnerObjectsFreed;
   nsresult rv;
 
   if (shouldResume) {
     nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
     if (ac) {
       for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
         ac->AddWindowListener(mEnabledSensors[i], this);
     }
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -599,16 +599,22 @@ public:
   static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
                                           nsGlobalWindow *aWindow);
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
                                                                    nsIDOMEventTarget)
 
+#ifdef DEBUG
+  // Call Unlink on this window. This may cause bad things to happen, so use
+  // with caution.
+  void RiskyUnlink();
+#endif
+
   virtual NS_HIDDEN_(JSObject*)
     GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
 
   virtual NS_HIDDEN_(void)
     CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                              JS::Handle<JSObject*> aHandler);
 
   virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod);
@@ -1402,16 +1408,20 @@ protected:
   // when true, show focus rings for the current focused content only.
   // This will be reset when another element is focused
   bool                   mShowFocusRingForContent : 1;
 
   // true if tab navigation has occurred for this window. Focus rings
   // should be displayed.
   bool                   mFocusByKeyOccurred : 1;
 
+  // Ensure that a call to ResumeTimeouts() after FreeInnerObjects() does nothing.
+  // This member is only used by inner windows.
+  bool                   mInnerObjectsFreed : 1;
+
   // Indicates whether this window wants gamepad input events
   bool                   mHasGamepad : 1;
 #ifdef MOZ_GAMEPAD
   nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
   bool mHasSeenGamepadInput;
 #endif
 
   // whether we've sent the destroy notification for our window id
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -831,8 +831,50 @@ NS_IMPL_ISUPPORTS1(nsWindowMemoryReporte
 /* static */ int64_t
 nsWindowMemoryReporter::GhostWindowsReporter::DistinguishedAmount()
 {
   nsTHashtable<nsUint64HashKey> ghostWindows;
   sWindowReporter->CheckForGhostWindows(&ghostWindows);
   return ghostWindows.Count();
 }
 
+#ifdef DEBUG
+static PLDHashOperator
+UnlinkGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void *)
+{
+  nsGlobalWindow::WindowByIdTable* windowsById =
+    nsGlobalWindow::GetWindowsTable();
+  if (!windowsById) {
+    return PL_DHASH_NEXT;
+  }
+
+  nsRefPtr<nsGlobalWindow> window = windowsById->Get(aIDHashKey->GetKey());
+  if (window) {
+    window->RiskyUnlink();
+  }
+
+  return PL_DHASH_NEXT;
+}
+
+/* static */ void
+nsWindowMemoryReporter::UnlinkGhostWindows()
+{
+  if (!sWindowReporter) {
+    return;
+  }
+
+  nsGlobalWindow::WindowByIdTable* windowsById =
+    nsGlobalWindow::GetWindowsTable();
+  if (!windowsById) {
+    return;
+  }
+
+  // Hold on to every window in memory so that window objects can't be
+  // destroyed while we're calling the UnlinkGhostWindows callback.
+  WindowArray windows;
+  windowsById->Enumerate(GetWindows, &windows);
+
+  // Get the IDs of all the "ghost" windows, and unlink them all.
+  nsTHashtable<nsUint64HashKey> ghostWindows;
+  sWindowReporter->CheckForGhostWindows(&ghostWindows);
+  ghostWindows.EnumerateEntries(UnlinkGhostWindowsEnumerator, nullptr);
+}
+#endif
--- a/dom/base/nsWindowMemoryReporter.h
+++ b/dom/base/nsWindowMemoryReporter.h
@@ -141,16 +141,24 @@ class nsWindowMemoryReporter MOZ_FINAL :
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMEMORYREPORTER
   NS_DECL_NSIOBSERVER
 
   static void Init();
 
+#ifdef DEBUG
+  /**
+   * Unlink all known ghost windows, to enable investigating what caused them
+   * to become ghost windows in the first place.
+   */
+  static void UnlinkGhostWindows();
+#endif
+
 private:
   /**
    * nsGhostWindowReporter generates the "ghost-windows" report, which counts
    * the number of ghost windows present.
    */
   class GhostWindowsReporter MOZ_FINAL : public nsIMemoryReporter
   {
   public:
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -60,37 +60,45 @@ BrowserElementParentFactory.prototype = 
     debug("_init");
     this._initialized = true;
 
     // Maps frame elements to BrowserElementParent objects.  We never look up
     // anything in this map; the purpose is to keep the BrowserElementParent
     // alive for as long as its frame element lives.
     this._bepMap = new WeakMap();
 
-    Services.obs.addObserver(this, 'remote-browser-frame-pending', /* ownsWeak = */ true);
-    Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', /* ownsWeak = */ true);
+    Services.obs.addObserver(this, 'remote-browser-pending', /* ownsWeak = */ true);
+    Services.obs.addObserver(this, 'inprocess-browser-shown', /* ownsWeak = */ true);
   },
 
   _browserFramesPrefEnabled: function() {
     try {
       return Services.prefs.getBoolPref(BROWSER_FRAMES_ENABLED_PREF);
     }
     catch(e) {
       return false;
     }
   },
 
   _observeInProcessBrowserFrameShown: function(frameLoader) {
+    // Ignore notifications that aren't from a BrowserOrApp
+    if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
+      return;
+    }
     debug("In-process browser frame shown " + frameLoader);
     this._createBrowserElementParent(frameLoader,
                                      /* hasRemoteFrame = */ false,
                                      /* pending frame */ false);
   },
 
   _observeRemoteBrowserFramePending: function(frameLoader) {
+    // Ignore notifications that aren't from a BrowserOrApp
+    if (!frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsBrowserOrAppFrame) {
+      return;
+    }
     debug("Remote browser frame shown " + frameLoader);
     this._createBrowserElementParent(frameLoader,
                                      /* hasRemoteFrame = */ true,
                                      /* pending frame */ true);
   },
 
   _createBrowserElementParent: function(frameLoader, hasRemoteFrame, isPendingFrame) {
     let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
@@ -103,19 +111,19 @@ BrowserElementParentFactory.prototype = 
     case 'app-startup':
       this._init();
       break;
     case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
       if (data == BROWSER_FRAMES_ENABLED_PREF) {
         this._init();
       }
       break;
-    case 'remote-browser-frame-pending':
+    case 'remote-browser-pending':
       this._observeRemoteBrowserFramePending(subject);
       break;
-    case 'in-process-browser-or-app-frame-shown':
+    case 'inprocess-browser-shown':
       this._observeInProcessBrowserFrameShown(subject);
       break;
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParentFactory]);
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -307,16 +307,17 @@ private:
   nsresult Notify(const char* aReason, class DeviceStorageFile* aFile);
 
   friend class WatchFileEvent;
   friend class DeviceStorageRequest;
 
   class VolumeNameCache : public mozilla::RefCounted<VolumeNameCache>
   {
   public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeNameCache)
     nsTArray<nsString>  mVolumeNames;
   };
   static mozilla::StaticRefPtr<VolumeNameCache> sVolumeNameCache;
 
 #ifdef MOZ_WIDGET_GONK
   nsString mLastStatus;
   void DispatchMountChangeEvent(nsAString& aVolumeStatus);
 #endif
--- a/dom/devicestorage/DeviceStorageFileDescriptor.h
+++ b/dom/devicestorage/DeviceStorageFileDescriptor.h
@@ -8,13 +8,14 @@
 #define DeviceStorageFileDescriptor_h
 
 #include "mozilla/ipc/FileDescriptor.h"
 
 class DeviceStorageFileDescriptor MOZ_FINAL
   : public mozilla::RefCounted<DeviceStorageFileDescriptor>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageFileDescriptor)
   nsRefPtr<DeviceStorageFile> mDSFile;
   mozilla::ipc::FileDescriptor mFileDescriptor;
 };
 
 #endif
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -177,16 +177,17 @@ DeviceStorageUsedSpaceCache::SetUsedSize
   cacheEntry->mMusicUsedSize = aMusicSize;
   cacheEntry->mTotalUsedSize = aTotalUsedSize;
   cacheEntry->mDirty = false;
 }
 
 class GlobalDirs : public RefCounted<GlobalDirs>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(GlobalDirs)
 #if !defined(MOZ_WIDGET_GONK)
   nsCOMPtr<nsIFile> pictures;
   nsCOMPtr<nsIFile> videos;
   nsCOMPtr<nsIFile> music;
   nsCOMPtr<nsIFile> sdcard;
 #endif
   nsCOMPtr<nsIFile> apps;
   nsCOMPtr<nsIFile> crashes;
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -116,16 +116,17 @@ public:
                     uint64_t aMusicSize, uint64_t aTotalSize);
 
 private:
   friend class InvalidateRunnable;
 
   class CacheEntry : public mozilla::RefCounted<CacheEntry> 
   {
   public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageUsedSpaceCache::CacheEntry)
     bool mDirty;
     nsString mStorageName;
     int64_t  mFreeBytes;
     uint64_t mPicturesUsedSize;
     uint64_t mVideosUsedSize;
     uint64_t mMusicUsedSize;
     uint64_t mTotalUsedSize;
   };
--- a/dom/events/nsDOMMouseEvent.cpp
+++ b/dom/events/nsDOMMouseEvent.cpp
@@ -91,17 +91,17 @@ nsDOMMouseEvent::InitMouseEvent(const ns
                                 bool aCanBubble,
                                 bool aCancelable,
                                 nsIDOMWindow* aView,
                                 int32_t aDetail,
                                 int32_t aScreenX,
                                 int32_t aScreenY,
                                 int32_t aClientX,
                                 int32_t aClientY,
-                                uint16_t aButton,
+                                int16_t aButton,
                                 nsIDOMEventTarget *aRelatedTarget,
                                 const nsAString& aModifiersList)
 {
   Modifiers modifiers = ComputeModifierState(aModifiersList);
 
   nsresult rv = InitMouseEvent(aType, aCanBubble, aCancelable, aView,
                                aDetail, aScreenX, aScreenY, aClientX, aClientY,
                                (modifiers & MODIFIER_CONTROL) != 0,
@@ -174,24 +174,24 @@ nsDOMMouseEvent::InitNSMouseEvent(const 
 
   WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
   mouseEventBase->pressure = aPressure;
   mouseEventBase->inputSource = aInputSource;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMMouseEvent::GetButton(uint16_t* aButton)
+nsDOMMouseEvent::GetButton(int16_t* aButton)
 {
   NS_ENSURE_ARG_POINTER(aButton);
   *aButton = Button();
   return NS_OK;
 }
 
-uint16_t
+int16_t
 nsDOMMouseEvent::Button()
 {
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
--- a/dom/events/nsDOMMouseEvent.h
+++ b/dom/events/nsDOMMouseEvent.h
@@ -42,17 +42,17 @@ public:
   int32_t ScreenX();
   int32_t ScreenY();
   int32_t ClientX();
   int32_t ClientY();
   bool CtrlKey();
   bool ShiftKey();
   bool AltKey();
   bool MetaKey();
-  uint16_t Button();
+  int16_t Button();
   uint16_t Buttons();
   already_AddRefed<mozilla::dom::EventTarget> GetRelatedTarget();
   void InitMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
                       nsIDOMWindow* aView, int32_t aDetail, int32_t aScreenX,
                       int32_t aScreenY, int32_t aClientX, int32_t aClientY,
                       bool aCtrlKey, bool aAltKey, bool aShiftKey,
                       bool aMetaKey, uint16_t aButton,
                       mozilla::dom::EventTarget *aRelatedTarget,
@@ -103,17 +103,17 @@ protected:
                           bool aCanBubble,
                           bool aCancelable,
                           nsIDOMWindow* aView,
                           int32_t aDetail,
                           int32_t aScreenX,
                           int32_t aScreenY,
                           int32_t aClientX,
                           int32_t aClientY,
-                          uint16_t aButton,
+                          int16_t aButton,
                           nsIDOMEventTarget *aRelatedTarget,
                           const nsAString& aModifiersList);
 };
 
 #define NS_FORWARD_TO_NSDOMMOUSEEVENT         \
   NS_FORWARD_NSIDOMMOUSEEVENT(nsDOMMouseEvent::) \
   NS_FORWARD_TO_NSDOMUIEVENT
 
--- a/dom/events/nsEventStateManager.cpp
+++ b/dom/events/nsEventStateManager.cpp
@@ -4098,16 +4098,17 @@ nsEventStateManager::DispatchMouseOrPoin
     PROFILER_LABEL("Input", "DispatchMouseEvent");
     newMouseEvent =
       new WidgetMouseEvent(aMouseEvent->mFlags.mIsTrusted, aMessage,
                            aMouseEvent->widget, WidgetMouseEvent::eReal);
     event = newMouseEvent.get();
   }
   event->refPoint = aMouseEvent->refPoint;
   event->modifiers = aMouseEvent->modifiers;
+  event->button = aMouseEvent->button;
   event->buttons = aMouseEvent->buttons;
   event->pluginEvent = aMouseEvent->pluginEvent;
   event->relatedTarget = aRelatedContent;
   event->inputSource = aMouseEvent->inputSource;
 
   nsWeakFrame previousTarget = mCurrentTarget;
 
   mCurrentTargetContent = aTargetContent;
--- a/dom/events/nsIMEStateManager.cpp
+++ b/dom/events/nsIMEStateManager.cpp
@@ -308,17 +308,17 @@ nsIMEStateManager::OnClickInEditor(nsPre
 
   bool isTrusted;
   nsresult rv = aMouseEvent->GetIsTrusted(&isTrusted);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (!isTrusted) {
     return; // ignore untrusted event.
   }
 
-  uint16_t button;
+  int16_t button;
   rv = aMouseEvent->GetButton(&button);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (button != 0) {
     return; // not a left click event.
   }
 
   int32_t clickCount;
   rv = aMouseEvent->GetDetail(&clickCount);
--- a/dom/inputmethod/Keyboard.jsm
+++ b/dom/inputmethod/Keyboard.jsm
@@ -47,18 +47,18 @@ this.Keyboard = {
 
   sendToKeyboard: function(name, data) {
     try {
       this._keyboardMM.sendAsyncMessage(name, data);
     } catch(e) { }
   },
 
   init: function keyboardInit() {
-    Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
-    Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
+    Services.obs.addObserver(this, 'inprocess-browser-shown', false);
+    Services.obs.addObserver(this, 'remote-browser-shown', false);
     Services.obs.addObserver(this, 'oop-frameloader-crashed', false);
 
     for (let name of this._messageNames)
       ppmm.addMessageListener('Keyboard:' + name, this);
   },
 
   observe: function keyboardObserve(subject, topic, data) {
     let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
@@ -66,16 +66,20 @@ this.Keyboard = {
 
     if (topic == 'oop-frameloader-crashed') {
       if (this.formMM == mm) {
         // The application has been closed unexpectingly. Let's tell the
         // keyboard app that the focus has been lost.
         this.sendToKeyboard('Keyboard:FocusChange', { 'type': 'blur' });
       }
     } else {
+      // Ignore notifications that aren't from a BrowserOrApp
+      if (!frameLoader.ownerIsBrowserOrAppFrame) {
+        return;
+      }
       this.initFormsFrameScript(mm);
     }
   },
 
   initFormsFrameScript: function(mm) {
     mm.addMessageListener('Forms:Input', this);
     mm.addMessageListener('Forms:SelectionChange', this);
     mm.addMessageListener('Forms:GetText:Result:OK', this);
--- a/dom/interfaces/events/nsIDOMMouseEvent.idl
+++ b/dom/interfaces/events/nsIDOMMouseEvent.idl
@@ -8,34 +8,34 @@
 /**
  * The nsIDOMMouseEvent interface is the datatype for all mouse events
  * in the Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Events/
  */
 
-[scriptable, builtinclass, uuid(afb2e57b-2822-4969-b2a9-0cada6859534)]
+[scriptable, builtinclass, uuid(df068636-9a5b-11e3-b71f-2c27d728e7f9)]
 interface nsIDOMMouseEvent : nsIDOMUIEvent
 {
   readonly attribute long               screenX;
   readonly attribute long               screenY;
 
   readonly attribute long               mozMovementX;
   readonly attribute long               mozMovementY;
 
   readonly attribute long               clientX;
   readonly attribute long               clientY;
 
   readonly attribute boolean            ctrlKey;
   readonly attribute boolean            shiftKey;
   readonly attribute boolean            altKey;
   readonly attribute boolean            metaKey;
 
-  readonly attribute unsigned short     button;
+  readonly attribute short              button;
   readonly attribute unsigned short     buttons;
   readonly attribute nsIDOMEventTarget  relatedTarget;
 
   void                      initMouseEvent(in DOMString typeArg,
                                            in boolean canBubbleArg,
                                            in boolean cancelableArg,
                                            in nsIDOMWindow viewArg,
                                            in long detailArg,
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -595,17 +595,17 @@ ParticularProcessPriorityManager::Partic
 void
 ParticularProcessPriorityManager::Init()
 {
   RegisterWakeLockObserver(this);
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->AddObserver(this, "audio-channel-process-changed", /* ownsWeak */ true);
-    os->AddObserver(this, "remote-browser-frame-shown", /* ownsWeak */ true);
+    os->AddObserver(this, "remote-browser-shown", /* ownsWeak */ true);
     os->AddObserver(this, "ipc:browser-destroyed", /* ownsWeak */ true);
     os->AddObserver(this, "frameloader-visible-changed", /* ownsWeak */ true);
   }
 
   // This process may already hold the CPU lock; for example, our parent may
   // have acquired it on our behalf.
   WakeLockInformation info1, info2;
   GetWakeLockInfo(NS_LITERAL_STRING("cpu"), &info1);
@@ -667,17 +667,17 @@ ParticularProcessPriorityManager::Observ
     // We've been shut down.
     return NS_OK;
   }
 
   nsDependentCString topic(aTopic);
 
   if (topic.EqualsLiteral("audio-channel-process-changed")) {
     OnAudioChannelProcessChanged(aSubject);
-  } else if (topic.EqualsLiteral("remote-browser-frame-shown")) {
+  } else if (topic.EqualsLiteral("remote-browser-shown")) {
     OnRemoteBrowserFrameShown(aSubject);
   } else if (topic.EqualsLiteral("ipc:browser-destroyed")) {
     OnTabParentDestroyed(aSubject);
   } else if (topic.EqualsLiteral("frameloader-visible-changed")) {
     OnFrameloaderVisibleChanged(aSubject);
   } else {
     MOZ_ASSERT(false);
   }
@@ -740,16 +740,23 @@ ParticularProcessPriorityManager::OnAudi
 }
 
 void
 ParticularProcessPriorityManager::OnRemoteBrowserFrameShown(nsISupports* aSubject)
 {
   nsCOMPtr<nsIFrameLoader> fl = do_QueryInterface(aSubject);
   NS_ENSURE_TRUE_VOID(fl);
 
+  // Ignore notifications that aren't from a BrowserOrApp
+  bool isBrowserOrApp;
+  fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
+  if (!isBrowserOrApp) {
+    return;
+  }
+
   nsCOMPtr<nsITabParent> tp;
   fl->GetTabParent(getter_AddRefs(tp));
   NS_ENSURE_TRUE_VOID(tp);
 
   if (static_cast<TabParent*>(tp.get())->Manager() != mContentParent) {
     return;
   }
 
--- a/dom/plugins/base/nsNPAPIPlugin.h
+++ b/dom/plugins/base/nsNPAPIPlugin.h
@@ -65,17 +65,18 @@ protected:
   NPPluginFuncs mPluginFuncs;
   PluginLibrary* mLibrary;
 };
 
 namespace mozilla {
 namespace plugins {
 namespace parent {
 
-JS_STATIC_ASSERT(sizeof(NPIdentifier) == sizeof(jsid));
+static_assert(sizeof(NPIdentifier) == sizeof(jsid),
+              "NPIdentifier must be binary compatible with jsid.");
 
 inline jsid
 NPIdentifierToJSId(NPIdentifier id)
 {
     jsid tmp;
     JSID_BITS(tmp) = (size_t)id;
     return tmp;
 }
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1,27 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set ts=2 sts=2 sw=2 et cin:
 /* 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/. */
 
-#ifdef MOZ_WIDGET_QT
-#include <QWidget>
-#include <QKeyEvent>
-#if defined(MOZ_X11)
-#if defined(Q_WS_X11)
-#include <QX11Info>
-#else
-#include "gfxQtPlatform.h"
-#endif
-#endif
-#undef slots
-#endif
-
 #ifdef MOZ_X11
 #include <cairo-xlib.h>
 #include "gfxXlibSurface.h"
 /* X headers suck */
 enum { XKeyPress = KeyPress };
 #include "mozilla/X11Util.h"
 using mozilla::DefaultXDisplay;
 #endif
@@ -2145,56 +2132,16 @@ nsEventStatus nsPluginInstanceOwner::Pro
               event.type = XKeyPress;
               break;
             case NS_KEY_UP:
               event.type = KeyRelease;
               break;
             }
 #endif
 
-#ifdef MOZ_WIDGET_QT
-          const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
-
-          memset( &event, 0, sizeof(event) );
-          event.time = anEvent.time;
-
-          QWidget* qWidget = static_cast<QWidget*>(widget->GetNativeData(NS_NATIVE_WINDOW));
-
-          if (qWidget)
-#if defined(Q_WS_X11)
-            event.root = qWidget->x11Info().appRootWindow();
-#else
-            event.root = RootWindowOfScreen(DefaultScreenOfDisplay(gfxQtPlatform::GetXDisplay(qWidget)));
-#endif
-
-          // deduce keycode from the information in the attached QKeyEvent
-          const QKeyEvent* qtEvent = static_cast<const QKeyEvent*>(anEvent.pluginEvent);
-          if (qtEvent) {
-
-            if (qtEvent->nativeModifiers())
-              event.state = qtEvent->nativeModifiers();
-            else // fallback
-              event.state = XInputEventState(keyEvent);
-
-            if (qtEvent->nativeScanCode())
-              event.keycode = qtEvent->nativeScanCode();
-            else // fallback
-              event.keycode = XKeysymToKeycode( (widget ? static_cast<Display*>(widget->GetNativeData(NS_NATIVE_DISPLAY)) : nullptr), qtEvent->key());
-          }
-
-          switch (anEvent.message)
-            {
-            case NS_KEY_DOWN:
-              event.type = XKeyPress;
-              break;
-            case NS_KEY_UP:
-              event.type = KeyRelease;
-              break;
-           }
-#endif
           // Information that could be obtained from pluginEvent but we may not
           // want to promise to provide:
           event.subwindow = None;
           event.x = 0;
           event.y = 0;
           event.x_root = -1;
           event.y_root = -1;
           event.same_screen = False;
--- a/dom/plugins/test/testplugin/nptest_qt.cpp
+++ b/dom/plugins/test/testplugin/nptest_qt.cpp
@@ -25,30 +25,20 @@
  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * 
  * Contributor(s):
  *   Josh Aas <josh@mozilla.com>
  * 
  * ***** END LICENSE BLOCK ***** */
-#include <QWidget>
-#include <QPainter>
-
 #include "nptest_platform.h"
 #include "npapi.h"
 
-struct _PlatformData {
-#ifdef MOZ_X11
-  Display* display;
-  Visual* visual;
-  Colormap colormap;
-#endif
-};
- using namespace std;
+using namespace std;
 
 bool
 pluginSupportsWindowMode()
 {
   return false;
 }
 
 bool
@@ -61,34 +51,18 @@ bool
 pluginSupportsAsyncBitmapDrawing()
 {
   return false;
 }
 
 NPError
 pluginInstanceInit(InstanceData* instanceData)
 {
-#ifdef MOZ_X11
-  instanceData->platformData = static_cast<PlatformData*>
-    (NPN_MemAlloc(sizeof(PlatformData)));
-  if (!instanceData->platformData){
-    //printf("NPERR_OUT_OF_MEMORY_ERROR\n");
-    return NPERR_OUT_OF_MEMORY_ERROR;
-  }
-
-  instanceData->platformData->display = nullptr;
-  instanceData->platformData->visual = nullptr;
-  instanceData->platformData->colormap = None;
-
-  return NPERR_NO_ERROR;
-#else
   printf("NPERR_INCOMPATIBLE_VERSION_ERROR\n");
   return NPERR_INCOMPATIBLE_VERSION_ERROR;
-#endif
-  return NPERR_NO_ERROR;
 }
 
 void
 pluginInstanceShutdown(InstanceData* instanceData)
 {
   NPN_MemFree(instanceData->platformData);
   instanceData->platformData = 0;
 }
@@ -100,112 +74,19 @@ pluginDoSetWindow(InstanceData* instance
 }
 
 void
 pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
 {
   // XXX nothing here yet since we don't support windowed plugins
 }
 
-static void
-pluginDrawWindow(InstanceData* instanceData, void* event)
-{
-  NPWindow& window = instanceData->window;
-  // When we have a widget, window.x/y are meaningless since our
-  // widget is always positioned correctly and we just draw into it at 0,0
-  int x = instanceData->hasWidget ? 0 : window.x;
-  int y = instanceData->hasWidget ? 0 : window.y;
-  int width = window.width;
-  int height = window.height;
-
-#ifdef MOZ_X11
-  XEvent* nsEvent = (XEvent*)event;
-  const XGraphicsExposeEvent& expose = nsEvent->xgraphicsexpose;
-
-  QColor drawColor((QColor)instanceData->scriptableObject->drawColor);//QRgb qRgba ( int r, int g, int b, int a )
-#ifdef Q_WS_X11
-  QPixmap pixmap = QPixmap::fromX11Pixmap(expose.drawable, QPixmap::ExplicitlyShared);
-
-  QRect exposeRect(expose.x, expose.y, expose.width, expose.height);
-  if (instanceData->scriptableObject->drawMode == DM_SOLID_COLOR) {
-    //printf("Drawing Solid\n");
-    // drawing a solid color for reftests
-    QPainter painter(&pixmap);
-    painter.fillRect(exposeRect, drawColor);
-    notifyDidPaint(instanceData);
-    return;
-
-  }
-#endif
-#endif
-
-  NPP npp = instanceData->npp;
-  if (!npp)
-    return;
-
-  QString text (NPN_UserAgent(npp));
-  if (text.isEmpty())
-    return;
-
-#ifdef MOZ_X11
-#ifdef Q_WS_X11
-  //printf("Drawing Default\n");
-  // drawing a solid color for reftests
-  QColor color;
-  QPainter painter(&pixmap);
-  QRect theRect(x, y, width, height);
-  QRect clipRect(QPoint(window.clipRect.left, window.clipRect.top),
-                 QPoint(window.clipRect.right, window.clipRect.bottom));
-  painter.setClipRect(clipRect);
-  painter.fillRect(theRect, QColor(128,128,128,255));
-  painter.drawRect(theRect);
-  painter.drawText(QRect(theRect), Qt::AlignCenter, text);
-  notifyDidPaint(instanceData);
-#endif
-#endif
-  return;
-}
-
 int16_t
 pluginHandleEvent(InstanceData* instanceData, void* event)
 {
-#ifdef MOZ_X11
-  XEvent* nsEvent = (XEvent*)event;
-  //printf("\nEvent Type %d\n", nsEvent->type);
-  switch (nsEvent->type) {
-  case GraphicsExpose: {
-    //printf("GraphicsExpose\n");
-
-    pluginDrawWindow(instanceData, event);
-    break;
-  }
-  case MotionNotify: {
-    //printf("MotionNotify\n");
-    XMotionEvent* motion = &nsEvent->xmotion;
-    instanceData->lastMouseX = motion->x;
-    instanceData->lastMouseY = motion->y;
-    break;
-  }
-  case ButtonPress:{
-    ////printf("ButtonPress\n");
-    break;
-  }
-  case ButtonRelease: {
-    //printf("ButtonRelease\n");
-    XButtonEvent* button = &nsEvent->xbutton;
-    instanceData->lastMouseX = button->x;
-    instanceData->lastMouseY = button->y;
-    instanceData->mouseUpEventCount++;
-    break;
-  }
-  default:
-    break;
-  }
-#endif
-
   return 0;
 }
 
 int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
 {
   // XXX nothing here yet since we don't support windowed plugins
   return NPTEST_INT32_ERROR;
 }
--- a/dom/src/geolocation/Makefile.in
+++ b/dom/src/geolocation/Makefile.in
@@ -1,9 +1,9 @@
 # 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 $(topsrcdir)/config/rules.mk
 
-ifdef MOZ_ENABLE_QTMOBILITY
+ifdef MOZ_ENABLE_QT5GEOPOSITION
 CXXFLAGS += $(MOZ_QT_CFLAGS)
 endif
--- a/dom/src/geolocation/moz.build
+++ b/dom/src/geolocation/moz.build
@@ -21,17 +21,17 @@ include('/ipc/chromium/chromium-config.m
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/dom/base',
     '/dom/events',
     '/dom/ipc',
 ]
 
-if CONFIG['MOZ_ENABLE_QTMOBILITY']:
+if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
     LOCAL_INCLUDES += [
         '/dom/system/unix',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     LOCAL_INCLUDES += [
         '/dom/system/android',
     ]
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -23,17 +23,17 @@
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 
 class nsIPrincipal;
 
-#ifdef MOZ_ENABLE_QTMOBILITY
+#ifdef MOZ_ENABLE_QT5GEOPOSITION
 #include "QTMLocationProvider.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidLocationProvider.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
@@ -662,17 +662,17 @@ nsresult nsGeolocationService::Init()
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return NS_ERROR_FAILURE;
   }
 
   obs->AddObserver(this, "quit-application", false);
   obs->AddObserver(this, "mozsettings-changed", false);
 
-#ifdef MOZ_ENABLE_QTMOBILITY
+#ifdef MOZ_ENABLE_QT5GEOPOSITION
   mProvider = new QTMLocationProvider();
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
   mProvider = new AndroidLocationProvider();
 #endif
 
 #ifdef MOZ_WIDGET_GONK
--- a/dom/system/moz.build
+++ b/dom/system/moz.build
@@ -1,18 +1,18 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
 
-if toolkit in ('qt', 'gtk2', 'gtk3'):
-    DIRS += ['unix']
+if toolkit in ('qt'):
+    DIRS += ['qt']
 elif toolkit == 'windows':
     DIRS += ['windows']
 elif toolkit == 'cocoa':
     DIRS += ['mac']
 elif toolkit == 'android':
     DIRS += ['android']
 elif toolkit == 'gonk':
     DIRS += ['gonk']
rename from dom/system/unix/Makefile.in
rename to dom/system/qt/Makefile.in
--- a/dom/system/unix/Makefile.in
+++ b/dom/system/qt/Makefile.in
@@ -1,9 +1,9 @@
 # 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 $(topsrcdir)/config/rules.mk
 
-ifdef MOZ_ENABLE_QTMOBILITY
+ifdef MOZ_ENABLE_QT5GEOPOSITION
 CXXFLAGS += $(MOZ_QT_CFLAGS)
 endif
rename from dom/system/unix/QTMLocationProvider.cpp
rename to dom/system/qt/QTMLocationProvider.cpp
--- a/dom/system/unix/QTMLocationProvider.cpp
+++ b/dom/system/qt/QTMLocationProvider.cpp
@@ -7,16 +7,19 @@
 #include "nsGeoPosition.h"
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS1(QTMLocationProvider, nsIGeolocationProvider)
 
 QTMLocationProvider::QTMLocationProvider()
 {
+    if (QMetaType::type("QGeoPositionInfo") == QMetaType::UnknownType) {
+        qRegisterMetaType<QGeoPositionInfo>("QGeoPositionInfo");
+    }
     mLocation = QGeoPositionInfoSource::createDefaultSource(this);
     if (mLocation)
         connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
 }
 
 QTMLocationProvider::~QTMLocationProvider()
 {
     delete mLocation;
@@ -52,16 +55,19 @@ QTMLocationProvider::positionUpdated(con
 }
 
 NS_IMETHODIMP
 QTMLocationProvider::Startup()
 {
     if (!mLocation)
         return NS_ERROR_NOT_IMPLEMENTED;
 
+    // Not all versions of qt5positioning set default prefered method
+    // thus this workaround initializing QGeoPositionSource explicitly
+    SetHighAccuracy(false);
     mLocation->startUpdates();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
@@ -78,12 +84,18 @@ QTMLocationProvider::Shutdown()
 
     mLocation->stopUpdates();
     mCallback = nullptr;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-QTMLocationProvider::SetHighAccuracy(bool)
+QTMLocationProvider::SetHighAccuracy(bool aHigh)
 {
-  return NS_OK;
+    if (!mLocation)
+        return NS_ERROR_NOT_IMPLEMENTED;
+
+    mLocation->setPreferredPositioningMethods(aHigh ?
+                                              QGeoPositionInfoSource::SatellitePositioningMethods :
+                                              QGeoPositionInfoSource::AllPositioningMethods);
+    return NS_OK;
 }
rename from dom/system/unix/QTMLocationProvider.h
rename to dom/system/qt/QTMLocationProvider.h
--- a/dom/system/unix/QTMLocationProvider.h
+++ b/dom/system/qt/QTMLocationProvider.h
@@ -5,19 +5,16 @@
 #ifndef QTMLocationProvider_h
 #define QTMLocationProvider_h
 
 #include <QGeoPositionInfoSource>
 #include "nsGeolocation.h"
 #include "nsIGeolocationProvider.h"
 #include "nsCOMPtr.h"
 
-
-using namespace QtMobility;
-
 class QTMLocationProvider : public QObject,
                             public nsIGeolocationProvider
 {
     Q_OBJECT
 
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIGEOLOCATIONPROVIDER
rename from dom/system/unix/nsHapticFeedback.cpp
rename to dom/system/qt/QtHapticFeedback.cpp
--- a/dom/system/unix/nsHapticFeedback.cpp
+++ b/dom/system/qt/QtHapticFeedback.cpp
@@ -1,68 +1,20 @@
 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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/. */
 
-#if (MOZ_PLATFORM_MAEMO == 5)
-#include <dbus/dbus.h>
-#include <mce/dbus-names.h>
-#endif
-#if defined(MOZ_ENABLE_QTMOBILITY)
 #include <QFeedbackEffect>
-using namespace QtMobility;
-#endif
+#include "QtHapticFeedback.h"
 
-#include "nsHapticFeedback.h"
-
-NS_IMPL_ISUPPORTS1(nsHapticFeedback, nsIHapticFeedback)
+NS_IMPL_ISUPPORTS1(QtHapticFeedback, nsIHapticFeedback)
 
 NS_IMETHODIMP
-nsHapticFeedback::PerformSimpleAction(int32_t aType)
+QtHapticFeedback::PerformSimpleAction(int32_t aType)
 {
-#if (MOZ_PLATFORM_MAEMO == 5)
-    DBusError err;
-    dbus_error_init(&err);
-
-    DBusConnection  *connection;
-    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-    if (dbus_error_is_set(&err)) {
-        dbus_error_free(&err);
-        return NS_ERROR_FAILURE;
-    }
-    if (nullptr == connection) {
-        return NS_ERROR_FAILURE;
-    }
-
-    dbus_connection_set_exit_on_disconnect(connection,false);
-
-    DBusMessage* msg =
-        dbus_message_new_method_call(MCE_SERVICE, MCE_REQUEST_PATH,
-                                     MCE_REQUEST_IF, MCE_ACTIVATE_VIBRATOR_PATTERN);
-
-    if (!msg) {
-        return NS_ERROR_FAILURE;
-    }
-
-    dbus_message_set_no_reply(msg, true);
-
-    DBusMessageIter iter;
-    dbus_message_iter_init_append(msg, &iter);
-    const char* pattern = "PatternTouchscreen";
-    dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pattern);
-
-    if (dbus_connection_send(connection, msg, nullptr)) {
-        dbus_connection_flush(connection);
-        dbus_message_unref(msg);
-    } else {
-        dbus_message_unref(msg);
-        return NS_ERROR_FAILURE;
-    }
-#elif defined(MOZ_ENABLE_QTMOBILITY)
     if (aType == ShortPress)
-        QFeedbackEffect::playThemeEffect(QFeedbackEffect::ThemeBasicButton);
+        QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressWeak);
     if (aType == LongPress)
-        QFeedbackEffect::playThemeEffect(QFeedbackEffect::ThemeLongPress);
-#endif
+        QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressStrong);
 
     return NS_OK;
 }
rename from dom/system/unix/nsHapticFeedback.h
rename to dom/system/qt/QtHapticFeedback.h
--- a/dom/system/unix/nsHapticFeedback.h
+++ b/dom/system/qt/QtHapticFeedback.h
@@ -1,13 +1,13 @@
 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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 "nsIHapticFeedback.h"
 
-class nsHapticFeedback : public nsIHapticFeedback
+class QtHapticFeedback : public nsIHapticFeedback
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIHAPTICFEEDBACK
 };
rename from dom/system/unix/moz.build
rename to dom/system/qt/moz.build
--- a/dom/system/unix/moz.build
+++ b/dom/system/qt/moz.build
@@ -1,23 +1,28 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-if CONFIG['MOZ_ENABLE_QTMOBILITY']:
+if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
     GENERATED_SOURCES += [
         'moc_QTMLocationProvider.cpp',
     ]
     SOURCES += [
         'QTMLocationProvider.cpp',
     ]
 
     LOCAL_INCLUDES += [
         '/dom/src/geolocation',
     ]
 
+if CONFIG['MOZ_ENABLE_QT5FEEDBACK']:
+    SOURCES += [
+        'QtHapticFeedback.cpp',
+    ]
+
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
--- a/dom/webidl/MouseEvent.webidl
+++ b/dom/webidl/MouseEvent.webidl
@@ -14,17 +14,17 @@ interface MouseEvent : UIEvent {
   readonly attribute long           screenX;
   readonly attribute long           screenY;
   readonly attribute long           clientX;
   readonly attribute long           clientY;
   readonly attribute boolean        ctrlKey;
   readonly attribute boolean        shiftKey;
   readonly attribute boolean        altKey;
   readonly attribute boolean        metaKey;
-  readonly attribute unsigned short button;
+  readonly attribute short          button;
   readonly attribute unsigned short buttons;
   readonly attribute EventTarget?   relatedTarget;
   // Deprecated in DOM Level 3:
   [Throws]
   void                              initMouseEvent(DOMString typeArg, 
                                                    boolean canBubbleArg, 
                                                    boolean cancelableArg, 
                                                    WindowProxy? viewArg, 
@@ -32,17 +32,17 @@ interface MouseEvent : UIEvent {
                                                    long screenXArg, 
                                                    long screenYArg, 
                                                    long clientXArg, 
                                                    long clientYArg, 
                                                    boolean ctrlKeyArg, 
                                                    boolean altKeyArg, 
                                                    boolean shiftKeyArg, 
                                                    boolean metaKeyArg, 
-                                                   unsigned short buttonArg,
+                                                   short buttonArg,
                                                    EventTarget? relatedTargetArg);
   // Introduced in DOM Level 3:
   boolean                           getModifierState(DOMString keyArg);
 };
 
 
 // Event Constructor Syntax:
 [Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)]
@@ -64,17 +64,17 @@ dictionary MouseEventInit {
   long           screenX       = 0;
   long           screenY       = 0;
   long           clientX       = 0;
   long           clientY       = 0;
   boolean        ctrlKey       = false;
   boolean        shiftKey      = false;
   boolean        altKey        = false;
   boolean        metaKey       = false;
-  unsigned short button        = 0;
+  short          button        = 0;
   // Note: "buttons" was not previously initializable through initMouseEvent!
   unsigned short buttons       = 0;
   EventTarget?   relatedTarget = null;
 };
 
 // Mozilla extensions
 partial interface MouseEvent
 {
@@ -104,15 +104,15 @@ partial interface MouseEvent
                                        long screenXArg,
                                        long screenYArg,
                                        long clientXArg,
                                        long clientYArg,
                                        boolean ctrlKeyArg,
                                        boolean altKeyArg,
                                        boolean shiftKeyArg,
                                        boolean metaKeyArg,
-                                       unsigned short buttonArg,
+                                       short buttonArg,
                                        EventTarget? relatedTargetArg,
                                        float pressure,
                                        unsigned short inputSourceArg);
 
 };
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1549,16 +1549,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   nsXHREventTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUpload)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XMLHttpRequest,
                                                 nsXHREventTarget)
   tmp->ReleaseProxy(XHRIsGoingAway);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mUpload)
+  tmp->mStateData.mResponse.setUndefined();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(XMLHttpRequest,
                                                nsXHREventTarget)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mStateData.mResponse)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 JSObject*
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -218,101 +218,97 @@ nsXBLDocGlobalObject::GetPrincipal()
   if (!document)
     return nullptr;
 
   return document->NodePrincipal();
 }
 
 /* Implementation file */
 
-static bool
-TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+TraverseProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Traverse(*cb);
-  return kHashEnumerateNext;
+  aProto->Traverse(*cb);
+  return PL_DHASH_NEXT;
 }
 
-static bool
-UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+UnlinkProtoJSObjects(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->UnlinkJSObjects();
-  return kHashEnumerateNext;
+  aProto->UnlinkJSObjects();
+  return PL_DHASH_NEXT;
 }
 
 struct ProtoTracer
 {
   const TraceCallbacks &mCallbacks;
   void *mClosure;
 };
 
-static bool
-TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+TraceProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
   ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Trace(closure->mCallbacks, closure->mClosure);
-  return kHashEnumerateNext;
+  aProto->Trace(closure->mCallbacks, closure->mClosure);
+  return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nullptr);
+    tmp->mBindingTable->EnumerateRead(UnlinkProtoJSObjects, nullptr);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mDocument &&
       nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
+    tmp->mBindingTable->EnumerateRead(TraverseProtos, &cb);
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
     ProtoTracer closure = { aCallbacks, aClosure };
-    tmp->mBindingTable->Enumerate(TraceProtos, &closure);
+    tmp->mBindingTable->EnumerateRead(TraceProtos, &closure);
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 static void
 UnmarkXBLJSObject(void* aP, const char* aName, void* aClosure)
 {
   JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP));
 }
 
-static bool
-UnmarkProtos(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+UnmarkProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
-  return kHashEnumerateNext;
+  aProto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
+  return PL_DHASH_NEXT;
 }
 
 void
 nsXBLDocumentInfo::MarkInCCGeneration(uint32_t aGeneration)
 {
   if (mDocument) {
     mDocument->MarkUncollectableForCCGeneration(aGeneration);
   }
   // Unmark any JS we hold
   if (mBindingTable) {
-    mBindingTable->Enumerate(UnmarkProtos, nullptr);
+    mBindingTable->EnumerateRead(UnmarkProtos, nullptr);
   }
   if (mGlobalObject) {
     mGlobalObject->UnmarkCompilationGlobal();
   }
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@@ -321,17 +317,16 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLDocumentInfo)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXBLDocumentInfo)
 
 nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
   : mDocument(aDocument),
     mScriptAccess(true),
     mIsChrome(false),
-    mBindingTable(nullptr),
     mFirstBinding(nullptr)
 {
   nsIURI* uri = aDocument->GetDocumentURI();
   if (IsChromeURI(uri)) {
     // Cache whether or not this chrome XBL can execute scripts.
     nsCOMPtr<nsIXULChromeRegistry> reg =
       mozilla::services::GetXULChromeRegistryService();
     if (reg) {
@@ -362,84 +357,63 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsI
 }
 
 nsXBLDocumentInfo::~nsXBLDocumentInfo()
 {
   /* destructor code */
   if (mGlobalObject) {
     mGlobalObject->ClearGlobalObjectOwner(); // just in case
   }
-  if (mBindingTable) {
-    delete mBindingTable;
-    mBindingTable = nullptr;
-    mozilla::DropJSObjects(this);
-  }
+  mozilla::DropJSObjects(this);
 }
 
 nsXBLPrototypeBinding*
 nsXBLDocumentInfo::GetPrototypeBinding(const nsACString& aRef)
 {
   if (!mBindingTable)
     return nullptr;
 
   if (aRef.IsEmpty()) {
     // Return our first binding
     return mFirstBinding;
   }
 
-  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-  nsCStringKey key(flat.get());
-  return static_cast<nsXBLPrototypeBinding*>(mBindingTable->Get(&key));
-}
-
-static bool
-DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure)
-{
-  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding*>(aData);
-  delete binding;
-  return true;
+  return mBindingTable->Get(aRef);
 }
 
 nsresult
 nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
 {
   if (!mBindingTable) {
-    mBindingTable = new nsObjectHashtable(nullptr, nullptr, DeletePrototypeBinding, nullptr);
-
+    mBindingTable = new nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>();
     mozilla::HoldJSObjects(this);
   }
 
-  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-  nsCStringKey key(flat.get());
-  NS_ENSURE_STATE(!mBindingTable->Get(&key));
-  mBindingTable->Put(&key, aBinding);
+  NS_ENSURE_STATE(!mBindingTable->Get(aRef));
+  mBindingTable->Put(aRef, aBinding);
 
   return NS_OK;
 }
 
 void
 nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef)
 {
   if (mBindingTable) {
-    // Use a flat string to avoid making a copy.
-    const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-    nsCStringKey key(flat);
-    mBindingTable->Remove(&key);
+    mBindingTable->Remove(aRef);
   }
 }
 
 // Callback to enumerate over the bindings from this document and write them
 // out to the cache.
-bool
-WriteBinding(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+WriteBinding(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding *>(aData);
-  binding->Write((nsIObjectOutputStream*)aClosure);
+  aProto->Write((nsIObjectOutputStream*)aClosure);
 
-  return kHashEnumerateNext;
+  return PL_DHASH_NEXT;
 }
 
 // static
 nsresult
 nsXBLDocumentInfo::ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocInfo)
 {
   *aDocInfo = nullptr;
 
@@ -525,18 +499,19 @@ nsXBLDocumentInfo::WritePrototypeBinding
   rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(stream),
                                            getter_AddRefs(storageStream),
                                            true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = stream->Write32(XBLBinding_Serialize_Version);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (mBindingTable)
-    mBindingTable->Enumerate(WriteBinding, stream);
+  if (mBindingTable) {
+    mBindingTable->EnumerateRead(WriteBinding, stream);
+  }
 
   // write a end marker at the end
   rv = stream->Write8(XBLBinding_Serialize_NoMoreBindings);
   NS_ENSURE_SUCCESS(rv, rv);
 
   stream->Close();
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -549,28 +524,29 @@ nsXBLDocumentInfo::WritePrototypeBinding
 }
 
 void
 nsXBLDocumentInfo::SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding)
 {
   mFirstBinding = aBinding;
 }
 
-bool FlushScopedSkinSheets(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+FlushScopedSkinSheets(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* proto = (nsXBLPrototypeBinding*)aData;
-  proto->FlushSkinSheets();
-  return true;
+  aProto->FlushSkinSheets();
+  return PL_DHASH_NEXT;
 }
 
 void
 nsXBLDocumentInfo::FlushSkinStylesheets()
 {
-  if (mBindingTable)
-    mBindingTable->Enumerate(FlushScopedSkinSheets);
+  if (mBindingTable) {
+    mBindingTable->EnumerateRead(FlushScopedSkinSheets, nullptr);
+  }
 }
 
 JSObject*
 nsXBLDocumentInfo::GetCompilationGlobal()
 {
   EnsureGlobalObject();
   return mGlobalObject->GetCompilationGlobal();
 }
--- a/dom/xbl/nsXBLDocumentInfo.h
+++ b/dom/xbl/nsXBLDocumentInfo.h
@@ -8,17 +8,16 @@
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsXBLPrototypeBinding;
-class nsObjectHashtable;
 class nsXBLDocGlobalObject;
 
 class nsXBLDocumentInfo : public nsSupportsWeakReference
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsXBLDocumentInfo(nsIDocument* aDocument);
@@ -36,17 +35,17 @@ public:
                                nsXBLPrototypeBinding* aBinding);
 
   // This removes the binding without deleting it
   void RemovePrototypeBinding(const nsACString& aRef);
 
   nsresult WritePrototypeBindings();
 
   void SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding);
-  
+
   void FlushSkinStylesheets();
 
   bool IsChrome() { return mIsChrome; }
 
   JSObject* GetCompilationGlobal();
 
   void MarkInCCGeneration(uint32_t aGeneration);
 
@@ -55,17 +54,18 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsXBLDocumentInfo)
 
 private:
   void EnsureGlobalObject();
   nsCOMPtr<nsIDocument> mDocument;
   bool mScriptAccess;
   bool mIsChrome;
   // the binding table owns each nsXBLPrototypeBinding
-  nsObjectHashtable* mBindingTable;
+  nsAutoPtr<nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>> mBindingTable;
+
   // non-owning pointer to the first binding in the table
   nsXBLPrototypeBinding* mFirstBinding;
 
   nsRefPtr<nsXBLDocGlobalObject> mGlobalObject;
 };
 
 #ifdef DEBUG
 void AssertInCompilationScope();
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -95,17 +95,16 @@ protected:
 nsXBLPrototypeBinding::nsXBLPrototypeBinding()
 : mImplementation(nullptr),
   mBaseBinding(nullptr),
   mInheritStyle(true),
   mCheckedBaseProto(false),
   mKeyHandlersRegistered(false),
   mChromeOnlyContent(false),
   mResources(nullptr),
-  mAttributeTable(nullptr),
   mBaseNameSpaceID(kNameSpaceID_None)
 {
   MOZ_COUNT_CTOR(nsXBLPrototypeBinding);
 }
 
 nsresult
 nsXBLPrototypeBinding::Init(const nsACString& aID,
                             nsXBLDocumentInfo* aInfo,
@@ -176,17 +175,16 @@ nsXBLPrototypeBinding::Initialize()
   if (content) {
     ConstructAttributeTable(content);
   }
 }
 
 nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
 {
   delete mResources;
-  delete mAttributeTable;
   delete mImplementation;
   MOZ_COUNT_DTOR(nsXBLPrototypeBinding);
 }
 
 void
 nsXBLPrototypeBinding::SetBasePrototype(nsXBLPrototypeBinding* aBinding)
 {
   if (mBaseBinding == aBinding)
@@ -320,24 +318,22 @@ nsXBLPrototypeBinding::AttributeChanged(
                                         int32_t aNameSpaceID,
                                         bool aRemoveFlag, 
                                         nsIContent* aChangedElement,
                                         nsIContent* aAnonymousContent,
                                         bool aNotify)
 {
   if (!mAttributeTable)
     return;
-  nsPRUint32Key nskey(aNameSpaceID);
-  nsObjectHashtable *attributesNS = static_cast<nsObjectHashtable*>(mAttributeTable->Get(&nskey));
+
+  InnerAttributeTable *attributesNS = mAttributeTable->Get(aNameSpaceID);
   if (!attributesNS)
     return;
 
-  nsISupportsKey key(aAttribute);
-  nsXBLAttributeEntry* xblAttr = static_cast<nsXBLAttributeEntry*>
-                                            (attributesNS->Get(&key));
+  nsXBLAttributeEntry* xblAttr = attributesNS->Get(aAttribute);
   if (!xblAttr)
     return;
 
   // Iterate over the elements in the array.
   nsCOMPtr<nsIContent> content = GetImmediateChild(nsGkAtoms::content);
   while (xblAttr) {
     nsIContent* element = xblAttr->GetElement();
 
@@ -495,22 +491,22 @@ struct nsXBLAttrChangeData
   int32_t mSrcNamespace;
 
   nsXBLAttrChangeData(nsXBLPrototypeBinding* aProto,
                       nsIContent* aElt, nsIContent* aContent) 
   :mProto(aProto), mBoundElement(aElt), mContent(aContent) {}
 };
 
 // XXXbz this duplicates lots of AttributeChanged
-bool SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+SetAttrs(nsISupports* aKey, nsXBLAttributeEntry* aEntry, void* aClosure)
 {
-  nsXBLAttributeEntry* entry = static_cast<nsXBLAttributeEntry*>(aData);
   nsXBLAttrChangeData* changeData = static_cast<nsXBLAttrChangeData*>(aClosure);
 
-  nsIAtom* src = entry->GetSrcAttribute();
+  nsIAtom* src = aEntry->GetSrcAttribute();
   int32_t srcNs = changeData->mSrcNamespace;
   nsAutoString value;
   bool attrPresent = true;
 
   if (src == nsGkAtoms::text && srcNs == kNameSpaceID_XBL) {
     nsContentUtils::GetNodeTextContent(changeData->mBoundElement, false,
                                        value);
     value.StripChar(char16_t('\n'));
@@ -524,17 +520,17 @@ bool SetAttrs(nsHashKey* aKey, void* aDa
   else {
     attrPresent = changeData->mBoundElement->GetAttr(srcNs, src, value);
   }
 
   if (attrPresent) {
     nsIContent* content =
       changeData->mProto->GetImmediateChild(nsGkAtoms::content);
 
-    nsXBLAttributeEntry* curr = entry;
+    nsXBLAttributeEntry* curr = aEntry;
     while (curr) {
       nsIAtom* dst = curr->GetDstAttribute();
       int32_t dstNs = curr->GetDstNameSpace();
       nsIContent* element = curr->GetElement();
 
       nsIContent *realElement =
         changeData->mProto->LocateInstance(changeData->mBoundElement, content,
                                            changeData->mContent, element);
@@ -555,39 +551,38 @@ bool SetAttrs(nsHashKey* aKey, void* aDa
           realElement->AppendChildTo(textContent, false);
         }
       }
 
       curr = curr->GetNext();
     }
   }
 
-  return true;
+  return PL_DHASH_NEXT;
 }
 
-bool SetAttrsNS(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+SetAttrsNS(const uint32_t &aNamespace,
+           nsXBLPrototypeBinding::InnerAttributeTable* aXBLAttributes,
+           void* aClosure)
 {
-  if (aData && aClosure) {
-    nsPRUint32Key * key = static_cast<nsPRUint32Key*>(aKey);
-    nsObjectHashtable* xblAttributes =
-      static_cast<nsObjectHashtable*>(aData);
-    nsXBLAttrChangeData * changeData = static_cast<nsXBLAttrChangeData *>
-                                                  (aClosure);
-    changeData->mSrcNamespace = key->GetValue();
-    xblAttributes->Enumerate(SetAttrs, (void*)changeData);
+  if (aXBLAttributes && aClosure) {
+    nsXBLAttrChangeData* changeData = static_cast<nsXBLAttrChangeData*>(aClosure);
+    changeData->mSrcNamespace = aNamespace;
+    aXBLAttributes->EnumerateRead(SetAttrs, aClosure);
   }
-  return true;
+  return PL_DHASH_NEXT;
 }
 
 void
 nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
 {
   if (mAttributeTable) {
     nsXBLAttrChangeData data(this, aBoundElement, aAnonymousContent);
-    mAttributeTable->Enumerate(SetAttrsNS, (void*)&data);
+    mAttributeTable->EnumerateRead(SetAttrsNS, &data);
   }
 }
 
 nsIStyleRuleProcessor*
 nsXBLPrototypeBinding::GetRuleProcessor()
 {
   if (mResources) {
     return mResources->mRuleProcessor;
@@ -611,63 +606,41 @@ nsXBLPrototypeBinding::GetStyleSheets()
 {
   if (mResources) {
     return &mResources->mStyleSheetList;
   }
 
   return nullptr;
 }
 
-static bool
-DeleteAttributeEntry(nsHashKey* aKey, void* aData, void* aClosure)
-{
-  delete static_cast<nsXBLAttributeEntry*>(aData);
-  return true;
-}
-
-static bool
-DeleteAttributeTable(nsHashKey* aKey, void* aData, void* aClosure)
-{
-  delete static_cast<nsObjectHashtable*>(aData);
-  return true;
-}
-
 void
 nsXBLPrototypeBinding::EnsureAttributeTable()
 {
   if (!mAttributeTable) {
-    mAttributeTable = new nsObjectHashtable(nullptr, nullptr,
-                                            DeleteAttributeTable,
-                                            nullptr, 4);
+    mAttributeTable = new nsClassHashtable<nsUint32HashKey, InnerAttributeTable>(4);
   }
 }
 
 void
 nsXBLPrototypeBinding::AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
                                            int32_t aDestNamespaceID, nsIAtom* aDestTag,
                                            nsIContent* aContent)
 {
-    nsPRUint32Key nskey(aSourceNamespaceID);
-    nsObjectHashtable* attributesNS =
-      static_cast<nsObjectHashtable*>(mAttributeTable->Get(&nskey));
+    InnerAttributeTable* attributesNS = mAttributeTable->Get(aSourceNamespaceID);
     if (!attributesNS) {
-      attributesNS = new nsObjectHashtable(nullptr, nullptr,
-                                           DeleteAttributeEntry,
-                                           nullptr, 4);
-      mAttributeTable->Put(&nskey, attributesNS);
+      attributesNS = new InnerAttributeTable(4);
+      mAttributeTable->Put(aSourceNamespaceID, attributesNS);
     }
 
     nsXBLAttributeEntry* xblAttr =
       new nsXBLAttributeEntry(aSourceTag, aDestTag, aDestNamespaceID, aContent);
 
-    nsISupportsKey key(aSourceTag);
-    nsXBLAttributeEntry* entry = static_cast<nsXBLAttributeEntry*>
-                                            (attributesNS->Get(&key));
+    nsXBLAttributeEntry* entry = attributesNS->Get(aSourceTag);
     if (!entry) {
-      attributesNS->Put(&key, xblAttr);
+      attributesNS->Put(aSourceTag, xblAttr);
     } else {
       while (entry->GetNext())
         entry = entry->GetNext();
       entry->SetNext(xblAttr);
     }
 }
 
 void
@@ -1416,54 +1389,51 @@ struct WriteAttributeData
 
   WriteAttributeData(nsXBLPrototypeBinding* aBinding,
                      nsIObjectOutputStream* aStream,
                      nsIContent* aContent)
     : binding(aBinding), stream(aStream), content(aContent)
   { }
 };
 
-static
-bool
-WriteAttribute(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+WriteAttribute(nsISupports* aKey, nsXBLAttributeEntry* aEntry, void* aClosure)
 {
   WriteAttributeData* data = static_cast<WriteAttributeData *>(aClosure);
   nsIObjectOutputStream* stream = data->stream;
   const int32_t srcNamespace = data->srcNamespace;
 
-  nsXBLAttributeEntry* entry = static_cast<nsXBLAttributeEntry *>(aData);
   do {
-    if (entry->GetElement() == data->content) {
+    if (aEntry->GetElement() == data->content) {
       data->binding->WriteNamespace(stream, srcNamespace);
-      stream->WriteWStringZ(nsDependentAtomString(entry->GetSrcAttribute()).get());
-      data->binding->WriteNamespace(stream, entry->GetDstNameSpace());
-      stream->WriteWStringZ(nsDependentAtomString(entry->GetDstAttribute()).get());
+      stream->WriteWStringZ(nsDependentAtomString(aEntry->GetSrcAttribute()).get());
+      data->binding->WriteNamespace(stream, aEntry->GetDstNameSpace());
+      stream->WriteWStringZ(nsDependentAtomString(aEntry->GetDstAttribute()).get());
     }
 
-    entry = entry->GetNext();
-  } while (entry);
+    aEntry = aEntry->GetNext();
+  } while (aEntry);
 
-  return kHashEnumerateNext;
+  return PL_DHASH_NEXT;
 }
 
 // WriteAttributeNS is the callback to enumerate over the attribute
 // forwarding entries. Since these are stored in a hash of hashes,
 // we need to iterate over the inner hashes, calling WriteAttribute
 // to do the actual work.
-static
-bool
-WriteAttributeNS(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+WriteAttributeNS(const uint32_t &aNamespace,
+                 nsXBLPrototypeBinding::InnerAttributeTable* aXBLAttributes,
+                 void* aClosure)
 {
   WriteAttributeData* data = static_cast<WriteAttributeData *>(aClosure);
-  data->srcNamespace = static_cast<nsPRUint32Key *>(aKey)->GetValue();
+  data->srcNamespace = aNamespace;
+  aXBLAttributes->EnumerateRead(WriteAttribute, data);
 
-  nsObjectHashtable* attributes = static_cast<nsObjectHashtable*>(aData);
-  attributes->Enumerate(WriteAttribute, data);
-
-  return kHashEnumerateNext;
+  return PL_DHASH_NEXT;
 }
 
 nsresult
 nsXBLPrototypeBinding::WriteContentNode(nsIObjectOutputStream* aStream,
                                         nsIContent* aNode)
 {
   nsresult rv;
 
@@ -1537,17 +1507,17 @@ nsXBLPrototypeBinding::WriteContentNode(
     aNode->GetAttr(attr->NamespaceID(), attr->LocalName(), val);
     rv = aStream->WriteWStringZ(val.get());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Write out the attribute fowarding information
   if (mAttributeTable) {
     WriteAttributeData data(this, aStream, aNode);
-    mAttributeTable->Enumerate(WriteAttributeNS, &data);
+    mAttributeTable->EnumerateRead(WriteAttributeNS, &data);
   }
   rv = aStream->Write8(XBLBinding_Serialize_NoMoreAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Finally, write out the child nodes.
   count = aNode->GetChildCount();
   rv = aStream->Write32(count);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -4,31 +4,31 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXBLPrototypeBinding_h__
 #define nsXBLPrototypeBinding_h__
 
 #include "nsClassHashtable.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
-#include "nsHashtable.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsInterfaceHashtable.h"
 #include "nsWeakReference.h"
 #include "nsXBLDocumentInfo.h"
 #include "nsXBLProtoImpl.h"
 #include "nsXBLProtoImplMethod.h"
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLPrototypeResources.h"
 
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
+class nsXBLAttributeEntry;
+class nsXBLBinding;
 class nsXBLProtoImplField;
-class nsXBLBinding;
 
 // *********************************************************************/
 // The XBLPrototypeBinding class
 
 // Instances of this class are owned by the nsXBLDocumentInfo object returned
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
 class nsXBLPrototypeBinding
@@ -240,16 +240,19 @@ public:
    */
   nsIContent* GetImmediateChild(nsIAtom* aTag);
   nsIContent* LocateInstance(nsIContent* aBoundElt,
                              nsIContent* aTemplRoot,
                              nsIContent* aCopyRoot,
                              nsIContent* aTemplChild);
 
   bool ChromeOnlyContent() { return mChromeOnlyContent; }
+
+  typedef nsClassHashtable<nsISupportsHashKey, nsXBLAttributeEntry> InnerAttributeTable;
+
 protected:
   // Ensure that mAttributeTable has been created.
   void EnsureAttributeTable();
   // Ad an entry to the attribute table
   void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
                            int32_t aDestNamespaceID, nsIAtom* aDestTag,
                            nsIContent* aContent);
   void ConstructAttributeTable(nsIContent* aElement);
@@ -273,19 +276,20 @@ protected:
   bool mCheckedBaseProto;
   bool mKeyHandlersRegistered;
   bool mChromeOnlyContent;
 
   nsXBLPrototypeResources* mResources; // If we have any resources, this will be non-null.
 
   nsXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info.  Weak, since it owns us.
 
-  nsObjectHashtable* mAttributeTable; // A table for attribute containers. Namespace IDs are used as
-                                      // keys in the table. Containers are nsObjectHashtables.
-                                      // This table is used to efficiently handle attribute changes.
+  // A table for attribute containers. Namespace IDs are used as
+  // keys in the table. Containers are InnerAttributeTables.
+  // This table is used to efficiently handle attribute changes.
+  nsAutoPtr<nsClassHashtable<nsUint32HashKey, InnerAttributeTable>> mAttributeTable;
 
   class IIDHashKey : public PLDHashEntryHdr
   {
   public:
     typedef const nsIID& KeyType;
     typedef const nsIID* KeyTypePointer;
 
     IIDHashKey(const nsIID* aKey)
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -639,17 +639,17 @@ nsXBLPrototypeHandler::KeyEventMatched(n
 }
 
 bool
 nsXBLPrototypeHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
 {
   if (mDetail == -1 && mMisc == 0 && (mKeyMask & cAllModifiers) == 0)
     return true; // No filters set up. It's generic.
 
-  uint16_t button;
+  int16_t button;
   aMouseEvent->GetButton(&button);
   if (mDetail != -1 && (button != mDetail))
     return false;
 
   int32_t clickcount;
   aMouseEvent->GetDetail(&clickcount);
   if (mMisc != 0 && (clickcount != mMisc))
     return false;
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -582,17 +582,17 @@ nsEditorEventListener::MouseClick(nsIDOM
     // We're done if 'preventdefault' is true (see for example bug 70698).
     return rv;
   }
 
   // If we got a mouse down inside the editing area, we should force the 
   // IME to commit before we change the cursor position
   mEditor->ForceCompositionEnd();
 
-  uint16_t button = (uint16_t)-1;
+  int16_t button = -1;
   mouseEvent->GetButton(&button);
   // middle-mouse click (paste);
   if (button == 1)
   {
     if (Preferences::GetBool("middlemouse.paste", false))
     {
       // Set the selection to the point under the mouse cursor:
       nsCOMPtr<nsIDOMNode> parent;
--- a/editor/libeditor/html/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/html/nsHTMLEditorEventListener.cpp
@@ -86,17 +86,17 @@ nsHTMLEditorEventListener::MouseDown(nsI
     return NS_OK;
   }
 
   nsHTMLEditor* htmlEditor = GetHTMLEditor();
 
   // Detect only "context menu" click
   //XXX This should be easier to do!
   // But eDOMEvents_contextmenu and NS_CONTEXTMENU is not exposed in any event interface :-(
-  uint16_t buttonNumber;
+  int16_t buttonNumber;
   nsresult res = mouseEvent->GetButton(&buttonNumber);
   NS_ENSURE_SUCCESS(res, res);
 
   bool isContextClick = buttonNumber == 2;
 
   int32_t clickCount;
   res = mouseEvent->GetDetail(&clickCount);
   NS_ENSURE_SUCCESS(res, res);
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -1942,17 +1942,17 @@ nsresult mozInlineSpellChecker::Blur(nsI
 
 nsresult mozInlineSpellChecker::MouseClick(nsIDOMEvent *aMouseEvent)
 {
   nsCOMPtr<nsIDOMMouseEvent>mouseEvent = do_QueryInterface(aMouseEvent);
   NS_ENSURE_TRUE(mouseEvent, NS_OK);
 
   // ignore any errors from HandleNavigationEvent as we don't want to prevent 
   // anyone else from seeing this event.
-  uint16_t button;
+  int16_t button;
   mouseEvent->GetButton(&button);
   HandleNavigationEvent(button != 0);
   return NS_OK;
 }
 
 nsresult mozInlineSpellChecker::KeyPress(nsIDOMEvent* aKeyEvent)
 {
   nsCOMPtr<nsIDOMKeyEvent>keyEvent = do_QueryInterface(aKeyEvent);
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -159,16 +159,17 @@ struct DrawSurfaceOptions {
 /*
  * This class is used to store gradient stops, it can only be used with a
  * matching DrawTarget. Not adhering to this condition will make a draw call
  * fail.
  */
 class GradientStops : public RefCounted<GradientStops>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(GradientStops)
   virtual ~GradientStops() {}
 
   virtual BackendType GetBackendType() const = 0;
 
 protected:
   GradientStops() {}
 };
 
@@ -311,16 +312,17 @@ public:
 /*
  * This is the base class for source surfaces. These objects are surfaces
  * which may be used as a source in a SurfacePattern or a DrawSurface call.
  * They cannot be drawn to directly.
  */
 class SourceSurface : public RefCounted<SourceSurface>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(SourceSurface)
   virtual ~SourceSurface() {}
 
   virtual SurfaceType GetType() const = 0;
   virtual IntSize GetSize() const = 0;
   virtual SurfaceFormat GetFormat() const = 0;
 
   /* This returns false if some event has made this source surface invalid for
    * usage with current DrawTargets. For example in the case of Direct2D this
@@ -391,16 +393,17 @@ public:
 
   DebugOnly<bool> mIsMapped;
 };
 
 /* This is an abstract object that accepts path segments. */
 class PathSink : public RefCounted<PathSink>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(PathSink)
   virtual ~PathSink() {}
 
   /* Move the current point in the path, any figure currently being drawn will
    * be considered closed during fill operations, however when stroking the
    * closing line segment will not be drawn.
    */
   virtual void MoveTo(const Point &aPoint) = 0;
   /* Add a linesegment to the current figure */
@@ -429,16 +432,17 @@ class PathBuilder;
 class FlattenedPath;
 
 /* The path class is used to create (sets of) figures of any shape that can be
  * filled or stroked to a DrawTarget
  */
 class Path : public RefCounted<Path>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(Path)
   virtual ~Path();
   
   virtual BackendType GetBackendType() const = 0;
 
   /* This returns a PathBuilder object that contains a copy of the contents of
    * this path and is still writable.
    */
   virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
@@ -528,16 +532,17 @@ struct GlyphBuffer
 
 /* This class is an abstraction of a backend/platform specific font object
  * at a particular size. It is passed into text drawing calls to describe
  * the font used for the drawing call.
  */
 class ScaledFont : public RefCounted<ScaledFont>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(ScaledFont)
   virtual ~ScaledFont() {}
 
   typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex, Float aGlyphSize, void *aBaton);
 
   virtual FontType GetType() const = 0;
 
   /* This allows getting a path that describes the outline of a set of glyphs.
    * A target is passed in so that the guarantee is made the returned path
@@ -586,32 +591,34 @@ struct FontOptions
  * parameters to the glyph drawing functions. This is an empty wrapper class
  * merely used to allow holding on to and passing around platform specific
  * parameters. This is because different platforms have unique rendering
  * parameters.
  */
 class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(GlyphRenderingOptions)
   virtual ~GlyphRenderingOptions() {}
 
   virtual FontType GetType() const = 0;
 
 protected:
   GlyphRenderingOptions() {}
 };
 
 /* This is the main class used for all the drawing. It is created through the
  * factory and accepts drawing commands. The results of drawing to a target
  * may be used either through a Snapshot or by flushing the target and directly
  * accessing the backing store a DrawTarget was created with.
  */
 class DrawTarget : public RefCounted<DrawTarget>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(DrawTarget)
   DrawTarget() : mTransformDirty(false), mPermitSubpixelAA(false) {}
   virtual ~DrawTarget() {}
 
   virtual BackendType GetType() const = 0;
   /**
    * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget.
    * Multiple calls to Snapshot() without any drawing operations in between will
    * normally return the same SourceSurface object.
@@ -984,16 +991,17 @@ protected:
   bool mPermitSubpixelAA : 1;
 
   SurfaceFormat mFormat;
 };
 
 class DrawEventRecorder : public RefCounted<DrawEventRecorder>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(DrawEventRecorder)
   virtual ~DrawEventRecorder() { }
 };
 
 class GFX2D_API Factory
 {
 public:
   static bool HasSSE2();
 
--- a/gfx/2d/Filters.h
+++ b/gfx/2d/Filters.h
@@ -461,16 +461,17 @@ enum PremultiplyInputs
 enum UnpremultiplyInputs
 {
   IN_UNPREMULTIPLY_IN = 0
 };
 
 class FilterNode : public RefCounted<FilterNode>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(FilterMode)
   virtual ~FilterNode() {}
 
   virtual FilterBackend GetBackendType() = 0;
 
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) { MOZ_CRASH(); }
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) { MOZ_CRASH(); }
 
   virtual void SetAttribute(uint32_t aIndex, bool) { MOZ_CRASH(); }
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -57,16 +57,17 @@ enum CGContextType {
   CG_CONTEXT_TYPE_BITMAP = 4,
   CG_CONTEXT_TYPE_IOSURFACE = 8
 };
 
 CGContextType GetContextType(CGContextRef ref);
 
 class MacIOSurface : public mozilla::RefCounted<MacIOSurface> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(MacIOSurface)
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
   static mozilla::TemporaryRef<MacIOSurface> CreateIOSurface(int aWidth, int aHeight,
                                                              double aContentsScaleFactor = 1.0,
                                                              bool aHasAlpha = true);
   static void ReleaseIOSurface(MacIOSurface *aIOSurface);
   static mozilla::TemporaryRef<MacIOSurface> LookupSurface(IOSurfaceID aSurfaceID,
                                                            double aContentsScaleFactor = 1.0,
--- a/gfx/2d/QuartzSupport.h
+++ b/gfx/2d/QuartzSupport.h
@@ -22,16 +22,17 @@ CGColorSpaceRef CreateSystemColorSpace()
 // Manages a CARenderer
 struct _CGLPBufferObject;
 struct _CGLContextObject;
 
 enum AllowOfflineRendererEnum { ALLOW_OFFLINE_RENDERER, DISALLOW_OFFLINE_RENDERER };
 
 class nsCARenderer : public mozilla::RefCounted<nsCARenderer> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(nsCARenderer)
   nsCARenderer() : mCARenderer(nullptr), mWrapperCALayer(nullptr), mFBOTexture(0),
                    mOpenGLContext(nullptr), mCGImage(nullptr), mCGData(nullptr),
                    mIOSurface(nullptr), mFBO(0), mIOTexture(0),
                    mUnsupportedWidth(UINT32_MAX), mUnsupportedHeight(UINT32_MAX),
                    mAllowOfflineRenderer(DISALLOW_OFFLINE_RENDERER),
                    mContentsScaleFactor(1.0) {}
   ~nsCARenderer();
   // aWidth and aHeight are in "display pixels".  A "display pixel" is the
--- a/gfx/cairo/cairo/src/cairo-qt-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-qt-surface.cpp
@@ -51,17 +51,16 @@
 
 #include <QtGui/QPainter>
 #include <QtGui/QPaintEngine>
 #include <QtGui/QPaintDevice>
 #include <QtGui/QImage>
 #include <QtGui/QPixmap>
 #include <QtGui/QBrush>
 #include <QtGui/QPen>
-#include <QWidget>
 #include <QtCore/QVarLengthArray>
 
 #include <sys/time.h>
 
 /* Enable workaround slow regional Qt paths */
 #define ENABLE_FAST_FILL 0
 #define ENABLE_FAST_CLIP 0
 
@@ -584,18 +583,16 @@ static cairo_status_t
 	QPaintDevice *rpd = QPainter::redirected(pd, &offset);
 	if (rpd)
 	    pd = rpd;
 
         if (pd->devType() == QInternal::Image) {
             qimg = new QImage(((QImage*) pd)->copy());
         } else if (pd->devType() == QInternal::Pixmap) {
             qimg = new QImage(((QPixmap*) pd)->toImage());
-        } else if (pd->devType() == QInternal::Widget) {
-            qimg = new QImage(QPixmap::grabWindow(((QWidget*)pd)->winId()).toImage());
         }
     }
 
     if (qimg == NULL)
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     *image_out = (cairo_image_surface_t*)
                  cairo_image_surface_create_for_data (qimg->bits(),
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -8,16 +8,18 @@
 #include "GLContextEGL.h"
 
 #if defined(XP_UNIX)
 
 #ifdef MOZ_WIDGET_GTK
 #include <gdk/gdkx.h>
 // we're using default display for now
 #define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
+#elif defined(MOZ_WIDGET_QT)
+#define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)(aWidget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW))
 #elif defined(MOZ_WIDGET_GONK)
 #define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
 #include "HwcComposer2D.h"
 #include "libdisplay/GonkDisplay.h"
 #endif
 
 #if defined(ANDROID)
 /* from widget */
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -3,18 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef MOZ_WIDGET_GTK
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #define GET_NATIVE_WINDOW(aWidget) GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
 #elif defined(MOZ_WIDGET_QT)
-#include <QWidget>
-#define GET_NATIVE_WINDOW(aWidget) static_cast<QWidget*>(aWidget->GetNativeData(NS_NATIVE_SHELLWIDGET))->winId()
+#define GET_NATIVE_WINDOW(aWidget) (Window)(aWidget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW))
 #endif
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/X11Util.h"
 
old mode 100644
new mode 100755
old mode 100644
new mode 100755
--- a/gfx/gl/SurfaceStream.cpp
+++ b/gfx/gl/SurfaceStream.cpp
@@ -16,17 +16,17 @@ namespace gfx {
 SurfaceStreamType
 SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc,
                                   bool preserveBuffer)
 {
     if (omtc == SurfaceStream::OffMainThread) {
         if (preserveBuffer)
             return SurfaceStreamType::TripleBuffer_Copy;
         else
-            return SurfaceStreamType::TripleBuffer_Async;
+            return SurfaceStreamType::TripleBuffer;
     } else {
         if (preserveBuffer)
             return SurfaceStreamType::SingleBuffer;
         else
             return SurfaceStreamType::TripleBuffer;
     }
 }
 
@@ -37,19 +37,16 @@ SurfaceStream::CreateForType(SurfaceStre
 
     switch (type) {
         case SurfaceStreamType::SingleBuffer:
             result = new SurfaceStream_SingleBuffer(prevStream);
             break;
         case SurfaceStreamType::TripleBuffer_Copy:
             result = new SurfaceStream_TripleBuffer_Copy(prevStream);
             break;
-        case SurfaceStreamType::TripleBuffer_Async:
-            result = new SurfaceStream_TripleBuffer_Async(prevStream);
-            break;
         case SurfaceStreamType::TripleBuffer:
             result = new SurfaceStream_TripleBuffer(prevStream);
             break;
         default:
             MOZ_CRASH("Invalid Type.");
     }
 
     result->mGLContext = glContext;
@@ -410,19 +407,17 @@ SurfaceStream_TripleBuffer::SwapProducer
                                          const gfx::IntSize& size)
 {
     PROFILER_LABEL("SurfaceStream_TripleBuffer", "SwapProducer");
 
     MonitorAutoLock lock(mMonitor);
     if (mProducer) {
         RecycleScraps(factory);
 
-        // If WaitForCompositor succeeds, mStaging has moved to mConsumer.
-        // If it failed, we might have to scrap it.
-        if (mStaging && !WaitForCompositor())
+        if (mStaging)
             Scrap(mStaging);
 
         MOZ_ASSERT(!mStaging);
         Move(mProducer, mStaging);
         mStaging->Fence();
     }
 
     MOZ_ASSERT(!mProducer);
@@ -439,31 +434,10 @@ SurfaceStream_TripleBuffer::SwapConsumer
         Scrap(mConsumer);
         Move(mStaging, mConsumer);
         mMonitor.NotifyAll();
     }
 
     return mConsumer;
 }
 
-SurfaceStream_TripleBuffer_Async::SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream)
-    : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async, prevStream)
-{
-}
-
-SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async()
-{
-}
-
-bool
-SurfaceStream_TripleBuffer_Async::WaitForCompositor()
-{
-    PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", "WaitForCompositor");
-
-    // We are assumed to be locked
-    while (mStaging)
-        mMonitor.Wait();
-
-    return true;
-}
-
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SurfaceStream.h
+++ b/gfx/gl/SurfaceStream.h
@@ -178,19 +178,16 @@ public:
 
 class SurfaceStream_TripleBuffer
     : public SurfaceStream
 {
 protected:
     SharedSurface* mStaging;
     SharedSurface* mConsumer;
 
-    // Returns true if we were able to wait, false if not
-    virtual bool WaitForCompositor() { return false; }
-
     // To support subclasses initializing the mType.
     SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
 
 public:
     SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer();
 
 private:
@@ -202,24 +199,12 @@ public:
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
                                         const gfx::IntSize& size);
 
     virtual SharedSurface* SwapConsumer_NoWait();
 
     virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer);
 };
 
-class SurfaceStream_TripleBuffer_Async
-    : public SurfaceStream_TripleBuffer
-{
-protected:
-    virtual bool WaitForCompositor();
-
-public:
-    SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream);
-    virtual ~SurfaceStream_TripleBuffer_Async();
-};
-
-
 } /* namespace gfx */
 } /* namespace mozilla */
 
 #endif /* SURFACESTREAM_H_ */
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -82,17 +82,16 @@ MOZ_BEGIN_ENUM_CLASS(SharedSurfaceType, 
 
     Max
 MOZ_END_ENUM_CLASS(SharedSurfaceType)
 
 
 MOZ_BEGIN_ENUM_CLASS(SurfaceStreamType, uint8_t)
     SingleBuffer,
     TripleBuffer_Copy,
-    TripleBuffer_Async,
     TripleBuffer,
     Max
 MOZ_END_ENUM_CLASS(SurfaceStreamType)
 
 
 MOZ_BEGIN_ENUM_CLASS(APITypeT, uint8_t)
     Generic = 0,
 
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -174,16 +174,17 @@ enum SurfaceInitMode
  * by CreateRenderTarget or CreateRenderTargetFromSource.
  *
  * The target and viewport methods can be called before any DrawQuad call and
  * affect any subsequent DrawQuad calls.
  */
 class Compositor : public RefCounted<Compositor>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(Compositor)
   Compositor(PCompositorParent* aParent = nullptr)
     : mCompositorID(0)
     , mDiagnosticTypes(DIAGNOSTIC_NONE)
     , mParent(aParent)
   {
     MOZ_COUNT_CTOR(Compositor);
   }
   virtual ~Compositor()
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -34,16 +34,17 @@ namespace layers {
  * During the rendering process, an effect chain is created by the layer being
  * rendered and the primary effect is added by the compositable host. Secondary
  * effects may be added by the layer or compositable. The effect chain is passed
  * to the compositor by the compositable host as a parameter to DrawQuad.
  */
 
 struct Effect : public RefCounted<Effect>
 {
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(Effect)
   Effect(EffectTypes aType) : mType(aType) {}
 
   EffectTypes mType;
 
   virtual ~Effect() {}
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix) =0;
 };
 
--- a/gfx/layers/ImageDataSerializer.cpp
+++ b/gfx/layers/ImageDataSerializer.cpp
@@ -43,82 +43,94 @@ struct SurfaceBufferInfo
   static uint32_t GetOffset()
   {
     return GetAlignedStride<16>(sizeof(SurfaceBufferInfo));
   }
 };
 } // anonymous namespace
 
 static SurfaceBufferInfo*
-GetBufferInfo(uint8_t* aBuffer)
+GetBufferInfo(uint8_t* aData, size_t aDataSize)
 {
-  return reinterpret_cast<SurfaceBufferInfo*>(aBuffer);
+  return aDataSize >= sizeof(SurfaceBufferInfo)
+         ? reinterpret_cast<SurfaceBufferInfo*>(aData)
+         : nullptr;
 }
 
-
 void
 ImageDataSerializer::InitializeBufferInfo(IntSize aSize,
                                           SurfaceFormat aFormat)
 {
-  SurfaceBufferInfo* info = GetBufferInfo(mData);
+  SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
+  MOZ_ASSERT(info); // OK to assert here, this method is client-side-only
   info->width = aSize.width;
   info->height = aSize.height;
   info->format = aFormat;
+  Validate();
 }
 
 static inline uint32_t
 ComputeStride(SurfaceFormat aFormat, uint32_t aWidth)
 {
   return GetAlignedStride<4>(BytesPerPixel(aFormat) * aWidth);
 }
 
 uint32_t
-ImageDataSerializer::ComputeMinBufferSize(IntSize aSize,
+ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
                                           SurfaceFormat aFormat)
 {
   uint32_t bufsize = aSize.height * ComputeStride(aFormat, aSize.width);
   return SurfaceBufferInfo::GetOffset()
        + GetAlignedStride<16>(bufsize);
 }
 
-bool
-ImageDataSerializerBase::IsValid() const
+void
+ImageDataSerializerBase::Validate()
 {
-  // XXX - We could use some sanity checks here.
-  return !!mData;
+  mIsValid = false;
+  if (!mData) {
+    return;
+  }
+  SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
+  if (!info) {
+    return;
+  }
+  size_t requiredSize =
+           ComputeMinBufferSize(IntSize(info->width, info->height), info->format);
+  mIsValid = requiredSize <= mDataSize;
 }
 
 uint8_t*
 ImageDataSerializerBase::GetData()
 {
   MOZ_ASSERT(IsValid());
   return mData + SurfaceBufferInfo::GetOffset();
 }
 
 uint32_t
 ImageDataSerializerBase::GetStride() const
 {
   MOZ_ASSERT(IsValid());
-  SurfaceBufferInfo* info = GetBufferInfo(mData);
+  SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
   return ComputeStride(GetFormat(), info->width);
 }
 
 IntSize
 ImageDataSerializerBase::GetSize() const
 {
   MOZ_ASSERT(IsValid());
-  SurfaceBufferInfo* info = GetBufferInfo(mData);
+  SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
   return IntSize(info->width, info->height);
 }
 
 SurfaceFormat
 ImageDataSerializerBase::GetFormat() const
 {
   MOZ_ASSERT(IsValid());
-  return GetBufferInfo(mData)->format;
+  return GetBufferInfo(mData, mDataSize)->format;
 }
 
 TemporaryRef<gfxImageSurface>
 ImageDataSerializerBase::GetAsThebesSurface()
 {
   MOZ_ASSERT(IsValid());
   IntSize size = GetSize();
   return new gfxImageSurface(GetData(),
--- a/gfx/layers/ImageDataSerializer.h
+++ b/gfx/layers/ImageDataSerializer.h
@@ -24,56 +24,74 @@ class DrawTarget;
 } // namespace mozilla
 
 namespace mozilla {
 namespace layers {
 
 class ImageDataSerializerBase
 {
 public:
-  bool IsValid() const;
+  bool IsValid() const { return mIsValid; }
 
   uint8_t* GetData();
   uint32_t GetStride() const;
   gfx::IntSize GetSize() const;
   gfx::SurfaceFormat GetFormat() const;
   TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
   TemporaryRef<gfxImageSurface> GetAsThebesSurface();
   TemporaryRef<gfx::DrawTarget> GetAsDrawTarget();
 
+  static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
+                                       gfx::SurfaceFormat aFormat);
+
 protected:
 
-  ImageDataSerializerBase(uint8_t* aData)
-  : mData(aData) {}
+  ImageDataSerializerBase(uint8_t* aData, size_t aDataSize)
+    : mData(aData)
+    , mDataSize(aDataSize)
+    , mIsValid(false)
+  {}
+
+  void Validate();
+
   uint8_t* mData;
+  size_t mDataSize;
+  bool mIsValid;
 };
 
 /**
  * A facility to serialize an image into a buffer of memory.
  * This is intended for use with the IPC code, in order to copy image data
  * into shared memory.
  * Note that there is a separate serializer class for YCbCr images
  * (see YCbCrImageDataSerializer.h).
  */
 class MOZ_STACK_CLASS ImageDataSerializer : public ImageDataSerializerBase
 {
 public:
-  ImageDataSerializer(uint8_t* aData) : ImageDataSerializerBase(aData) {}
+  ImageDataSerializer(uint8_t* aData, size_t aDataSize)
+    : ImageDataSerializerBase(aData, aDataSize)
+  {
+    // a serializer needs to be usable before correct buffer info has been written to it
+    mIsValid = !!mData;
+  }
   void InitializeBufferInfo(gfx::IntSize aSize,
                             gfx::SurfaceFormat aFormat);
-  static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
-                                       gfx::SurfaceFormat aFormat);
 };
 
 /**
  * A facility to deserialize image data that has been serialized by an
  * ImageDataSerializer.
  */
 class MOZ_STACK_CLASS ImageDataDeserializer : public ImageDataSerializerBase
 {
 public:
-  ImageDataDeserializer(uint8_t* aData) : ImageDataSerializerBase(aData) {}
+  ImageDataDeserializer(uint8_t* aData, size_t aDataSize)
+    : ImageDataSerializerBase(aData, aDataSize)
+  {
+    Validate();
+  }
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/YCbCrImageDataSerializer.cpp
+++ b/gfx/layers/YCbCrImageDataSerializer.cpp
@@ -46,137 +46,159 @@ struct YCbCrBufferInfo
   uint32_t mYWidth;
   uint32_t mYHeight;
   uint32_t mCbCrStride;
   uint32_t mCbCrWidth;
   uint32_t mCbCrHeight;
   StereoMode mStereoMode;
 };
 
-static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
+static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData, size_t aDataSize)
 {
-  return reinterpret_cast<YCbCrBufferInfo*>(aData);
+  return aDataSize >= sizeof(YCbCrBufferInfo)
+         ? reinterpret_cast<YCbCrBufferInfo*>(aData)
+         : nullptr;
 }
 
-bool YCbCrImageDataDeserializerBase::IsValid()
+void YCbCrImageDataDeserializerBase::Validate()
 {
-  if (mData == nullptr) {
-    return false;
+  mIsValid = false;
+  if (!mData) {
+    return;
+  }
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
+  if (!info) {
+    return;
   }
-  return true;
+  size_t requiredSize = ComputeMinBufferSize(
+                          IntSize(info->mYWidth, info->mYHeight),
+                          info->mYStride,
+                          IntSize(info->mCbCrWidth, info->mCbCrHeight),
+                          info->mCbCrStride);
+  mIsValid = requiredSize <= mDataSize;
+
 }
 
 uint8_t* YCbCrImageDataDeserializerBase::GetYData()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return reinterpret_cast<uint8_t*>(info) + info->mYOffset;
 }
 
 uint8_t* YCbCrImageDataDeserializerBase::GetCbData()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return reinterpret_cast<uint8_t*>(info) + info->mCbOffset;
 }
 
 uint8_t* YCbCrImageDataDeserializerBase::GetCrData()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return reinterpret_cast<uint8_t*>(info) + info->mCrOffset;
 }
 
 uint8_t* YCbCrImageDataDeserializerBase::GetData()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return (reinterpret_cast<uint8_t*>(info)) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
 }
 
 uint32_t YCbCrImageDataDeserializerBase::GetYStride()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return info->mYStride;
 }
 
 uint32_t YCbCrImageDataDeserializerBase::GetCbCrStride()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return info->mCbCrStride;
 }
 
 gfx::IntSize YCbCrImageDataDeserializerBase::GetYSize()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return gfx::IntSize(info->mYWidth, info->mYHeight);
 }
 
 gfx::IntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return gfx::IntSize(info->mCbCrWidth, info->mCbCrHeight);
 }
 
 StereoMode YCbCrImageDataDeserializerBase::GetStereoMode()
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
   return info->mStereoMode;
 }
 
 // Offset in bytes
 static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
 {
   return MOZ_ALIGN_WORD(aHeight * aStride);
 }
 
 // Minimum required shmem size in bytes
 size_t
-YCbCrImageDataSerializer::ComputeMinBufferSize(const gfx::IntSize& aYSize,
-                                               const gfx::IntSize& aCbCrSize)
+YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
+                                                   uint32_t aYStride,
+                                                   const gfx::IntSize& aCbCrSize,
+                                                   uint32_t aCbCrStride)
 {
-  uint32_t yStride = aYSize.width;
-  uint32_t CbCrStride = aCbCrSize.width;
+  return ComputeOffset(aYSize.height, aYStride)
+         + 2 * ComputeOffset(aCbCrSize.height, aCbCrStride)
+         + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
+}
 
-  return ComputeOffset(aYSize.height, yStride)
-         + 2 * ComputeOffset(aCbCrSize.height, CbCrStride)
-         + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
+// Minimum required shmem size in bytes
+size_t
+YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
+                                                   const gfx::IntSize& aCbCrSize)
+{
+  return ComputeMinBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width);
 }
 
 // Offset in bytes
 static size_t ComputeOffset(uint32_t aSize)
 {
   return MOZ_ALIGN_WORD(aSize);
 }
 
 // Minimum required shmem size in bytes
 size_t
-YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
+YCbCrImageDataDeserializerBase::ComputeMinBufferSize(uint32_t aSize)
 {
   return ComputeOffset(aSize) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
 }
 
 void
 YCbCrImageDataSerializer::InitializeBufferInfo(uint32_t aYOffset,
                                                uint32_t aCbOffset,
                                                uint32_t aCrOffset,
                                                uint32_t aYStride,
                                                uint32_t aCbCrStride,
                                                const gfx::IntSize& aYSize,
                                                const gfx::IntSize& aCbCrSize,
                                                StereoMode aStereoMode)
 {
-  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
+  YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
+  MOZ_ASSERT(info); // OK to assert here, this method is client-side-only
   uint32_t info_size = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
   info->mYOffset = info_size + aYOffset;
   info->mCbOffset = info_size + aCbOffset;
   info->mCrOffset = info_size + aCrOffset;
   info->mYStride = aYStride;
   info->mYWidth = aYSize.width;
   info->mYHeight = aYSize.height;
   info->mCbCrStride = aCbCrStride;
   info->mCbCrWidth = aCbCrSize.width;
   info->mCbCrHeight = aCbCrSize.height;
   info->mStereoMode = aStereoMode;
+  Validate();
 }
 
 void
 YCbCrImageDataSerializer::InitializeBufferInfo(uint32_t aYStride,
                                                uint32_t aCbCrStride,
                                                const gfx::IntSize& aYSize,
                                                const gfx::IntSize& aCbCrSize,
                                                StereoMode aStereoMode)
--- a/gfx/layers/YCbCrImageDataSerializer.h
+++ b/gfx/layers/YCbCrImageDataSerializer.h
@@ -25,17 +25,17 @@ class Image;
 /**
  * Convenience class to share code between YCbCrImageDataSerializer
  * and YCbCrImageDataDeserializer.
  * Do not use it.
  */
 class YCbCrImageDataDeserializerBase
 {
 public:
-  bool IsValid();
+  bool IsValid() const { return mIsValid; }
 
   /**
    * Returns the Y channel data pointer.
    */
   uint8_t* GetYData();
   /**
    * Returns the Cb channel data pointer.
    */
@@ -68,21 +68,42 @@ public:
    * Stereo mode for the image.
    */
   StereoMode GetStereoMode();
 
   /**
    * Return a pointer to the begining of the data buffer.
    */
   uint8_t* GetData();
+
+  /**
+   * This function is meant as a helper to know how much shared memory we need
+   * to allocate in a shmem in order to place a shared YCbCr image blob of
+   * given dimensions.
+   */
+  static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
+                                     uint32_t aYStride,
+                                     const gfx::IntSize& aCbCrSize,
+                                     uint32_t aCbCrStride);
+  static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
+                                     const gfx::IntSize& aCbCrSize);
+  static size_t ComputeMinBufferSize(uint32_t aSize);
+
 protected:
-  YCbCrImageDataDeserializerBase(uint8_t* aData)
-  : mData (aData) {}
+  YCbCrImageDataDeserializerBase(uint8_t* aData, size_t aDataSize)
+    : mData (aData)
+    , mDataSize(aDataSize)
+    , mIsValid(false)
+  {}
+
+  void Validate();
 
   uint8_t* mData;
+  size_t mDataSize;
+  bool mIsValid;
 };
 
 /**
  * A view on a YCbCr image stored with its metadata in a blob of memory.
  * It is only meant as a convenience to access the image data, and does not own
  * the data. The instance can live on the stack and used as follows:
  *
  * const YCbCrImage& yuv = sharedImage.get_YCbCrImage();
@@ -90,26 +111,22 @@ protected:
  * if (!deserializer.IsValid()) {
  *   // handle error
  * }
  * size = deserializer.GetYSize(); // work with the data, etc...
  */
 class MOZ_STACK_CLASS YCbCrImageDataSerializer : public YCbCrImageDataDeserializerBase
 {
 public:
-  YCbCrImageDataSerializer(uint8_t* aData) : YCbCrImageDataDeserializerBase(aData) {}
-
-  /**
-   * This function is meant as a helper to know how much shared memory we need
-   * to allocate in a shmem in order to place a shared YCbCr image blob of
-   * given dimensions.
-   */
-  static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
-                                     const gfx::IntSize& aCbCrSize);
-  static size_t ComputeMinBufferSize(uint32_t aSize);
+  YCbCrImageDataSerializer(uint8_t* aData, size_t aDataSize)
+    : YCbCrImageDataDeserializerBase(aData, aDataSize)
+  {
+    // a serializer needs to be usable before correct buffer info has been written to it
+    mIsValid = !!mData;
+  }
 
   /**
    * Write the image informations in the buffer for given dimensions.
    * The provided pointer should point to the beginning of the (chunk of)
    * buffer on which we want to store the image.
    */
   void InitializeBufferInfo(uint32_t aYOffset,
                             uint32_t aCbOffset,
@@ -144,17 +161,21 @@ public:
  * if (!deserializer.IsValid()) {
  *   // handle error
  * }
  * size = deserializer.GetYSize(); // work with the data, etc...
  */
 class MOZ_STACK_CLASS YCbCrImageDataDeserializer : public YCbCrImageDataDeserializerBase
 {
 public:
-  YCbCrImageDataDeserializer(uint8_t* aData) : YCbCrImageDataDeserializerBase(aData) {}
+  YCbCrImageDataDeserializer(uint8_t* aData, size_t aDataSize)
+    : YCbCrImageDataDeserializerBase(aData, aDataSize)
+  {
+    Validate();
+  }
 
   /**
    * Convert the YCbCr data into RGB and return a DataSourceSurface.
    * This is a costly operation, so use it only when YCbCr compositing is
    * not supported.
    */
   TemporaryRef<gfx::DataSourceSurface> ToDataSourceSurface();
 };
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -175,17 +175,18 @@ public:
     if (!mBuffer) {
       return false;
     }
     return ConvertImageToRGB(*mBuffer);
   }
 
   bool ConvertImageToRGB(const SurfaceDescriptor& aImage)
   {
-    YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
+    YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
+                                            aImage.get_YCbCrImage().data().Size<uint8_t>());
     PlanarYCbCrData data;
     DeserializerToPlanarYCbCrImageData(deserializer, data);
 
     gfx::SurfaceFormat format = SurfaceFormat::B8G8R8X8;
     gfx::IntSize size;
     gfx::GetYCbCrToRGBDestFormatAndSize(data, format, size);
     if (size.width > PlanarYCbCrImage::MAX_DIMENSION ||
         size.height > PlanarYCbCrImage::MAX_DIMENSION) {
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -67,16 +67,17 @@ class TextureClientData;
  * Subclasses: Thebes layers use ContentClients, ImageLayers use ImageClients,
  * Canvas layers use CanvasClients (but ImageHosts). We have a different subclass
  * where we have a different way of interfacing with the textures - in terms of
  * drawing into the compositable and/or passing its contents to the compostior.
  */
 class CompositableClient : public AtomicRefCounted<CompositableClient>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableClient)
   CompositableClient(CompositableForwarder* aForwarder);
 
   virtual ~CompositableClient();
 
   virtual TextureInfo GetTextureInfo() const = 0;
 
   LayersBackend GetCompositorBackendType() const;
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -50,16 +50,17 @@ namespace layers {
  * During the deallocation phase, a TextureChild may hold its recently destroyed
  * TextureClient's data until the compositor side confirmed that it is safe to
  * deallocte or recycle the it.
  */
 class TextureChild : public PTextureChild
                    , public AtomicRefCounted<TextureChild>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureChild)
   TextureChild()
   : mForwarder(nullptr)
   , mTextureData(nullptr)
   , mTextureClient(nullptr)
   , mIPCOpen(false)
   {
     MOZ_COUNT_CTOR(TextureChild);
   }
@@ -445,17 +446,17 @@ BufferTextureClient::~BufferTextureClien
 
 bool
 BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
 {
   MOZ_ASSERT(aSurface);
   MOZ_ASSERT(!IsImmutable());
   MOZ_ASSERT(IsValid());
 
-  ImageDataSerializer serializer(GetBuffer());
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   if (!serializer.IsValid()) {
     return false;
   }
 
   if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
     RefPtr<DrawTarget> dt = GetAsDrawTarget();
     RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aSurface);
 
@@ -483,17 +484,17 @@ BufferTextureClient::UpdateSurface(gfxAS
   return true;
 }
 
 already_AddRefed<gfxASurface>
 BufferTextureClient::GetAsSurface()
 {
   MOZ_ASSERT(IsValid());
 
-  ImageDataSerializer serializer(GetBuffer());
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   if (!serializer.IsValid()) {
     return nullptr;
   }
 
   RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
   nsRefPtr<gfxASurface> result = surf.get();
   return result.forget();
 }
@@ -510,34 +511,34 @@ BufferTextureClient::AllocateForSurface(
   if (!Allocate(bufSize)) {
     return false;
   }
 
   if (aFlags & ALLOC_CLEAR_BUFFER) {
     memset(GetBuffer(), 0, bufSize);
   }
 
-  ImageDataSerializer serializer(GetBuffer());
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   serializer.InitializeBufferInfo(aSize, mFormat);
   mSize = aSize;
   return true;
 }
 
 TemporaryRef<gfx::DrawTarget>
 BufferTextureClient::GetAsDrawTarget()
 {
   MOZ_ASSERT(IsValid());
   // XXX - Turn this into a fatal assertion as soon as Bug 952507 is fixed
   NS_WARN_IF_FALSE(mLocked, "GetAsDrawTarget should be called on locked textures only");
 
   if (mDrawTarget) {
     return mDrawTarget;
   }
 
-  ImageDataSerializer serializer(GetBuffer());
+  ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   if (!serializer.IsValid()) {
     return nullptr;
   }
 
   MOZ_ASSERT(mUsingFallbackDrawTarget == false);
   mDrawTarget = serializer.GetAsDrawTarget();
   if (mDrawTarget) {
     return mDrawTarget;
@@ -584,17 +585,17 @@ BufferTextureClient::Unlock()
   mDrawTarget->Flush();
   if (mUsingFallbackDrawTarget && (mOpenMode & OPEN_WRITE)) {
     // When we are using a fallback DrawTarget, it means we could not create
     // a DrawTarget wrapping the TextureClient's shared memory. In this scenario
     // we need to put the content of the fallback draw target back into our shared
     // memory.
     RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
     RefPtr<DataSourceSurface> surface = snapshot->GetDataSurface();
-    ImageDataSerializer serializer(GetBuffer());
+    ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
     if (!serializer.IsValid() || serializer.GetSize() != surface->GetSize()) {
       NS_WARNING("Could not write the data back into the texture.");
       mDrawTarget = nullptr;
       mUsingFallbackDrawTarget = false;
       return;
     }
     MOZ_ASSERT(surface->GetSize() == serializer.GetSize());
     MOZ_ASSERT(surface->GetFormat() == serializer.GetFormat());
@@ -612,17 +613,17 @@ BufferTextureClient::Unlock()
 bool
 BufferTextureClient::UpdateYCbCr(const PlanarYCbCrData& aData)
 {
   MOZ_ASSERT(mFormat == gfx::SurfaceFormat::YUV, "This textureClient can only use YCbCr data");
   MOZ_ASSERT(!IsImmutable());
   MOZ_ASSERT(IsValid());
   MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
 
-  YCbCrImageDataSerializer serializer(GetBuffer());
+  YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   MOZ_ASSERT(serializer.IsValid());
   if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
                            aData.mYSize, aData.mYStride,
                            aData.mCbCrSize, aData.mCbCrStride,
                            aData.mYSkip, aData.mCbSkip)) {
     NS_WARNING("Failed to copy image data!");
     return false;
   }
@@ -642,17 +643,17 @@ BufferTextureClient::AllocateForYCbCr(gf
 {
   MOZ_ASSERT(IsValid());
 
   size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
                                                                   aCbCrSize);
   if (!Allocate(bufSize)) {
     return false;
   }
-  YCbCrImageDataSerializer serializer(GetBuffer());
+  YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
   serializer.InitializeBufferInfo(aYSize,
                                   aCbCrSize,
                                   aStereoMode);
   mSize = aYSize;
   return true;
 }
 
 
@@ -965,17 +966,17 @@ AutoLockYCbCrClient::Update(PlanarYCbCrI
   }
 
   if (!EnsureDeprecatedTextureClient(aImage)) {
     return false;
   }
 
   ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
 
-  YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
   if (!serializer.CopyData(data->mYChannel, data->mCbChannel, data->mCrChannel,
                            data->mYSize, data->mYStride,
                            data->mCbCrSize, data->mCbCrStride,
                            data->mYSkip, data->mCbSkip)) {
     NS_WARNING("Failed to copy image data!");
     return false;
   }
   return true;
@@ -994,17 +995,17 @@ bool AutoLockYCbCrClient::EnsureDeprecat
     return false;
   }
 
   bool needsAllocation = false;
   if (mDescriptor->type() != SurfaceDescriptor::TYCbCrImage) {
     needsAllocation = true;
   } else {
     ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
-    YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
+    YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
     if (serializer.GetYSize() != data->mYSize ||
         serializer.GetCbCrSize() != data->mCbCrSize) {
       needsAllocation = true;
     }
   }
 
   if (!needsAllocation) {
     return true;
@@ -1015,17 +1016,17 @@ bool AutoLockYCbCrClient::EnsureDeprecat
   ipc::SharedMemory::SharedMemoryType shmType = OptimalShmemType();
   size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(data->mYSize,
                                                                data->mCbCrSize);
   ipc::Shmem shmem;
   if (!mDeprecatedTextureClient->GetForwarder()->AllocUnsafeShmem(size, shmType, &shmem)) {
     return false;
   }
 
-  YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
   serializer.InitializeBufferInfo(data->mYSize,
                                   data->mCbCrSize,
                                   data->mStereoMode);
 
   *mDescriptor = YCbCrImage(shmem, 0);
 
   return true;
 }
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -505,16 +505,17 @@ struct TextureClientAutoUnlock
  * same semantics.
  *
  * Ownership of the surface descriptor depends on how the DeprecatedTextureClient/Host is
  * used by the CompositableClient/Host.
  */
 class DeprecatedTextureClient : public RefCounted<DeprecatedTextureClient>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(DeprecatedTextureClient)
   typedef gl::SharedTextureHandle SharedTextureHandle;
   typedef gl::GLContext GLContext;
   typedef gl::TextureImage TextureImage;
 
   virtual ~DeprecatedTextureClient();
 
   /* This will return an identifier that can be sent accross a process or
    * thread boundary and used to construct a DeprecatedTextureHost object
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -61,16 +61,17 @@ struct ViewTransform {
  * usually dealt with by dom or layout when main thread rendering, but which can
  * short circuit that stuff to directly affect layers as they are composited,
  * for example, off-main thread animation, async video, async pan/zoom.
  */
 class AsyncCompositionManager MOZ_FINAL : public RefCounted<AsyncCompositionManager>
 {
   friend class AutoResolveRefLayers;
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(AsyncCompositionManager)
   AsyncCompositionManager(LayerManagerComposite* aManager)
     : mLayerManager(aManager)
     , mIsFirstPaint(false)
     , mLayersUpdated(false)
     , mReadyForCompose(true)
   {
     MOZ_COUNT_CTOR(AsyncCompositionManager);
   }
--- a/gfx/layers/composite/CanvasLayerComposite.cpp
+++ b/gfx/layers/composite/CanvasLayerComposite.cpp
@@ -38,18 +38,26 @@ CanvasLayerComposite::~CanvasLayerCompos
   MOZ_COUNT_DTOR(CanvasLayerComposite);
 
   CleanupResources();
 }
 
 bool
 CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost)
 {
-  mImageHost = aHost;
-  return true;
+  switch (aHost->GetType()) {
+    case BUFFER_IMAGE_SINGLE:
+    case BUFFER_IMAGE_BUFFERED:
+    case COMPOSITABLE_IMAGE:
+      mImageHost = aHost;
+      return true;
+    default:
+      return false;
+  }
+
 }
 
 Layer*
 CanvasLayerComposite::GetLayer()
 {
   return this;
 }
 
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -55,16 +55,17 @@ class TiledLayerComposer;
 struct EffectChain;
 
 /**
  * A base class for doing CompositableHost and platform dependent task on TextureHost.
  */
 class CompositableBackendSpecificData : public RefCounted<CompositableBackendSpecificData>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableBackendSpecificData)
   CompositableBackendSpecificData()
   {
     MOZ_COUNT_CTOR(CompositableBackendSpecificData);
   }
   virtual ~CompositableBackendSpecificData()
   {
     MOZ_COUNT_DTOR(CompositableBackendSpecificData);
   }
@@ -84,16 +85,17 @@ public:
  *
  * Composite is called by the owning layer when it is composited. CompositableHost
  * will use its TextureHost(s) and call Compositor::DrawQuad to do the actual
  * rendering.
  */
 class CompositableHost : public RefCounted<CompositableHost>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableHost)
   CompositableHost(const TextureInfo& aTextureInfo);
 
   virtual ~CompositableHost();
 
   static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
 
   virtual CompositableType GetType() = 0;
 
--- a/gfx/layers/composite/ImageLayerComposite.cpp
+++ b/gfx/layers/composite/ImageLayerComposite.cpp
@@ -45,18 +45,25 @@ ImageLayerComposite::~ImageLayerComposit
   MOZ_ASSERT(mDestroyed);
 
   CleanupResources();
 }
 
 bool
 ImageLayerComposite::SetCompositableHost(CompositableHost* aHost)
 {
-  mImageHost = aHost;
-  return true;
+  switch (aHost->GetType()) {
+    case BUFFER_IMAGE_SINGLE:
+    case BUFFER_IMAGE_BUFFERED:
+    case COMPOSITABLE_IMAGE:
+      mImageHost = aHost;
+      return true;
+    default:
+      return false;
+  }
 }
 
 void
 ImageLayerComposite::Disconnect()
 {
   Destroy();
 }
 
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -17,16 +17,17 @@
 #ifdef MOZ_X11
 #include "mozilla/layers/X11TextureHost.h"
 #endif
 #include "mozilla/layers/YCbCrImageDataSerializer.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "mozilla/layers/PTextureParent.h"
+#include <limits>
 
 struct nsIntPoint;
 
 namespace mozilla {
 namespace layers {
 
 /**
  * TextureParent is the host-side IPDL glue between TextureClient and TextureHost.
@@ -488,17 +489,17 @@ BufferTextureHost::Upload(nsIntRegion *a
     // earlier. It is conceivable that on certain rare conditions with async-video
     // we may end up here for the first frame, but this should not happen repeatedly.
     return false;
   }
   if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
     NS_WARNING("BufferTextureHost: unsupported format!");
     return false;
   } else if (mFormat == gfx::SurfaceFormat::YUV) {
-    YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
+    YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
     MOZ_ASSERT(yuvDeserializer.IsValid());
 
     if (!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
       RefPtr<gfx::DataSourceSurface> surf = yuvDeserializer.ToDataSourceSurface();
       if (!mFirstSource) {
         mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
       }
       mFirstSource->Update(surf, aRegion);
@@ -552,19 +553,19 @@ BufferTextureHost::Upload(nsIntRegion *a
       NS_WARNING("failed to update the DataTextureSource");
       return false;
     }
   } else {
     // non-YCbCr case
     if (!mFirstSource) {
       mFirstSource = mCompositor->CreateDataTextureSource();
     }
-    ImageDataDeserializer deserializer(GetBuffer());
+    ImageDataDeserializer deserializer(GetBuffer(), GetBufferSize());
     if (!deserializer.IsValid()) {
-      NS_WARNING("failed to open shmem surface");
+      NS_ERROR("Failed to deserialize image!");
       return false;
     }
 
     RefPtr<gfx::DataSourceSurface> surf = deserializer.GetAsSurface();
     if (!surf) {
       return false;
     }
 
@@ -579,24 +580,25 @@ BufferTextureHost::Upload(nsIntRegion *a
 TemporaryRef<gfx::DataSourceSurface>
 BufferTextureHost::GetAsSurface()
 {
   RefPtr<gfx::DataSourceSurface> result;
   if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
     NS_WARNING("BufferTextureHost: unsupported format!");
     return nullptr;
   } else if (mFormat == gfx::SurfaceFormat::YUV) {
-    YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
+    YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
     if (!yuvDeserializer.IsValid()) {
       return nullptr;
     }
     result = yuvDeserializer.ToDataSourceSurface();
   } else {
-    ImageDataDeserializer deserializer(GetBuffer());
+    ImageDataDeserializer deserializer(GetBuffer(), GetBufferSize());
     if (!deserializer.IsValid()) {
+      NS_ERROR("Failed to deserialize image!");
       return nullptr;
     }
     result = deserializer.GetAsSurface();
   }
   return result.forget();
 }
 
 ShmemTextureHost::ShmemTextureHost(const ipc::Shmem& aShmem,
@@ -645,16 +647,21 @@ ShmemTextureHost::OnShutdown()
   mShmem = nullptr;
 }
 
 uint8_t* ShmemTextureHost::GetBuffer()
 {
   return mShmem ? mShmem->get<uint8_t>() : nullptr;
 }
 
+size_t ShmemTextureHost::GetBufferSize()
+{
+  return mShmem ? mShmem->Size<uint8_t>() : 0;
+}
+
 MemoryTextureHost::MemoryTextureHost(uint8_t* aBuffer,
                                      gfx::SurfaceFormat aFormat,
                                      TextureFlags aFlags)
 : BufferTextureHost(aFormat, aFlags)
 , mBuffer(aBuffer)
 {
   MOZ_COUNT_CTOR(MemoryTextureHost);
 }
@@ -683,16 +690,25 @@ MemoryTextureHost::ForgetSharedData()
   mBuffer = nullptr;
 }
 
 uint8_t* MemoryTextureHost::GetBuffer()
 {
   return mBuffer;
 }
 
+size_t MemoryTextureHost::GetBufferSize()
+{
+  // MemoryTextureHost just trusts that the buffer size is large enough to read
+  // anything we need to. That's because MemoryTextureHost has to trust the buffer
+  // pointer anyway, so the security model here is just that MemoryTexture's
+  // are restricted to same-process clients.
+  return std::numeric_limits<size_t>::max();
+}
+
 TextureParent::TextureParent(ISurfaceAllocator* aAllocator)
 : mAllocator(aAllocator)
 {
   MOZ_COUNT_CTOR(TextureParent);
 }
 
 TextureParent::~TextureParent()
 {
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -76,16 +76,17 @@ public:
  * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
  * access to these interfaces.
  *
  * This class is used on the compositor side.
  */
 class TextureSource : public RefCounted<TextureSource>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureSource)
   TextureSource();
   virtual ~TextureSource();
 
   /**
    * Return the size of the texture in texels.
    * If this is a tile iterator, GetSize must return the size of the current tile.
    */
   virtual gfx::IntSize GetSize() const = 0;
@@ -439,16 +440,17 @@ class BufferTextureHost : public Texture
 {
 public:
   BufferTextureHost(gfx::SurfaceFormat aFormat,
                     TextureFlags aFlags);
 
   ~BufferTextureHost();
 
   virtual uint8_t* GetBuffer() = 0;
+  virtual size_t GetBufferSize() = 0;
 
   virtual void Updated(const nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
 
   virtual bool Lock() MOZ_OVERRIDE;
 
   virtual void Unlock() MOZ_OVERRIDE;
 
   virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE;
@@ -501,16 +503,18 @@ public:
   ~ShmemTextureHost();
 
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
   virtual void ForgetSharedData() MOZ_OVERRIDE;
 
   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
 
+  virtual size_t GetBufferSize() MOZ_OVERRIDE;
+
   virtual const char *Name() MOZ_OVERRIDE { return "ShmemTextureHost"; }
 
   virtual void OnShutdown() MOZ_OVERRIDE;
 
 protected:
   mozilla::ipc::Shmem* mShmem;
   RefPtr<ISurfaceAllocator> mDeallocator;
 };
@@ -531,16 +535,18 @@ public:
   ~MemoryTextureHost();
 
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
   virtual void ForgetSharedData() MOZ_OVERRIDE;
 
   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
 
+  virtual size_t GetBufferSize() MOZ_OVERRIDE;
+
   virtual const char *Name() MOZ_OVERRIDE { return "MemoryTextureHost"; }
 
 protected:
   uint8_t* mBuffer;
 };
 
 
 /**
--- a/gfx/layers/composite/ThebesLayerComposite.cpp
+++ b/gfx/layers/composite/ThebesLayerComposite.cpp
@@ -47,18 +47,28 @@ ThebesLayerComposite::~ThebesLayerCompos
 {
   MOZ_COUNT_DTOR(ThebesLayerComposite);
   CleanupResources();
 }
 
 bool
 ThebesLayerComposite::SetCompositableHost(CompositableHost* aHost)
 {
-  mBuffer = static_cast<ContentHost*>(aHost);
-  return true;
+  switch (aHost->GetType()) {
+    case BUFFER_CONTENT:
+    case BUFFER_CONTENT_DIRECT:
+    case BUFFER_CONTENT_INC:
+    case BUFFER_TILED:
+    case COMPOSITABLE_CONTENT_SINGLE:
+    case COMPOSITABLE_CONTENT_DOUBLE:
+      mBuffer = static_cast<ContentHost*>(aHost);
+      return true;
+    default:
+      return false;
+  }
 }
 
 void
 ThebesLayerComposite::Disconnect()
 {
   Destroy();
 }
 
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -891,17 +891,18 @@ DeprecatedTextureHostYCbCrD3D11::SetComp
 
 void
 DeprecatedTextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage,
                                   nsIntRegion* aRegion,
                                   nsIntPoint* aOffset)
 {
   MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
 
-  YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
+  YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
+                                             aImage.get_YCbCrImage().data().Size<uint8_t>());
 
   gfx::IntSize gfxCbCrSize = yuvDeserializer.GetCbCrSize();
 
   gfx::IntSize size = yuvDeserializer.GetYSize();
 
   RefPtr<DataTextureSource> srcY;
   RefPtr<DataTextureSource> srcCb;
   RefPtr<DataTextureSource> srcCr;
--- a/gfx/layers/d3d9/TextureD3D9.cpp
+++ b/gfx/layers/d3d9/TextureD3D9.cpp
@@ -437,17 +437,18 @@ DeprecatedTextureHostYCbCrD3D9::UpdateIm
                                  nsIntPoint *aOffset)
 {
   MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
 
   if (!mCompositor->device()) {
     return;
   }
 
-  YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
+  YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
+                                             aImage.get_YCbCrImage().data().Size<uint8_t>());
 
   mSize = yuvDeserializer.GetYSize();
   IntSize cbCrSize = yuvDeserializer.GetCbCrSize();
   mStereoMode = yuvDeserializer.GetStereoMode();
 
   DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
   RefPtr<DataTextureSource> srcY;
   RefPtr<DataTextureSource> srcCb;
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -93,17 +93,23 @@ CompositableParentManager::ReceiveCompos
                                                  op.textureInfo(),
                                                  op.bufferRect());
       break;
     }
     case CompositableOperation::TOpDestroyThebesBuffer: {
       MOZ_LAYERS_LOG(("[ParentSide] Created double buffer"));
       const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer();
       CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
-      DeprecatedContentHostBase* content = static_cast<DeprecatedContentHostBase*>(compositableParent->GetCompositableHost());
+      CompositableHost* compositableHost = compositableParent->GetCompositableHost();
+      if (compositableHost->GetType() != COMPOSITABLE_CONTENT_SINGLE &&
+          compositableHost->GetType() != COMPOSITABLE_CONTENT_DOUBLE)
+      {
+        return false;
+      }
+      DeprecatedContentHostBase* content = static_cast<DeprecatedContentHostBase*>(compositableHost);
       content->DestroyTextures();
 
       break;
     }
     case CompositableOperation::TOpPaintTexture: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X"));
       const OpPaintTexture& op = aEdit.get_OpPaintTexture();
 
@@ -157,18 +163,21 @@ CompositableParentManager::ReceiveCompos
     }
     case CompositableOperation::TOpPaintTextureRegion: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
 
       const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
       CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
       CompositableHost* compositable =
         compositableParent->GetCompositableHost();
-      ThebesLayerComposite* thebes =
-        static_cast<ThebesLayerComposite*>(compositable->GetLayer());
+      Layer* layer = compositable->GetLayer();
+      if (!layer || layer->GetType() != Layer::TYPE_THEBES) {
+        return false;
+      }
+      ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer);
 
       const ThebesBufferData& bufferData = op.bufferData();
 
       RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());
 
       nsIntRegion frontUpdatedRegion;
       if (!compositable->UpdateThebes(bufferData,
                                       op.updatedRegion(),
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -71,16 +71,17 @@ bool ReleaseOwnedSurfaceDescriptor(const
  * Most of the methods here correspond to methods that are implemented by IPDL
  * actors without a common polymorphic interface.
  * These methods should be only called in the ipdl implementor's thread, unless
  * specified otherwise in the implementing class.
  */
 class ISurfaceAllocator : public AtomicRefCounted<ISurfaceAllocator>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(ISurfaceAllocator)
   ISurfaceAllocator() {}
 
   /**
    * Allocate shared memory that can be accessed by only one process at a time.
    * Ownership of this memory is passed when the memory is sent in an IPDL
    * message.
    */
   virtual bool AllocShmem(size_t aSize,
--- a/gfx/layers/ipc/LayerTransactionChild.h
+++ b/gfx/layers/ipc/LayerTransactionChild.h
@@ -21,16 +21,17 @@ class RenderFrameChild;
 }
 
 namespace layers {
 
 class LayerTransactionChild : public PLayerTransactionChild
                             , public AtomicRefCounted<LayerTransactionChild>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(LayerTransactionChild)
   /**
    * Clean this up, finishing with Send__delete__().
    *
    * It is expected (checked with an assert) that all shadow layers
    * created by this have already been destroyed and
    * Send__delete__()d by the time this method is called.
    */
   void Destroy();
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -385,17 +385,21 @@ LayerTransactionParent::RecvUpdate(const
       mLayerManager->GetCompositor()->SetDiagnosticTypes(
         edit.get_OpSetDiagnosticTypes().diagnostics());
       break;
     }
     // Tree ops
     case Edit::TOpSetRoot: {
       MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
 
-      mRoot = AsLayerComposite(edit.get_OpSetRoot())->AsLayer();
+      Layer* newRoot = AsLayerComposite(edit.get_OpSetRoot())->AsLayer();
+      if (newRoot->GetParent()) {
+        return false;
+      }
+      mRoot = newRoot;
       break;
     }
     case Edit::TOpInsertAfter: {
       MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
 
       const OpInsertAfter& oia = edit.get_OpInsertAfter();
       ShadowContainer(oia)->AsContainerLayerComposite()->InsertAfter(
         ShadowChild(oia)->AsLayer(), ShadowAfter(oia)->AsLayer());
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -286,16 +286,26 @@ GrallocBufferActor::Create(const gfx::In
   uint32_t format = aFormat;
   uint32_t usage = aUsage;
 
   if (format == 0 || usage == 0) {
     printf_stderr("GrallocBufferActor::Create -- format and usage must be non-zero");
     return actor;
   }
 
+  // If the requested size is too big (i.e. exceeds the commonly used max GL texture size)
+  // then we risk OOMing the parent process. It's better to just deny the allocation and
+  // kill the child process, which is what the following code does.
+  // TODO: actually use GL_MAX_TEXTURE_SIZE instead of hardcoding 4096
+  if (aSize.width > 4096 || aSize.height > 4096) {
+    printf_stderr("GrallocBufferActor::Create -- requested gralloc buffer is too big. Killing child instead.");
+    delete actor;
+    return nullptr;
+  }
+
   sp<GraphicBuffer> buffer(new GraphicBuffer(aSize.width, aSize.height, format, usage));
   if (buffer->initCheck() != OK)
     return actor;
 
   size_t bpp = BytesPerPixelForPixelFormat(format);
   actor->mAllocBytes = aSize.width * aSize.height * bpp;
   GrallocReporter::sAmount += actor->mAllocBytes;
 
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -120,17 +120,17 @@ SharedPlanarYCbCrImage::SetData(const Pl
   }
   // do not set mBuffer like in PlanarYCbCrImage because the later
   // will try to manage this memory without knowing it belongs to a
   // shmem.
   mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
                                                                mData.mCbCrSize);
   mSize = mData.mPicSize;
 
-  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   mData.mYChannel = serializer.GetYData();
   mData.mCbChannel = serializer.GetCbData();
   mData.mCrChannel = serializer.GetCrData();
   mTextureClient->MarkImmutable();
 }
 
 // needs to be overriden because the parent class sets mBuffer which we
 // do not want to happen.
@@ -143,32 +143,32 @@ SharedPlanarYCbCrImage::AllocateAndGetNe
   // get new buffer _without_ setting mBuffer.
   if (!mTextureClient->Allocate(size)) {
     return nullptr;
   }
 
   // update buffer size
   mBufferSize = size;
 
-  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   return serializer.GetData();
 }
 
 void
 SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
 {
   mData = aData;
   mSize = aData.mPicSize;
   /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating
    * memory previously allocated with AllocateAndGetNewBuffer().
    * serializer.GetData() returns the address of the memory previously allocated
    * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
    * channels to compute 0-based offsets to pass to InitializeBufferInfo.
    */
-  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   uint8_t *base = serializer.GetData();
   uint32_t yOffset = aData.mYChannel - base;
   uint32_t cbOffset = aData.mCbChannel - base;
   uint32_t crOffset = aData.mCrChannel - base;
   serializer.InitializeBufferInfo(yOffset,
                                   cbOffset,
                                   crOffset,
                                   aData.mYStride,
@@ -202,17 +202,17 @@ SharedPlanarYCbCrImage::Allocate(PlanarY
 
   size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
                                                                aData.mCbCrSize);
 
   if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
     return false;
   }
 
-  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
+  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   serializer.InitializeBufferInfo(aData.mYSize,
                                   aData.mCbCrSize,
                                   aData.mStereoMode);
   MOZ_ASSERT(serializer.IsValid());
 
   aData.mYChannel = serializer.GetYData();
   aData.mCbChannel = serializer.GetCbData();
   aData.mCrChannel = serializer.GetCrData();
@@ -253,17 +253,17 @@ DeprecatedSharedPlanarYCbCrImage::SetDat
 
   // do not set mBuffer like in PlanarYCbCrImage because the later
   // will try to manage this memory without knowing it belongs to a
   // shmem.
   mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
                                                                mData.mCbCrSize);
   mSize = mData.mPicSize;
 
-  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
   MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
   if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
                            aData.mYSize, aData.mYStride,
                            aData.mCbCrSize, aData.mCbCrStride,
                            aData.mYSkip, aData.mCbSkip)) {
     NS_WARNING("Failed to copy image data!");
   }
   mData.mYChannel = serializer.GetYData();
@@ -282,26 +282,26 @@ DeprecatedSharedPlanarYCbCrImage::Alloca
   // get new buffer _without_ setting mBuffer.
   if (!AllocateBuffer(size)) {
     return nullptr;
   }
 
   // update buffer size
   mBufferSize = size;
 
-  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
   return serializer.GetData();
 }
 
 void
 DeprecatedSharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
 {
   mData = aData;
   mSize = aData.mPicSize;
-  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
   serializer.InitializeBufferInfo(aData.mYSize,
                                   aData.mCbCrSize,
                                   aData.mStereoMode);
 }
 
 uint8_t* 
 DeprecatedSharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
 {
@@ -322,17 +322,17 @@ DeprecatedSharedPlanarYCbCrImage::Alloca
 
   size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
                                                                aData.mCbCrSize);
 
   if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
     return false;
   }
 
-  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
+  YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
   serializer.InitializeBufferInfo(aData.mYSize,
                                   aData.mCbCrSize,
                                   aData.mStereoMode);
   if (!serializer.IsValid() || mShmem.Size<uint8_t>() < size) {
     mSurfaceAllocator->DeallocShmem(mShmem);
     return false;
   }
 
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -211,17 +211,17 @@ SharedRGBImage::Allocate(gfx::IntSize aS
 
 uint8_t*
 SharedRGBImage::GetBuffer()
 {
   if (!mTextureClient) {
     return nullptr;
   }
 
-  ImageDataSerializer serializer(mTextureClient->GetBuffer());
+  ImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   return serializer.GetData();
 }
 
 gfx::IntSize
 SharedRGBImage::GetSize()
 {
   return mSize;
 }
--- a/gfx/skia/generate_mozbuild.py
+++ b/gfx/skia/generate_mozbuild.py
@@ -49,25 +49,26 @@ LOCAL_INCLUDES += [
     'trunk/src/utils/win',
 ]
 
 DEFINES['SK_A32_SHIFT'] = 24
 DEFINES['SK_R32_SHIFT'] = 16
 DEFINES['SK_G32_SHIFT'] = 8
 DEFINES['SK_B32_SHIFT'] = 0
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'cocoa'):
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'qt', 'gonk', 'cocoa'):
     DEFINES['SK_USE_POSIX_THREADS'] = 1
 
 if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['HAVE_TOOLCHAIN_SUPPORT_MSSSE3']:
     DEFINES['SK_BUILD_SSSE3'] = 1
 
 if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or \
    (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa') or \
    (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk') or \
+   CONFIG['MOZ_WIDGET_QT'] or \
    CONFIG['MOZ_WIDGET_GTK']:
     DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     DEFINES['SKIA_DLL'] = 1
 
 DEFINES['SKIA_IMPLEMENTATION'] = 1
 DEFINES['GR_IMPLEMENTATION'] = 1
@@ -267,16 +268,19 @@ def write_mozbuild(includes, sources):
   write_list(f, 'SOURCES', sources['android'], 4)
 
   f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':\n")
   write_list(f, 'SOURCES', sources['mac'], 4)
 
   f.write("if CONFIG['MOZ_WIDGET_GTK']:\n")
   write_list(f, 'SOURCES', sources['linux'], 4)
 
+  f.write("if CONFIG['MOZ_WIDGET_QT']:\n")
+  write_list(f, 'SOURCES', sources['linux'], 4)
+
   f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n")
   write_list(f, 'SOURCES', sources['win'], 4)
 
   f.write("\n\n")
   f.write("if CONFIG['INTEL_ARCHITECTURE']:\n")
   write_list(f, 'SOURCES', sources['intel'], 4)
 
   f.write("elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:\n")
--- a/gfx/skia/moz.build
+++ b/gfx/skia/moz.build
@@ -729,16 +729,28 @@ if CONFIG['MOZ_WIDGET_GTK']:
         'trunk/src/ports/SkFontHost_cairo.cpp',
         'trunk/src/ports/SkFontHost_FreeType.cpp',
         'trunk/src/ports/SkFontHost_FreeType_common.cpp',
         'trunk/src/ports/SkOSFile_posix.cpp',
         'trunk/src/ports/SkTime_Unix.cpp',
         'trunk/src/ports/SkTLS_pthread.cpp',
         'trunk/src/utils/SkThreadUtils_pthread.cpp',
     ]
+if CONFIG['MOZ_WIDGET_QT']:
+    SOURCES += [
+        'trunk/src/ports/SkDebug_stdio.cpp',
+        'trunk/src/ports/SkFontHost_cairo.cpp',
+        'trunk/src/ports/SkFontHost_FreeType.cpp',
+        'trunk/src/ports/SkFontHost_FreeType_common.cpp',
+        'trunk/src/ports/SkOSFile_posix.cpp',
+        'trunk/src/ports/SkTime_Unix.cpp',
+        'trunk/src/ports/SkTLS_pthread.cpp',
+        'trunk/src/utils/SkThreadUtils_pthread.cpp',
+        'trunk/src/utils/SkThreadUtils_pthread_linux.cpp',
+    ]
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'trunk/src/ports/SkDebug_win.cpp',
         'trunk/src/ports/SkFontHost_win.cpp',
         'trunk/src/ports/SkFontMgr_default_gdi.cpp',
         'trunk/src/ports/SkOSFile_win.cpp',
         'trunk/src/ports/SkTime_win.cpp',
         'trunk/src/ports/SkTLS_win.cpp',
@@ -825,22 +837,22 @@ LOCAL_INCLUDES += [
     'trunk/src/utils/win',
 ]
 
 DEFINES['SK_A32_SHIFT'] = 24
 DEFINES['SK_R32_SHIFT'] = 16
 DEFINES['SK_G32_SHIFT'] = 8
 DEFINES['SK_B32_SHIFT'] = 0
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'cocoa'):
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'qt', 'gonk', 'cocoa'):
     DEFINES['SK_USE_POSIX_THREADS'] = 1
 
 if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['HAVE_TOOLCHAIN_SUPPORT_MSSSE3']:
     DEFINES['SK_BUILD_SSSE3'] = 1
 
-if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk') or    (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa') or    CONFIG['MOZ_WIDGET_GTK']:
+if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk') or    (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa') or    CONFIG['MOZ_WIDGET_GTK'] or    CONFIG['MOZ_WIDGET_QT']:
     DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     DEFINES['SKIA_DLL'] = 1
 
 DEFINES['SKIA_IMPLEMENTATION'] = 1
 DEFINES['GR_IMPLEMENTATION'] = 1
--- a/gfx/src/FilterSupport.cpp
+++ b/gfx/src/FilterSupport.cpp
@@ -228,16 +228,17 @@ namespace FilterWrappers {
 // ->ForColorModel(colorModel) in order to get a FilterNode which outputs to
 // the specified colorModel.
 // Internally, this is achieved by wrapping the original FilterNode with
 // conversion FilterNodes. These filter nodes are cached in such a way that no
 // repeated or back-and-forth conversions happen.
 class FilterCachedColorModels : public RefCounted<FilterCachedColorModels>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(FilterCachedColorModels)
   // aFilter can be null. In that case, ForColorModel will return a non-null
   // completely transparent filter for all color models.
   FilterCachedColorModels(DrawTarget* aDT,
                           FilterNode* aFilter,
                           ColorModel aOriginalColorModel);
 
   // Get a FilterNode for the specified color model, guaranteed to be non-null.
   TemporaryRef<FilterNode> ForColorModel(ColorModel aColorModel);
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -176,17 +176,17 @@ void TestTextureClientYCbCr(TextureClien
   ASSERT_EQ(host->GetFlags(), client->GetFlags());
 
   // host read
   ASSERT_TRUE(host->Lock());
 
   // This will work iff the compositor is not BasicCompositor
   ASSERT_EQ(host->GetFormat(), mozilla::gfx::SurfaceFormat::YUV);
 
-  YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer());
+  YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer(), host->GetBufferSize());
   ASSERT_TRUE(yuvDeserializer.IsValid());
   PlanarYCbCrData data;
   data.mYChannel = yuvDeserializer.GetYData();
   data.mCbChannel = yuvDeserializer.GetCbData();
   data.mCrChannel = yuvDeserializer.GetCrData();
   data.mYStride = yuvDeserializer.GetYStride();
   data.mCbCrStride = yuvDeserializer.GetCbCrStride();
   data.mStereoMode = yuvDeserializer.GetStereoMode();
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2076,17 +2076,17 @@ static bool sPrefLayersDrawFPS = false;
 static bool sPrefLayersDump = false;
 static bool sPrefLayersScrollGraph = false;
 static bool sPrefLayersEnableTiles = false;
 static bool sLayersSupportsD3D9 = false;
 static int  sPrefLayoutFrameRate = -1;
 static int  sPrefLayersCompositionFrameRate = -1;
 static bool sBufferRotationEnabled = false;
 static bool sComponentAlphaEnabled = true;
-static bool sPrefBrowserTabsRemote = false;
+static bool sPrefBrowserTabsRemoteAutostart = false;
 
 static bool sLayersAccelerationPrefsInitialized = false;
 
 void
 InitLayersAccelerationPrefs()
 {
   if (!sLayersAccelerationPrefsInitialized)
   {
@@ -2106,17 +2106,17 @@ InitLayersAccelerationPrefs()
     sPrefLayersDrawFPS = Preferences::GetBool("layers.acceleration.draw-fps", false);
     sPrefLayersDump = Preferences::GetBool("layers.dump", false);
     sPrefLayersScrollGraph = Preferences::GetBool("layers.scroll-graph", false);
     sPrefLayersEnableTiles = Preferences::GetBool("layers.enable-tiles", false);
     sPrefLayoutFrameRate = Preferences::GetInt("layout.frame_rate", -1);
     sPrefLayersCompositionFrameRate = Preferences::GetInt("layers.offmainthreadcomposition.frame-rate", -1);
     sBufferRotationEnabled = Preferences::GetBool("layers.bufferrotation.enabled", true);
     sComponentAlphaEnabled = Preferences::GetBool("layers.componentalpha.enabled", true);
-    sPrefBrowserTabsRemote = BrowserTabsRemote();
+    sPrefBrowserTabsRemoteAutostart = Preferences::GetBool("browser.tabs.remote.autostart", false);
 
 #ifdef XP_WIN
     if (sPrefLayersAccelerationForceEnabled) {
       sLayersSupportsD3D9 = true;
     } else {
       nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
       if (gfxInfo) {
         int32_t status;
@@ -2156,20 +2156,20 @@ gfxPlatform::GetPrefLayersAccelerationFo
   return sPrefLayersAccelerationForceEnabled;
 }
 
 bool gfxPlatform::OffMainThreadCompositionRequired()
 {
   InitLayersAccelerationPrefs();
 #if defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD)
   // Linux users who chose OpenGL are being grandfathered in to OMTC
-  return sPrefBrowserTabsRemote ||
+  return sPrefBrowserTabsRemoteAutostart ||
          sPrefLayersAccelerationForceEnabled;
 #else
-  return sPrefBrowserTabsRemote;
+  return sPrefBrowserTabsRemoteAutostart;
 #endif
 }
 
 bool
 gfxPlatform::GetPrefLayersAccelerationDisabled()
 {
   InitLayersAccelerationPrefs();
   return sPrefLayersAccelerationDisabled;
--- a/gfx/thebes/gfxQtNativeRenderer.cpp
+++ b/gfx/thebes/gfxQtNativeRenderer.cpp
@@ -32,17 +32,17 @@ gfxQtNativeRenderer::Draw(gfxContext* ct
                                gfxIntSize(size.width, size.height));
 
     if (!isOpaque) {
         nsRefPtr<gfxContext> tempCtx = new gfxContext(xsurf);
         tempCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
         tempCtx->Paint();
     }
 
-    nsresult rv = DrawWithXlib(xsurf.get(), nsIntPoint(0, 0), nullptr, 0);
+    nsresult rv = DrawWithXlib(xsurf->CairoSurface(), nsIntPoint(0, 0), nullptr, 0);
 
     if (NS_FAILED(rv))
         return rv;
 
     ctx->SetSource(xsurf);
     ctx->Paint();
 
     return rv;
--- a/gfx/thebes/gfxQtNativeRenderer.h
+++ b/gfx/thebes/gfxQtNativeRenderer.h
@@ -25,19 +25,19 @@ public:
     /**
      * Perform the native drawing.
      * @param offsetX draw at this offset into the given drawable
      * @param offsetY draw at this offset into the given drawable
      * @param clipRects an array of rects; clip to the union
      * @param numClipRects the number of rects in the array, or zero if
      * no clipping is required
      */
-    virtual nsresult DrawWithXlib(gfxXlibSurface *xsurf,
-            nsIntPoint offset,
-            nsIntRect* clipRects, uint32_t numClipRects) = 0;
+    virtual nsresult DrawWithXlib(cairo_surface_t* surface,
+                                  nsIntPoint offset,
+                                  nsIntRect* clipRects, uint32_t numClipRects) = 0;
   
     enum {
         // If set, then Draw() is opaque, i.e., every pixel in the intersection
         // of the clipRect and (offset.x,offset.y,bounds.width,bounds.height)
         // will be set and there is no dependence on what the existing pixels
         // in the drawable are set to.
         DRAW_IS_OPAQUE = 0x01,
         // If set, then numClipRects can be zero or one
--- a/gfx/thebes/gfxQtPlatform.cpp
+++ b/gfx/thebes/gfxQtPlatform.cpp
@@ -1,24 +1,21 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 <QPixmap>
-#include <qglobal.h>
-#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
-#  include <QX11Info>
-#else
-#  include <qpa/qplatformnativeinterface.h>
-#  include <qpa/qplatformintegration.h>
+#include <QWindow>
+#ifdef MOZ_X11
+#include <qpa/qplatformnativeinterface.h>
+#include <qpa/qplatformintegration.h>
 #endif
-#include <QApplication>
-#include <QDesktopWidget>
-#include <QPaintEngine>
+#include <QGuiApplication>
+#include <QScreen>
 
 #include "gfxQtPlatform.h"
 
 #include "gfxFontconfigUtils.h"
 
 #include "mozilla/gfx/2D.h"
 
 #include "cairo.h"
@@ -28,187 +25,107 @@
 #include "nsUnicodeProperties.h"
 
 #include "gfxPangoFonts.h"
 #include "gfxContext.h"
 #include "gfxUserFontSet.h"
 
 #include "nsUnicharUtils.h"
 
-#include <fontconfig/fontconfig.h>
-
 #include "nsMathUtils.h"
 #include "nsTArray.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
+#include "prenv.h"
 #endif
 
 #include "qcms.h"
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::unicode;
 using namespace mozilla::gfx;
 
-#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
-#define DEFAULT_RENDER_MODE RENDER_DIRECT
-#else
-#define DEFAULT_RENDER_MODE RENDER_BUFFERED
+gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nullptr;
+#ifdef MOZ_X11
+bool gfxQtPlatform::sUseXRender = true;
 #endif
 
-static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::Raster;
-gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nullptr;
-static cairo_user_data_key_t cairo_qt_pixmap_key;
-static void do_qt_pixmap_unref (void *data)
-{
-    QPixmap *pmap = (QPixmap*)data;
-    delete pmap;
-}
-
 static gfxImageFormat sOffscreenFormat = gfxImageFormat::RGB24;
 
 gfxQtPlatform::gfxQtPlatform()
 {
-    mPrefFonts.Init(50);
-
+#ifdef MOZ_X11
+    sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
+#endif
     if (!sFontconfigUtils)
         sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
 
-    g_type_init();
-
-    nsresult rv;
-    // 0 - default gfxQPainterSurface
-    // 1 - gfxImageSurface
-    int32_t ival = Preferences::GetInt("mozilla.widget-qt.render-mode", DEFAULT_RENDER_MODE);
-
-    const char *envTypeOverride = getenv("MOZ_QT_RENDER_TYPE");
-    if (envTypeOverride)
-        ival = atoi(envTypeOverride);
-
-    switch (ival) {
-        case 0:
-            mRenderMode = RENDER_QPAINTER;
-            break;
-        case 1:
-            mRenderMode = RENDER_BUFFERED;
-            break;
-        case 2:
-            mRenderMode = RENDER_DIRECT;
-            break;
-        default:
-            mRenderMode = RENDER_QPAINTER;
-    }
-
-    // Qt doesn't provide a public API to detect the graphicssystem type. We hack
-    // around this by checking what type of graphicssystem a test QPixmap uses.
-    QPixmap pixmap(1, 1);
-    if (pixmap.depth() == 16) {
+    mScreenDepth = qApp->primaryScreen()->depth();
+    if (mScreenDepth == 16) {
         sOffscreenFormat = gfxImageFormat::RGB16_565;
     }
-    mScreenDepth = pixmap.depth();
-#if (QT_VERSION < QT_VERSION_CHECK(4,8,0))
-    if (pixmap.paintEngine())
-        sDefaultQtPaintEngineType = pixmap.paintEngine()->type();
-#endif
     uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
     uint32_t contentMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
     InitBackendPrefs(canvasMask, BackendType::CAIRO,
                      contentMask, BackendType::CAIRO);
 }
 
 gfxQtPlatform::~gfxQtPlatform()
 {
     gfxFontconfigUtils::Shutdown();
     sFontconfigUtils = nullptr;
 
     gfxPangoFontGroup::Shutdown();
-
-#if 0
-    // It would be nice to do this (although it might need to be after
-    // the cairo shutdown that happens in ~gfxPlatform).  It even looks
-    // idempotent.  But it has fatal assertions that fire if stuff is
-    // leaked, and we hit them.
-    FcFini();
-#endif
 }
 
 #ifdef MOZ_X11
 Display*
-gfxQtPlatform::GetXDisplay(QWidget* aWindow)
+gfxQtPlatform::GetXDisplay(QWindow* aWindow)
 {
-#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
-#ifdef Q_WS_X11
-  return aWindow ? aWindow->x11Info().display() : QX11Info::display();
-#else
-  return nullptr;
-#endif
-#else
-  return (Display*)(qApp->platformNativeInterface()->
-    nativeResourceForWindow("display", aWindow ? aWindow->windowHandle() : nullptr));
-#endif
+    return (Display*)(qApp->platformNativeInterface()->
+        nativeResourceForScreen("display", aWindow ? aWindow->screen() : qApp->primaryScreen()));
 }
 
 Screen*
-gfxQtPlatform::GetXScreen(QWidget* aWindow)
+gfxQtPlatform::GetXScreen(QWindow* aWindow)
 {
-#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
-#ifdef Q_WS_X11
-  return ScreenOfDisplay(GetXDisplay(aWindow), aWindow ? aWindow->x11Info().screen() : QX11Info().screen());
-#else
-  return nullptr;
-#endif
-#else
-  return ScreenOfDisplay(GetXDisplay(aWindow),
-                         (int)(intptr_t)qApp->platformNativeInterface()->
-                           nativeResourceForWindow("screen",
-                             aWindow ? aWindow->windowHandle() : nullptr));
-#endif
+    return ScreenOfDisplay(GetXDisplay(aWindow),
+        (int)(intptr_t)qApp->platformNativeInterface()->
+            nativeResourceForScreen("screen", aWindow ? aWindow->screen() : qApp->primaryScreen()));
 }
 #endif
 
 already_AddRefed<gfxASurface>
 gfxQtPlatform::CreateOffscreenSurface(const IntSize& size,
                                       gfxContentType contentType)
 {
-    nsRefPtr<gfxASurface> newSurface = nullptr;
-
     gfxImageFormat imageFormat = OptimalFormatForContent(contentType);
 
-#ifdef CAIRO_HAS_QT_SURFACE
-    if (mRenderMode == RENDER_QPAINTER) {
-      newSurface = new gfxQPainterSurface(ThebesIntSize(size), imageFormat);
-      return newSurface.forget();
-    }
-#endif
-
-    if ((mRenderMode == RENDER_BUFFERED || mRenderMode == RENDER_DIRECT) &&
-        sDefaultQtPaintEngineType != QPaintEngine::X11) {
-      newSurface = new gfxImageSurface(ThebesIntSize(size), imageFormat);
-      return newSurface.forget();
-    }
-
-#ifdef MOZ_X11
-    XRenderPictFormat* xrenderFormat =
-        gfxXlibSurface::FindRenderFormat(GetXDisplay(), imageFormat);
-
-    Screen* screen = GetXScreen();
-    newSurface = gfxXlibSurface::Create(screen, xrenderFormat,
-                                        ThebesIntSize(size));
-#endif
-
-    if (newSurface) {
-        gfxContext ctx(newSurface);
-        ctx.SetOperator(gfxContext::OPERATOR_CLEAR);
-        ctx.Paint();
-    }
+    nsRefPtr<gfxASurface> newSurface =
+        new gfxImageSurface(gfxIntSize(size.width, size.height), imageFormat);
 
     return newSurface.forget();
 }
 
+already_AddRefed<gfxASurface>
+gfxQtPlatform::OptimizeImage(gfxImageSurface *aSurface,
+                             gfxImageFormat format)
+{
+    /* Qt have no special offscreen surfaces so we can avoid a copy */
+    if (OptimalFormatForContent(gfxASurface::ContentFromFormat(format)) ==
+        format) {
+        return nullptr;
+    }
+
+    return gfxPlatform::OptimizeImage(aSurface, format);
+}
+
+
 nsresult
 gfxQtPlatform::GetFontList(nsIAtom *aLangGroup,
                            const nsACString& aGenericFamily,
                            nsTArray<nsString>& aListOfFonts)
 {
     return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
                                          aListOfFonts);
 }
@@ -255,16 +172,27 @@ gfxQtPlatform::MakePlatformFont(const gf
                                  const uint8_t *aFontData, uint32_t aLength)
 {
     // passing ownership of the font data to the new font entry
     return gfxPangoFontGroup::NewFontEntry(*aProxyEntry,
                                            aFontData, aLength);
 }
 
 bool
+gfxQtPlatform::SupportsOffMainThreadCompositing()
+{
+#if defined(MOZ_X11) && !defined(NIGHTLY_BUILD)
+  return (PR_GetEnv("MOZ_USE_OMTC") != nullptr) ||
+         (PR_GetEnv("MOZ_OMTC_ENABLED") != nullptr);
+#else
+  return true;
+#endif
+}
+
+bool
 gfxQtPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
 {
     // check for strange format flags
     NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
                  "strange font format hint set");
 
     // accept supported formats
     // Pango doesn't apply features from AAT TrueType extensions.
@@ -280,28 +208,27 @@ gfxQtPlatform::IsFontFormatSupported(nsI
     if (aFormatFlags != 0) {
         return false;
     }
 
     // no format hint set, need to look at data
     return true;
 }
 
-qcms_profile*
-gfxQtPlatform::GetPlatformCMSOutputProfile()
+void
+gfxQtPlatform::GetPlatformCMSOutputProfile(void *&mem, size_t &size)
 {
-    return nullptr;
+    mem = nullptr;
+    size = 0;
 }
 
 int32_t
 gfxQtPlatform::GetDPI()
 {
-    QDesktopWidget* rootWindow = qApp->desktop();
-    int32_t dpi = rootWindow->logicalDpiY(); // y-axis DPI for fonts
-    return dpi <= 0 ? 96 : dpi;
+    return qApp->primaryScreen()->logicalDotsPerInch();
 }
 
 gfxImageFormat
 gfxQtPlatform::GetOffscreenFormat()
 {
     return sOffscreenFormat;
 }
 
--- a/gfx/thebes/gfxQtPlatform.h
+++ b/gfx/thebes/gfxQtPlatform.h
@@ -10,106 +10,111 @@
 #include "nsAutoRef.h"
 #include "nsDataHashtable.h"
 #include "nsTArray.h"
 #ifdef MOZ_X11
 #include "X11/Xlib.h"
 #endif
 
 class gfxFontconfigUtils;
-class QWidget;
+class QWindow;
 
 class gfxQtPlatform : public gfxPlatform {
 public:
-
-    enum RenderMode {
-        /* Use QPainter surfaces */
-        RENDER_QPAINTER = 0,
-        /* Use offscreen buffer for rendering with image or xlib gfx backend */
-        RENDER_BUFFERED,
-        /* Direct rendering to Widget surface */
-        RENDER_DIRECT,
-        /* max */
-        RENDER_MODE_MAX
-    };
-
     gfxQtPlatform();
     virtual ~gfxQtPlatform();
 
     static gfxQtPlatform *GetPlatform() {
-        return (gfxQtPlatform*) gfxPlatform::GetPlatform();
+        return static_cast<gfxQtPlatform*>(gfxPlatform::GetPlatform());
     }
 
     virtual already_AddRefed<gfxASurface>
+    OptimizeImage(gfxImageSurface *aSurface,
+                  gfxImageFormat format) MOZ_OVERRIDE;
+    virtual already_AddRefed<gfxASurface>
       CreateOffscreenSurface(const IntSize& size,
                              gfxContentType contentType) MOZ_OVERRIDE;
 
-    mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
-      GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont);
+    virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
+      GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont) MOZ_OVERRIDE;
 
-    nsresult GetFontList(nsIAtom *aLangGroup,
-                         const nsACString& aGenericFamily,
-                         nsTArray<nsString>& aListOfFonts);
+    virtual nsresult GetFontList(nsIAtom *aLangGroup,
+                                 const nsACString& aGenericFamily,
+                                 nsTArray<nsString>& aListOfFonts) MOZ_OVERRIDE;
 
-    nsresult UpdateFontList();
+    virtual nsresult UpdateFontList() MOZ_OVERRIDE;
 
-    nsresult ResolveFontName(const nsAString& aFontName,
-                             FontResolverCallback aCallback,
-                             void *aClosure, bool& aAborted);
+    virtual nsresult ResolveFontName(const nsAString& aFontName,
+                                     FontResolverCallback aCallback,
+                                     void *aClosure, bool& aAborted) MOZ_OVERRIDE;
 
-    nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
+    virtual nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) MOZ_OVERRIDE;
 
-    gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
-                                  const gfxFontStyle *aStyle,
-                                  gfxUserFontSet* aUserFontSet);
+    virtual gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
+                                          const gfxFontStyle *aStyle,
+                                          gfxUserFontSet* aUserFontSet) MOZ_OVERRIDE;
 
     /**
      * Look up a local platform font using the full font face name (needed to
      * support @font-face src local() )
      */
     virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
-                                          const nsAString& aFontName);
+                                          const nsAString& aFontName) MOZ_OVERRIDE;
 
     /**
      * Activate a platform font (needed to support @font-face src url() )
      *
      */
     virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                            const uint8_t *aFontData,
-                                           uint32_t aLength);
+                                           uint32_t aLength) MOZ_OVERRIDE;
 
     /**
      * Check whether format is supported on a platform or not (if unclear,
      * returns true).
      */
     virtual bool IsFontFormatSupported(nsIURI *aFontURI,
-                                         uint32_t aFormatFlags);
+                                       uint32_t aFormatFlags) MOZ_OVERRIDE;
 
-    void ClearPrefFonts() { mPrefFonts.Clear(); }
-
-    RenderMode GetRenderMode() { return mRenderMode; }
-    void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }
+    virtual void ClearPrefFonts() { mPrefFonts.Clear(); }
 
     static int32_t GetDPI();
 
-    virtual gfxImageFormat GetOffscreenFormat();
+    virtual gfxImageFormat GetOffscreenFormat() MOZ_OVERRIDE;
 #ifdef MOZ_X11
-    static Display* GetXDisplay(QWidget* aWindow = 0);
-    static Screen* GetXScreen(QWidget* aWindow = 0);
+    static Display* GetXDisplay(QWindow* aWindow = 0);
+    static Screen* GetXScreen(QWindow* aWindow = 0);
 #endif
 
-    virtual int GetScreenDepth() const;
+    virtual int GetScreenDepth() const MOZ_OVERRIDE;
+
+    virtual bool SupportsOffMainThreadCompositing() MOZ_OVERRIDE;
 
 protected:
     static gfxFontconfigUtils *sFontconfigUtils;
 
 private:
-    virtual qcms_profile *GetPlatformCMSOutputProfile();
+
+    bool UseXRender() {
+#if defined(MOZ_X11)
+        if (GetContentBackend() != mozilla::gfx::BackendType::NONE &&
+            GetContentBackend() != mozilla::gfx::BackendType::CAIRO)
+            return false;
+
+        return sUseXRender;
+#else
+        return false;
+#endif
+    }
+
+    virtual void GetPlatformCMSOutputProfile(void *&mem, size_t &size) MOZ_OVERRIDE;
 
     // TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList
     nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
 
-    RenderMode mRenderMode;
     int mScreenDepth;
+#ifdef MOZ_X11
+    static bool sUseXRender;
+#endif
 };
 
 #endif /* GFX_PLATFORM_QT_H */
 
--- a/image/decoders/icon/qt/nsIconChannel.cpp
+++ b/image/decoders/icon/qt/nsIconChannel.cpp
@@ -1,16 +1,14 @@
 /* vim:set ts=2 sw=2 sts=2 cin et: */
 /* 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 <QIcon>
-#include <QStyle>
-#include <QApplication>
 
 #include <stdlib.h>
 #include <unistd.h>
 
 #include "nsMimeTypes.h"
 #include "nsIMIMEService.h"
 
 #include "nsIStringBundle.h"
@@ -103,28 +101,18 @@ nsIconChannel::Init(nsIURI* aURI)
 
   uint32_t desiredImageSize;
   iconURI->GetImageSize(&desiredImageSize);
 
   nsAutoCString iconStateString;
   iconURI->GetIconState(iconStateString);
   bool disabled = iconStateString.EqualsLiteral("disabled");
 
-  QStyle::StandardPixmap sp_icon = (QStyle::StandardPixmap)0;
-  nsCOMPtr <nsIGtkQtIconsConverter> converter = do_GetService("@mozilla.org/gtkqticonsconverter;1");
-  if (converter) {
-    int32_t res = 0;
-    stockIcon.Cut(0,4);
-    converter->Convert(stockIcon.get(), &res);
-    sp_icon = (QStyle::StandardPixmap)res;
-    // printf("ConvertIcon: icon:'%s' -> res:%i\n", stockIcon.get(), res);
-  }
-  if (!sp_icon)
-    return NS_ERROR_FAILURE;
+  // This is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=662299
+  // Try to find corresponding freedesktop icon and fallback to empty QIcon if failed.
+  QIcon icon = QIcon::fromTheme(QString(stockIcon.get()).replace("gtk-", "edit-"));
+  QPixmap pixmap = icon.pixmap(desiredImageSize, desiredImageSize, disabled ? QIcon::Disabled : QIcon::Normal);
 
-  QStyle *style = qApp->style();
-  NS_ENSURE_TRUE(style, NS_ERROR_NULL_POINTER);
-  QPixmap pixmap = style->standardIcon(sp_icon).pixmap(desiredImageSize, desiredImageSize, disabled?QIcon::Disabled:QIcon::Normal);
   QImage image = pixmap.toImage();
 
   return moz_qicon_to_channel(&image, iconURI,
                               getter_AddRefs(mRealChannel));
 }
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -139,16 +139,17 @@ class FrameAnimator;
 class RasterImage : public ImageResource
                   , public nsIProperties
                   , public SupportsWeakPtr<RasterImage>
 #ifdef DEBUG
                   , public imgIContainerDebug
 #endif
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(RasterImage)
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIPROPERTIES
   NS_DECL_IMGICONTAINER
 #ifdef DEBUG
   NS_DECL_IMGICONTAINERDEBUG
 #endif
 
   // (no public constructor - use ImageFactory)
--- a/image/src/SurfaceCache.cpp
+++ b/image/src/SurfaceCache.cpp
@@ -107,16 +107,17 @@ private:
 
 /*
  * A CachedSurface associates a surface with a key that uniquely identifies that
  * surface.
  */
 class CachedSurface : public RefCounted<CachedSurface>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(CachedSurface)
   CachedSurface(DrawTarget*       aTarget,
                 const IntSize     aTargetSize,
                 const Cost        aCost,
                 const ImageKey    aImageKey,
                 const SurfaceKey& aSurfaceKey)
     : mTarget(aTarget)
     , mTargetSize(aTargetSize)
     , mCost(aCost)
@@ -152,16 +153,17 @@ private:
  * An ImageSurfaceCache is a per-image surface cache. For correctness we must be
  * able to remove all surfaces associated with an image when the image is
  * destroyed or invalidated. Since this will happen frequently, it makes sense
  * to make it cheap by storing the surfaces for each image separately.
  */
 class ImageSurfaceCache : public RefCounted<ImageSurfaceCache>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache)
   typedef nsRefPtrHashtable<nsGenericHashKey<SurfaceKey>, CachedSurface> SurfaceTable;
 
   bool IsEmpty() const { return mSurfaces.Count() == 0; }
   
   void Insert(const SurfaceKey& aKey, CachedSurface* aSurface)
   {
     MOZ_ASSERT(aSurface, "Should have a surface");
     mSurfaces.Put(aKey, aSurface);
--- a/image/src/imgDecoderObserver.h
+++ b/image/src/imgDecoderObserver.h
@@ -31,16 +31,17 @@ struct nsIntRect;
  * situation. If imgIDecoder::FLAG_SYNC_DECODE is passed to a function that
  * triggers a decode, all notifications that can be generated from the currently
  * loaded data fire before the call returns. If FLAG_SYNC_DECODE is not passed,
  * all, some, or none of the notifications may fire before the call returns.
  */
 class imgDecoderObserver : public mozilla::RefCounted<imgDecoderObserver>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(imgDecoderObserver)
   virtual ~imgDecoderObserver() = 0;
 
   /**
    * Load notification.
    *
    * called at the same time that nsIRequestObserver::onStartRequest would be
    * (used only for observers of imgIRequest objects, which are nsIRequests,
    * not imgIDecoder objects)
--- a/image/src/imgRequestProxy.h
+++ b/image/src/imgRequestProxy.h
@@ -43,16 +43,17 @@ class ImageURL;
 
 class imgRequestProxy : public imgIRequest,
                         public nsISupportsPriority,
                         public nsISecurityInfoProvider,
                         public nsITimedChannel,
                         public mozilla::SupportsWeakPtr<imgRequestProxy>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
   typedef mozilla::image::ImageURL ImageURL;
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIREQUEST
   NS_DECL_NSIREQUEST
   NS_DECL_NSISUPPORTSPRIORITY
   NS_DECL_NSISECURITYINFOPROVIDER
   // nsITimedChannel declared below
 
--- a/image/src/imgStatusTracker.h
+++ b/image/src/imgStatusTracker.h
@@ -104,16 +104,17 @@ enum {
  * the Notify() method on this class with the relevant proxy as its argument,
  * and the notifications will be replayed to the proxy asynchronously.
  */
 
 
 class imgStatusTracker : public mozilla::SupportsWeakPtr<imgStatusTracker>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(imgStatusTracker)
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(imgStatusTracker)
 
   // aImage is the image that this status tracker will pass to the
   // imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
   // alive as long as this instance is, because we hold a weak reference to it.
   imgStatusTracker(mozilla::image::Image* aImage);
   virtual ~imgStatusTracker();
 
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -221,17 +221,17 @@ if os_linux:
         SOURCES += [
             'src/base/message_pump_glib.cc',
         ]
     if CONFIG['MOZ_ENABLE_QT']:
         SOURCES += [
             'src/base/message_pump_qt.cc',
         ]
         GENERATED_SOURCES += [
-            'src/base/moc_message_pump_qt.cc',
+            'moc_message_pump_qt.cc',
         ]
     if not CONFIG['MOZ_NATIVE_LIBEVENT']:
         if CONFIG['OS_TARGET'] != 'Android':
             SOURCES += [
                 'src/third_party/libevent/epoll_sub.c',
             ]
         SOURCES += [
             'src/third_party/libevent/epoll.c',
@@ -258,17 +258,17 @@ if os_bsd:
         SOURCES += [
             'src/base/message_pump_glib.cc',
         ]
     if CONFIG['MOZ_ENABLE_QT']:
         SOURCES += [
             'src/base/message_pump_qt.cc',
         ]
         GENERATED_SOURCES += [
-            'src/base/moc_message_pump_qt.cc',
+            'moc_message_pump_qt.cc',
         ]
     if not CONFIG['MOZ_NATIVE_LIBEVENT']:
         SOURCES += [
             'src/third_party/libevent/kqueue.c',
         ]
         LOCAL_INCLUDES += ['src/third_party/libevent/bsd']
 
 if CONFIG['_MSC_VER']:
--- a/ipc/chromium/src/base/message_pump_qt.cc
+++ b/ipc/chromium/src/base/message_pump_qt.cc
@@ -34,21 +34,17 @@ MessagePumpForUI::MessagePumpForUI()
 
 MessagePumpForUI::~MessagePumpForUI() {
 }
 
 MessagePumpQt::MessagePumpQt(MessagePumpForUI &aPump)
   : pump(aPump), mTimer(new QTimer(this))
 {
   // Register our custom event type, to use in qApp event loop
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
   sPokeEvent = QEvent::registerEventType();
-#else
-  sPokeEvent = QEvent::User+5000;
-#endif
   connect(mTimer, SIGNAL(timeout()), this, SLOT(dispatchDelayed()));
   mTimer->setSingleShot(true);
 }
 
 MessagePumpQt::~MessagePumpQt()
 {
   mTimer->stop();
   delete mTimer;
--- a/ipc/glue/MessageLink.h
+++ b/ipc/glue/MessageLink.h
@@ -55,16 +55,17 @@ enum RacyInterruptPolicy {
     RIPParentWins
 };
 
 class MessageListener
   : protected HasResultCodes,
     public mozilla::SupportsWeakPtr<MessageListener>
 {
   public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(MessageListener)
     typedef IPC::Message Message;
 
     virtual ~MessageListener() { }
 
     virtual void OnChannelClose() = 0;
     virtual void OnChannelError() = 0;
     virtual Result OnMessageReceived(const Message& aMessage) = 0;
     virtual Result OnMessageReceived(const Message& aMessage, Message *& aReply) = 0;
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1231,17 +1231,17 @@ class CloneBufferObject : public JSObjec
         size_t nbytes;
         buffer->steal(&datap, &nbytes);
         obj->setData(datap);
         obj->setNBytes(nbytes);
         return obj;
     }
 
     uint64_t *data() const {
-        return static_cast<uint64_t*>(getReservedSlot(0).toPrivate());
+        return static_cast<uint64_t*>(getReservedSlot(DATA_SLOT).toPrivate());
     }
 
     void setData(uint64_t *aData) {
         JS_ASSERT(!data());
         setReservedSlot(DATA_SLOT, PrivateValue(aData));
     }
 
     size_t nbytes() const {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug-952818.js
@@ -0,0 +1,9 @@
+(function() {
+    eval("\
+        (function() {\
+            var f = function(){\
+                f\
+            }\
+        })()\
+    ")
+})()
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -7941,16 +7941,19 @@ IonBuilder::jsop_rest()
     for (unsigned i = numFormals; i < numActuals; i++) {
         index = MConstant::New(alloc(), Int32Value(i - numFormals));
         current->add(index);
 
         MDefinition *arg = inlineCallInfo_->argv()[i];
         MStoreElement *store = MStoreElement::New(alloc(), elements, index, arg,
                                                   /* needsHoleCheck = */ false);
         current->add(store);
+
+        if (NeedsPostBarrier(info(), arg))
+            current->add(MPostWriteBarrier::New(alloc(), array, arg));
     }
 
     // The array's length is incorrectly 0 now, from the template object
     // created by BaselineCompiler::emit_JSOP_REST() before the actual argument
     // count was known. Set the correct length now that we know that count.
     MSetArrayLength *length = MSetArrayLength::New(alloc(), elements, index);
     current->add(length);
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3108,26 +3108,16 @@ JS_DefineProperty(JSContext *cx, JSObjec
                   PropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
 {
     RootedObject obj(cx, objArg);
     RootedValue value(cx, valueArg);
     return DefineProperty(cx, obj, name, value, GetterWrapper(getter),
                           SetterWrapper(setter), attrs, 0, 0);
 }
 
-JS_PUBLIC_API(bool)
-JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *objArg, const char *name, int8_t tinyid,
-                            jsval valueArg, PropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
-{
-    RootedObject obj(cx, objArg);
-    RootedValue value(cx, valueArg);
-    return DefineProperty(cx, obj, name, value, GetterWrapper(getter),
-                          SetterWrapper(setter), attrs, Shape::HAS_SHORTID, tinyid);
-}
-
 static bool
 DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
                  const Value &value_, PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                  unsigned flags, int tinyid)
 {
     RootedValue value(cx, value_);
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
@@ -3143,27 +3133,16 @@ JS_DefineUCProperty(JSContext *cx, JSObj
                     jsval valueArg, JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
 {
     RootedObject obj(cx, objArg);
     RootedValue value(cx, valueArg);
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen,
-                              int8_t tinyid, jsval valueArg,
-                              JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
-{
-    RootedObject obj(cx, objArg);
-    RootedValue value(cx, valueArg);
-    return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs,
-                            Shape::HAS_SHORTID, tinyid);
-}
-
-JS_PUBLIC_API(bool)
 JS_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, jsval descriptorArg, bool *bp)
 {
     RootedObject obj(cx, objArg);
     RootedId id(cx, idArg);
     RootedValue descriptor(cx, descriptorArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id, descriptor);
@@ -6306,8 +6285,15 @@ JSAutoByteString::encodeLatin1(Exclusive
     return mBytes;
 }
 
 JS_PUBLIC_API(void)
 JS::SetLargeAllocationFailureCallback(JSRuntime *rt, JS::LargeAllocationFailureCallback lafc)
 {
     rt->largeAllocationFailureCallback = lafc;
 }
+
+JS_PUBLIC_API(void)
+JS::SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb)
+{
+    rt->oomCallback = cb;
+}
+
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2783,22 +2783,16 @@ JS_DefineProperty(JSContext *cx, JSObjec
 extern JS_PUBLIC_API(bool)
 JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
                       JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
 
 extern JS_PUBLIC_API(bool)
 JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, bool *bp);
 
 extern JS_PUBLIC_API(bool)
-JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
-                            int8_t tinyid, jsval value,
-                            JSPropertyOp getter, JSStrictPropertyOp setter,
-                            unsigned attrs);
-
-extern JS_PUBLIC_API(bool)
 JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
                          bool *foundp);
 
 extern JS_PUBLIC_API(bool)
 JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
                              bool *foundp);
 
 extern JS_PUBLIC_API(bool)
@@ -3022,23 +3016,16 @@ JS_DeletePropertyById2(JSContext *cx, JS
 
 extern JS_PUBLIC_API(bool)
 JS_DefineUCProperty(JSContext *cx, JSObject *obj,
                     const jschar *name, size_t namelen, jsval value,
                     JSPropertyOp getter, JSStrictPropertyOp setter,
                     unsigned attrs);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
-                              const jschar *name, size_t namelen,
-                              int8_t tinyid, jsval value,
-                              JSPropertyOp getter, JSStrictPropertyOp setter,
-                              unsigned attrs);
-
-extern JS_PUBLIC_API(bool)
 JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
                            size_t namelen, bool *foundp);
 
 extern JS_PUBLIC_API(bool)
 JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
                  const jschar *name, size_t namelen,
                  bool *vp);
 
@@ -4911,20 +4898,38 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(ForO
     bool materializeArrayIterator();
 };
 
 
 /*
  * If a large allocation fails, the JS engine may call the large-allocation-
  * failure callback, if set, to allow the embedding to flush caches, possibly
  * perform shrinking GCs, etc. to make some room so that the allocation will
- * succeed if retried.
+ * succeed if retried. After the callback returns, the JS engine will try to
+ * allocate again and may be succesful.
  */
 
 typedef void
 (* LargeAllocationFailureCallback)();
 
 extern JS_PUBLIC_API(void)
 SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc);
 
+/*
+ * Unlike the error reporter, which is only called if the exception for an OOM
+ * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
+ * at the OOM site to allow the embedding to capture the current state of heap
+ * allocation before anything is freed. If the large-allocation-failure callback
+ * is called at all (not all allocation sites call the large-allocation-failure
+ * callback on failure), it is called before the out-of-memory callback; the
+ * out-of-memory callback is only called if the allocation still fails after the
+ * large-allocation-failure callback has returned.
+ */
+
+typedef void
+(* OutOfMemoryCallback)(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb);
+
 } /* namespace JS */
 
 #endif /* jsapi_h */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -365,19 +365,25 @@ js_ReportOutOfMemory(ThreadSafeContext *
 
     if (cxArg->isForkJoinContext()) {
         cxArg->asForkJoinContext()->setPendingAbortFatal(ParallelBailoutOutOfMemory);
         return;
     }
 
     if (!cxArg->isJSContext())
         return;
+
     JSContext *cx = cxArg->asJSContext();
+    cx->runtime()->hadOutOfMemory = true;
 
-    cx->runtime()->hadOutOfMemory = true;
+    /* Report the oom. */
+    if (JS::OutOfMemoryCallback oomCallback = cx->runtime()->oomCallback) {
+        AutoSuppressGC suppressGC(cx);
+        oomCallback(cx);
+    }
 
     if (JS_IsRunning(cx)) {
         cx->setPendingException(StringValue(cx->names().outOfMemory));
         return;
     }
 
     /* Get the message for this error, but we don't expand any arguments. */
     const JSErrorFormatString *efs =
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -829,17 +829,19 @@ ParseCompileOptions(JSContext *cx, Compi
     }
 
     if (!JS_GetProperty(cx, opts, "sourcePolicy", &v))
         return false;
     if (!v.isUndefined()) {
         JSString *s = ToString(cx, v);
         if (!s)
             return false;
-        char *policy = JS_EncodeStringToUTF8(cx, s);
+
+        JSAutoByteString bytes;
+        char *policy = bytes.encodeUtf8(cx, s);
         if (!policy)
             return false;
         if (strcmp(policy, "NO_SOURCE") == 0) {
             options.setSourcePolicy(CompileOptions::NO_SOURCE);
         } else if (strcmp(policy, "LAZY_SOURCE") == 0) {
             options.setSourcePolicy(CompileOptions::LAZY_SOURCE);
         } else if (strcmp(policy, "SAVE_SOURCE") == 0) {
             options.setSourcePolicy(CompileOptions::SAVE_SOURCE);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4509,30 +4509,33 @@ DebuggerGenericEval(JSContext *cx, const
                 !dbg->unwrapDebuggeeValue(cx, valp))
             {
                 return false;
             }
         }
     }
 
     /* Set options from object if provided. */
+    JSAutoByteString url_bytes;
     char *url = nullptr;
     unsigned lineNumber = 1;
 
     if (options.isObject()) {
         RootedObject opts(cx, &options.toObject());
         RootedValue v(cx);
 
         if (!JS_GetProperty(cx, opts, "url", &v))
             return false;
         if (!v.isUndefined()) {
             RootedString url_str(cx, ToString<CanGC>(cx, v));
             if (!url_str)
                 return false;
-            url = JS_EncodeString(cx, url_str);
+            url = url_bytes.encodeLatin1(cx, url_str);
+            if (!url)
+                return false;
         }
 
         if (!JS_GetProperty(cx, opts, "lineNumber", &v))
             return false;
         if (!v.isUndefined()) {
             uint32_t lineno;
             if (!ToUint32(cx, v, &lineno))
                 return false;
@@ -4589,18 +4592,16 @@ DebuggerGenericEval(JSContext *cx, const
 
     /* Run the code and produce the completion value. */
     RootedValue rval(cx);
     JS::Anchor<JSString *> anchor(flat);
     AbstractFramePtr frame = iter ? iter->abstractFramePtr() : NullFramePtr();
     bool ok = EvaluateInEnv(cx, env, thisv, frame,
                             ConstTwoByteChars(flat->chars(), flat->length()),
                             flat->length(), url ? url : "debugger eval code", lineNumber, &rval);
-    if (url)
-        JS_free(cx, url);
     return dbg->receiveCompletionValue(ac, ok, rval, vp);
 }
 
 static bool
 DebuggerFrame_eval(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_FRAME_ITER(cx, argc, vp, "eval", args, thisobj, _, iter);
     REQUIRE_ARGC("Debugger.Frame.prototype.eval", 1);
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -296,17 +296,18 @@ JSRuntime::JSRuntime(JSRuntime *parentRu
     ionReturnOverride_(MagicValue(JS_ARG_POISON)),
     useHelperThreads_(useHelperThreads),
     parallelIonCompilationEnabled_(true),
     parallelParsingEnabled_(true),
     isWorkerRuntime_(false),
 #ifdef DEBUG
     enteredPolicy(nullptr),
 #endif
-    largeAllocationFailureCallback(nullptr)
+    largeAllocationFailureCallback(nullptr),
+    oomCallback(nullptr)
 {
     liveRuntimesCount++;
 
     setGCMode(JSGC_MODE_GLOBAL);
 
     /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
     JS_INIT_CLIST(&onNewGlobalObjectWatchers);
 
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1726,21 +1726,25 @@ struct JSRuntime : public JS::shadow::Ru
         return isWorkerRuntime_;
     }
 
 #ifdef DEBUG
   public:
     js::AutoEnterPolicy *enteredPolicy;
 #endif
 
+    /* See comment for JS::SetLargeAllocationFailureCallback in jsapi.h. */
+    JS::LargeAllocationFailureCallback largeAllocationFailureCallback;
+    /* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */
+    JS::OutOfMemoryCallback oomCallback;
+
     /*
      * These variations of malloc/calloc/realloc will call the
      * large-allocation-failure callback on OOM and retry the allocation.
      */
-    JS::LargeAllocationFailureCallback largeAllocationFailureCallback;
 
     static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
 
     void *callocCanGC(size_t bytes) {
         void *p = calloc_(bytes);
         if (MOZ_LIKELY(!!p))
             return p;
         if (!largeAllocationFailureCallback || bytes < LARGE_ALLOCATION)
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -87,37 +87,35 @@ js::intrinsic_ThrowError(JSContext *cx, 
     uint32_t errorNumber = args[0].toInt32();
 
 #ifdef DEBUG
     const JSErrorFormatString *efs =
         js_GetLocalizedErrorMessage(cx, nullptr, nullptr, errorNumber);
     JS_ASSERT(efs->argCount == args.length() - 1);
 #endif
 
-    char *errorArgs[3] = {nullptr, nullptr, nullptr};
+    JSAutoByteString errorArgs[3];
     for (unsigned i = 1; i < 4 && i < args.length(); i++) {
         RootedValue val(cx, args[i]);
         if (val.isInt32()) {
             JSString *str = ToString<CanGC>(cx, val);
             if (!str)
                 return false;
-            errorArgs[i - 1] = JS_EncodeString(cx, str);
+            errorArgs[i - 1].encodeLatin1(cx, str);
         } else if (val.isString()) {
-            errorArgs[i - 1] = JS_EncodeString(cx, ToString<CanGC>(cx, val));
+            errorArgs[i - 1].encodeLatin1(cx, val.toString());
         } else {
-            errorArgs[i - 1] = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
+            errorArgs[i - 1].initBytes(DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr()));
         }
         if (!errorArgs[i - 1])
             return false;
     }
 
     JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, errorNumber,
-                         errorArgs[0], errorArgs[1], errorArgs[2]);
-    for (unsigned i = 0; i < 3; i++)
-        js_free(errorArgs[i]);
+                         errorArgs[0].ptr(), errorArgs[1].ptr(), errorArgs[2].ptr());
     return false;
 }
 
 /**
  * Handles an assertion failure in self-hosted code just like an assertion
  * failure in C++ code. Information about the failure can be provided in args[0].
  */
 static bool
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -116,17 +116,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(f4b12240-02aa-47e5-99d5-43cd50fbd4b7)]
+[scriptable, uuid(0b81b4f2-cad7-4602-a5cb-b99c9d514196)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -274,16 +274,22 @@ interface nsIXPCComponents_Utils : nsISu
     void schedulePreciseGC(in ScheduledGCCallback callback);
 
     /*
      * Schedule a shrinking garbage collection cycle for a point in the future
      * when no JS is running. Call the provided function once this has occured.
      */
     void schedulePreciseShrinkingGC(in ScheduledGCCallback callback);
 
+    /*
+     * In a debug build, unlink any ghost windows. This is only for debugging
+     * leaks, and can cause bad things to happen if called.
+     */
+    void unlinkGhostWindows();
+
     /**
      * Return the keys in a weak map.  This operation is
      * non-deterministic because it is affected by the scheduling of the
      * garbage collector and the cycle collector.
      *
      * This should only be used to write tests of the interaction of
      * the GC and CC with weak maps.
      *
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2852,16 +2852,28 @@ nsXPCComponents_Utils::SchedulePreciseGC
 /* void schedulePreciseShrinkingGC(in ScheduledGCCallback callback); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback)
 {
     nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true);
     return NS_DispatchToMainThread(event);
 }
 
+/* void unlinkGhostWindows(); */
+NS_IMETHODIMP
+nsXPCComponents_Utils::UnlinkGhostWindows()
+{
+#ifdef DEBUG
+    nsWindowMemoryReporter::UnlinkGhostWindows();
+    return NS_OK;
+#else
+    return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
 /* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(HandleValue aMap,
                                                       JSContext *aCx,
                                                       MutableHandleValue aKeys)
 {
     if (!aMap.isObject()) {
         aKeys.setUndefined();
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -11,16 +11,17 @@
 #include "xpcprivate.h"
 #include "xpcpublic.h"
 #include "XPCWrapper.h"
 #include "XPCJSMemoryReporter.h"
 #include "WrapperFactory.h"
 #include "dom_quickstubs.h"
 #include "mozJSComponentLoader.h"
 
+#include "nsIMemoryInfoDumper.h"
 #include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsIDebug2.h"
 #include "amIAddonManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
@@ -1391,16 +1392,35 @@ XPCJSRuntime::OperationCallback(JSContex
     // machinery with a pref of the user opted out of future slow-script dialogs.
     self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
     if (response == nsGlobalWindow::AlwaysContinueSlowScript)
         Preferences::SetInt(prefName, 0);
 
     return true;
 }
 
+/* static */ void
+XPCJSRuntime::OutOfMemoryCallback(JSContext *cx)
+{
+    if (!Preferences::GetBool("memory.dump_reports_on_oom")) {
+        return;
+    }
+
+    nsCOMPtr<nsIMemoryInfoDumper> dumper =
+        do_GetService("@mozilla.org/memory-info-dumper;1");
+    if (!dumper) {
+        return;
+    }
+
+    // If this fails, it fails silently.
+    dumper->DumpMemoryInfoToTempDir(NS_LITERAL_STRING("due-to-JS-OOM"),
+                                    /* minimizeMemoryUsage = */ false,
+                                    /* dumpChildProcesses = */ false);
+}
+
 size_t
 XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
 {
     size_t n = 0;
     n += mallocSizeOf(this);
     n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf);
     n += mIID2NativeInterfaceMap->SizeOfIncludingThis(mallocSizeOf);
     n += mClassInfo2NativeSetMap->ShallowSizeOfIncludingThis(mallocSizeOf);
@@ -3096,16 +3116,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     if (PseudoStack *stack = mozilla_get_pseudo_stack())
         stack->sampleRuntime(runtime);
 #endif
     JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
     js::SetDefaultJSContextCallback(runtime, DefaultJSContextCallback);
     js::SetActivityCallback(runtime, ActivityCallback, this);
     js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
     JS_SetOperationCallback(runtime, OperationCallback);
+    JS::SetOutOfMemoryCallback(runtime, OutOfMemoryCallback);
 
     // The JS engine needs to keep the source code around in order to implement
     // Function.prototype.toSource(). It'd be nice to not have to do this for
     // chrome code and simply stub out requests for source on it. Life is not so
     // easy, unfortunately. Nobody relies on chrome toSource() working in core
     // browser code, but chrome tests use it. The worst offenders are addons,
     // which like to monkeypatch chrome functions by calling toSource() on them
     // and using regular expressions to modify them. We avoid keeping most browser
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -562,16 +562,17 @@ public:
     void AddContextCallback(xpcContextCallback cb);
     void RemoveContextCallback(xpcContextCallback cb);
 
     static JSContext* DefaultJSContextCallback(JSRuntime *rt);
     static void ActivityCallback(void *arg, bool active);
     static void CTypesActivityCallback(JSContext *cx,
                                        js::CTypesActivityType type);
     static bool OperationCallback(JSContext *cx);
+    static void OutOfMemoryCallback(JSContext *cx);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
 
     JSObject* GetJunkScope();
     void DeleteJunkScope();
 
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -43,16 +43,17 @@ enum LayerState {
   // Special layer that is metadata only.
   LAYER_ACTIVE_EMPTY,
   // Inactive style layer for rendering SVG effects.
   LAYER_SVG_EFFECTS
 };
 
 class RefCountedRegion : public RefCounted<RefCountedRegion> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(RefCountedRegion)
   RefCountedRegion() : mIsInfinite(false) {}
   nsRegion mRegion;
   bool mIsInfinite;
 };
 
 struct ContainerLayerParameters {
   ContainerLayerParameters() :
     mXScale(1), mYScale(1), mAncestorClipRect(nullptr),
--- a/layout/base/crashtests/653133-1.html
+++ b/layout/base/crashtests/653133-1.html
@@ -1,9 +1,9 @@
-<html reftest-displayport-w="800" reftest-displayport-h="6000">
+<html reftest-displayport-w="800" reftest-displayport-h="4096">
 <head>
 <style type="text/css">
 body
 {
 background-image:url("");
 background-attachment:fixed;
 }
 </style>
--- a/layout/base/tests/test_bug588174.html
+++ b/layout/base/tests/test_bug588174.html
@@ -17,41 +17,50 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 569520 **/
 SimpleTest.waitForExplicitFinish();
 
 var startNow = Date.now();
 var start = window.mozAnimationStartTime;
-var firstListenerTime;
-var secondListenerTime;
+var firstListenerArg;
+var secondListenerArg;
+var thirdListenerTime;
 
-function secondListener(time) {
-  secondListenerTime = time;
+// callback arg is wallclock from mozRequestAnimationFrame
+function thirdListener(t) {
+  thirdListenerTime = t;
 
   // They really shouldn't be more than 100ms apart, but we can get weird
   // effects on slow machines.  5 minutes is our test timeout, though.
   ok(Math.abs(startNow - start) <= 5 * 60 * 1000, "Bogus animation start time");
-  ok(firstListenerTime >= start, "First listener should fire after start");
-  // FIXME: The timer filtering code makes the refresh driver call back in 0ms
-  // sometimes!
-  ok(secondListenerTime >= firstListenerTime,
+
+  ok(secondListenerArg >= firstListenerArg, // callback args from consecutive unprefixed requestAnimationFrame
      "Second listener should fire after first listener");
+
+  ok(thirdListenerTime >= start, "Third listener should fire after start");
+
   SimpleTest.finish();
 }
-                            
-function firstListener(time) {
-  firstListenerTime = time;
-  mozRequestAnimationFrame(secondListener);
+
+// callback arg is from requestAnimationFrame and comparable to performance.now()
+function secondListener(t) {
+  secondListenerArg = t;
+  mozRequestAnimationFrame(thirdListener);
 }
-                            
+
+function firstListener(t) {
+  firstListenerArg = t;
+  requestAnimationFrame(secondListener);
+}
+
 addLoadEvent(function() {
     setTimeout(function() {
-      mozRequestAnimationFrame(firstListener);
+      requestAnimationFrame(firstListener);
     }, 100);
   });
 
 
 
 
 </script>
 </pre>
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -1501,17 +1501,17 @@ nsListControlFrame::IsOptionDisabled(int
 // helper
 //----------------------------------------------------------------------
 bool
 nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent)
 {
   // only allow selection with the left button
   nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
   if (mouseEvent) {
-    uint16_t whichButton;
+    int16_t whichButton;
     if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) {
       return whichButton != 0?false:true;
     }
   }
   return false;
 }
 
 nscoord
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/974746-1.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+
+    <pattern id="patternRotated" width="1" patternTransform="rotate(45 50 50)">
+        <rect/>
+    </pattern>
+
+    <rect width="100" height="100" fill="url(#patternRotated)"/>
+
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -173,8 +173,9 @@ load 890782-1.svg
 load 890783-1.svg
 load 893510-1.svg
 load 895311-1.svg
 load 897342-1.svg
 load 898909-1.svg
 load 898951-1.svg
 load 919371-1.xhtml
 load 952270-1.svg
+load 974746-1.svg
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -310,16 +310,19 @@ nsSVGPatternFrame::PaintPattern(gfxASurf
   } else {
     patternFrame->mCTM = new gfxMatrix(ctm);
   }
 
   // Get the bounding box of the pattern.  This will be used to determine
   // the size of the surface, and will also be used to define the bounding
   // box for the pattern tile.
   gfxRect bbox = GetPatternRect(patternUnits, callerBBox, ToMatrix(aContextMatrix), aSource);
+  if (bbox.Width() <= 0.0 || bbox.Height() <= 0.0) {
+    return NS_ERROR_FAILURE;
+  }
 
   // Get the pattern transform
   gfxMatrix patternTransform = GetPatternTransform();
 
   // revert the vector effect transform so that the pattern appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     patternTransform.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert());
   }
--- a/layout/tools/reftest/runreftestb2g.py
+++ b/layout/tools/reftest/runreftestb2g.py
@@ -500,24 +500,26 @@ def run_remote_reftests(parser, options,
         kwargs['homedir'] = options.b2gPath
     if options.marionette:
         host,port = options.marionette.split(':')
         kwargs['host'] = host
         kwargs['port'] = int(port)
     marionette = Marionette.getMarionetteOrExit(**kwargs)
     auto.marionette = marionette
 
-    # create the DeviceManager
-    kwargs = {'adbPath': options.adbPath,
-              'deviceRoot': options.remoteTestRoot}
-    if options.deviceIP:
-        kwargs.update({'host': options.deviceIP,
-                       'port': options.devicePort})
-
-    dm = DeviceManagerADB(**kwargs)
+    if options.emulator:
+        dm = marionette.emulator.dm
+    else:
+        # create the DeviceManager
+        kwargs = {'adbPath': options.adbPath,
+                  'deviceRoot': options.remoteTestRoot}
+        if options.deviceIP:
+            kwargs.update({'host': options.deviceIP,
+                           'port': options.devicePort})
+        dm = DeviagerADB(**kwargs)
     auto.setDeviceManager(dm)
 
     options = parser.verifyRemoteOptions(options)
 
     if (options == None):
         print "ERROR: Invalid options specified, use --help for a list of valid options"
         sys.exit(1)
 
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -597,17 +597,17 @@ nsSplitterFrameInner::MouseUp(nsIDOMEven
 nsresult
 nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
 {  
   NS_ENSURE_TRUE(mOuter, NS_OK);
   nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aMouseEvent));
   if (!mouseEvent)
     return NS_OK;
 
-  uint16_t button = 0;
+  int16_t button = 0;
   mouseEvent->GetButton(&button);
 
   // only if left button
   if (button != 0)
      return NS_OK;
 
   if (mOuter->GetContent()->
         AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -37,16 +37,20 @@ template<typename T> OutParamRef<T> byRe
  *
  * Live RefCounted<T> have refcount > 0.  The lifetime (refcounts) of
  * live RefCounted<T> are controlled by RefPtr<T> and
  * RefPtr<super/subclass of T>.  Upon a transition from refcounted==1
  * to 0, the RefCounted<T> "dies" and is destroyed.  The "destroyed"
  * state is represented in DEBUG builds by refcount==0xffffdead.  This
  * state distinguishes use-before-ref (refcount==0) from
  * use-after-destroy (refcount==0xffffdead).
+ *
+ * Note that when deriving from RefCounted or AtomicRefCounted, you
+ * should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public
+ * section of your class, where ClassName is the name of your class.
  */
 namespace detail {
 #ifdef DEBUG
 static const int DEAD = 0xffffdead;
 #endif
 
 // This is used WeakPtr.h as well as this file.
 enum RefCountAtomicity
@@ -91,16 +95,19 @@ class RefCounted
       MOZ_ASSERT(refCnt > 0);
       return refCnt == 1;
     }
 
   private:
     mutable typename Conditional<Atomicity == AtomicRefCount, Atomic<int>, int>::Type refCnt;
 };
 
+#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \
+  const char* typeName() const { return #T; }
+
 }
 
 template<typename T>
 class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
 {
   public:
     ~RefCounted() {
       static_assert(IsBaseOf<RefCounted, T>::value,
@@ -296,16 +303,17 @@ byRef(RefPtr<T>& ptr)
 // Command line that builds these tests
 //
 //   cp RefPtr.h test.cc && g++ -g -Wall -pedantic -DDEBUG -o test test.cc && ./test
 
 using namespace mozilla;
 
 struct Foo : public RefCounted<Foo>
 {
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo)
   Foo() : dead(false) { }
   ~Foo() {
     MOZ_ASSERT(!dead);
     dead = true;
     numDestroyed++;
   }
 
   bool dead;
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -9,26 +9,31 @@
 /**
  * SupportsWeakPtr lets you have a pointer to an object 'Foo' without affecting
  * its lifetime. It works by creating a single shared reference counted object
  * (WeakReference) that each WeakPtr will access 'Foo' through. This lets 'Foo'
  * clear the pointer in the WeakReference without having to know about all of
  * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime
  * of 'Foo'.
  *
+ * Note that when deriving from SupportsWeakPtr you should add
+ * MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public section of your
+ * class, where ClassName is the name of your class.
+ *
  * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional
  * dereference, and an additional heap allocated pointer sized object shared
  * between all of the WeakPtrs.
  *
  * Example of usage:
  *
  *   // To have a class C support weak pointers, inherit from SupportsWeakPtr<C>.
  *   class C : public SupportsWeakPtr<C>
  *   {
  *    public:
+ *      MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
  *      int num;
  *      void act();
  *   };
  *
  *   C* ptr =  new C();
  *
  *   // Get weak pointers to ptr. The first time asWeakPtr is called
  *   // a reference counted WeakReference object is created that
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -4126,16 +4126,19 @@ pref("memory.ghost_window_timeout_second
 // Disable freeing dirty pages when minimizing memory.
 pref("memory.free_dirty_pages", false);
 
 // Disable the Linux-specific, system-wide memory reporter.
 #ifdef XP_LINUX
 pref("memory.system_memory_reporter", false);
 #endif
 
+// Don't dump memory reports on OOM, by default.
+pref("memory.dump_reports_on_oom", false);
+
 // Number of stack frames to capture in createObjectURL for about:memory.
 pref("memory.blob_report.stack_frames", 0);
 
 pref("social.enabled", false);
 // comma separated list of domain origins (e.g. https://domain.com) for
 // providers that can install from their own website without user warnings.
 // entries are
 pref("social.whitelist", "https://mozsocial.cliqz.com,https://now.msn.com,https://mixi.jp");
--- a/netwerk/base/src/nsAutodialQt.cpp
+++ b/netwerk/base/src/nsAutodialQt.cpp
@@ -23,17 +23,17 @@ nsresult
 nsAutodial::Init()
 {
   return NS_OK;
 }
 
 nsresult
 nsAutodial::DialDefault(const char16_t* hostName)
 {
-  if (nsQtNetworkManager::get()->openConnection(QString::fromUtf16(hostName))) {
+  if (nsQtNetworkManager::get()->openConnection(QString::fromUtf16((const ushort*)hostName))) {
     return NS_OK;
   }
 
   return NS_ERROR_FAILURE;
 }
 
 bool
 nsAutodial::ShouldDialOnNetworkError()
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -305,18 +305,16 @@ npnComplete:
     mNPNComplete = true;
     return true;
 }
 
 // called on the socket thread
 nsresult
 nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri)
 {
-    nsresult rv;
-
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnection::Activate [this=%p trans=%x caps=%x]\n",
          this, trans, caps));
 
     if (!trans->IsNullTransaction())
         mExperienced = true;
 
     mTransactionCaps = caps;
@@ -343,39 +341,38 @@ nsHttpConnection::Activate(nsAHttpTransa
     MOZ_ASSERT(!mIdleMonitoring, "Activating a connection with an Idle Monitor");
     mIdleMonitoring = false;
 
     // set mKeepAlive according to what will be requested
     mKeepAliveMask = mKeepAlive = (caps & NS_HTTP_ALLOW_KEEPALIVE);
 
     // need to handle HTTP CONNECT tunnels if this is the first time if
     // we are tunneling through a proxy
+    nsresult rv = NS_OK;
     if (mConnInfo->UsingConnect() && !mCompletedProxyConnect) {
         rv = SetupProxyConnect();
         if (NS_FAILED(rv))
             goto failed_activation;
         mProxyConnectInProgress = true;
     }
 
     // Clear the per activation counter
     mCurrentBytesRead = 0;
 
     // The overflow state is not needed between activations
     mInputOverflow = nullptr;
 
     mResponseTimeoutEnabled = mTransaction->ResponseTimeout() > 0 &&
                               mTransaction->ResponseTimeoutEnabled();
 
-    if (NS_SUCCEEDED(rv)) {
-        nsresult rv2 = StartShortLivedTCPKeepalives();
-        if (NS_WARN_IF(NS_FAILED(rv2))) {
-            LOG(("nsHttpConnection::Activate [%p] "
-                 "StartShortLivedTCPKeepalives failed rv2[0x%x]",
-                 this, rv2));
-        }
+    rv = StartShortLivedTCPKeepalives();
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        LOG(("nsHttpConnection::Activate [%p] "
+             "StartShortLivedTCPKeepalives failed rv[0x%x]",
+             this, rv));
     }
 
     rv = OnOutputStreamReady(mSocketOut);
 
 failed_activation:
     if (NS_FAILED(rv)) {
         mTransaction = nullptr;
     }
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -100,16 +100,17 @@ class DataChannelConnection: public nsIT
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
   class DataConnectionListener : public SupportsWeakPtr<DataConnectionListener>
   {
   public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(DataChannelConnection::DataConnectionListener)
     virtual ~DataConnectionListener() {}
 
     // Called when a the connection is open
     virtual void NotifyConnection() = 0;
 
     // Called when a the connection is lost/closed
     virtual void NotifyClosedConnection() = 0;
 
--- a/security/manager/ssl/src/SharedCertVerifier.h
+++ b/security/manager/ssl/src/SharedCertVerifier.h
@@ -10,16 +10,17 @@
 #include "mozilla/RefPtr.h"
 
 namespace mozilla { namespace psm {
 
 class SharedCertVerifier : public mozilla::psm::CertVerifier,
                            public mozilla::AtomicRefCounted<SharedCertVerifier>
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedCertVerifier)
   SharedCertVerifier(implementation_config ic,
 #ifndef NSS_NO_LIBPKIX
                      missing_cert_download_config ac, crl_download_config cdc,
 #endif
                      ocsp_download_config odc, ocsp_strict_config osc,
                      ocsp_get_config ogc)
     : mozilla::psm::CertVerifier(ic,
 #ifndef NSS_NO_LIBPKIX
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -116,17 +116,16 @@ extern PRLogModuleInfo* gPIPNSSLog;
 #endif
 
 nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
   : mFd(nullptr),
     mCertVerificationState(before_cert_verification),
     mSharedState(aState),
     mForSTARTTLS(false),
     mHandshakePending(true),
-    mHasCleartextPhase(false),
     mRememberClientAuthCertificate(false),
     mPreliminaryHandshakeDone(false),
     mNPNCompleted(false),
     mFalseStartCallbackCalled(false),
     mFalseStarted(false),
     mIsFullHandshake(false),
     mHandshakeCompleted(false),
     mJoined(false),
@@ -192,28 +191,16 @@ nsNSSSocketInfo::GetRememberClientAuthCe
 
 NS_IMETHODIMP
 nsNSSSocketInfo::SetRememberClientAuthCertificate(bool aRemember)
 {
   mRememberClientAuthCertificate = aRemember;
   return NS_OK;
 }
 
-void
-nsNSSSocketInfo::SetHasCleartextPhase(bool aHasCleartextPhase)
-{
-  mHasCleartextPhase = aHasCleartextPhase;
-}
-
-bool
-nsNSSSocketInfo::GetHasCleartextPhase()
-{
-  return mHasCleartextPhase;
-}
-
 NS_IMETHODIMP
 nsNSSSocketInfo::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks)
 {
   *aCallbacks = mCallbacks;
   NS_IF_ADDREF(*aCallbacks);
   return NS_OK;
 }
 
@@ -402,28 +389,26 @@ nsNSSSocketInfo::JoinConnection(const ns
     return NS_OK;
 
   // All tests pass - this is joinable
   mJoined = true;
   *_retval = true;
   return NS_OK;
 }
 
-nsresult
-nsNSSSocketInfo::GetForSTARTTLS(bool* aForSTARTTLS)
+bool
+nsNSSSocketInfo::GetForSTARTTLS()
 {
-  *aForSTARTTLS = mForSTARTTLS;
-  return NS_OK;
+  return mForSTARTTLS;
 }
 
-nsresult
+void
 nsNSSSocketInfo::SetForSTARTTLS(bool aForSTARTTLS)
 {
   mForSTARTTLS = aForSTARTTLS;
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::ProxyStartSSL()
 {
   return ActivateSSL();
 }
 
@@ -1000,17 +985,17 @@ retryDueToTLSIntolerance(PRErrorCode err
       // resets, because connection resets have too many false positives,
       // and we want to maximize how often we send TLS 1.0+ with extensions
       // if at all reasonable. Unfortunately, it appears we have to allow
       // fallback from TLS 1.2 and TLS 1.1 for connection resets due to bad
       // servers and possibly bad intermediaries.
     conditional:
       if ((err == PR_CONNECT_RESET_ERROR &&
            range.max <= SSL_LIBRARY_VERSION_TLS_1_0) ||
-          socketInfo->GetHasCleartextPhase()) {
+          socketInfo->GetForSTARTTLS()) {
         return false;
       }
       break;
 
     default:
       return false;
   }
 
@@ -2296,17 +2281,16 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
                        const char* proxyHost, const char* host, int32_t port,
                        nsNSSSocketInfo* infoObject)
 {
   nsNSSShutDownPreventionLock locker;
   if (forSTARTTLS || proxyHost) {
     if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
       return NS_ERROR_FAILURE;
     }
-    infoObject->SetHasCleartextPhase(true);
   }
 
   // Let's see if we're trying to connect to a site we know is
   // TLS intolerant.
   nsAutoCString key;
   key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port);
 
   SSLVersionRange range;
--- a/security/manager/ssl/src/nsNSSIOLayer.h
+++ b/security/manager/ssl/src/nsNSSIOLayer.h
@@ -30,30 +30,27 @@ class nsNSSSocketInfo : public mozilla::
 {
 public:
   nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSISSLSOCKETCONTROL
   NS_DECL_NSICLIENTAUTHUSERDECISION
 
-  nsresult SetForSTARTTLS(bool aForSTARTTLS);
-  nsresult GetForSTARTTLS(bool* aForSTARTTLS);
+  void SetForSTARTTLS(bool aForSTARTTLS);
+  bool GetForSTARTTLS();
 
   nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
   nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
 
   bool IsHandshakePending() const { return mHandshakePending; }
   void SetHandshakeNotPending() { mHandshakePending = false; }
 
   void GetPreviousCert(nsIX509Cert** _result);
 
-  void SetHasCleartextPhase(bool aHasCleartextPhase);
-  bool GetHasCleartextPhase();
-
   void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; }
   SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; };
 
   PRStatus CloseSocketAndDestroy(
                 const nsNSSShutDownPreventionLock& proofOfLock);
 
   void SetNegotiatedNPN(const char* value, uint32_t length);
 
@@ -116,17 +113,16 @@ private:
   PRFileDesc* mFd;
 
   CertVerificationState mCertVerificationState;
 
   mozilla::psm::SharedSSLState& mSharedState;
   bool mForSTARTTLS;
   SSLVersionRange mTLSVersionRange;
   bool mHandshakePending;
-  bool mHasCleartextPhase;
   bool mRememberClientAuthCertificate;
   bool mPreliminaryHandshakeDone; // after false start items are complete
 
   nsresult ActivateSSL();
 
   nsCString mNegotiatedNPN;
   bool      mNPNCompleted;
   bool      mFalseStartCallbackCalled;
--- a/testing/marionette/client/marionette/tests/unit/test_session.py
+++ b/testing/marionette/client/marionette/tests/unit/test_session.py
@@ -36,20 +36,22 @@ class TestCapabilities(marionette_test.M
         super(TestCapabilities, self).setUp()
         self.caps = self.marionette.session_capabilities
         self.marionette.set_context("chrome")
         self.appinfo = self.marionette.execute_script(
             "return Services.appinfo")
 
     def test_mandates_capabilities(self):
         self.assertIn("browserName", self.caps)
+        self.assertIn("browserVersion", self.caps)
         self.assertIn("platformName", self.caps)
         self.assertIn("platformVersion", self.caps)
 
         self.assertEqual(self.caps["browserName"], self.appinfo["name"])
+        self.assertEqual(self.caps["browserVersion"], self.appinfo["version"])
         self.assertEqual(self.caps["platformName"], self.appinfo["OS"].upper())
         self.assertEqual(self.caps["platformVersion"],
                          self.appinfo["platformVersion"])
 
     def test_supported_features(self):
         self.assertIn("cssSelectorsEnabled", self.caps)
         self.assertIn("handlesAlerts", self.caps)
         self.assertIn("javascriptEnabled", self.caps)
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -550,16 +550,17 @@ MarionetteServerConnection.prototype = {
     this.command_id = this.getCommandId();
 
     let isB2G = appName == "B2G";
     let platformName = Services.appinfo.OS.toUpperCase();
 
     let caps = {
       // Mandated capabilities
       "browserName": appName,
+      "browserVersion": Services.appinfo.version,
       "platformName": platformName,
       "platformVersion": Services.appinfo.platformVersion,
 
       // Supported features
       "cssSelectorsEnabled": true,
       "handlesAlerts": false,
       "javascriptEnabled": true,
       "nativeEvents": false,
@@ -2485,16 +2486,17 @@ MarionetteServerConnection.prototype.req
   "importScript": MarionetteServerConnection.prototype.importScript,
   "clearImportedScripts": MarionetteServerConnection.prototype.clearImportedScripts,
   "getAppCacheStatus": MarionetteServerConnection.prototype.getAppCacheStatus,
   "close": MarionetteServerConnection.prototype.close,
   "closeWindow": MarionetteServerConnection.prototype.close,  // deprecated
   "setTestName": MarionetteServerConnection.prototype.setTestName,
   "takeScreenshot": MarionetteServerConnection.prototype.takeScreenshot,
   "screenShot": MarionetteServerConnection.prototype.takeScreenshot,  // deprecated
+  "screenshot": MarionetteServerConnection.prototype.takeScreenshot,  // Selenium 2 compat
   "addCookie": MarionetteServerConnection.prototype.addCookie,
   "getCookies": MarionetteServerConnection.prototype.getCookies,
   "getAllCookies": MarionetteServerConnection.prototype.getCookies,  // deprecated
   "deleteAllCookies": MarionetteServerConnection.prototype.deleteAllCookies,
   "deleteCookie": MarionetteServerConnection.prototype.deleteCookie,
   "getActiveElement": MarionetteServerConnection.prototype.getActiveElement,
   "getScreenOrientation": MarionetteServerConnection.prototype.getScreenOrientation,
   "setScreenOrientation": MarionetteServerConnection.prototype.setScreenOrientation
--- a/testing/mochitest/runtestsb2g.py
+++ b/testing/mochitest/runtestsb2g.py
@@ -305,23 +305,27 @@ def run_remote_mochitests(parser, option
         kwargs['homedir'] = options.b2gPath
     if options.marionette:
         host, port = options.marionette.split(':')
         kwargs['host'] = host
         kwargs['port'] = int(port)
 
     marionette = Marionette.getMarionetteOrExit(**kwargs)
 
-    # create the DeviceManager
-    kwargs = {'adbPath': options.adbPath,
-              'deviceRoot': options.remoteTestRoot}
-    if options.deviceIP:
-        kwargs.update({'host': options.deviceIP,
-                       'port': options.devicePort})
-    dm = DeviceManagerADB(**kwargs)
+    if options.emulator:
+        dm = marionette.emulator.dm
+    else:
+        # create the DeviceManager
+        kwargs = {'adbPath': options.adbPath,
+                  'deviceRoot': options.remoteTestRoot}
+        if options.deviceIP:
+            kwargs.update({'host': options.deviceIP,
+                           'port': options.devicePort})
+        dm = DeviceManagerADB(**kwargs)
+
     options = parser.verifyRemoteOptions(options)
     if (options == None):
         print "ERROR: Invalid options specified, use --help for a list of valid options"
         sys.exit(1)
 
     mochitest = B2GDeviceMochitest(marionette, dm, options.profile_data_dir, options.xrePath,
                                    remote_test_root=options.remoteTestRoot,
                                    remote_log_file=options.remoteLogFile)
--- a/testing/xpcshell/runtestsb2g.py
+++ b/testing/xpcshell/runtestsb2g.py
@@ -178,23 +178,26 @@ def main():
         host, port = options.address.split(':')
         kwargs['host'] = host
         kwargs['port'] = int(port)
         kwargs['baseurl'] = 'http://%s:%d/' % (host, int(port))
         if options.emulator:
             kwargs['connectToRunningEmulator'] = True
     marionette = Marionette(**kwargs)
 
-    # Create the DeviceManager instance
-    kwargs = {'adbPath': options.adb_path}
-    if options.deviceIP:
-        kwargs['host'] = options.deviceIP
-        kwargs['port'] = options.devicePort
-    kwargs['deviceRoot'] = options.remoteTestRoot
-    dm = devicemanagerADB.DeviceManagerADB(**kwargs)
+    if options.emulator:
+        dm = marionette.emulator.dm
+    else:
+        # Create the DeviceManager instance
+        kwargs = {'adbPath': options.adb_path}
+        if options.deviceIP:
+            kwargs['host'] = options.deviceIP
+            kwargs['port'] = options.devicePort
+        kwargs['deviceRoot'] = options.remoteTestRoot
+        dm = devicemanagerADB.DeviceManagerADB(**kwargs)
 
     if not options.remoteTestRoot:
         options.remoteTestRoot = dm.getDeviceRoot()
     xpcsh = B2GXPCShellRemote(dm, options, args)
 
     # we don't run concurrent tests on mobile
     options.sequential = True
 
--- a/toolkit/components/downloads/ApplicationReputation.cpp
+++ b/toolkit/components/downloads/ApplicationReputation.cpp
@@ -38,16 +38,17 @@
 #include "nsReadableUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOMStrings.h"
 
 using mozilla::Preferences;
+using mozilla::TimeStamp;
 using mozilla::Telemetry::Accumulate;
 using safe_browsing::ClientDownloadRequest;
 using safe_browsing::ClientDownloadRequest_SignatureInfo;
 using safe_browsing::ClientDownloadRequest_CertificateChain;
 
 // Preferences that we need to initialize the query. We may need another
 // preference than browser.safebrowsing.malware.enabled, or simply use
 // browser.safebrowsing.appRepURL. See bug 887041.
--- a/toolkit/components/remote/nsQtRemoteService.cpp
+++ b/toolkit/components/remote/nsQtRemoteService.cpp
@@ -1,34 +1,35 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=8:
  */
 /* 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 <QWidget>
+#include <QWindow>
 #include "nsQtRemoteService.h"
 
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/X11Util.h"
 #include "nsIServiceManager.h"
 #include "nsIAppShellService.h"
 
 #include "nsCOMPtr.h"
 
 /**
   Helper class which is used to receive notification about property changes
 */
-class MozQRemoteEventHandlerWidget: public QWidget {
+class MozQRemoteEventHandlerWidget: public QWindow {
 public:
   /**
     Constructor
     @param aRemoteService remote service, which is notified about atom change
   */
   MozQRemoteEventHandlerWidget(nsQtRemoteService &aRemoteService);
+  virtual ~MozQRemoteEventHandlerWidget() {}
 
 protected:
   /**
     Event filter, which receives all XEvents
     @return false which continues event handling
   */
   bool x11Event(XEvent *);
 
--- a/toolkit/components/remote/nsQtRemoteService.h
+++ b/toolkit/components/remote/nsQtRemoteService.h
@@ -16,22 +16,21 @@ class RemoteEventHandlerWidget;
 class nsQtRemoteService : public nsXRemoteService
 {
 public:
   // We will be a static singleton, so don't use the ordinary methods.
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREMOTESERVICE  
 
   nsQtRemoteService();
+  virtual ~nsQtRemoteService() { };
 
 private:
-  ~nsQtRemoteService() { };
-
   virtual void SetDesktopStartupIDOrTimestamp(const nsACString& aDesktopStartupID,
                                               uint32_t aTimestamp);
 
   void PropertyNotifyEvent(XEvent *evt);
   friend class MozQRemoteEventHandlerWidget;
 
-  QWidget *mServerWindow;
+  QWindow *mServerWindow;
 };
 
 #endif // __nsQtRemoteService_h__
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -957,17 +957,17 @@ nsFormFillController::MouseDown(nsIDOMEv
   if (!mouseEvent)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMHTMLInputElement> targetInput = do_QueryInterface(
     aEvent->InternalDOMEvent()->GetTarget());
   if (!targetInput)
     return NS_OK;
 
-  uint16_t button;
+  int16_t button;
   mouseEvent->GetButton(&button);
   if (button != 0)
     return NS_OK;
 
   bool isOpen = false;
   GetPopupOpen(&isOpen);
   if (isOpen)
     return NS_OK;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1,21 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; 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/. */
 
 #if defined(MOZ_WIDGET_QT)
-#include <QApplication>
+#include <QGuiApplication>
 #include <QStringList>
 #include "nsQAppInstance.h"
-#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
-#include <QInputContextFactory>
-#include <QInputContext>
-#endif
 #endif // MOZ_WIDGET_QT
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
--- a/toolkit/xre/nsQAppInstance.cpp
+++ b/toolkit/xre/nsQAppInstance.cpp
@@ -1,48 +1,31 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 et sw=2 tw=80: */
 /* 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 "nsQAppInstance.h"
-#include <QApplication>
-#ifdef MOZ_ENABLE_MEEGOTOUCH
-#include <MComponentData>
-#include <MApplicationService>
-#endif
+#include <QGuiApplication>
 #include "prenv.h"
 #include "nsXPCOMPrivate.h"
 #include <stdlib.h>
 
-QApplication *nsQAppInstance::sQAppInstance = nullptr;
-#ifdef MOZ_ENABLE_MEEGOTOUCH
-MComponentData* nsQAppInstance::sMComponentData = nullptr;
-#endif
+QGuiApplication *nsQAppInstance::sQAppInstance = nullptr;
 int nsQAppInstance::sQAppRefCount = 0;
 
 void nsQAppInstance::AddRef(int& aArgc, char** aArgv, bool aDefaultProcess) {
   if (qApp)
     return;
   if (!sQAppInstance) {
-#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
-    const char *graphicsSystem = getenv("MOZ_QT_GRAPHICSSYSTEM");
-    if (graphicsSystem) {
-      QApplication::setGraphicsSystem(QString(graphicsSystem));
-    }
-#endif
     mozilla::SetICUMemoryFunctions();
-    sQAppInstance = new QApplication(aArgc, aArgv);
+    sQAppInstance = new QGuiApplication(aArgc, aArgv);
   }
   sQAppRefCount++;
 }
 
 void nsQAppInstance::Release(void) {
   if (sQAppInstance && !--sQAppRefCount) {
-#ifdef MOZ_ENABLE_MEEGOTOUCH
-    delete sMComponentData;
-    sMComponentData = nullptr;
-#endif
     delete sQAppInstance;
     sQAppInstance = nullptr;
   }
 }
--- a/toolkit/xre/nsQAppInstance.h
+++ b/toolkit/xre/nsQAppInstance.h
@@ -6,25 +6,23 @@
 
 #ifndef nsQAppInstance_h
 #define nsQAppInstance_h
 
 // declared in nsAppRunner.cpp
 extern int    gArgc;
 extern char **gArgv;
 
-class QApplication;
-class MComponentData;
+class QGuiApplication;
 class nsQAppInstance
 {
 public:
   static void AddRef(int& aArgc = gArgc,
                      char** aArgv = gArgv,
                      bool aDefaultProcess = false);
   static void Release(void);
 
 private:
-  static QApplication *sQAppInstance;
-  static MComponentData* sMComponentData;
+  static QGuiApplication *sQAppInstance;
   static int sQAppRefCount;
 };
 
 #endif /* nsQAppInstance_h */
--- a/tools/profiler/PseudoStack.h
+++ b/tools/profiler/PseudoStack.h
@@ -377,17 +377,18 @@ public:
 
   void sampleRuntime(JSRuntime *runtime) {
     mRuntime = runtime;
     if (!runtime) {
       // JS shut down
       return;
     }
 
-    JS_STATIC_ASSERT(sizeof(mStack[0]) == sizeof(js::ProfileEntry));
+    static_assert(sizeof(mStack[0]) == sizeof(js::ProfileEntry),
+                  "mStack must be binary compatible with js::ProfileEntry.");
     js::SetRuntimeProfilingStack(runtime,
                                  (js::ProfileEntry*) mStack,
                                  (uint32_t*) &mStackPointer,
                                  uint32_t(mozilla::ArrayLength(mStack)));
     if (mStartJSSampling)
       enableJSSampling();
   }
   void enableJSSampling() {
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -184,26 +184,28 @@ private:
     nsCString mManifestHashValue;
     nsCString mOldManifestHashValue;
 };
 
 class nsOfflineCacheUpdateOwner
   : public mozilla::SupportsWeakPtr<nsOfflineCacheUpdateOwner>
 {
 public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdateOwner)
     virtual ~nsOfflineCacheUpdateOwner() {}
     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0;
 };
 
 class nsOfflineCacheUpdate MOZ_FINAL : public nsIOfflineCacheUpdate
                                      , public nsIOfflineCacheUpdateObserver
                                      , public nsIRunnable
                                      , public nsOfflineCacheUpdateOwner
 {
 public:
+    MOZ_DECLARE_REFCOUNTED_TYPENAME(nsOfflineCacheUpdate)
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOFFLINECACHEUPDATE
     NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
     NS_DECL_NSIRUNNABLE
 
     nsOfflineCacheUpdate();
     ~nsOfflineCacheUpdate();
 
--- a/widget/cocoa/OSXNotificationCenter.mm
+++ b/widget/cocoa/OSXNotificationCenter.mm
@@ -110,16 +110,17 @@ typedef NSInteger NSUserNotificationActi
 }
 
 @end
 
 namespace mozilla {
 
 class OSXNotificationInfo : public RefCounted<OSXNotificationInfo> {
 public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(OSXNotificationInfo)
   OSXNotificationInfo(NSString *name, nsIObserver *observer,
                       const nsAString & alertCookie);
   ~OSXNotificationInfo();
 
   NSString *mName;
   nsCOMPtr<nsIObserver> mObserver;
   nsString mCookie;
   nsRefPtr<imgRequestProxy> mIconRequest;
--- a/widget/nsWidgetInitData.h
+++ b/widget/nsWidgetInitData.h
@@ -97,17 +97,18 @@ struct nsWidgetInitData {
       mDropShadow(false),
       mListenForResizes(false),
       mUnicode(true),
       mRTL(false),
       mNoAutoHide(false),
       mIsDragPopup(false),
       mIsAnimationSuppressed(false),
       mSupportTranslucency(false),
-      mMouseTransparent(false)
+      mMouseTransparent(false),
+      mRequireOffMainThreadCompositing(false)
   {
   }
 
   nsWindowType  mWindowType;
   nsBorderStyle mBorderStyle;
   nsPopupType   mPopupHint;
   nsPopupLevel  mPopupLevel;
   // when painting exclude area occupied by child windows and sibling windows
@@ -119,11 +120,14 @@ struct nsWidgetInitData {
   bool          mIsDragPopup;  // true for drag feedback panels
   // true if window creation animation is suppressed, e.g. for session restore
   bool          mIsAnimationSuppressed;
   // true if the window should support an alpha channel, if available.
   bool          mSupportTranslucency;
   // true if the window should be transparent to mouse events. Currently this is
   // only valid for eWindowType_popup widgets
   bool          mMouseTransparent;
+  // Windows with out-of-process tabs always require OMTC. This flag designates
+  // such windows.
+  bool          mRequireOffMainThreadCompositing;
 };
 
 #endif // nsWidgetInitData_h__
--- a/widget/qt/Makefile.in
+++ b/widget/qt/Makefile.in
@@ -1,9 +1,9 @@
 #
 # 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 $(topsrcdir)/config/rules.mk
 
-CXXFLAGS	+= $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
-CFLAGS		+= $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
+CXXFLAGS	+= $(MOZ_QT_CFLAGS) $(MOZ_CAIRO_CFLAGS)
+CFLAGS		+= $(MOZ_QT_CFLAGS) $(MOZ_CAIRO_CFLAGS)
deleted file mode 100644
--- a/widget/qt/faststartupqt/Makefile.in
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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/.
-
-DIST_INSTALL = 1
-STL_FLAGS=
-
-EXPORT_SOURCES = \
-	$(topsrcdir)/widget/qt/moziqwidget.h \
-	$(topsrcdir)/toolkit/xre/nsQAppInstance.h \
-	$(topsrcdir)/toolkit/xre/nsQAppInstance.cpp \
-	$(topsrcdir)/widget/qt/mozqglwidgetwrapper.h \
-	$(topsrcdir)/widget/qt/mozqglwidgetwrapper.cpp
-
-GARBAGE += $(EXPORT_SOURCES)
-export:: $(EXPORT_SOURCES)
-	$(INSTALL) $^ .
-
-include $(topsrcdir)/config/rules.mk
-
-CXXFLAGS += \
-	$(MOZ_QT_CFLAGS) \
-	$(NULL)
deleted file mode 100644
--- a/widget/qt/faststartupqt/moz.build
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-GENERATED_SOURCES += [
-    'moc_moziqwidget.cpp',
-    'moc_nsFastStartupQt.cpp',
-    'mozqwidgetfast.cpp',
-]
-
-SOURCES += [
-    TOPSRCDIR + '/toolkit/xre/nsQAppInstance.cpp',
-    TOPSRCDIR + '/widget/qt/mozqglwidgetwrapper.cpp',
-]
-
-SOURCES += [
-    'nsFastStartupQt.cpp',
-]
-
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
-    '/widget/qt',
-    '/xpcom/build',
-]
-
-
-DEFINES['LIBRARY_FILENAME'] = '%s%s%s' % (
-    CONFIG['DLL_PREFIX'],
-    LIBRARY_NAME,
-    CONFIG['DLL_SUFFIX']
-)
-
-DEFINES['MOZ_NO_MOZALLOC'] = True
-DEFINES['XPCOM_GLUE'] = True
deleted file mode 100644
--- a/widget/qt/faststartupqt/mozqwidgetfast.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=4 et sw=4 tw=80: */
-/* 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 <QtCore/QUrl>
-#include "mozqwidgetfast.h"
-#include "nsFastStartupQt.h"
-#include "nsIFile.h"
-#include "nsString.h"
-#include "BinaryPath.h"
-
-#define TOOLBAR_SPLASH "toolbar_splash.png"
-#define FAVICON_SPLASH "favicon32.png"
-#define DRAWABLE_PATH "res/drawable/"
-
-MozQWidgetFast::MozQWidgetFast(nsWindow* aReceiver, QGraphicsItem* aParent)
-{
-  setParentItem(aParent);
-  char exePath[MAXPATHLEN];
-  QStringList arguments = qApp->arguments();
-  nsresult rv =
-    mozilla::BinaryPath::Get(arguments.at(0).toLocal8Bit().constData(),
-                             exePath);
-  if (NS_FAILED(rv)) {
-    printf("Cannot read default path\n");
-    return;
-  }
-  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
-  if (!lastSlash ||
-      (lastSlash - exePath > int(MAXPATHLEN - sizeof(XPCOM_DLL) - 1))) {
-     return;
-  }
-  strcpy(++lastSlash, "/");
-  QString resourcePath(QString((const char*)&exePath) + DRAWABLE_PATH);
-  mToolbar.load(resourcePath + TOOLBAR_SPLASH);
-  mIcon.load(resourcePath + FAVICON_SPLASH);
-  for (int i = 1; i < arguments.size(); i++) {
-    QUrl url = QUrl::fromUserInput(arguments.at(i));
-    if (url.isValid()) {
-      mUrl = url.toString();
-    }
-  }
-}
-
-void MozQWidgetFast::paint(QPainter* aPainter,
-                           const QStyleOptionGraphicsItem*,
-                           QWidget*)
-{
-  // toolbar height
-  int toolbarHeight = 80;
-  // Offset of favicon starting from left toolbar edge
-  int faviconOffset = 25;
-  // favicon size
-  int faviconSize = 32;
-  // width of left and right TOOLBAR_SPLASH part
-  // |------------------------------|
-  // |LeftPart|tile...part|RightPart|
-  float toolbarPartWidth = 77;
-  // width of TOOLBAR_SPLASH part after toolbarPartWidth,
-  // that can be used for tiled toolbar area
-  int tileWidth = 2;
-  // Paint left toolbar part
-  aPainter->drawPixmap(QRect(0, 0, toolbarPartWidth, toolbarHeight),
-                       mToolbar, QRect(0, 0, toolbarPartWidth, toolbarHeight));
-
-  // Paint Tile pixmap of middle toolbar part
-  QPixmap tile(tileWidth, toolbarHeight);
-  QPainter p(&tile);
-  p.drawPixmap(QRect(0, 0, tileWidth, toolbarHeight), mToolbar,
-               QRect(toolbarPartWidth, 0, tileWidth, toolbarHeight));
-  aPainter->drawTiledPixmap(QRect(toolbarPartWidth, 0, rect().width() - toolbarPartWidth * 2,
-                                  toolbarHeight),
-                            tile);
-  // Paint Favicon
-  aPainter->drawPixmap(QRect(faviconOffset, faviconOffset,
-                             faviconSize, faviconSize),
-                       mIcon);
-  if (!mUrl.isEmpty()) {
-    // Height or URL string (font height)
-    float urlHeight = 24.0f;
-    // Start point of URL string, relative to window 0,0
-    int urlOffsetX = 80;
-    int urlOffsetY = 48;
-    QFont font = aPainter->font();
-    font.setPixelSize(urlHeight);
-    font.setFamily(QString("Nokia Sans"));
-    font.setKerning(true);
-    aPainter->setFont(font);
-    aPainter->setRenderHint(QPainter::TextAntialiasing, true);
-    aPainter->drawText(urlOffsetX, urlOffsetY,
-                       aPainter->fontMetrics().elidedText(mUrl, Qt::ElideRight, rect().width() - urlOffsetX * 2));
-  }
-
-  // Paint Right toolbar part
-  aPainter->drawPixmap(QRect(rect().width() - toolbarPartWidth,
-                             0, toolbarPartWidth,
-                             toolbarHeight),
-                       mToolbar,
-                       QRect(mToolbar.width() - toolbarPartWidth, 0,
-                             toolbarPartWidth, toolbarHeight));
-
-  nsFastStartup::GetSingleton()->painted();
-}
deleted file mode 100644
--- a/widget/qt/faststartupqt/mozqwidgetfast.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=4 et sw=4 tw=80: */
-/* 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 MOZQWIDGETFAST_H
-#define MOZQWIDGETFAST_H
-
-#include <QtCore/QObject>
-#include "moziqwidget.h"
-
-class MozQWidgetFast : public IMozQWidget
-{
-public:
-    MozQWidgetFast(nsWindow* aReceiver, QGraphicsItem *aParent);
-    ~MozQWidgetFast() {}
-
-protected:
-    virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
-
-private:
-    QPixmap mToolbar;
-    QPixmap mIcon;
-    QString mUrl;
-};
-
-#endif
deleted file mode 100644
--- a/widget/qt/faststartupqt/nsFastStartupQt.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=4 et sw=4 tw=80: */
-/* 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 <QApplication>
-#include "nsQAppInstance.h"
-#include <QtOpenGL/QGLWidget>
-#include <QThread>
-#if defined MOZ_ENABLE_MEEGOTOUCH
-#include <MScene>
-#endif
-#include "moziqwidget.h"
-#include "mozqwidgetfast.h"
-#include "nsFastStartupQt.h"
-#include "nsXPCOMGlue.h"
-#include "nsXULAppAPI.h"
-
-
-static nsFastStartup* sFastStartup = nullptr;
-
-void
-GeckoThread::run()
-{
-  Q_EMIT symbolsLoadingFinished(mFunc(mExecPath));
-}
-
-void
-nsFastStartup::symbolsLoadingFinished(bool preloaded)
-{
-  mSymbolsLoaded = preloaded;
-  if (mWidgetPainted && mSymbolsLoaded) {
-    mLoop.quit();
-  }
-}
-
-void nsFastStartup::painted()
-{
-  mWidgetPainted = true;
-  if (mWidgetPainted && mSymbolsLoaded) {
-    mLoop.quit();
-  }
-}
-
-MozGraphicsView*
-nsFastStartup::GetStartupGraphicsView(QWidget* parentWidget, IMozQWidget* aTopChild)
-{
-  MozGraphicsView* view = nullptr;
-  if (sFastStartup && sFastStartup->mGraphicsView) {
-    view = sFastStartup->mGraphicsView;
-  } else {
-    view = new MozGraphicsView(parentWidget);
-    Qt::WindowFlags flags = Qt::Widget;
-    view->setWindowFlags(flags);
-  }
-  view->SetTopLevel(aTopChild, parentWidget);
-
-  return view;
-}
-
-nsFastStartup*
-nsFastStartup::GetSingleton()
-{
-  return sFastStartup;
-}
-
-nsFastStartup::nsFastStartup()
- : mGraphicsView(0)
- , mFakeWidget(0)
- , mSymbolsLoaded(false)
- , mWidgetPainted(false)
- , mThread(0)
-
-{
-  sFastStartup = this;
-}
-
-nsFastStartup::~nsFastStartup()
-{
-  nsQAppInstance::Release();
-  sFastStartup = 0;
-}
-
-void
-nsFastStartup::RemoveFakeLayout()
-{
-  if (mFakeWidget && mGraphicsView) {
-    mGraphicsView->scene()->removeItem(mFakeWidget);
-    mFakeWidget->deleteLater();
-    mFakeWidget = 0;
-    // Forget GraphicsView, ownership moved to nsIWidget
-    mGraphicsView = 0;
-  }
-}
-
-bool
-nsFastStartup::CreateFastStartup(int& argc, char ** argv,
-                                 const char* execPath,
-                                 GeckoLoaderFunc aFunc)
-{
-  gArgc = argc;
-  gArgv = argv;
-  // Create main QApplication instance
-  nsQAppInstance::AddRef(argc, argv, true);
-  // Create symbols loading thread
-  mThread = new GeckoThread();
-  // Setup thread loading finished callbacks
-  connect(mThread, SIGNAL(symbolsLoadingFinished(bool)),
-          this, SLOT(symbolsLoadingFinished(bool)));
-  mThread->SetLoader(aFunc, execPath);
-  // Create Static UI widget and view
-  IMozQWidget* fakeWidget = new MozQWidgetFast(nullptr, nullptr);
-  mGraphicsView = GetStartupGraphicsView(nullptr, fakeWidget);
-  mFakeWidget = fakeWidget;
-
-  mThread->start();
-  mGraphicsView->showNormal();
-
-  // Start native loop in order to get view opened and painted once
-  // Will block CreateFastStartup function and
-  // exit when symbols are loaded and Static UI shown
-  mLoop.exec();
-
-  return true;
-}
deleted file mode 100644
--- a/widget/qt/faststartupqt/nsFastStartupQt.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=4 et sw=4 tw=80: */
-/* 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 FAST_STARTUP_H
-#define FAST_ST