Merge inbound to m-c
authorWes Kocher <wkocher@mozilla.com>
Tue, 10 Dec 2013 16:42:47 -0800
changeset 160175 3ea3d3baa67bb33c82e46e0b37af61e5286d23f4
parent 160174 410b864e932081b0e17548928bfbb66c35f8cbb4 (current diff)
parent 160141 800d25188e9fc065bcbf66584220be4fe85d1734 (diff)
child 160176 5dc2bc88108d38dc3baaa0782c0978cab8a6d089
child 160252 ca62c888ae7d303611b1eb8a898083e075001804
child 160268 d6cbcd3000c0704deb8dc1ffe39ca9715a20433b
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
milestone29.0a1
Merge inbound to m-c
media/libvpx/vpx_config_armv7-android-gcc.c
media/libvpx/vpx_config_c.c
media/libvpx/vpx_config_generic-gnu.c
media/libvpx/vpx_config_x86-darwin9-gcc.c
media/libvpx/vpx_config_x86-linux-gcc.c
media/libvpx/vpx_config_x86-win32-vs8.c
media/libvpx/vpx_config_x86_64-darwin9-gcc.c
media/libvpx/vpx_config_x86_64-linux-gcc.c
media/libvpx/vpx_config_x86_64-win64-vs8.c
media/libvpx/vpx_x86-darwin9-gcc.c
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -653,40 +653,25 @@ HyperTextAccessible::FindOffset(int32_t 
     frameAtOffset->PeekOffset(&pos);
   }
   if (!pos.mResultContent)
     return -1;
 
   // Turn the resulting node and offset into a hyperTextOffset
   // If finalAccessible is nullptr, then DOMPointToHypertextOffset() searched
   // through the hypertext children without finding the node/offset position.
-  int32_t hyperTextOffset;
+  int32_t hyperTextOffset = 0;
   Accessible* finalAccessible =
     DOMPointToHypertextOffset(pos.mResultContent, pos.mContentOffset,
                               &hyperTextOffset, aDirection == eDirNext);
 
-  if (!finalAccessible && aDirection == eDirPrevious) {
-    // If we reached the end during search, this means we didn't find the DOM point
-    // and we're actually at the start of the paragraph
-    hyperTextOffset = 0;
-  }  
-  else if (aAmount == eSelectBeginLine) {
-    Accessible* firstChild = mChildren.SafeElementAt(0, nullptr);
-    // For line selection with needsStart, set start of line exactly to line break
-    if (pos.mContentOffset == 0 && firstChild &&
-        firstChild->Role() == roles::STATICTEXT &&
-        static_cast<int32_t>(nsAccUtils::TextLength(firstChild)) == hyperTextOffset) {
-      // XXX Bullet hack -- we should remove this once list bullets use anonymous content
-      hyperTextOffset = 0;
-    }
-    if (aWordMovementType != eStartWord && aAmount != eSelectBeginLine &&
-        hyperTextOffset > 0) {
-      -- hyperTextOffset;
-    }
-  }
+  // If we reached the end during search, this means we didn't find the DOM point
+  // and we're actually at the start of the paragraph
+  if (!finalAccessible && aDirection == eDirPrevious)
+    return 0;
 
   return hyperTextOffset;
 }
 
 int32_t
 HyperTextAccessible::FindLineBoundary(int32_t aOffset,
                                       EWhichLineBoundary aWhichLineBoundary)
 {
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -427,19 +427,19 @@ protected:
    */
   int32_t FindLineBoundary(int32_t aOffset,
                            EWhichLineBoundary aWhichLineBoundary);
 
   /**
    * Return an offset corresponding to the given direction and selection amount
    * relative the given offset. A helper used to find word or line boundaries.
    */
-  int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
-                     nsSelectionAmount aAmount,
-                     EWordMovementType aWordMovementType = eDefaultBehavior);
+  virtual int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
+                             nsSelectionAmount aAmount,
+                             EWordMovementType aWordMovementType = eDefaultBehavior);
 
   /**
     * Provides information for substring that is defined by the given start
     * and end offsets for this hyper text.
     *
     * @param  aStartOffset  [inout] the start offset into the hyper text. This
     *                       is also an out parameter used to return the offset
     *                       into the start frame's rendered text content
--- a/accessible/src/html/HTMLListAccessible.cpp
+++ b/accessible/src/html/HTMLListAccessible.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=2 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 "HTMLListAccessible.h"
 
 #include "DocAccessible.h"
+#include "nsAccUtils.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsBlockFrame.h"
 #include "nsBulletFrame.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -92,16 +93,43 @@ HTMLLIAccessible::GetBounds(int32_t* aX,
   rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aWidth += *aX - bulletX;
   *aX = bulletX; // Move x coordinate of list item over to cover bullet as well
   return NS_OK;
 }
 
+int32_t
+HTMLLIAccessible::FindOffset(int32_t aOffset, nsDirection aDirection,
+                             nsSelectionAmount aAmount,
+                             EWordMovementType aWordMovementType)
+{
+  Accessible* child = GetChildAtOffset(aOffset);
+  if (!child)
+    return -1;
+
+  if (child != mBullet) {
+    if (aDirection == eDirPrevious &&
+        (aAmount == eSelectBeginLine || aAmount == eSelectLine))
+      return 0;
+
+    return HyperTextAccessible::FindOffset(aOffset, aDirection,
+                                           aAmount, aWordMovementType);
+  }
+
+  if (aDirection == eDirPrevious)
+    return 0;
+
+  if (aAmount == eSelectEndLine || aAmount == eSelectLine)
+    return CharacterCount();
+
+  return nsAccUtils::TextLength(child);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLIAccessible: public
 
 void
 HTMLLIAccessible::UpdateBullet(bool aHasBullet)
 {
   if (aHasBullet == !!mBullet) {
     NS_NOTREACHED("Bullet and accessible are in sync already!");
--- a/accessible/src/html/HTMLListAccessible.h
+++ b/accessible/src/html/HTMLListAccessible.h
@@ -50,17 +50,22 @@ public:
   NS_IMETHOD GetBounds(int32_t* aX, int32_t* aY,
                        int32_t* aWidth, int32_t* aHeight);
 
   // Accessible
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
 
-  // nsHTMLLIAccessible
+  // HyperTextAccessible
+  virtual int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
+                             nsSelectionAmount aAmount,
+                             EWordMovementType aWordMovementType) MOZ_OVERRIDE;
+
+  // HTMLLIAccessible
   void UpdateBullet(bool aHasBullet);
 
 protected:
   // Accessible
   virtual void CacheChildren();
 
 private:
   nsRefPtr<HTMLListBulletAccessible> mBullet;
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -74,17 +74,18 @@ const STATE_BUSY = nsIAccessibleStates.S
 const SCROLL_TYPE_ANYWHERE = nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE;
 
 const COORDTYPE_SCREEN_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE;
 const COORDTYPE_WINDOW_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_WINDOW_RELATIVE;
 const COORDTYPE_PARENT_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_PARENT_RELATIVE;
 
 const kEmbedChar = String.fromCharCode(0xfffc);
 
-const kDiscBulletText = String.fromCharCode(0x2022) + " ";
+const kDiscBulletChar = String.fromCharCode(0x2022);
+const kDiscBulletText = kDiscBulletChar + " ";
 const kCircleBulletText = String.fromCharCode(0x25e6) + " ";
 const kSquareBulletText = String.fromCharCode(0x25aa) + " ";
 
 const MAX_TRIM_LENGTH = 100;
 
 /**
  * nsIAccessibleRetrieval service.
  */
--- a/accessible/tests/mochitest/text/test_lineboundary.html
+++ b/accessible/tests/mochitest/text/test_lineboundary.html
@@ -103,16 +103,22 @@
 
       testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
                        BOUNDARY_LINE_START,
                        [ [ 0, 3, "foo", 0, 3 ] ]);
       testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
                        BOUNDARY_LINE_START,
                        [ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]);
 
+      //////////////////////////////////////////////////////////////////////////
+      // list items
+
+      testTextAtOffset([ "li1" ], BOUNDARY_LINE_START,
+                       [ [ 0, 5, kDiscBulletChar + "Item", 0, 5 ] ]);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
@@ -161,10 +167,14 @@ two words
 two words
 </textarea>
   </pre>
 
   <iframe id="ht_1" src="data:text/html,<html><body>a <a href=''>b</a> c</body></html>"></iframe>
 
   <iframe id="ht_2" src="data:text/html,<div contentEditable='true'>foo<br/></div>"></iframe>
   <iframe id="ht_3" src="data:text/html,<div contentEditable='true'>foo<br/><br/></div>"></iframe>
+
+  <ul>
+    <li id="li1">Item</li>
+  </ul>
 </body>
 </html>
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -726,16 +726,17 @@ var gPluginHandler = {
     }
 
     let browser = aNotification.browser;
     let contentWindow = browser.contentWindow;
     if (aNewState != "continue") {
       let principal = contentWindow.document.nodePrincipal;
       Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
                                       permission, expireType, expireTime);
+      aPluginInfo.pluginPermissionType = expireType;
     }
 
     // Manually activate the plugins that would have been automatically
     // activated.
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
     let plugins = cwu.plugins;
     let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -100,16 +100,17 @@ support-files =
 
 [browser_CTP_context_menu.js]
 skip-if = toolkit == "gtk2" || toolkit == "gtk3"   # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342)
 [browser_CTP_crashreporting.js]
 run-if = crashreporter
 [browser_CTP_data_urls.js]
 [browser_CTP_drag_drop.js]
 [browser_CTP_hideBar.js]
+[browser_CTP_multi_allow.js]
 [browser_CTP_nonplugins.js]
 [browser_CTP_resize.js]
 [browser_URLBarSetURI.js]
 [browser_aboutHealthReport.js]
 skip-if = os == "linux" # Bug 924307
 [browser_aboutHome.js]
 [browser_aboutSyncProgress.js]
 [browser_addKeywordSearch.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_CTP_multi_allow.js
@@ -0,0 +1,138 @@
+var rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir;
+const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
+
+var gTestBrowser = null;
+var gNextTest = null;
+var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  registerCleanupFunction(function() {
+    clearAllPluginPermissions();
+    Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
+  });
+  Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
+
+  var newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  gTestBrowser = gBrowser.selectedBrowser;
+  gTestBrowser.addEventListener("load", pageLoad, true);
+
+  Services.prefs.setBoolPref("plugins.click_to_play", true);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
+
+  prepareTest(test1a, gHttpTestRoot + "plugin_two_types.html");
+}
+
+function finishTest() {
+  clearAllPluginPermissions();
+  gTestBrowser.removeEventListener("load", pageLoad, true);
+  gBrowser.removeCurrentTab();
+  window.focus();
+  finish();
+}
+
+function pageLoad() {
+  // The plugin events are async dispatched and can come after the load event
+  // This just allows the events to fire before we then go on to test the states
+  executeSoon(gNextTest);
+}
+
+function prepareTest(nextTest, url) {
+  gNextTest = nextTest;
+  gTestBrowser.contentWindow.location = url;
+}
+
+// Due to layout being async, "PluginBindAttached" may trigger later.
+// This wraps a function to force a layout flush, thus triggering it,
+// and schedules the function execution so they're definitely executed
+// afterwards.
+function runAfterPluginBindingAttached(func) {
+  return function() {
+    let doc = gTestBrowser.contentDocument;
+    let elems = doc.getElementsByTagName('embed');
+    if (elems.length < 1) {
+      elems = doc.getElementsByTagName('object');
+    }
+    elems[0].clientTop;
+    executeSoon(func);
+  };
+}
+
+// Test that the click-to-play doorhanger for multiple plugins shows the correct
+// state when re-opening without reloads or navigation.
+
+function test1a() {
+  let doc = gTestBrowser.contentDocument;
+  let plugin = doc.getElementById("test");
+  let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test1a, Plugin should not be activated");
+
+  let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 1a, Should have a click-to-play notification");
+  notification.reshow();
+
+  is(notification.options.centerActions.size, 2,
+     "Test 1a, Should have two types of plugin in the notification");
+
+  let pluginItem = null;
+  for (let item of PopupNotifications.panel.firstChild.childNodes) {
+    is(item.value, "block", "Test 1a, all plugins should start out blocked");
+    if (item.action.pluginName == "Test") {
+      pluginItem = item;
+    }
+  }
+
+  // Choose "Allow now" for the test plugin
+  pluginItem.value = "allownow";
+  PopupNotifications.panel.firstChild._primaryButton.click();
+
+  waitForCondition(() => objLoadingContent.activated, test1b,
+                   "Test 1a, Waited too long for plugin to activate");
+}
+
+function test1b() {
+  let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 1b, Should have a click-to-play notification");
+  notification.reshow();
+
+  let pluginItem = null;
+  for (let item of PopupNotifications.panel.firstChild.childNodes) {
+    if (item.action.pluginName == "Test") {
+      is(item.value, "allownow", "Test 1b, Test plugin should now be set to 'Allow now'");
+    } else {
+      is(item.value, "block", "Test 1b, Second Test plugin should still be blocked");
+      pluginItem = item;
+    }
+  }
+
+  // Choose "Allow and remember" for the Second Test plugin
+  pluginItem.value = "allowalways";
+  PopupNotifications.panel.firstChild._primaryButton.click();
+
+  let doc = gTestBrowser.contentDocument;
+  let plugin = doc.getElementById("secondtestA");
+  let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  waitForCondition(() => objLoadingContent.activated, test1c,
+                   "Test 1b, Waited too long for plugin to activate");
+}
+
+function test1c() {
+  let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 1c, Should have a click-to-play notification");
+  notification.reshow();
+
+  for (let item of PopupNotifications.panel.firstChild.childNodes) {
+    if (item.action.pluginName == "Test") {
+      is(item.value, "allownow", "Test 1c, Test plugin should be set to 'Allow now'");
+    } else {
+      is(item.value, "allowalways", "Test 1c, Second Test plugin should be set to 'Allow always'");
+    }
+  }
+
+  finishTest();
+}
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -550,22 +550,34 @@ function resizeAndCheckWidths(first, sec
   }
   let count = checks.length;
   let [width, numExpectedVisible, why] = checks.shift();
   info("<< Check " + count + ": " + why);
   info(count + ": " + "resizing window to " + width + ", expect " + numExpectedVisible + " visible items");
   resizeWindowToChatAreaWidth(width, function(sizedOk) {
     checkPopup();
     ok(sizedOk, count+": window resized correctly");
-    if (sizedOk) {
-      let numVisible = [first, second, third].filter(function(item) !item.collapsed).length;
-      is(numVisible, numExpectedVisible, count + ": " + "correct number of chats visible");
+    function collapsedObserver(r, m) {
+      if ([first, second, third].filter(function(item) !item.collapsed).length == numExpectedVisible) {
+        if (m) {
+          m.disconnect();
+        }
+        ok(true, count + ": " + "correct number of chats visible");
+        info(">> Check " + count);
+        resizeAndCheckWidths(first, second, third, checks, cb);
+        return true;
+      }
+      return false;
     }
-    info(">> Check " + count);
-    resizeAndCheckWidths(first, second, third, checks, cb);
+    if (!collapsedObserver()) {
+      let m = new MutationObserver(collapsedObserver);
+      m.observe(first, {attributes: true });
+      m.observe(second, {attributes: true });
+      m.observe(third, {attributes: true });
+    }
   }, count);
 }
 
 function getPopupWidth() {
   let popup = window.SocialChatBar.chatbar.menupopup;
   ok(!popup.parentNode.collapsed, "asking for popup width when it is visible");
   let cs = document.defaultView.getComputedStyle(popup.parentNode);
   let margins = parseInt(cs.marginLeft) + parseInt(cs.marginRight);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js
@@ -9,20 +9,24 @@ function test() {
   waitForExplicitFinish();
 
   function testNoSessionRestoreButton() {
     let win = OpenBrowserWindow({private: true});
     win.addEventListener("load", function onLoad() {
       win.removeEventListener("load", onLoad, false);
       executeSoon(function() {
         info("The second private window got loaded");
-        let newTab = win.gBrowser.addTab("about:home");
+        let newTab = win.gBrowser.addTab();
         win.gBrowser.selectedTab = newTab;
         let tabBrowser = win.gBrowser.getBrowserForTab(newTab);
         tabBrowser.addEventListener("load", function tabLoadListener() {
+          if (win.content.location != "about:home") {
+            win.content.location = "about:home";
+            return;
+          }
           tabBrowser.removeEventListener("load", tabLoadListener, true);
           executeSoon(function() {
             info("about:home got loaded");
             let sessionRestoreButton = win.gBrowser
                                           .contentDocument
                                           .getElementById("restorePreviousSession");
             is(win.getComputedStyle(sessionRestoreButton).display, 
                "none", "The Session Restore about:home button should be disabled");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -9,16 +9,20 @@ function test() {
   const testPageURL = "http://mochi.test:8888/browser/" +
     "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
   waitForExplicitFinish();
 
     function checkGeolocation(aPrivateMode, aWindow, aCallback) {
     executeSoon(function() {
       aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
       aWindow.gBrowser.selectedBrowser.addEventListener("load", function () {
+        if (aWindow.content.location != testPageURL) {
+          aWindow.content.location = testPageURL;
+          return;
+        }
         aWindow.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
         function runTest() {
           let notification = aWindow.PopupNotifications.getNotification("geolocation");
           if (!notification) {
             // Wait until the notification is available
             executeSoon(runTest);
             return;
@@ -31,17 +35,16 @@ function test() {
           }
           notification.remove();
 
           aWindow.gBrowser.removeCurrentTab();
           aCallback();
         }
         runTest();
       }, true);
-      aWindow.content.location = testPageURL;
     });
   };
 
   let windowsToClose = [];
   function testOnWindow(options, callback) {
     let win = OpenBrowserWindow(options);
     win.addEventListener("load", function onLoad() {
       win.removeEventListener("load", onLoad, false);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
@@ -1,33 +1,37 @@
 /* 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/. */
 
 function test() {
   waitForExplicitFinish();
 
+  const page1 = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
+                'browser_privatebrowsing_localStorage_page1.html'
+
   function checkLocalStorage(aWindow, aCallback) {
     executeSoon(function() {
       let tab = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
       let browser = aWindow.gBrowser.selectedBrowser;
       browser.addEventListener('load', function() {
+        if (browser.contentWindow.location != page1) {
+          browser.loadURI(page1);
+          return;
+        }
         browser.removeEventListener('load', arguments.callee, true);
         let tab2 = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
         browser.contentWindow.location = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
                          'browser_privatebrowsing_localStorage_page2.html';
         browser.addEventListener('load', function() {
           browser.removeEventListener('load', arguments.callee, true);
           is(browser.contentWindow.document.title, '2', "localStorage should contain 2 items");
           aCallback();
         }, true);
       }, true);
-
-      browser.loadURI('http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
-                      'browser_privatebrowsing_localStorage_page1.html');
     });
   }
 
   let windowsToClose = [];
   function testOnWindow(options, callback) {
     let win = OpenBrowserWindow(options);
     win.addEventListener("load", function onLoad() {
       win.removeEventListener("load", onLoad, false);
--- a/config/config.mk
+++ b/config/config.mk
@@ -461,17 +461,17 @@ MY_RULES	:= $(DEPTH)/config/myrules.mk
 #
 CCC = $(CXX)
 
 # Java macros
 JAVA_GEN_DIR  = _javagen
 JAVA_DIST_DIR = $(DEPTH)/$(JAVA_GEN_DIR)
 JAVA_IFACES_PKG_NAME = org/mozilla/interfaces
 
-OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS)
+OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
 
 # NSPR_CFLAGS and NSS_CFLAGS must appear ahead of OS_INCLUDES to avoid Linux
 # builds wrongly picking up system NSPR/NSS header files.
 INCLUDES = \
   -I$(srcdir) \
   -I. \
   $(LOCAL_INCLUDES) \
   -I$(DIST)/include \
--- a/config/external/moz.build
+++ b/config/external/moz.build
@@ -22,17 +22,17 @@ if CONFIG['MOZ_TREMOR']:
     external_dirs += ['media/libtremor']
 
 if CONFIG['MOZ_OPUS']:
     external_dirs += ['media/libopus']
 
 if CONFIG['MOZ_WEBM']:
     external_dirs += ['media/libnestegg']
 
-if CONFIG['MOZ_VP8'] and not CONFIG['MOZ_NATIVE_LIBVPX']:
+if CONFIG['MOZ_VPX'] and not CONFIG['MOZ_NATIVE_LIBVPX']:
     external_dirs += ['media/libvpx']
 
 if CONFIG['MOZ_OGG']:
     external_dirs += ['media/libogg', 'media/libtheora']
 
 if not CONFIG['MOZ_NATIVE_PNG']:
     external_dirs += ['media/libpng']
 
--- a/configure.in
+++ b/configure.in
@@ -3962,19 +3962,18 @@ MOZ_WEBRTC=1
 MOZ_PEERCONNECTION=
 MOZ_SRTP=
 MOZ_WEBRTC_SIGNALING=
 MOZ_WEBRTC_ASSERT_ALWAYS=1
 MOZ_SCTP=
 MOZ_MEDIA_PLUGINS=
 MOZ_MEDIA_NAVIGATOR=
 MOZ_OMX_PLUGIN=
-MOZ_VP8=
-MOZ_VP8_ERROR_CONCEALMENT=
-MOZ_VP8_ENCODER=1
+MOZ_VPX=
+MOZ_VPX_ERROR_CONCEALMENT=
 MOZ_WEBSPEECH=1
 VPX_AS=
 VPX_ASFLAGS=
 VPX_AS_DASH_C_FLAG=
 VPX_AS_CONVERSION=
 VPX_ASM_SUFFIX=
 VPX_X86_ASM=
 VPX_ARM_ASM=
@@ -5109,18 +5108,18 @@ MOZ_ARG_DISABLE_BOOL(webrtc,
     MOZ_WEBRTC=1)
 
 if test -n "$MOZ_WEBRTC"; then
     AC_DEFINE(MOZ_WEBRTC)
     dnl MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
     dnl opt/production builds (via MOZ_CRASH())
     AC_DEFINE(MOZ_WEBRTC_ASSERT_ALWAYS)
     MOZ_RAW=1
-    MOZ_VP8=1
-    MOZ_VP8_ERROR_CONCEALMENT=1
+    MOZ_VPX=1
+    MOZ_VPX_ERROR_CONCEALMENT=1
 
 dnl enable once Signaling lands
     MOZ_WEBRTC_SIGNALING=1
     AC_DEFINE(MOZ_WEBRTC_SIGNALING)
 dnl enable once PeerConnection lands
     MOZ_PEERCONNECTION=1
     AC_DEFINE(MOZ_PEERCONNECTION)
     MOZ_SCTP=1
@@ -5223,17 +5222,17 @@ dnl = Disable VP8 decoder support
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(webm,
 [  --disable-webm          Disable support for WebM media (VP8 video and Vorbis audio)],
     MOZ_WEBM=,
     MOZ_WEBM=1)
 
 if test -n "$MOZ_WEBM"; then
     AC_DEFINE(MOZ_WEBM)
-    MOZ_VP8=1
+    MOZ_VPX=1
 fi;
 
 dnl ========================================================
 dnl = DirectShow support
 dnl ========================================================
 if test "$OS_ARCH" = "WINNT"; then
     dnl Enable DirectShow support by default.
     MOZ_DIRECTSHOW=1
@@ -5359,23 +5358,20 @@ dnl system libvpx Support
 dnl ========================================================
 MOZ_ARG_WITH_BOOL(system-libvpx,
 [  --with-system-libvpx    Use system libvpx (located with pkgconfig)],
     MOZ_NATIVE_LIBVPX=1)
 
 MOZ_LIBVPX_CFLAGS=
 MOZ_LIBVPX_LIBS=
 
-if test -n "$MOZ_VP8"; then
-    AC_DEFINE(MOZ_VP8)
-    if test -n "$MOZ_VP8_ERROR_CONCEALMENT" ; then
-        AC_DEFINE(MOZ_VP8_ERROR_CONCEALMENT)
-    fi
-    if test -n "$MOZ_VP8_ENCODER" ; then
-        AC_DEFINE(MOZ_VP8_ENCODER)
+if test -n "$MOZ_VPX"; then
+    AC_DEFINE(MOZ_VPX)
+    if test -n "$MOZ_VPX_ERROR_CONCEALMENT" ; then
+        AC_DEFINE(MOZ_VPX_ERROR_CONCEALMENT)
     fi
 
     if test -n "$MOZ_NATIVE_LIBVPX"; then
         dnl ============================
         dnl === libvpx Version check ===
         dnl ============================
         dnl Check to see if we have a system libvpx package.
         PKG_CHECK_MODULES(MOZ_LIBVPX, vpx >= 1.3.0)
@@ -5397,17 +5393,17 @@ AC_SUBST(MOZ_LIBVPX_LIBS)
 if test "$MOZ_WEBM" -o "$MOZ_OGG"; then
     if test "$MOZ_SAMPLE_TYPE_FLOAT32"; then
         MOZ_VORBIS=1
     else
         MOZ_TREMOR=1
     fi
 fi
 
-if test -n "$MOZ_VP8" -a -z "$MOZ_NATIVE_LIBVPX"; then
+if test -n "$MOZ_VPX" -a -z "$MOZ_NATIVE_LIBVPX"; then
 
     dnl Detect if we can use an assembler to compile optimized assembly for libvpx.
     dnl We currently require yasm on all x86 platforms and require yasm 1.1.0 on Win32.
     dnl We currently require gcc on all arm platforms.
     VPX_AS=$YASM
     VPX_ASM_SUFFIX=asm
     VPX_NEED_OBJ_INT_EXTRACT=
 
@@ -5462,18 +5458,17 @@ if test -n "$MOZ_VP8" -a -z "$MOZ_NATIVE
       fi
     ;;
     esac
 
     if test -n "$COMPILE_ENVIRONMENT" -a -n "$VPX_X86_ASM" -a -z "$VPX_AS"; then
       AC_MSG_ERROR([yasm is a required build tool for this architecture when webm is enabled. You may either install yasm or --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
     fi
 
-    if test -n "$MOZ_VP8_ENCODER" -a \
-            -z "$GNU_CC" -a -z "$INTEL_CC" -a -z "$CLANG_CC" ; then
+    if test -z "$GNU_CC" -a -z "$INTEL_CC" -a -z "$CLANG_CC" ; then
       dnl We prefer to get asm offsets using inline assembler, which the above
       dnl compilers can do. When we're not using one of those, we have to fall
       dnl back to obj_int_extract, which reads them from a compiled object
       dnl file. Unfortunately, that only works if we're compiling on a system
       dnl with the header files for the appropriate object file format.
       VPX_NEED_OBJ_INT_EXTRACT=1
     fi
 
@@ -8615,19 +8610,18 @@ AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_OPUS)
 AC_SUBST(MOZ_WEBM)
 AC_SUBST(MOZ_WMF)
 AC_SUBST(MOZ_FMP4)
 AC_SUBST(MOZ_DIRECTSHOW)
 AC_SUBST(MOZ_MEDIA_PLUGINS)
 AC_SUBST(MOZ_APPLEMEDIA)
 AC_SUBST(MOZ_OMX_PLUGIN)
-AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT)
-AC_SUBST(MOZ_VP8_ENCODER)
-AC_SUBST(MOZ_VP8)
+AC_SUBST(MOZ_VPX_ERROR_CONCEALMENT)
+AC_SUBST(MOZ_VPX)
 AC_SUBST(MOZ_OGG)
 AC_SUBST(VPX_AS)
 AC_SUBST(VPX_ASFLAGS)
 AC_SUBST(VPX_DASH_C_FLAG)
 AC_SUBST(VPX_AS_CONVERSION)
 AC_SUBST(VPX_ASM_SUFFIX)
 AC_SUBST(VPX_X86_ASM)
 AC_SUBST(VPX_ARM_ASM)
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -306,37 +306,28 @@ public:
   }
 
   friend class nsNodeUtils;
   friend class nsNodeWeakReference;
   friend class nsNodeSupportsWeakRefTearoff;
   friend class nsAttrAndChildArray;
 
 #ifdef MOZILLA_INTERNAL_API
-#ifdef _MSC_VER
-#pragma warning(push)
-// Disable annoying warning about 'this' in initializers.
-#pragma warning(disable:4355)
-#endif
   nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : mNodeInfo(aNodeInfo),
     mParent(nullptr),
     mBoolFlags(0),
     mNextSibling(nullptr),
     mPreviousSibling(nullptr),
     mFirstChild(nullptr),
-    mSubtreeRoot(this),
+    mSubtreeRoot(MOZ_THIS_IN_INITIALIZER_LIST()),
     mSlots(nullptr)
   {
     SetIsDOMBinding();
   }
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
 #endif
 
   virtual ~nsINode();
 
   /**
    * Bit-flags to pass (or'ed together) to IsNodeOfType()
    */
   enum {
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/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_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
--- a/content/events/public/nsDOMKeyNameList.h
+++ b/content/events/public/nsDOMKeyNameList.h
@@ -97,24 +97,16 @@ DEFINE_KEYNAME_WITH_SAME_NAME(Menu)
 DEFINE_KEYNAME_WITH_SAME_NAME(Pause)
 DEFINE_KEYNAME_WITH_SAME_NAME(Play)
 DEFINE_KEYNAME_WITH_SAME_NAME(ScrollLock) // IE9 users "Scroll"
 DEFINE_KEYNAME_WITH_SAME_NAME(Execute)
 DEFINE_KEYNAME_WITH_SAME_NAME(Cancel)
 DEFINE_KEYNAME_WITH_SAME_NAME(Esc)
 DEFINE_KEYNAME_WITH_SAME_NAME(Exit)
 DEFINE_KEYNAME_WITH_SAME_NAME(Zoom)
-DEFINE_KEYNAME_WITH_SAME_NAME(Separator)
-DEFINE_KEYNAME_WITH_SAME_NAME(Spacebar)
-DEFINE_KEYNAME_WITH_SAME_NAME(Add)
-DEFINE_KEYNAME_WITH_SAME_NAME(Subtract)
-DEFINE_KEYNAME_WITH_SAME_NAME(Multiply)
-DEFINE_KEYNAME_WITH_SAME_NAME(Divide)
-DEFINE_KEYNAME_WITH_SAME_NAME(Equals)
-DEFINE_KEYNAME_WITH_SAME_NAME(Decimal)
 DEFINE_KEYNAME_WITH_SAME_NAME(BrightnessDown)
 DEFINE_KEYNAME_WITH_SAME_NAME(BrightnessUp)
 DEFINE_KEYNAME_WITH_SAME_NAME(Camera)
 DEFINE_KEYNAME_WITH_SAME_NAME(Eject)
 DEFINE_KEYNAME_WITH_SAME_NAME(Power)
 DEFINE_KEYNAME_WITH_SAME_NAME(PrintScreen)
 DEFINE_KEYNAME_WITH_SAME_NAME(BrowserFavorites)
 DEFINE_KEYNAME_WITH_SAME_NAME(BrowserHome)
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -212,17 +212,17 @@ public:
           static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])) +
           aBufferOffset;
 
         WebAudioUtils::SpeexResamplerProcess(resampler, i,
                                              inputData, &inSamples,
                                              outputData, &outSamples);
         if (++i == aChannels) {
           mPosition += inSamples;
-          MOZ_ASSERT(mPosition <= mDuration);
+          MOZ_ASSERT(mPosition <= mDuration || mLoop);
           aFramesWritten = outSamples;
           if (inSamples == aAvailableInInputBuffer && !mLoop) {
             // If the available output space were unbounded then the input
             // latency would always be the correct amount of extra input to
             // provide in order to advance the output position to align with
             // the final point in the buffer.  However, when the output space
             // becomes full, the resampler may read all available input
             // without writing out the corresponding output.  Add one more
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -31,31 +31,21 @@ nsSMILTimeValueSpec::EventListener::Hand
     mSpec->HandleEvent(aEvent);
   }
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // Implementation
 
-#ifdef _MSC_VER
-// Disable "warning C4355: 'this' : used in base member initializer list".
-// We can ignore that warning because we know that mReferencedElement's
-// constructor doesn't dereference the pointer passed to it.
-#pragma warning(push)
-#pragma warning(disable:4355)
-#endif
 nsSMILTimeValueSpec::nsSMILTimeValueSpec(nsSMILTimedElement& aOwner,
                                          bool aIsBegin)
   : mOwner(&aOwner),
     mIsBegin(aIsBegin),
-    mReferencedElement(this)
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
+    mReferencedElement(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 nsSMILTimeValueSpec::~nsSMILTimeValueSpec()
 {
   UnregisterFromReferencedElement(mReferencedElement.get());
   if (mEventListener) {
     mEventListener->Disconnect();
--- a/content/svg/content/src/SVGAnimationElement.cpp
+++ b/content/svg/content/src/SVGAnimationElement.cpp
@@ -38,29 +38,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   SVGAnimationElementBase)
   tmp->mHrefTarget.Traverse(&cb);
   tmp->mTimedElement.Traverse(&cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 //----------------------------------------------------------------------
 // Implementation
 
-#ifdef _MSC_VER
-// Disable "warning C4355: 'this' : used in base member initializer list".
-// We can ignore that warning because we know that mHrefTarget's constructor 
-// doesn't dereference the pointer passed to it.
-#pragma warning(push)
-#pragma warning(disable:4355)
-#endif
 SVGAnimationElement::SVGAnimationElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGAnimationElementBase(aNodeInfo),
-    mHrefTarget(this)
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
+    mHrefTarget(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 nsresult
 SVGAnimationElement::Init()
 {
   nsresult rv = SVGAnimationElementBase::Init();
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/svg/content/src/SVGMPathElement.cpp
+++ b/content/svg/content/src/SVGMPathElement.cpp
@@ -50,29 +50,19 @@ NS_IMPL_RELEASE_INHERITED(SVGMPathElemen
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGMPathElement)
   NS_INTERFACE_TABLE_INHERITED4(SVGMPathElement, nsIDOMNode, nsIDOMElement,
                                 nsIDOMSVGElement,
                                 nsIMutationObserver)
 NS_INTERFACE_TABLE_TAIL_INHERITING(SVGMPathElementBase)
 
 // Constructor
-#ifdef _MSC_VER
-// Disable "warning C4355: 'this' : used in base member initializer list".
-// We can ignore that warning because we know that mHrefTarget's constructor 
-// doesn't dereference the pointer passed to it.
-#pragma warning(push)
-#pragma warning(disable:4355)
-#endif
 SVGMPathElement::SVGMPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGMPathElementBase(aNodeInfo),
-    mHrefTarget(this)
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
+    mHrefTarget(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 SVGMPathElement::~SVGMPathElement()
 {
   UnlinkHrefTarget(false);
 }
 
--- a/content/svg/content/src/SVGUseElement.cpp
+++ b/content/svg/content/src/SVGUseElement.cpp
@@ -66,28 +66,18 @@ NS_IMPL_RELEASE_INHERITED(SVGUseElement,
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGUseElement)
   NS_INTERFACE_TABLE_INHERITED1(SVGUseElement, nsIMutationObserver)
 NS_INTERFACE_TABLE_TAIL_INHERITING(SVGUseElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
-#ifdef _MSC_VER
-// Disable "warning C4355: 'this' : used in base member initializer list".
-// We can ignore that warning because we know that mSource's constructor 
-// doesn't dereference the pointer passed to it.
-#pragma warning(push)
-#pragma warning(disable:4355)
-#endif
 SVGUseElement::SVGUseElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : SVGUseElementBase(aNodeInfo), mSource(this)
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
+  : SVGUseElementBase(aNodeInfo), mSource(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 SVGUseElement::~SVGUseElement()
 {
   UnlinkSource();
 }
 
--- a/dom/plugins/base/Makefile.in
+++ b/dom/plugins/base/Makefile.in
@@ -2,11 +2,10 @@
 # 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_CAIRO_CFLAGS) \
-  $(MOZ_PIXMAN_CFLAGS) \
   $(TK_CFLAGS) \
   $(NULL)
--- a/dom/plugins/base/android/Makefile.in
+++ b/dom/plugins/base/android/Makefile.in
@@ -1,9 +1,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/.
 
 CXXFLAGS += \
   $(MOZ_CAIRO_CFLAGS) \
-  $(MOZ_PIXMAN_CFLAGS) \
   $(NULL)
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -13,27 +13,27 @@
 #include <map>
 #include "FilterProcessing.h"
 #include "mozilla/PodOperations.h"
 
 // #define DEBUG_DUMP_SURFACES
 
 #ifdef DEBUG_DUMP_SURFACES
 #include "gfxImageSurface.h"
-#include "gfx2DGlue.h"
 namespace mozilla {
 namespace gfx {
 static void
 DumpAsPNG(SourceSurface* aSurface)
 {
   RefPtr<DataSourceSurface> dataSource = aSurface->GetDataSurface();
   IntSize size = dataSource->GetSize();
   nsRefPtr<gfxImageSurface> imageSurface =
     new gfxImageSurface(dataSource->GetData(), gfxIntSize(size.width, size.height),
-                        dataSource->Stride(), SurfaceFormatToImageFormat(aSurface->GetFormat()));
+                        dataSource->Stride(),
+                        aSurface->GetFormat() == FORMAT_A8 ? gfxImageFormatA8 : gfxImageFormatARGB32);
   imageSurface->PrintAsDataURL();
 }
 } // namespace gfx
 } // namespace mozilla
 #endif
 
 namespace mozilla {
 namespace gfx {
@@ -554,64 +554,56 @@ FilterNodeSoftware::Create(FilterType aT
 
 void
 FilterNodeSoftware::Draw(DrawTarget* aDrawTarget,
                          const Rect &aSourceRect,
                          const Point &aDestPoint,
                          const DrawOptions &aOptions)
 {
 #ifdef DEBUG_DUMP_SURFACES
-  printf("<pre>\nRendering...\n");
+  printf("<style>section{margin:10px;}</style><pre>\nRendering filter %s...\n", GetName());
 #endif
 
   Rect renderRect = aSourceRect;
   renderRect.RoundOut();
   IntRect renderIntRect(int32_t(renderRect.x), int32_t(renderRect.y),
                         int32_t(renderRect.width), int32_t(renderRect.height));
   IntRect outputRect = renderIntRect.Intersect(GetOutputRectInRect(renderIntRect));
 
-  // Render.
-  RefPtr<DataSourceSurface> result = GetOutput(outputRect);
+  RefPtr<DataSourceSurface> result;
+  if (!outputRect.IsEmpty()) {
+    result = GetOutput(outputRect);
+  }
+
   if (!result) {
+    // Null results are allowed and treated as transparent. Don't draw anything.
 #ifdef DEBUG_DUMP_SURFACES
     printf("output returned null\n");
     printf("</pre>\n");
 #endif
     return;
   }
 
-  // Add transparency around outputRect in renderIntRect.
-  result = GetDataSurfaceInRect(result, outputRect, renderIntRect, EDGE_MODE_NONE);
-  if (!result) {
 #ifdef DEBUG_DUMP_SURFACES
-    printf("GetDataSurfaceInRect for output returned null\n");
-    printf("</pre>\n");
-#endif
-    return;
-  }
-
-#ifdef DEBUG_DUMP_SURFACES
-  printf("output:\n");
+  printf("output from %s:\n", GetName());
   printf("<img src='"); DumpAsPNG(result); printf("'>\n");
   printf("</pre>\n");
 #endif
 
-  // Draw.
-  aDrawTarget->DrawSurface(result, Rect(aDestPoint, aSourceRect.Size()),
-                           aSourceRect - renderIntRect.TopLeft(),
+  Point sourceToDestOffset = aDestPoint - aSourceRect.TopLeft();
+  Rect renderedSourceRect = Rect(outputRect).Intersect(aSourceRect);
+  Rect renderedDestRect = renderedSourceRect + sourceToDestOffset;
+  aDrawTarget->DrawSurface(result, renderedDestRect,
+                           renderedSourceRect - Point(outputRect.TopLeft()),
                            DrawSurfaceOptions(), aOptions);
 }
 
 TemporaryRef<DataSourceSurface>
 FilterNodeSoftware::GetOutput(const IntRect &aRect)
 {
-  if (aRect.IsEmpty()) {
-    return nullptr;
-  }
-
   MOZ_ASSERT(GetOutputRectInRect(aRect).Contains(aRect));
   if (!mCachedRect.Contains(aRect)) {
     RequestRect(aRect);
     mCachedOutput = Render(mRequestedRect);
     if (!mCachedOutput) {
       mCachedRect = IntRect();
       mRequestedRect = IntRect();
       return nullptr;
@@ -659,71 +651,83 @@ FilterNodeSoftware::DesiredFormat(Surfac
 TemporaryRef<DataSourceSurface>
 FilterNodeSoftware::GetInputDataSourceSurface(uint32_t aInputEnumIndex,
                                               const IntRect& aRect,
                                               FormatHint aFormatHint,
                                               ConvolveMatrixEdgeMode aEdgeMode,
                                               const IntRect *aTransparencyPaddedSourceRect)
 {
 #ifdef DEBUG_DUMP_SURFACES
-  printf("<h1>GetInputDataSourceSurface with aRect: %d, %d, %d, %d</h1>\n",
+  printf("<section><h1>GetInputDataSourceSurface with aRect: %d, %d, %d, %d</h1>\n",
          aRect.x, aRect.y, aRect.width, aRect.height);
 #endif
   int32_t inputIndex = InputIndex(aInputEnumIndex);
   if (inputIndex < 0 || (uint32_t)inputIndex >= NumberOfSetInputs()) {
     MOZ_CRASH();
     return nullptr;
   }
 
+  if (aRect.IsEmpty()) {
+    return nullptr;
+  }
+
   RefPtr<SourceSurface> surface;
   IntRect surfaceRect;
+
   if (mInputSurfaces[inputIndex]) {
+    // Input from input surface
     surface = mInputSurfaces[inputIndex];
 #ifdef DEBUG_DUMP_SURFACES
     printf("input from input surface:\n");
-    printf("<img src='"); DumpAsPNG(surface); printf("'>\n");
 #endif
     surfaceRect = IntRect(IntPoint(0, 0), surface->GetSize());
   } else {
+    // Input from input filter
+#ifdef DEBUG_DUMP_SURFACES
+    printf("getting input from input filter %s...\n", mInputFilters[inputIndex]->GetName());
+#endif
     RefPtr<FilterNodeSoftware> filter = mInputFilters[inputIndex];
     MOZ_ASSERT(filter, "missing input");
     IntRect inputFilterOutput = filter->GetOutputRectInRect(aRect);
     if (!inputFilterOutput.IsEmpty()) {
       surface = filter->GetOutput(inputFilterOutput);
     }
+#ifdef DEBUG_DUMP_SURFACES
+    printf("input from input filter %s:\n", mInputFilters[inputIndex]->GetName());
+#endif
     surfaceRect = inputFilterOutput;
     MOZ_ASSERT(!surface || surfaceRect.Size() == surface->GetSize());
   }
 
   if (surface && surface->GetFormat() == FORMAT_UNKNOWN) {
 #ifdef DEBUG_DUMP_SURFACES
-    printf("wrong input format\n\n");
+    printf("wrong input format</section>\n\n");
 #endif
     return nullptr;
   }
 
   if (!surfaceRect.IsEmpty() && !surface) {
 #ifdef DEBUG_DUMP_SURFACES
-    printf(" -- no input --\n\n");
+    printf(" -- no input --</section>\n\n");
 #endif
     return nullptr;
   }
 
   if (aTransparencyPaddedSourceRect && !aTransparencyPaddedSourceRect->IsEmpty()) {
     IntRect srcRect = aTransparencyPaddedSourceRect->Intersect(aRect);
     surface = GetDataSurfaceInRect(surface, surfaceRect, srcRect, EDGE_MODE_NONE);
     surfaceRect = srcRect;
   }
 
   RefPtr<DataSourceSurface> result =
     GetDataSurfaceInRect(surface, surfaceRect, aRect, aEdgeMode);
 
   if (!result) {
 #ifdef DEBUG_DUMP_SURFACES
-    printf(" -- no input --\n\n");
+    printf(" -- no input --</section>\n\n");
 #endif
     return nullptr;
   }
 
   if (result->Stride() != GetAlignedStride<16>(result->Stride()) ||
       reinterpret_cast<uintptr_t>(result->GetData()) % 16 != 0) {
     // Align unaligned surface.
     result = CloneAligned(result);
@@ -731,18 +735,17 @@ FilterNodeSoftware::GetInputDataSourceSu
 
   SurfaceFormat currentFormat = result->GetFormat();
   if (DesiredFormat(currentFormat, aFormatHint) == FORMAT_B8G8R8A8 &&
       currentFormat != FORMAT_B8G8R8A8) {
     result = FilterProcessing::ConvertToB8G8R8A8(result);
   }
 
 #ifdef DEBUG_DUMP_SURFACES
-  printf("input:\n");
-  printf("<img src='"); DumpAsPNG(result); printf("'>\n");
+  printf("<img src='"); DumpAsPNG(result); printf("'></section>");
 #endif
 
   MOZ_ASSERT(!result || result->GetSize() == aRect.Size(), "wrong surface size");
 
   return result;
 }
 
 IntRect
@@ -882,21 +885,33 @@ FilterNodeBlendSoftware::SetAttribute(ui
 
 TemporaryRef<DataSourceSurface>
 FilterNodeBlendSoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> input1 =
     GetInputDataSourceSurface(IN_BLEND_IN, aRect, NEED_COLOR_CHANNELS);
   RefPtr<DataSourceSurface> input2 =
     GetInputDataSourceSurface(IN_BLEND_IN2, aRect, NEED_COLOR_CHANNELS);
-  if (!input1 || !input2) {
+
+  // Null inputs need to be treated as transparent.
+
+  // First case: both are transparent.
+  if (!input1 && !input2) {
+    // Then the result is transparent, too.
     return nullptr;
   }
 
-  return FilterProcessing::ApplyBlending(input1, input2, mBlendMode);
+  // Second case: both are non-transparent.
+  if (input1 && input2) {
+    // Apply normal filtering.
+    return FilterProcessing::ApplyBlending(input1, input2, mBlendMode);
+  }
+
+  // Third case: one of them is transparent. Return the non-transparent one.
+  return input1 ? input1 : input2;
 }
 
 void
 FilterNodeBlendSoftware::RequestFromInputsForRect(const IntRect &aRect)
 {
   RequestInputRect(IN_BLEND_IN, aRect);
   RequestInputRect(IN_BLEND_IN2, aRect);
 }
@@ -935,16 +950,20 @@ FilterNodeTransformSoftware::SetAttribut
   MOZ_ASSERT(aIndex == ATT_TRANSFORM_MATRIX);
   mMatrix = aMatrix;
   Invalidate();
 }
 
 IntRect
 FilterNodeTransformSoftware::SourceRectForOutputRect(const IntRect &aRect)
 {
+  if (aRect.IsEmpty()) {
+    return IntRect();
+  }
+
   Matrix inverted(mMatrix);
   if (!inverted.Invert()) {
     return IntRect();
   }
 
   Rect neededRect = inverted.TransformBounds(Rect(aRect));
   neededRect.RoundOut();
   return GetInputRectInRect(IN_TRANSFORM_IN, RoundedToInt(neededRect));
@@ -988,16 +1007,20 @@ FilterNodeTransformSoftware::RequestFrom
 {
   RequestInputRect(IN_TRANSFORM_IN, SourceRectForOutputRect(aRect));
 }
 
 IntRect
 FilterNodeTransformSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   IntRect srcRect = SourceRectForOutputRect(aRect);
+  if (srcRect.IsEmpty()) {
+    return IntRect();
+  }
+
   Rect outRect = mMatrix.TransformBounds(Rect(srcRect));
   outRect.RoundOut();
   return RoundedToInt(outRect).Intersect(aRect);
 }
 
 FilterNodeMorphologySoftware::FilterNodeMorphologySoftware()
  : mOperator(MORPHOLOGY_OPERATOR_ERODE)
 {}
@@ -1317,16 +1340,19 @@ TemporaryRef<DataSourceSurface>
 FilterNodeFloodSoftware::GetOutput(const IntRect& aRect)
 {
   return Render(aRect);
 }
 
 IntRect
 FilterNodeFloodSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
+  if (mColor.a == 0.0f) {
+    return IntRect();
+  }
   return aRect;
 }
 
 int32_t
 FilterNodeTileSoftware::InputIndex(uint32_t aInputEnumIndex)
 {
   switch (aInputEnumIndex) {
     case IN_TILE_IN: return 0;
@@ -2239,30 +2265,38 @@ void
 FilterNodeConvolveMatrixSoftware::RequestFromInputsForRect(const IntRect &aRect)
 {
   RequestInputRect(IN_CONVOLVE_MATRIX_IN, InflatedSourceRect(aRect));
 }
 
 IntRect
 FilterNodeConvolveMatrixSoftware::InflatedSourceRect(const IntRect &aDestRect)
 {
+  if (aDestRect.IsEmpty()) {
+    return IntRect();
+  }
+
   IntMargin margin;
   margin.left = ceil(mTarget.x * mKernelUnitLength.width);
   margin.top = ceil(mTarget.y * mKernelUnitLength.height);
   margin.right = ceil((mKernelSize.width - mTarget.x - 1) * mKernelUnitLength.width);
   margin.bottom = ceil((mKernelSize.height - mTarget.y - 1) * mKernelUnitLength.height);
 
   IntRect srcRect = aDestRect;
   srcRect.Inflate(margin);
   return srcRect;
 }
 
 IntRect
 FilterNodeConvolveMatrixSoftware::InflatedDestRect(const IntRect &aSourceRect)
 {
+  if (aSourceRect.IsEmpty()) {
+    return IntRect();
+  }
+
   IntMargin margin;
   margin.left = ceil((mKernelSize.width - mTarget.x - 1) * mKernelUnitLength.width);
   margin.top = ceil((mKernelSize.height - mTarget.y - 1) * mKernelUnitLength.height);
   margin.right = ceil(mTarget.x * mKernelUnitLength.width);
   margin.bottom = ceil(mTarget.y * mKernelUnitLength.height);
 
   IntRect destRect = aSourceRect;
   destRect.Inflate(margin);
@@ -2508,35 +2542,63 @@ FilterNodeArithmeticCombineSoftware::Set
 
 TemporaryRef<DataSourceSurface>
 FilterNodeArithmeticCombineSoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> input1 =
     GetInputDataSourceSurface(IN_ARITHMETIC_COMBINE_IN, aRect, NEED_COLOR_CHANNELS);
   RefPtr<DataSourceSurface> input2 =
     GetInputDataSourceSurface(IN_ARITHMETIC_COMBINE_IN2, aRect, NEED_COLOR_CHANNELS);
-  if (!input1 || !input2) {
+  if (!input1 && !input2) {
     return nullptr;
   }
 
-  return FilterProcessing::ApplyArithmeticCombine(input1, input2, mK1, mK2, mK3, mK4);
+  // If one input is null, treat it as transparent by adjusting the factors.
+  Float k1 = mK1, k2 = mK2, k3 = mK3, k4 = mK4;
+  if (!input1) {
+    k1 = 0.0f;
+    k2 = 0.0f;
+    input1 = input2;
+  }
+
+  if (!input2) {
+    k1 = 0.0f;
+    k3 = 0.0f;
+    input2 = input1;
+  }
+
+  return FilterProcessing::ApplyArithmeticCombine(input1, input2, k1, k2, k3, k4);
 }
 
 void
 FilterNodeArithmeticCombineSoftware::RequestFromInputsForRect(const IntRect &aRect)
 {
   RequestInputRect(IN_ARITHMETIC_COMBINE_IN, aRect);
   RequestInputRect(IN_ARITHMETIC_COMBINE_IN2, aRect);
 }
 
 IntRect
 FilterNodeArithmeticCombineSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
-  return GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN, aRect).Union(
-    GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN2, aRect)).Intersect(aRect);
+  if (mK4 > 0.0f) {
+    return aRect;
+  }
+  IntRect rectFrom1 = GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN, aRect).Intersect(aRect);
+  IntRect rectFrom2 = GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN2, aRect).Intersect(aRect);
+  IntRect result;
+  if (mK1 > 0.0f) {
+    result = rectFrom1.Intersect(rectFrom2);
+  }
+  if (mK2 > 0.0f) {
+    result = result.Union(rectFrom1);
+  }
+  if (mK3 > 0.0f) {
+    result = result.Union(rectFrom2);
+  }
+  return result;
 }
 
 FilterNodeCompositeSoftware::FilterNodeCompositeSoftware()
  : mOperator(COMPOSITE_OPERATOR_OVER)
 {}
 
 int32_t
 FilterNodeCompositeSoftware::InputIndex(uint32_t aInputEnumIndex)
@@ -2554,27 +2616,51 @@ FilterNodeCompositeSoftware::SetAttribut
 
 TemporaryRef<DataSourceSurface>
 FilterNodeCompositeSoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> start =
     GetInputDataSourceSurface(IN_COMPOSITE_IN_START, aRect, NEED_COLOR_CHANNELS);
   RefPtr<DataSourceSurface> dest =
     Factory::CreateDataSourceSurface(aRect.Size(), FORMAT_B8G8R8A8);
-  if (!start || !dest) {
+  if (!dest) {
     return nullptr;
   }
-  CopyRect(start, dest, aRect - aRect.TopLeft(), IntPoint());
+
+  if (start) {
+    CopyRect(start, dest, aRect - aRect.TopLeft(), IntPoint());
+  } else {
+    ClearDataSourceSurface(dest);
+  }
+
   for (size_t inputIndex = 1; inputIndex < NumberOfSetInputs(); inputIndex++) {
     RefPtr<DataSourceSurface> input =
       GetInputDataSourceSurface(IN_COMPOSITE_IN_START + inputIndex, aRect, NEED_COLOR_CHANNELS);
-    if (!input) {
-      return nullptr;
+    if (input) {
+      FilterProcessing::ApplyComposition(input, dest, mOperator);
+    } else {
+      // We need to treat input as transparent. Depending on the composite
+      // operator, different things happen to dest.
+      switch (mOperator) {
+        case COMPOSITE_OPERATOR_OVER:
+        case COMPOSITE_OPERATOR_ATOP:
+        case COMPOSITE_OPERATOR_XOR:
+          // dest is unchanged.
+          break;
+        case COMPOSITE_OPERATOR_OUT:
+          // dest is now transparent, but it can become non-transparent again
+          // when compositing additional inputs.
+          ClearDataSourceSurface(dest);
+          break;
+        case COMPOSITE_OPERATOR_IN:
+          // Transparency always wins. We're completely transparent now and
+          // no additional input can get rid of that transparency.
+          return nullptr;
+      }
     }
-    FilterProcessing::ApplyComposition(input, dest, mOperator);
   }
   return dest;
 }
 
 void
 FilterNodeCompositeSoftware::RequestFromInputsForRect(const IntRect &aRect)
 {
   for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
@@ -2582,17 +2668,22 @@ FilterNodeCompositeSoftware::RequestFrom
   }
 }
 
 IntRect
 FilterNodeCompositeSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   IntRect rect;
   for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
-    rect = rect.Union(GetInputRectInRect(IN_COMPOSITE_IN_START + inputIndex, aRect));
+    IntRect inputRect = GetInputRectInRect(IN_COMPOSITE_IN_START + inputIndex, aRect);
+    if (mOperator == COMPOSITE_OPERATOR_IN && inputIndex > 0) {
+      rect = rect.Intersect(inputRect);
+    } else {
+      rect = rect.Union(inputRect);
+    }
   }
   return rect;
 }
 
 int32_t
 FilterNodeBlurXYSoftware::InputIndex(uint32_t aInputEnumIndex)
 {
   switch (aInputEnumIndex) {
@@ -2747,23 +2838,17 @@ FilterNodeCropSoftware::SetAttribute(uin
   mCropRect = IntRect(int32_t(srcRect.x), int32_t(srcRect.y),
                       int32_t(srcRect.width), int32_t(srcRect.height));
   Invalidate();
 }
 
 TemporaryRef<DataSourceSurface>
 FilterNodeCropSoftware::Render(const IntRect& aRect)
 {
-  IntRect sourceRect = aRect.Intersect(mCropRect);
-  RefPtr<DataSourceSurface> input =
-    GetInputDataSourceSurface(IN_CROP_IN, sourceRect);
-  if (!input) {
-    return nullptr;
-  }
-  return GetDataSurfaceInRect(input, sourceRect, aRect, EDGE_MODE_NONE);
+  return GetInputDataSourceSurface(IN_CROP_IN, aRect.Intersect(mCropRect));
 }
 
 void
 FilterNodeCropSoftware::RequestFromInputsForRect(const IntRect &aRect)
 {
   RequestInputRect(IN_CROP_IN, aRect.Intersect(mCropRect));
 }
 
@@ -3117,23 +3202,27 @@ FilterNodeLightingSoftware<LightType, Li
   IntRect srcRect = aRect;
   IntSize size = aRect.Size();
   srcRect.Inflate(ceil(float(aKernelUnitLengthX)),
                   ceil(float(aKernelUnitLengthY)));
   RefPtr<DataSourceSurface> input =
     GetInputDataSourceSurface(IN_LIGHTING_IN, srcRect, CAN_HANDLE_A8,
                               EDGE_MODE_DUPLICATE);
 
+  if (!input) {
+    return nullptr;
+  }
+
   if (input->GetFormat() != FORMAT_A8) {
     input = FilterProcessing::ExtractAlpha(input);
   }
 
   RefPtr<DataSourceSurface> target =
     Factory::CreateDataSourceSurface(size, FORMAT_B8G8R8A8);
-  if (!input || !target) {
+  if (!target) {
     return nullptr;
   }
 
   uint8_t* sourceData = input->GetData();
   int32_t sourceStride = input->Stride();
   uint8_t* targetData = target->GetData();
   int32_t targetStride = target->Stride();
 
--- a/gfx/2d/FilterNodeSoftware.h
+++ b/gfx/2d/FilterNodeSoftware.h
@@ -46,16 +46,18 @@ public:
   // Draw the filter, intended to be called by DrawTarget*::DrawFilter.
   void Draw(DrawTarget* aDrawTarget, const Rect &aSourceRect,
             const Point &aDestPoint, const DrawOptions &aOptions);
 
   virtual FilterBackend GetBackendType() MOZ_OVERRIDE { return FILTER_BACKEND_SOFTWARE; }
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) MOZ_OVERRIDE;
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) MOZ_OVERRIDE;
 
+  virtual const char* GetName() { return "Unknown"; }
+
   virtual void AddInvalidationListener(FilterInvalidationListener* aListener);
   virtual void RemoveInvalidationListener(FilterInvalidationListener* aListener);
 
   // FilterInvalidationListener implementation
   virtual void FilterInvalidated(FilterNodeSoftware* aFilter);
 
 protected:
 
@@ -211,16 +213,17 @@ protected:
 };
 
 // Subclasses for specific filters.
 
 class FilterNodeTransformSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeTransformSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Transform"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -231,16 +234,17 @@ private:
   Matrix mMatrix;
   Filter mFilter;
 };
 
 class FilterNodeBlendSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeBlendSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Blend"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlendMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
@@ -248,16 +252,17 @@ protected:
 private:
   BlendMode mBlendMode;
 };
 
 class FilterNodeMorphologySoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeMorphologySoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Morphology"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aRadii) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -266,16 +271,17 @@ protected:
 private:
   IntSize mRadii;
   MorphologyOperator mOperator;
 };
 
 class FilterNodeColorMatrixSoftware : public FilterNodeSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "ColorMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &aMatrix) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aAlphaMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -284,31 +290,33 @@ protected:
 private:
   Matrix5x4 mMatrix;
   AlphaMode mAlphaMode;
 };
 
 class FilterNodeFloodSoftware : public FilterNodeSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "Flood"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Color &aColor) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> GetOutput(const IntRect &aRect) MOZ_OVERRIDE;
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
 
 private:
   Color mColor;
 };
 
 class FilterNodeTileSoftware : public FilterNodeSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "Tile"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
@@ -341,16 +349,17 @@ protected:
   bool mDisableG;
   bool mDisableB;
   bool mDisableA;
 };
 
 class FilterNodeTableTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "TableTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
   void FillLookupTableImpl(std::vector<Float>& aTableValues, uint8_t aTable[256]);
@@ -359,16 +368,17 @@ private:
   std::vector<Float> mTableG;
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeDiscreteTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "DiscreteTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
   void FillLookupTableImpl(std::vector<Float>& aTableValues, uint8_t aTable[256]);
@@ -378,16 +388,17 @@ private:
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeLinearTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
   FilterNodeLinearTransferSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "LinearTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
   void FillLookupTableImpl(Float aSlope, Float aIntercept, uint8_t aTable[256]);
@@ -401,16 +412,17 @@ private:
   Float mInterceptB;
   Float mInterceptA;
 };
 
 class FilterNodeGammaTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
   FilterNodeGammaTransferSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "GammaTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
   void FillLookupTableImpl(Float aAmplitude, Float aExponent, Float aOffset, uint8_t aTable[256]);
@@ -428,16 +440,17 @@ private:
   Float mOffsetB;
   Float mOffsetA;
 };
 
 class FilterNodeConvolveMatrixSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeConvolveMatrixSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "ConvolveMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aKernelSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Float* aMatrix, uint32_t aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Size &aKernelUnitLength) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntPoint &aTarget) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aEdgeMode) MOZ_OVERRIDE;
@@ -468,16 +481,17 @@ private:
   Size mKernelUnitLength;
   bool mPreserveAlpha;
 };
 
 class FilterNodeDisplacementMapSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeDisplacementMapSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "DisplacementMap"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aScale) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -490,16 +504,17 @@ private:
   ColorChannel mChannelX;
   ColorChannel mChannelY;
 };
 
 class FilterNodeTurbulenceSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeTurbulenceSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Turbulence"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Size &aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aRenderRect) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, bool aStitchable) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -514,16 +529,17 @@ private:
   bool mStitchable;
   TurbulenceType mType;
 };
 
 class FilterNodeArithmeticCombineSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeArithmeticCombineSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "ArithmeticCombine"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
@@ -534,16 +550,17 @@ private:
   Float mK3;
   Float mK4;
 };
 
 class FilterNodeCompositeSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeCompositeSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Composite"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
@@ -566,81 +583,89 @@ protected:
   // Implemented by subclasses.
   virtual Size StdDeviationXY() = 0;
 };
 
 class FilterNodeGaussianBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
   FilterNodeGaussianBlurSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "GaussianBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
 
 private:
   Float mStdDeviation;
 };
 
 class FilterNodeDirectionalBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
   FilterNodeDirectionalBlurSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "DirectionalBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlurDirection) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
 
 private:
   Float mStdDeviation;
   BlurDirection mBlurDirection;
 };
 
 class FilterNodeCropSoftware : public FilterNodeSoftware
 {
 public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "Crop"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Rect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 
 private:
   IntRect mCropRect;
 };
 
 class FilterNodePremultiplySoftware : public FilterNodeSoftware
 {
+public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "Premultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
 class FilterNodeUnpremultiplySoftware : public FilterNodeSoftware
 {
+public:
+  virtual const char* GetName() MOZ_OVERRIDE { return "Unpremultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
 template<typename LightType, typename LightingType>
 class FilterNodeLightingSoftware : public FilterNodeSoftware
 {
 public:
   FilterNodeLightingSoftware();
+  virtual const char* GetName() MOZ_OVERRIDE { return "Lighting"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Size &) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Point3D &) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Color &) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -27,9 +27,9 @@ endif
 
 ifdef SOLARIS_SUNPRO_CXX
 ImageScalingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
 BlurSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
 FilterProcessingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
 endif
 endif
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -31,12 +31,8 @@ include $(topsrcdir)/config/rules.mk
 ifdef GNU_CC
 # Disable spammy "missing initializer" GCC warning
 CFLAGS += -Wno-missing-field-initializers
 
 # Disable spammy "implicit conversion from enumeration type 'cairo_" warnings.
 CFLAGS += -Wno-conversion
 endif # GNU_CC
 
-ifndef MOZ_TREE_PIXMAN
-CFLAGS += $(MOZ_PIXMAN_CFLAGS)
-CXXFLAGS += $(MOZ_PIXMAN_CFLAGS)
-endif
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -5,10 +5,10 @@
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 CXXFLAGS += -I$(ANDROID_SOURCE)/hardware/libhardware/include
 endif
 
 DEFINES := $(filter-out -DUNICODE,$(DEFINES))
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
-CFLAGS   += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
+CFLAGS   += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
--- a/gfx/ipc/Makefile.in
+++ b/gfx/ipc/Makefile.in
@@ -1,8 +1,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 $(topsrcdir)/config/rules.mk
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -19,17 +19,17 @@ include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += \
         -I$(ANDROID_SOURCE)/frameworks/base/include/media/stagefright \
         -I$(ANDROID_SOURCE)/frameworks/base/include/media/stagefright/openmax \
         -I$(ANDROID_SOURCE)/frameworks/av/include/media/stagefright \
         -I$(ANDROID_SOURCE)/frameworks/native/include/media/openmax \
         $(NULL)
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 ifdef _MSC_VER
 ifeq ($(CPU_ARCH),x86_64)
 # Workaround compiler bug (Bug 795594)
 NO_PROFILE_GUIDED_OPTIMIZE := \
   LayerTreeInvalidation.cpp \
   Layers.cpp \
   $(NULL)
--- a/gfx/src/FilterSupport.cpp
+++ b/gfx/src/FilterSupport.cpp
@@ -1256,28 +1256,52 @@ PostFilterExtentsForPrimitive(const Filt
 
     case FilterPrimitiveDescription::eNone:
       return nsIntRect();
 
     case FilterPrimitiveDescription::eComposite:
     {
       uint32_t op = atts.GetUint(eCompositeOperator);
       if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
+        // The arithmetic composite primitive can draw outside the bounding
+        // box of its source images.
         const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
         MOZ_ASSERT(coefficients.Length() == 4);
+
+        // The calculation is:
+        // r = c[0] * in[0] * in[1] + c[1] * in[0] + c[2] * in[1] + c[3]
+        nsIntRegion region;
+        if (coefficients[0] > 0.0f) {
+          region = aInputExtents[0].Intersect(aInputExtents[1]);
+        }
+        if (coefficients[1] > 0.0f) {
+          region.Or(region, aInputExtents[0]);
+        }
+        if (coefficients[2] > 0.0f) {
+          region.Or(region, aInputExtents[1]);
+        }
         if (coefficients[3] > 0.0f) {
-          // The arithmetic composite primitive can draw outside the bounding
-          // box of its source images.
-          return ThebesIntRect(aDescription.PrimitiveSubregion());
+          region = ThebesIntRect(aDescription.PrimitiveSubregion());
         }
+        return region;
+      }
+      if (op == SVG_FECOMPOSITE_OPERATOR_IN) {
+        return aInputExtents[0].Intersect(aInputExtents[1]);
       }
       return ResultChangeRegionForPrimitive(aDescription, aInputExtents);
     }
 
     case FilterPrimitiveDescription::eFlood:
+    {
+      if (atts.GetColor(eFloodColor).a == 0.0f) {
+        return nsIntRect();
+      }
+      return ThebesIntRect(aDescription.PrimitiveSubregion());
+    }
+
     case FilterPrimitiveDescription::eTurbulence:
     case FilterPrimitiveDescription::eImage:
     {
       return ThebesIntRect(aDescription.PrimitiveSubregion());
     }
 
     case FilterPrimitiveDescription::eMorphology:
     {
--- a/gfx/src/Makefile.in
+++ b/gfx/src/Makefile.in
@@ -1,16 +1,16 @@
 #
 # 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_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 ifdef MOZ_WIDGET_GTK
 CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
 CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -5,18 +5,18 @@
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 ACDEFINES +=	-UWIN32_LEAN_AND_MEAN
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES := $(filter-out -DUNICODE,$(DEFINES))
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
-CFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
+CFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
--- a/image/src/Makefile.in
+++ b/image/src/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
 
 # Because imgFrame.cpp includes "cairo.h"
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -461,17 +461,17 @@ MY_RULES	:= $(DEPTH)/config/myrules.mk
 #
 CCC = $(CXX)
 
 # Java macros
 JAVA_GEN_DIR  = _javagen
 JAVA_DIST_DIR = $(DEPTH)/$(JAVA_GEN_DIR)
 JAVA_IFACES_PKG_NAME = org/mozilla/interfaces
 
-OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS)
+OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
 
 # NSPR_CFLAGS and NSS_CFLAGS must appear ahead of OS_INCLUDES to avoid Linux
 # builds wrongly picking up system NSPR/NSS header files.
 INCLUDES = \
   -I$(srcdir) \
   -I. \
   $(LOCAL_INCLUDES) \
   -I$(DIST)/include \
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -91,17 +91,19 @@ class StoreBuffer
         LifoAlloc *storage_;
 
         explicit MonoTypeBuffer() : storage_(nullptr) {}
         ~MonoTypeBuffer() { js_delete(storage_); }
 
         MonoTypeBuffer &operator=(const MonoTypeBuffer& other) MOZ_DELETE;
 
         bool init() {
-            storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
+            if (!storage_)
+                storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
+            clear();
             return bool(storage_);
         }
 
         void clear() {
             if (!storage_)
                 return;
 
             storage_->used() ? storage_->releaseAll() : storage_->freeAll();
@@ -165,17 +167,19 @@ class StoreBuffer
         LifoAlloc *storage_;
 
         explicit GenericBuffer() : storage_(nullptr) {}
         ~GenericBuffer() { js_delete(storage_); }
 
         GenericBuffer &operator=(const GenericBuffer& other) MOZ_DELETE;
 
         bool init() {
-            storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
+            if (!storage_)
+                storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
+            clear();
             return bool(storage_);
         }
 
         void clear() {
             if (!storage_)
                 return;
 
             storage_->used() ? storage_->releaseAll() : storage_->freeAll();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/baseline/bug945223.js
@@ -0,0 +1,12 @@
+// |jit-test| error: InternalError
+
+Array.prototype.__proto__ = Proxy.create({
+    getPropertyDescriptor: function(name) {
+	return (560566);
+    },
+}, null);
+function f() {}
+function g() {  }    
+var x = [f,f,f,undefined,g];
+for (var i = 0; i < 5; ++i)
+  y = x[i]("x");
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -791,17 +791,21 @@ InitFromBailout(JSContext *cx, HandleScr
     }
 
     uint32_t pcOff = script->pcToOffset(pc);
     bool isCall = IsCallPC(pc);
     BaselineScript *baselineScript = script->baselineScript();
 
 #ifdef DEBUG
     uint32_t expectedDepth;
-    if (ReconstructStackDepth(cx, script, resumeAfter ? GetNextPc(pc) : pc, &expectedDepth)) {
+    bool reachablePC;
+    if (!ReconstructStackDepth(cx, script, resumeAfter ? GetNextPc(pc) : pc, &expectedDepth, &reachablePC))
+        return false;
+
+    if (reachablePC) {
         if (op != JSOP_FUNAPPLY || !iter.moreFrames() || resumeAfter) {
             if (op == JSOP_FUNCALL) {
                 // For fun.call(this, ...); the reconstructStackDepth will
                 // include the this. When inlining that is not included.
                 // So the exprStackSlots will be one less.
                 JS_ASSERT(expectedDepth - exprStackSlots <= 1);
             } else if (iter.moreFrames() && (IsGetPropPC(pc) || IsSetPropPC(pc))) {
                 // Accessors coming out of ion are inlined via a complete
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1810,17 +1810,17 @@ DoCompareFallback(JSContext *cx, Baselin
     if ((lhs.isNumber() && rhs.isUndefined()) ||
         (lhs.isUndefined() && rhs.isNumber()))
     {
         IonSpew(IonSpew_BaselineIC, "  Generating %s(%s, %s) stub", js_CodeName[op],
                     rhs.isUndefined() ? "Number" : "Undefined",
                     rhs.isUndefined() ? "Undefined" : "Number");
         ICCompare_NumberWithUndefined::Compiler compiler(cx, op, lhs.isUndefined());
         ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!stub)
+        if (!doubleStub)
             return false;
 
         stub->addNewStub(doubleStub);
         return true;
     }
 
     if (lhs.isBoolean() && rhs.isBoolean()) {
         IonSpew(IonSpew_BaselineIC, "  Generating %s(Boolean, Boolean) stub", js_CodeName[op]);
@@ -4291,29 +4291,41 @@ ICGetElemNativeCompiler::generateStubCod
 #if JS_HAS_NO_SUCH_METHOD
         if (isCallElem_) {
             Label afterNoSuchMethod;
             Label skipNoSuchMethod;
 
             masm.branchTestUndefined(Assembler::NotEqual, valAddr, &skipNoSuchMethod);
 
             GeneralRegisterSet regs = availableGeneralRegs(0);
+            regs.take(R1);
+            regs.take(R0);
             regs.takeUnchecked(objReg);
-            regs.take(R1);
-            Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
             if (popR1)
                 masm.pop(R1.scratchReg());
-            enterStubFrame(masm, scratch);
+
+            // Box and push obj and key onto baseline frame stack for decompiler.
+            masm.tagValue(JSVAL_TYPE_OBJECT, objReg, R0);
+            EmitStowICValues(masm, 2);
+
+            regs.add(R0);
+            regs.takeUnchecked(objReg);
+
+            enterStubFrame(masm, regs.getAnyExcluding(BaselineTailCallReg));
 
             masm.pushValue(R1);
             masm.push(objReg);
             if (!callVM(LookupNoSuchMethodHandlerInfo, masm))
                 return false;
 
             leaveStubFrame(masm);
+
+            // Pop pushed obj and key from baseline stack.
+            EmitUnstowICValues(masm, 2, /* discard = */ true);
+
             // Result is already in R0
             masm.jump(&afterNoSuchMethod);
             masm.bind(&skipNoSuchMethod);
 
             if (popR1)
                 masm.pop(R1.scratchReg());
             masm.loadValue(valAddr, R0);
             masm.bind(&afterNoSuchMethod);
@@ -4467,34 +4479,48 @@ ICGetElem_Dense::Compiler::generateStubC
 #if JS_HAS_NO_SUCH_METHOD
     entersStubFrame_ = true;
     if (isCallElem_) {
         Label afterNoSuchMethod;
         Label skipNoSuchMethod;
         regs = availableGeneralRegs(0);
         regs.takeUnchecked(obj);
         regs.takeUnchecked(key);
+        regs.takeUnchecked(BaselineTailCallReg);
         ValueOperand val = regs.takeValueOperand();
 
         masm.loadValue(element, val);
         masm.branchTestUndefined(Assembler::NotEqual, val, &skipNoSuchMethod);
+
+        // Box and push obj and key onto baseline frame stack for decompiler.
+        EmitRestoreTailCallReg(masm);
+        masm.tagValue(JSVAL_TYPE_OBJECT, obj, val);
+        masm.pushValue(val);
+        masm.tagValue(JSVAL_TYPE_INT32, key, val);
+        masm.pushValue(val);
+        EmitRepushTailCallReg(masm);
+
         regs.add(val);
 
         // Call __noSuchMethod__ checker.  Object pointer is in objReg.
         enterStubFrame(masm, regs.getAnyExcluding(BaselineTailCallReg));
 
         regs.take(val);
 
         masm.tagValue(JSVAL_TYPE_INT32, key, val);
         masm.pushValue(val);
         masm.push(obj);
         if (!callVM(LookupNoSuchMethodHandlerInfo, masm))
             return false;
 
         leaveStubFrame(masm);
+
+        // Pop pushed obj and key from baseline stack.
+        EmitUnstowICValues(masm, 2, /* discard = */ true);
+
         // Result is already in R0
         masm.jump(&afterNoSuchMethod);
         masm.bind(&skipNoSuchMethod);
 
         masm.moveValue(val, R0);
         masm.bind(&afterNoSuchMethod);
     } else {
         masm.loadValue(element, R0);
@@ -4698,29 +4724,43 @@ ICGetElem_Arguments::Compiler::generateS
     if (isCallElem_) {
         Label afterNoSuchMethod;
         Label skipNoSuchMethod;
 
         masm.branchTestUndefined(Assembler::NotEqual, tempVal, &skipNoSuchMethod);
 
         // Call __noSuchMethod__ checker.  Object pointer is in objReg.
         regs = availableGeneralRegs(0);
-        // R1 and objReg are guaranteed not to overlap.
         regs.takeUnchecked(objReg);
-        regs.take(R1);
-        masm.tagValue(JSVAL_TYPE_INT32, idxReg, R1);
-        scratchReg = regs.takeAnyExcluding(BaselineTailCallReg);
-        enterStubFrame(masm, scratchReg);
-
-        masm.pushValue(R1);
+        regs.takeUnchecked(idxReg);
+        regs.takeUnchecked(BaselineTailCallReg);
+        ValueOperand val = regs.takeValueOperand();
+
+        // Box and push obj and key onto baseline frame stack for decompiler.
+        EmitRestoreTailCallReg(masm);
+        masm.tagValue(JSVAL_TYPE_OBJECT, objReg, val);
+        masm.pushValue(val);
+        masm.tagValue(JSVAL_TYPE_INT32, idxReg, val);
+        masm.pushValue(val);
+        EmitRepushTailCallReg(masm);
+
+        regs.add(val);
+        enterStubFrame(masm, regs.getAnyExcluding(BaselineTailCallReg));
+        regs.take(val);
+
+        masm.pushValue(val);
         masm.push(objReg);
         if (!callVM(LookupNoSuchMethodHandlerInfo, masm))
             return false;
 
         leaveStubFrame(masm);
+
+        // Pop pushed obj and key from baseline stack.
+        EmitUnstowICValues(masm, 2, /* discard = */ true);
+
         // Result is already in R0
         masm.jump(&afterNoSuchMethod);
         masm.bind(&skipNoSuchMethod);
 
         masm.moveValue(tempVal, R0);
         masm.bind(&afterNoSuchMethod);
     } else {
         masm.moveValue(tempVal, R0);
@@ -6528,26 +6568,43 @@ ICGetPropNativeCompiler::generateStubCod
         Label afterNoSuchMethod;
         Label skipNoSuchMethod;
 
         masm.push(objReg);
         masm.loadValue(result, R0);
         masm.branchTestUndefined(Assembler::NotEqual, R0, &skipNoSuchMethod);
 
         masm.pop(objReg);
-        enterStubFrame(masm, scratch);
-
-        masm.movePtr(ImmGCPtr(propName_.get()), R1.scratchReg());
-        masm.tagValue(JSVAL_TYPE_STRING, R1.scratchReg(), R1);
-        masm.pushValue(R1);
+
+        // Call __noSuchMethod__ checker.  Object pointer is in objReg.
+        regs = availableGeneralRegs(0);
+        regs.takeUnchecked(objReg);
+        regs.takeUnchecked(BaselineTailCallReg);
+        ValueOperand val = regs.takeValueOperand();
+
+        // Box and push obj onto baseline frame stack for decompiler.
+        EmitRestoreTailCallReg(masm);
+        masm.tagValue(JSVAL_TYPE_OBJECT, objReg, val);
+        masm.pushValue(val);
+        EmitRepushTailCallReg(masm);
+
+        enterStubFrame(masm, regs.getAnyExcluding(BaselineTailCallReg));
+
+        masm.movePtr(ImmGCPtr(propName_.get()), val.scratchReg());
+        masm.tagValue(JSVAL_TYPE_STRING, val.scratchReg(), val);
+        masm.pushValue(val);
         masm.push(objReg);
         if (!callVM(LookupNoSuchMethodHandlerInfo, masm))
             return false;
 
         leaveStubFrame(masm);
+
+        // Pop pushed obj from baseline stack.
+        EmitUnstowICValues(masm, 1, /* discard = */ true);
+
         masm.jump(&afterNoSuchMethod);
         masm.bind(&skipNoSuchMethod);
 
         // Pop pushed objReg.
         masm.addPtr(Imm32(sizeof(void *)), BaselineStackReg);
         masm.bind(&afterNoSuchMethod);
     } else {
         masm.loadValue(result, R0);
--- a/js/src/jit/InlineList.h
+++ b/js/src/jit/InlineList.h
@@ -212,23 +212,18 @@ class InlineListNode : public InlineForw
     InlineListNode<T> *prev;
 };
 
 template <typename T>
 class InlineList : protected InlineListNode<T>
 {
     typedef InlineListNode<T> Node;
 
-    // Silence MSVC warning C4355
-    InlineList<T> *thisFromConstructor() {
-        return this;
-    }
-
   public:
-    InlineList() : InlineListNode<T>(thisFromConstructor(), thisFromConstructor())
+    InlineList() : InlineListNode<T>(MOZ_THIS_IN_INITIALIZER_LIST(), MOZ_THIS_IN_INITIALIZER_LIST())
     { }
 
   public:
     typedef InlineListIterator<T> iterator;
     typedef InlineListReverseIterator<T> reverse_iterator;
 
   public:
     iterator begin() const {
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -431,56 +431,71 @@ class TypeAnalyzer
 
     bool analyze();
 };
 
 } /* anonymous namespace */
 
 // Try to specialize this phi based on its non-cyclic inputs.
 static MIRType
-GuessPhiType(MPhi *phi)
+GuessPhiType(MPhi *phi, bool *hasInputsWithEmptyTypes)
 {
+    *hasInputsWithEmptyTypes = false;
+
     MIRType type = MIRType_None;
     bool convertibleToFloat32 = false;
+    bool hasPhiInputs = false;
     for (size_t i = 0, e = phi->numOperands(); i < e; i++) {
         MDefinition *in = phi->getOperand(i);
         if (in->isPhi()) {
+            hasPhiInputs = true;
             if (!in->toPhi()->triedToSpecialize())
                 continue;
             if (in->type() == MIRType_None) {
                 // The operand is a phi we tried to specialize, but we were
                 // unable to guess its type. propagateSpecialization will
                 // propagate the type to this phi when it becomes known.
                 continue;
             }
         }
+
+        // Ignore operands which we've never observed.
+        if (in->resultTypeSet() && in->resultTypeSet()->empty()) {
+            *hasInputsWithEmptyTypes = true;
+            continue;
+        }
+
         if (type == MIRType_None) {
             type = in->type();
             if (in->canProduceFloat32())
                 convertibleToFloat32 = true;
             continue;
         }
         if (type != in->type()) {
-            // Ignore operands which we've never observed.
-            if (in->resultTypeSet() && in->resultTypeSet()->empty())
-                continue;
-
             if (convertibleToFloat32 && in->type() == MIRType_Float32) {
                 // If we only saw definitions that can be converted into Float32 before and
                 // encounter a Float32 value, promote previous values to Float32
                 type = MIRType_Float32;
             } else if (IsNumberType(type) && IsNumberType(in->type())) {
                 // Specialize phis with int32 and double operands as double.
                 type = MIRType_Double;
                 convertibleToFloat32 &= in->canProduceFloat32();
             } else {
                 return MIRType_Value;
             }
         }
     }
+
+    if (type == MIRType_None && !hasPhiInputs) {
+        // All inputs are non-phis with empty typesets. Use MIRType_Value
+        // in this case, as it's impossible to get better type information.
+        JS_ASSERT(*hasInputsWithEmptyTypes);
+        type = MIRType_Value;
+    }
+
     return type;
 }
 
 bool
 TypeAnalyzer::respecialize(MPhi *phi, MIRType type)
 {
     if (phi->type() == type)
         return true;
@@ -532,51 +547,79 @@ TypeAnalyzer::propagateSpecialization(MP
     }
 
     return true;
 }
 
 bool
 TypeAnalyzer::specializePhis()
 {
+    Vector<MPhi *, 0, SystemAllocPolicy> phisWithEmptyInputTypes;
+
     for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) {
         if (mir->shouldCancel("Specialize Phis (main loop)"))
             return false;
 
         for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
-            MIRType type = GuessPhiType(*phi);
+            bool hasInputsWithEmptyTypes;
+            MIRType type = GuessPhiType(*phi, &hasInputsWithEmptyTypes);
             phi->specialize(type);
             if (type == MIRType_None) {
                 // We tried to guess the type but failed because all operands are
                 // phis we still have to visit. Set the triedToSpecialize flag but
                 // don't propagate the type to other phis, propagateSpecialization
                 // will do that once we know the type of one of the operands.
+
+                // Edge case: when this phi has a non-phi input with an empty
+                // typeset, it's possible for two phis to have a cyclic
+                // dependency and they will both have MIRType_None. Specialize
+                // such phis to MIRType_Value later on.
+                if (hasInputsWithEmptyTypes && !phisWithEmptyInputTypes.append(*phi))
+                    return false;
                 continue;
             }
             if (!propagateSpecialization(*phi))
                 return false;
         }
     }
 
-    while (!phiWorklist_.empty()) {
-        if (mir->shouldCancel("Specialize Phis (worklist)"))
-            return false;
+    do {
+        while (!phiWorklist_.empty()) {
+            if (mir->shouldCancel("Specialize Phis (worklist)"))
+                return false;
+
+            MPhi *phi = popPhi();
+            if (!propagateSpecialization(phi))
+                return false;
+        }
 
-        MPhi *phi = popPhi();
-        if (!propagateSpecialization(phi))
-            return false;
-    }
+        // When two phis have a cyclic dependency and inputs that have an empty
+        // typeset (which are ignored by GuessPhiType), we may still have to
+        // specialize these to MIRType_Value.
+        while (!phisWithEmptyInputTypes.empty()) {
+            if (mir->shouldCancel("Specialize Phis (phisWithEmptyInputTypes)"))
+                return false;
+
+            MPhi *phi = phisWithEmptyInputTypes.popCopy();
+            if (phi->type() == MIRType_None) {
+                phi->specialize(MIRType_Value);
+                if (!propagateSpecialization(phi))
+                    return false;
+            }
+        }
+    } while (!phiWorklist_.empty());
 
     return true;
 }
 
 void
 TypeAnalyzer::adjustPhiInputs(MPhi *phi)
 {
     MIRType phiType = phi->type();
+    JS_ASSERT(phiType != MIRType_None);
 
     // If we specialized a type that's not Value, there are 3 cases:
     // 1. Every input is of that type.
     // 2. Every observed input is of that type (i.e., some inputs haven't been executed yet).
     // 3. Inputs were doubles and int32s, and was specialized to double.
     if (phiType != MIRType_Value) {
         for (size_t i = 0, e = phi->numOperands(); i < e; i++) {
             MDefinition *in = phi->getOperand(i);
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -3841,17 +3841,16 @@ IonBuilder::inlineScriptedCall(CallInfo 
                                                      this->info().executionMode());
     if (!info)
         return false;
 
     MIRGraphReturns returns(alloc());
     AutoAccumulateReturns aar(graph(), returns);
 
     // Build the graph.
-    JS_ASSERT_IF(analysisContext, !analysisContext->isExceptionPending());
     IonBuilder inlineBuilder(analysisContext, compartment,
                              &alloc(), &graph(), constraints(), &inspector, info, nullptr,
                              inliningDepth_ + 1, loopDepth_);
     if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
         if (analysisContext && analysisContext->isExceptionPending()) {
             IonSpew(IonSpew_Abort, "Inline builder raised exception.");
             abortReason_ = AbortReason_Error;
             return false;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2936,20 +2936,20 @@ jit::PropertyReadNeedsTypeBarrier(JSCont
             if (propertycx)
                 typeObj->ensureTrackedProperty(propertycx, NameToId(name));
 
             if (!typeObj->unknownProperties()) {
                 types::HeapTypeSetKey property = typeObj->property(NameToId(name));
                 if (property.maybeTypes()) {
                     types::TypeSet::TypeList types;
                     if (!property.maybeTypes()->enumerateTypes(&types))
-                        return false;
+                        break;
                     if (types.length()) {
-                        if (!observed->addType(types[0], GetIonContext()->temp->lifoAlloc()))
-                            return false;
+                        // Note: the return value here is ignored.
+                        observed->addType(types[0], GetIonContext()->temp->lifoAlloc());
                         break;
                     }
                 }
             }
 
             obj = obj->getProto();
         }
     }
--- a/js/src/jit/PerfSpewer.cpp
+++ b/js/src/jit/PerfSpewer.cpp
@@ -211,17 +211,17 @@ PerfSpewer::writeProfile(JSScript *scrip
         uint32_t thisFunctionIndex = nextFunctionIndex++;
 
         size_t size = code->instructionsSize();
         if (size > 0) {
             fprintf(PerfFilePtr, "%zx %zx %s:%d: Func%02d\n",
                     reinterpret_cast<uintptr_t>(code->raw()),
                     size,
                     script->filename(),
-                    script->lineno,
+                    script->lineno(),
                     thisFunctionIndex);
         }
         unlockPerfMap();
         return;
     }
 
     if (PerfBlockEnabled() && basicBlocks_.length() > 0) {
         if (!lockPerfMap())
@@ -232,32 +232,32 @@ PerfSpewer::writeProfile(JSScript *scrip
         uintptr_t funcEndInlineCode = funcStart + masm.actualOffset(endInlineCode.offset());
         uintptr_t funcEnd = funcStart + code->instructionsSize();
 
         // function begins with the prologue, which is located before the first basic block
         size_t prologueSize = masm.actualOffset(basicBlocks_[0].start.offset());
 
         if (prologueSize > 0) {
             fprintf(PerfFilePtr, "%zx %zx %s:%d: Func%02d-Prologue\n",
-                    funcStart, prologueSize, script->filename(), script->lineno, thisFunctionIndex);
+                    funcStart, prologueSize, script->filename(), script->lineno(), thisFunctionIndex);
         }
 
         uintptr_t cur = funcStart + prologueSize;
         for (uint32_t i = 0; i < basicBlocks_.length(); i++) {
             Record &r = basicBlocks_[i];
 
             uintptr_t blockStart = funcStart + masm.actualOffset(r.start.offset());
             uintptr_t blockEnd = funcStart + masm.actualOffset(r.end.offset());
 
             JS_ASSERT(cur <= blockStart);
             if (cur < blockStart) {
                 fprintf(PerfFilePtr, "%zx %zx %s:%d: Func%02d-Block?\n",
                         static_cast<uintptr_t>(cur),
                         static_cast<uintptr_t>(blockStart - cur),
-                        script->filename(), script->lineno,
+                        script->filename(), script->lineno(),
                         thisFunctionIndex);
             }
             cur = blockEnd;
 
             size_t size = blockEnd - blockStart;
 
             if (size > 0) {
                 fprintf(PerfFilePtr, "%zx %zx %s:%d:%d: Func%02d-Block%d\n",
@@ -266,25 +266,25 @@ PerfSpewer::writeProfile(JSScript *scrip
                         thisFunctionIndex, r.id);
             }
         }
 
         JS_ASSERT(cur <= funcEndInlineCode);
         if (cur < funcEndInlineCode) {
             fprintf(PerfFilePtr, "%zx %zx %s:%d: Func%02d-Epilogue\n",
                     cur, funcEndInlineCode - cur,
-                    script->filename(), script->lineno,
+                    script->filename(), script->lineno(),
                     thisFunctionIndex);
         }
 
         JS_ASSERT(funcEndInlineCode <= funcEnd);
         if (funcEndInlineCode < funcEnd) {
             fprintf(PerfFilePtr, "%zx %zx %s:%d: Func%02d-OOL\n",
                     funcEndInlineCode, funcEnd - funcEndInlineCode,
-                    script->filename(), script->lineno,
+                    script->filename(), script->lineno(),
                     thisFunctionIndex);
         }
 
         unlockPerfMap();
         return;
     }
 }
 
@@ -296,17 +296,17 @@ js::jit::writePerfSpewerBaselineProfile(
 
     if (!lockPerfMap())
         return;
 
     size_t size = code->instructionsSize();
     if (size > 0) {
         fprintf(PerfFilePtr, "%zx %zx %s:%d: Baseline\n",
                 reinterpret_cast<uintptr_t>(code->raw()),
-                size, script->filename(), script->lineno);
+                size, script->filename(), script->lineno());
     }
 
     unlockPerfMap();
 }
 
 void
 js::jit::writePerfSpewerIonCodeProfile(IonCode *code, const char *msg)
 {
--- a/js/src/jit/arm/BaselineHelpers-arm.h
+++ b/js/src/jit/arm/BaselineHelpers-arm.h
@@ -21,16 +21,22 @@ static const size_t ICStackValueOffset =
 
 inline void
 EmitRestoreTailCallReg(MacroAssembler &masm)
 {
     // No-op on ARM because link register is always holding the return address.
 }
 
 inline void
+EmitRepushTailCallReg(MacroAssembler &masm)
+{
+    // No-op on ARM because link register is always holding the return address.
+}
+
+inline void
 EmitCallIC(CodeOffsetLabel *patchOffset, MacroAssembler &masm)
 {
     // Move ICEntry offset into BaselineStubReg
     CodeOffsetLabel offset = masm.movWithPatch(ImmWord(-1), BaselineStubReg);
     *patchOffset = offset;
 
     // Load stub pointer into BaselineStubReg
     masm.loadPtr(Address(BaselineStubReg, ICEntry::offsetOfFirstStub()), BaselineStubReg);
@@ -191,28 +197,35 @@ EmitStowICValues(MacroAssembler &masm, i
         // Stow R0 and R1
         masm.pushValue(R0);
         masm.pushValue(R1);
         break;
     }
 }
 
 inline void
-EmitUnstowICValues(MacroAssembler &masm, int values)
+EmitUnstowICValues(MacroAssembler &masm, int values, bool discard = false)
 {
     JS_ASSERT(values >= 0 && values <= 2);
     switch(values) {
       case 1:
         // Unstow R0
-        masm.popValue(R0);
+        if (discard)
+            masm.addPtr(Imm32(sizeof(Value)), BaselineStackReg);
+        else
+            masm.popValue(R0);
         break;
       case 2:
         // Unstow R0 and R1
-        masm.popValue(R1);
-        masm.popValue(R0);
+        if (discard) {
+            masm.addPtr(Imm32(sizeof(Value) * 2), BaselineStackReg);
+        } else {
+            masm.popValue(R1);
+            masm.popValue(R0);
+        }
         break;
     }
 }
 
 inline void
 EmitCallTypeUpdateIC(MacroAssembler &masm, IonCode *code, uint32_t objectOffset)
 {
     JS_ASSERT(R2 == ValueOperand(r1, r0));
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -276,17 +276,21 @@ CodeGeneratorShared::encode(LSnapshot *s
         // bailouts.
         DebugOnly<jsbytecode *> bailPC = pc;
         if (mir->mode() == MResumePoint::ResumeAfter)
           bailPC = GetNextPc(pc);
 
 #ifdef DEBUG
         if (GetIonContext()->cx) {
             uint32_t stackDepth;
-            if (ReconstructStackDepth(GetIonContext()->cx, script, bailPC, &stackDepth)) {
+            bool reachablePC;
+            if (!ReconstructStackDepth(GetIonContext()->cx, script, bailPC, &stackDepth, &reachablePC))
+                return false;
+
+            if (reachablePC) {
                 if (JSOp(*bailPC) == JSOP_FUNCALL) {
                     // For fun.call(this, ...); the reconstructStackDepth will
                     // include the this. When inlining that is not included.
                     // So the exprStackSlots will be one less.
                     JS_ASSERT(stackDepth - exprStack <= 1);
                 } else if (JSOp(*bailPC) != JSOP_FUNAPPLY &&
                            !IsGetPropPC(bailPC) && !IsSetPropPC(bailPC))
                 {
--- a/js/src/jit/x64/BaselineHelpers-x64.h
+++ b/js/src/jit/x64/BaselineHelpers-x64.h
@@ -21,16 +21,22 @@ static const size_t ICStackValueOffset =
 
 inline void
 EmitRestoreTailCallReg(MacroAssembler &masm)
 {
     masm.pop(BaselineTailCallReg);
 }
 
 inline void
+EmitRepushTailCallReg(MacroAssembler &masm)
+{
+    masm.push(BaselineTailCallReg);
+}
+
+inline void
 EmitCallIC(CodeOffsetLabel *patchOffset, MacroAssembler &masm)
 {
     // Move ICEntry offset into BaselineStubReg
     CodeOffsetLabel offset = masm.movWithPatch(ImmWord(-1), BaselineStubReg);
     *patchOffset = offset;
 
     // Load stub pointer into BaselineStubReg
     masm.loadPtr(Address(BaselineStubReg, (int32_t) ICEntry::offsetOfFirstStub()),
@@ -177,31 +183,38 @@ EmitStowICValues(MacroAssembler &masm, i
         masm.pushValue(R0);
         masm.pushValue(R1);
         masm.push(BaselineTailCallReg);
         break;
     }
 }
 
 inline void
-EmitUnstowICValues(MacroAssembler &masm, int values)
+EmitUnstowICValues(MacroAssembler &masm, int values, bool discard = false)
 {
     JS_ASSERT(values >= 0 && values <= 2);
     switch(values) {
       case 1:
         // Unstow R0
         masm.pop(BaselineTailCallReg);
-        masm.popValue(R0);
+        if (discard)
+            masm.addPtr(Imm32(sizeof(Value)), BaselineStackReg);
+        else
+            masm.popValue(R0);
         masm.push(BaselineTailCallReg);
         break;
       case 2:
         // Unstow R0 and R1
         masm.pop(BaselineTailCallReg);
-        masm.popValue(R1);
-        masm.popValue(R0);
+        if (discard) {
+            masm.addPtr(Imm32(sizeof(Value) * 2), BaselineStackReg);
+        } else {
+            masm.popValue(R1);
+            masm.popValue(R0);
+        }
         masm.push(BaselineTailCallReg);
         break;
     }
 }
 
 inline void
 EmitCallTypeUpdateIC(MacroAssembler &masm, IonCode *code, uint32_t objectOffset)
 {
--- a/js/src/jit/x86/BaselineHelpers-x86.h
+++ b/js/src/jit/x86/BaselineHelpers-x86.h
@@ -21,16 +21,22 @@ static const size_t ICStackValueOffset =
 
 inline void
 EmitRestoreTailCallReg(MacroAssembler &masm)
 {
     masm.pop(BaselineTailCallReg);
 }
 
 inline void
+EmitRepushTailCallReg(MacroAssembler &masm)
+{
+    masm.push(BaselineTailCallReg);
+}
+
+inline void
 EmitCallIC(CodeOffsetLabel *patchOffset, MacroAssembler &masm)
 {
     // Move ICEntry offset into BaselineStubReg
     CodeOffsetLabel offset = masm.movWithPatch(ImmWord(-1), BaselineStubReg);
     *patchOffset = offset;
 
     // Load stub pointer into BaselineStubReg
     masm.loadPtr(Address(BaselineStubReg, (int32_t) ICEntry::offsetOfFirstStub()),
@@ -183,31 +189,38 @@ EmitStowICValues(MacroAssembler &masm, i
         masm.pushValue(R0);
         masm.pushValue(R1);
         masm.push(BaselineTailCallReg);
         break;
     }
 }
 
 inline void
-EmitUnstowICValues(MacroAssembler &masm, int values)
+EmitUnstowICValues(MacroAssembler &masm, int values, bool discard = false)
 {
     JS_ASSERT(values >= 0 && values <= 2);
     switch(values) {
       case 1:
         // Unstow R0
         masm.pop(BaselineTailCallReg);
-        masm.popValue(R0);
+        if (discard)
+            masm.addPtr(Imm32(sizeof(Value)), BaselineStackReg);
+        else
+            masm.popValue(R0);
         masm.push(BaselineTailCallReg);
         break;
       case 2:
         // Unstow R0 and R1
         masm.pop(BaselineTailCallReg);
-        masm.popValue(R1);
-        masm.popValue(R0);
+        if (discard) {
+            masm.addPtr(Imm32(sizeof(Value) * 2), BaselineStackReg);
+        } else {
+            masm.popValue(R1);
+            masm.popValue(R0);
+        }
         masm.push(BaselineTailCallReg);
         break;
     }
 }
 
 inline void
 EmitCallTypeUpdateIC(MacroAssembler &masm, IonCode *code, uint32_t objectOffset)
 {
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -12,18 +12,16 @@
 #include "mozilla/MemoryReporting.h"
 
 #include "js/Vector.h"
 #include "vm/Runtime.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
-#pragma warning(push)
-#pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
 #endif
 
 struct DtoaState;
 
 extern void
 js_ReportOutOfMemory(js::ThreadSafeContext *cx);
 
 extern void
@@ -1084,12 +1082,11 @@ class AutoLockForExclusiveAccess
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 } /* namespace js */
 
 #ifdef _MSC_VER
 #pragma warning(pop)
-#pragma warning(pop)
 #endif
 
 #endif /* jscntxt_h */
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -692,26 +692,26 @@ BytecodeParser::parse()
     }
 
     return true;
 }
 
 #ifdef DEBUG
 
 bool
-js::ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth)
+js::ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth, bool *reachablePC)
 {
     BytecodeParser parser(cx, script);
     if (!parser.parse())
         return false;
 
-    if (!parser.isReachable(pc))
-        return false;
+    *reachablePC = parser.isReachable(pc);
 
-    *depth = parser.stackDepthAtPC(pc);
+    if (*reachablePC)
+        *depth = parser.stackDepthAtPC(pc);
 
     return true;
 }
 
 /*
  * If pc != nullptr, include a prefix indicating whether the PC is at the
  * current line. If showAll is true, include the source note type and the
  * entry stack depth.
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -353,17 +353,17 @@ StackDefs(JSScript *script, jsbytecode *
 
 #ifdef DEBUG
 /*
  * Given bytecode address pc in script's main program code, compute the operand
  * stack depth just before (JSOp) *pc executes.  If *pc is not reachable, return
  * false.
  */
 extern bool
-ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth);
+ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth, bool *reachablePC);
 #endif
 
 }  /* namespace js */
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -42,18 +42,16 @@
 #include "vm/DateTime.h"
 #include "vm/SPSProfiler.h"
 #include "vm/Stack.h"
 #include "vm/ThreadPool.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
-#pragma warning(push)
-#pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
 #endif
 
 namespace js {
 
 class PerThreadData;
 class ThreadSafeContext;
 class AutoKeepAtoms;
 
@@ -2067,12 +2065,11 @@ class AutoProtectHeapForCompilation
 #endif
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 } /* namespace js */
 
 #ifdef _MSC_VER
 #pragma warning(pop)
-#pragma warning(pop)
 #endif
 
 #endif /* vm_Runtime_h */
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -669,17 +669,17 @@ XPCJSRuntime::SuspectWrappedNative(XPCWr
 
 bool
 CanSkipWrappedJS(nsXPCWrappedJS *wrappedJS)
 {
     JSObject *obj = wrappedJS->GetJSObjectPreserveColor();
     // If traversing wrappedJS wouldn't release it, nor
     // cause any other objects to be added to the graph, no
     // need to add it to the graph at all.
-    bool isRootWrappedJS = wrappedJS->GetRootWrapper() == wrappedJS;
+    bool isRootWrappedJS = wrappedJS->IsRootWrapper();
     if (nsCCUncollectableMarker::sGeneration &&
         (!obj || !xpc_IsGrayGCThing(obj)) &&
         !wrappedJS->IsSubjectToFinalization() &&
         (isRootWrappedJS || CanSkipWrappedJS(wrappedJS->GetRootWrapper()))) {
         if (!wrappedJS->IsAggregatedToNative() || !isRootWrappedJS) {
             return true;
         } else {
             nsISupports* agg = wrappedJS->GetAggregatedNativeObject();
@@ -2943,17 +2943,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
    mDetachedWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DETACHED_NATIVE_PROTO_MAP_SIZE)),
    mGCIsRunning(false),
    mWrappedJSToReleaseArray(),
    mNativesToReleaseArray(),
    mDoingFinalization(false),
    mVariantRoots(nullptr),
    mWrappedJSRoots(nullptr),
    mObjectHolderRoots(nullptr),
-   mWatchdogManager(new WatchdogManager(this)),
+   mWatchdogManager(new WatchdogManager(MOZ_THIS_IN_INITIALIZER_LIST())),
    mJunkScope(nullptr),
    mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite())
 {
     DOM_InitInterfaces();
 
     // these jsids filled in later when we have a JSContext to work with.
     mStrIDs[0] = JSID_VOID;
 
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -5,19 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Class that wraps JS objects to appear as XPCOM objects. */
 
 #include "xpcprivate.h"
 #include "jsprf.h"
 #include "nsCxPusher.h"
 #include "nsContentUtils.h"
-#include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
-#include "nsTextFormatter.h"
 
 using namespace mozilla;
 
 // NOTE: much of the fancy footwork is done in xpcstubs.cpp
 
 NS_IMETHODIMP
 NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
    (void *p, nsCycleCollectionTraversalCallback &cb)
@@ -46,25 +44,22 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrapp
 
     if (refcnt > 1) {
         // nsXPCWrappedJS roots its mJSObj when its refcount is > 1, see
         // the comment above nsXPCWrappedJS::AddRef.
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSObj");
         cb.NoteJSChild(tmp->GetJSObjectPreserveColor());
     }
 
-    nsXPCWrappedJS* root = tmp->GetRootWrapper();
-    if (root == tmp) {
-        // The root wrapper keeps the aggregated native object alive.
+    if (tmp->IsRootWrapper()) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "aggregated native");
         cb.NoteXPCOMChild(tmp->GetAggregatedNativeObject());
     } else {
-        // Non-root wrappers keep their root alive.
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "root");
-        cb.NoteXPCOMChild(static_cast<nsIXPConnectWrappedJS*>(root));
+        cb.NoteXPCOMChild(static_cast<nsIXPConnectWrappedJS*>(tmp->GetRootWrapper()));
     }
 
     return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXPCWrappedJS)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPCWrappedJS)
@@ -214,17 +209,17 @@ nsXPCWrappedJS::GetTraceName(JSTracer* t
                                             (trc->debugPrintArg);
     JS_snprintf(buf, bufsize, "nsXPCWrappedJS[%s,0x%p:0x%p].mJSObj",
                 self->GetClass()->GetInterfaceName(), self, self->mXPTCStub);
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::GetWeakReference(nsIWeakReference** aInstancePtr)
 {
-    if (mRoot != this)
+    if (!IsRootWrapper())
         return mRoot->GetWeakReference(aInstancePtr);
 
     return nsSupportsWeakReference::GetWeakReference(aInstancePtr);
 }
 
 JSObject*
 nsXPCWrappedJS::GetJSObject()
 {
@@ -339,68 +334,66 @@ return_wrapper:
 
 nsXPCWrappedJS::nsXPCWrappedJS(JSContext* cx,
                                JSObject* aJSObj,
                                nsXPCWrappedJSClass* aClass,
                                nsXPCWrappedJS* root,
                                nsISupports* aOuter)
     : mJSObj(aJSObj),
       mClass(aClass),
-      mRoot(root ? root : this),
+      mRoot(root ? root : MOZ_THIS_IN_INITIALIZER_LIST()),
       mNext(nullptr),
       mOuter(root ? nullptr : aOuter)
 {
     InitStub(GetClass()->GetIID());
 
     // intentionally do double addref - see Release().
     NS_ADDREF_THIS();
     NS_ADDREF_THIS();
     NS_ADDREF(aClass);
     NS_IF_ADDREF(mOuter);
 
-    if (mRoot != this)
+    if (!IsRootWrapper())
         NS_ADDREF(mRoot);
 
 }
 
 nsXPCWrappedJS::~nsXPCWrappedJS()
 {
     NS_PRECONDITION(0 == mRefCnt, "refcounting error");
 
-    if (mRoot == this) {
-        // Remove this root wrapper from the map
+    if (IsRootWrapper()) {
         XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
         JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
         if (map)
             map->Remove(this);
     }
     Unlink();
 }
 
 void
 nsXPCWrappedJS::Unlink()
 {
     if (IsValid()) {
         XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
         if (rt) {
-            if (mRoot == this) {
-                // remove this root wrapper from the map
+            if (IsRootWrapper()) {
                 JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
                 if (map)
                     map->Remove(this);
             }
 
             if (mRefCnt > 1)
                 RemoveFromRootSet();
         }
 
         mJSObj = nullptr;
     }
 
-    if (mRoot == this) {
+    if (IsRootWrapper()) {
         ClearWeakReferences();
     } else if (mRoot) {
         // unlink this wrapper
         nsXPCWrappedJS* cur = mRoot;
         while (1) {
             if (cur->mNext == this) {
                 cur->mNext = mNext;
                 break;
@@ -546,38 +539,37 @@ nsXPCWrappedJS::GetProperty(const nsAStr
 
 NS_IMETHODIMP
 nsXPCWrappedJS::DebugDump(int16_t depth)
 {
 #ifdef DEBUG
     XPC_LOG_ALWAYS(("nsXPCWrappedJS @ %x with mRefCnt = %d", this, mRefCnt.get()));
         XPC_LOG_INDENT();
 
-        bool isRoot = mRoot == this;
         XPC_LOG_ALWAYS(("%s wrapper around JSObject @ %x", \
-                        isRoot ? "ROOT":"non-root", mJSObj.get()));
+                        IsRootWrapper() ? "ROOT":"non-root", mJSObj.get()));
         char* name;
         GetClass()->GetInterfaceInfo()->GetName(&name);
         XPC_LOG_ALWAYS(("interface name is %s", name));
         if (name)
             nsMemory::Free(name);
         char * iid = GetClass()->GetIID().ToString();
         XPC_LOG_ALWAYS(("IID number is %s", iid ? iid : "invalid"));
         if (iid)
             NS_Free(iid);
         XPC_LOG_ALWAYS(("nsXPCWrappedJSClass @ %x", mClass));
 
-        if (!isRoot)
+        if (!IsRootWrapper())
             XPC_LOG_OUTDENT();
         if (mNext) {
-            if (isRoot) {
+            if (IsRootWrapper()) {
                 XPC_LOG_ALWAYS(("Additional wrappers for this object..."));
                 XPC_LOG_INDENT();
             }
             mNext->DebugDump(depth);
-            if (isRoot)
+            if (IsRootWrapper())
                 XPC_LOG_OUTDENT();
         }
-        if (isRoot)
+        if (IsRootWrapper())
             XPC_LOG_OUTDENT();
 #endif
     return NS_OK;
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -243,21 +243,16 @@ inline void SetWNExpandoChain(JSObject *
 }
 
 inline JSObject* GetWNExpandoChain(JSObject *obj)
 {
     MOZ_ASSERT(IS_WN_REFLECTOR(obj));
     return JS_GetReservedSlot(obj, WN_XRAYEXPANDOCHAIN_SLOT).toObjectOrNull();
 }
 
-// We PROMISE to never screw this up.
-#ifdef _MSC_VER
-#pragma warning(disable : 4355) // OK to pass "this" in member initializer
-#endif
-
 /***************************************************************************
 ****************************************************************************
 *
 * Core runtime and context classes...
 *
 ****************************************************************************
 ***************************************************************************/
 
@@ -2497,16 +2492,17 @@ public:
     nsXPCWrappedJSClass*  GetClass() const {return mClass;}
     REFNSIID GetIID() const {return GetClass()->GetIID();}
     nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
     nsXPCWrappedJS* GetNextWrapper() const {return mNext;}
 
     nsXPCWrappedJS* Find(REFNSIID aIID);
     nsXPCWrappedJS* FindInherited(REFNSIID aIID);
 
+    bool IsRootWrapper() const {return mRoot == this;}
     bool IsValid() const {return mJSObj != nullptr;}
     void SystemIsBeingShutDown();
 
     // This is used by XPCJSRuntime::GCCallback to find wrappers that no
     // longer root their JSObject and are only still alive because they
     // were being used via nsSupportsWeakReference at the time when their
     // last (outside) reference was released. Wrappers that fit into that
     // category are only deleted when we see that their corresponding JSObject
--- a/layout/base/Makefile.in
+++ b/layout/base/Makefile.in
@@ -1,8 +1,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 $(topsrcdir)/config/rules.mk
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3568,20 +3568,43 @@ nsDisplayScrollLayer::TryMerge(nsDisplay
   // See Bug 729534 and Bug 731641.
   nsIFrame* tmp = mFrame;
   mFrame = other->mFrame;
   other->mFrame = tmp;
   MergeFromTrackingMergedFrames(other);
   return true;
 }
 
+void
+PropagateClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip,
+              nsDisplayList* aList)
+{
+  for (nsDisplayItem* i = aList->GetBottom(); i != nullptr; i = i->GetAbove()) {
+    DisplayItemClip clip(i->GetClip());
+    clip.IntersectWith(aClip);
+    i->SetClip(aBuilder, clip);
+    nsDisplayList* list = i->GetSameCoordinateSystemChildren();
+    if (list) {
+      PropagateClip(aBuilder, aClip, list);
+    }
+  }
+}
+
 bool
 nsDisplayScrollLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
 {
-  return GetScrollLayerCount() > 1;
+  if (GetScrollLayerCount() > 1) {
+    // Propagate our clip to our children. The clip for the scroll frame is
+    // on this item, but not our child items so that they can draw non-visible
+    // parts of the display port. But if we are flattening we failed and can't
+    // draw the extra content, so it needs to be clipped.
+    PropagateClip(aBuilder, GetClip(), &mList);
+    return true;
+  }
+  return false;
 }
 
 intptr_t
 nsDisplayScrollLayer::GetScrollLayerCount()
 {
   FrameProperties props = mScrolledFrame->Properties();
 #ifdef DEBUG
   bool hasCount = false;
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -5,17 +5,16 @@
 RESOURCES_HTML = \
 		$(srcdir)/folder.png \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += \
 		$(MOZ_CAIRO_CFLAGS) \
-		$(MOZ_PIXMAN_CFLAGS) \
 		$(NULL)
 
 ifdef MOZ_WIDGET_GTK
 CXXFLAGS += $(TK_CFLAGS)
 endif
 
 ifdef MOZ_ENABLE_QT
 CXXFLAGS += $(MOZ_QT_CFLAGS)
--- a/layout/media/symbols.def.in
+++ b/layout/media/symbols.def.in
@@ -24,33 +24,31 @@ nestegg_track_count
 nestegg_get_cue_point
 nestegg_track_seek
 nestegg_track_type
 nestegg_track_video_params
 nestegg_tstamp_scale
 nestegg_has_cues
 nestegg_sniff
 #endif
-#ifdef MOZ_VP8
+#ifdef MOZ_VPX
 #ifndef MOZ_NATIVE_LIBVPX
 vpx_codec_control_
 vpx_codec_dec_init_ver
 vpx_codec_decode
 vpx_codec_destroy
 vpx_codec_get_frame
 vpx_codec_peek_stream_info
 vpx_codec_vp8_dx
 vpx_codec_vp9_dx
 vpx_img_free
 vpx_codec_enc_config_set
 vpx_codec_enc_init_ver
-#ifdef MOZ_VP8_ENCODER
 vpx_codec_vp8_cx
 vpx_codec_vp9_cx
-#endif
 vpx_img_set_rect
 vpx_img_wrap
 vpx_codec_get_cx_data
 vpx_codec_enc_config_default
 vpx_img_alloc
 vpx_codec_encode
 #endif
 #endif
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/933264-1-ref.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+  <title>The Grid in an overflowing div</title>
+  <style type="text/css">
+    html {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    body {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    table {
+        padding: 0;
+        margin: 0;
+        border-top: none;
+        border-left: none;
+        border-right: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+    tr {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    td {
+        /* top border counts as part of height, but
+           left border doesn't count as part of width.
+           go figure.
+        */
+        min-height: 99px;
+        height: 99px;
+        max-height: 99px;
+        min-width: 99px;
+        width: 99px;
+        max-width: 99px;
+        padding: 0;
+        border-left: 1px solid black;
+        border-top: 1px solid black;
+        border-right: none;
+        border-bottom: none;
+        margin: 0;
+        font-size: 12px;
+        text-align: left;
+        vertical-align: top;
+        font-family: monospace;
+    }
+  </style>
+  <script type="text/javascript">
+    var val = 900;
+    function scroll() {
+        var div = document.getElementById('nest');
+        div.scrollLeft = val;
+        div.scrollTop = val;
+        document.documentElement.removeAttribute('class');
+    }
+
+    window.onload = scroll;
+  </script>
+ </head>
+ <body>
+  <div style="color: red">this text is above the scrolling div. the div below is 300x400</div>
+  <div id="nest" style="overflow: scroll; height: 400px; width: 300px; border: solid 1px black">
+    <div style="background: blue; width: 5000px; height: 5000px;"></div>
+  </div>
+  <div style="color: red">this text is below the scrolling div</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/933264-1.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+  <title>The Grid in an overflowing div</title>
+  <style type="text/css">
+    html {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    body {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    table {
+        padding: 0;
+        margin: 0;
+        border-top: none;
+        border-left: none;
+        border-right: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+    tr {
+        padding: 0;
+        border: 0;
+        margin: 0;
+    }
+    td {
+        /* top border counts as part of height, but
+           left border doesn't count as part of width.
+           go figure.
+        */
+        min-height: 99px;
+        height: 99px;
+        max-height: 99px;
+        min-width: 99px;
+        width: 99px;
+        max-width: 99px;
+        padding: 0;
+        border-left: 1px solid black;
+        border-top: 1px solid black;
+        border-right: none;
+        border-bottom: none;
+        margin: 0;
+        font-size: 12px;
+        text-align: left;
+        vertical-align: top;
+        font-family: monospace;
+    }
+  </style>
+  <script type="text/javascript">
+    var val = 100;
+    var max = 1000;
+    function scrollmore() {
+        if (val == max) {
+          document.documentElement.removeAttribute('class');
+          return;
+        }
+        var div = document.getElementById('nest');
+        div.scrollLeft = val;
+        div.scrollTop = val;
+        val += 100;
+        document.documentElement.offsetLeft;
+        setTimeout(scrollmore, 500);
+    }
+
+    window.onload = scrollmore;
+  </script>
+ </head>
+ <body>
+  <div style="color: red">this text is above the scrolling div. the div below is 300x400</div>
+  <div id="nest" style="overflow: scroll; height: 400px; width: 300px; border: solid 1px black">
+    <div style="background: blue; width: 5000px; height: 5000px;">text</div>
+  </div>
+  <div style="color: red">this text is below the scrolling div</div>
+ </body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1778,12 +1778,13 @@ random-if(B2G) == 849407-1.html 849407-1
 == 897491-2.html 897491-2-ref.html
 fuzzy(1,10000) fuzzy-if(Android&&AndroidVersion>=15,5,10000) == 902330-1.html 902330-1-ref.html
 fuzzy-if(Android,8,400) == 906199-1.html 906199-1-ref.html
 == 921716-1.html 921716-1-ref.html
 fuzzy-if(cocoaWidget,1,40) == 928607-1.html 928607-1-ref.html
 == 931464-1.html 931464-1-ref.html
 == 931853.html 931853-ref.html
 == 931853-quirks.html 931853-quirks-ref.html
+fuzzy-if(OSX==10.6,2,30) == 933264-1.html 933264-1-ref.html
 == 936670-1.svg 936670-1-ref.svg
 == 941940-1.html 941940-1-ref.html
 == 942017.html 942017-ref.html
 == 942672-1.html 942672-1-ref.html
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -61,31 +61,21 @@ nsSVGRenderingObserver::StopListening()
  * nsSVGIDRenderingObserver object also adds itself to an
  * nsSVGRenderingObserverList object belonging to the referenced
  * element.
  *
  * XXX: it would be nice to have a clear and concise executive summary of the
  * benefits/necessity of maintaining a second observer list.
  */
 
-#ifdef _MSC_VER
-// Disable "warning C4355: 'this' : used in base member initializer list".
-// We can ignore that warning because we know that mElement's constructor 
-// doesn't dereference the pointer passed to it.
-#pragma warning(push)
-#pragma warning(disable:4355)
-#endif
 nsSVGIDRenderingObserver::nsSVGIDRenderingObserver(nsIURI *aURI,
                                                    nsIFrame *aFrame,
                                                    bool aReferenceImage)
-  : mElement(this), mFrame(aFrame),
+  : mElement(MOZ_THIS_IN_INITIALIZER_LIST()), mFrame(aFrame),
     mFramePresShell(aFrame->PresContext()->PresShell())
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
 {
   // Start watching the target element
   mElement.Reset(aFrame->GetContent(), aURI, true, aReferenceImage);
   StartListening();
 }
 
 nsSVGIDRenderingObserver::~nsSVGIDRenderingObserver()
 {
--- a/media/libvpx/Makefile.in
+++ b/media/libvpx/Makefile.in
@@ -17,20 +17,17 @@ ifeq ($(OS_TARGET),Android)
 LOCAL_INCLUDES += -I$(ANDROID_NDK)/sources/android/cpufeatures
 ifndef MOZ_WEBRTC
 # For cpu-features.c
 VPATH += $(ANDROID_NDK)/sources/android/cpufeatures
 CSRCS += cpu-features.c
 endif
 endif
 
-ASM_OFFSETS = vpx_scale_asm_offsets.asm
-ifdef MOZ_VP8_ENCODER
-ASM_OFFSETS += vp8_asm_enc_offsets.asm
-endif
+ASM_OFFSETS = vpx_scale_asm_offsets.asm vp8_asm_enc_offsets.asm
 
 
 ifdef VPX_AS_CONVERSION
 # The ARM asm is written in ARM RVCT syntax, but we actually build it with
 # gas using GNU syntax. Add some rules to perform the conversion.
 
 GENERATED_DIRS += $(dir $(ASFILES))
 
@@ -49,21 +46,17 @@ ifdef VPX_NEED_OBJ_INT_EXTRACT
 
 ifdef VPX_ARM_ASM
 VPX_OIE_FORMAT := rvds
 else
 VPX_OIE_FORMAT := gas
 endif
 
 GARBAGE += vpx_scale_asm_offsets.$(OBJ_SUFFIX) vpx_scale_asm_offsets.asm
-
-ifdef MOZ_VP8_ENCODER
-
 GARBAGE += vp8_asm_enc_offsets.$(OBJ_SUFFIX) vp8_asm_enc_offsets.asm
-endif
 
 else
 
 # We can extract the asm offsets directly from generated assembly using inline
 # asm. This is the preferred method.
 
 vpx_scale_asm_offsets.s: CFLAGS += -DINLINE_ASM
 
@@ -77,33 +70,28 @@ vpx_scale_asm_offsets.s: $(srcdir)/vpx_s
 	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 vpx_scale_asm_offsets.asm: vpx_scale_asm_offsets.s
 	grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 GARBAGE += vpx_scale_asm_offsets.s vpx_scale_asm_offsets.asm
 
-ifdef MOZ_VP8_ENCODER
-
 vp8_asm_enc_offsets.s: CFLAGS += -DINLINE_ASM
 
 vp8_asm_enc_offsets.s: $(srcdir)/vp8/encoder/vp8_asm_enc_offsets.c
 	$(REPORT_BUILD)
 	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 vp8_asm_enc_offsets.asm: vp8_asm_enc_offsets.s
 	grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 GARBAGE += vp8_asm_enc_offsets.s vp8_asm_enc_offsets.asm
 
-
-endif
-
 endif
 
 EXTRA_MDDEPEND_FILES = vp8_asm_enc_offsets.s.pp vp8_asm_enc_offsets.$(OBJ_SUFFIX).pp vpx_scale_asm_offsets.s.pp vpx_scale_asm_offsets.$(OBJ_SUFFIX).pp
 
 include $(topsrcdir)/config/rules.mk
 
 # This must be after rules.mk in order to use $(OBJ_SUFFIX) outside a
 # recursively-expanded variable.
@@ -117,43 +105,36 @@ endif
 
 quantize_sse4.$(OBJ_SUFFIX): vp8_asm_enc_offsets.asm
 quantize_ssse3.$(OBJ_SUFFIX): vp8_asm_enc_offsets.asm
 
 ifdef VPX_NEED_OBJ_INT_EXTRACT
 
 # only for MSVC
 ifdef _MSC_VER
-NO_PROFILE_GUIDED_OPTIMIZE := vpx_scale_asm_offsets.c
+NO_PROFILE_GUIDED_OPTIMIZE := vpx_scale_asm_offsets.c vp8_asm_enc_offsets.c
 endif
 
 vpx_scale_asm_offsets.asm: vpx_scale_asm_offsets.$(OBJ_SUFFIX) $(HOST_PROGRAM)
 	./$(HOST_PROGRAM) $(VPX_OIE_FORMAT) $< \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 # Filter out this object, because we don't want to link against it.
 # It was generated solely so it could be parsed by obj_int_extract.
 OBJS := $(filter-out vpx_scale_asm_offsets.$(OBJ_SUFFIX),$(OBJS))
 
-ifdef MOZ_VP8_ENCODER
-
-ifdef _MSC_VER
-NO_PROFILE_GUIDED_OPTIMIZE += vp8_asm_enc_offsets.c
-endif
-
 vp8_asm_enc_offsets.asm: vp8_asm_enc_offsets.$(OBJ_SUFFIX) $(HOST_PROGRAM)
 	./$(HOST_PROGRAM) $(VPX_OIE_FORMAT) $< \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 # Filter out this object, because we don't want to link against it.
 # It was generated solely so it could be parsed by obj_int_extract.
 OBJS := $(filter-out vp8_asm_enc_offsets.$(OBJ_SUFFIX),$(OBJS))
 
 endif
-endif
 
 # Workaround a bug of Sun Studio (CR 6963410)
 ifdef SOLARIS_SUNPRO_CC
 ifeq (86,$(findstring 86,$(OS_TEST)))
 filter.o: filter.c Makefile.in
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(CC) -o $@ -c $(patsubst -xO[45],-xO3,$(COMPILE_CFLAGS)) $<
--- a/media/libvpx/moz.build
+++ b/media/libvpx/moz.build
@@ -10,73 +10,58 @@ EXPORTS.vpx += files['EXPORTS']
 
 if CONFIG['VPX_NEED_OBJ_INT_EXTRACT']:
     HOST_SOURCES += [
         'build/make/obj_int_extract.c',
     ]
 
     HOST_PROGRAM = 'host_obj_int_extract'
 
-SOURCES += files['COMMON']
-
-if CONFIG['MOZ_VP8_ERROR_CONCEALMENT']:
-    SOURCES += files['ERROR_CONCEALMENT']
+SOURCES += files['SOURCES']
 
-if CONFIG['MOZ_VP8_ENCODER']:
-    SOURCES += files['ENCODER']
-
-#postproc is only enabled on x86 with asm
-if CONFIG['VPX_X86_ASM']:
-    SOURCES += files['VP8_POSTPROC']
+if CONFIG['MOZ_VPX_ERROR_CONCEALMENT']:
+    SOURCES += files['ERROR_CONCEALMENT']
 
 if CONFIG['VPX_X86_ASM'] and CONFIG['OS_TARGET'] == 'WINNT':
     SOURCES += [
+        'vp8/encoder/vp8_asm_enc_offsets.c',
         'vpx_scale/vpx_scale_asm_offsets.c',
     ]
-    if CONFIG['MOZ_VP8_ENCODER']:
-        SOURCES += [
-            'vp8/encoder/vp8_asm_enc_offsets.c',
-        ]
 
 if CONFIG['VPX_X86_ASM']:
     SOURCES += files['X86_ASM']
 
     if '64' in CONFIG['OS_TEST']:
         SOURCES += files['X86-64_ASM']
 
     # AVX2 only supported on
     # Darwin toolchain right now
     if CONFIG['OS_TARGET'] == 'Darwin':
         SOURCES += files['AVX2']
 
-if CONFIG['VPX_X86_ASM'] and CONFIG['MOZ_VP8_ENCODER']:
-    SOURCES += files['X86_ASM_ENCODER']
-    if '64' in CONFIG['OS_TEST']:
-        SOURCES += files['X86-64_ASM_ENCODER']
+    #postproc is only enabled on x86 with asm
+    SOURCES += files['VP8_POSTPROC']
 
 arm_asm_files = []
 if CONFIG['VPX_ARM_ASM']:
     arm_asm_files += files['ARM_ASM']
-    if CONFIG['MOZ_VP8_ENCODER']:
-        arm_asm_files += files['ARM_ASM_ENCODER']
 
     if CONFIG['VPX_AS_CONVERSION']:
         GENERATED_SOURCES += [ "%s.%s" % (f, CONFIG['VPX_ASM_SUFFIX'])
             for f in sorted(arm_asm_files) if f.endswith('.asm')
         ]
         SOURCES += [
             f for f in sorted(arm_asm_files) if not f.endswith('.asm')
         ]
     else:
         SOURCES += sorted(arm_asm_files)
 
 # boolhuff_armv5te.asm defines the same functions as boolhuff.c instead of
 # using RTCD, so we have to make sure we only add one of the two.
-if CONFIG['MOZ_VP8_ENCODER'] \
-    and 'vp8/encoder/arm/armv5te/boolhuff_armv5te.asm' not in arm_asm_files:
+if 'vp8/encoder/arm/armv5te/boolhuff_armv5te.asm' not in arm_asm_files:
     SOURCES += [
         'vp8/encoder/boolhuff.c',
     ]
 
 MSVC_ENABLE_PGO = True
 
 if CONFIG['GKMEDIAS_SHARED_LIBRARY']:
     NO_VISIBILITY_FLAGS = True
--- a/media/libvpx/sources.mozbuild
+++ b/media/libvpx/sources.mozbuild
@@ -1,243 +1,247 @@
 files = {
- 'ARM_ASM': ['vp8/common/arm/armv6/bilinearfilter_v6.asm',
-             'vp8/common/arm/armv6/copymem16x16_v6.asm',
-             'vp8/common/arm/armv6/copymem8x4_v6.asm',
-             'vp8/common/arm/armv6/copymem8x8_v6.asm',
-             'vp8/common/arm/armv6/dc_only_idct_add_v6.asm',
-             'vp8/common/arm/armv6/dequant_idct_v6.asm',
-             'vp8/common/arm/armv6/dequantize_v6.asm',
-             'vp8/common/arm/armv6/filter_v6.asm',
-             'vp8/common/arm/armv6/idct_blk_v6.c',
-             'vp8/common/arm/armv6/idct_v6.asm',
-             'vp8/common/arm/armv6/intra4x4_predict_v6.asm',
-             'vp8/common/arm/armv6/iwalsh_v6.asm',
-             'vp8/common/arm/armv6/loopfilter_v6.asm',
-             'vp8/common/arm/armv6/simpleloopfilter_v6.asm',
-             'vp8/common/arm/armv6/sixtappredict8x4_v6.asm',
-             'vp8/common/arm/armv6/vp8_sad16x16_armv6.asm',
-             'vp8/common/arm/armv6/vp8_variance16x16_armv6.asm',
-             'vp8/common/arm/armv6/vp8_variance8x8_armv6.asm',
-             'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_h_armv6.asm',
-             'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_hv_armv6.asm',
-             'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_v_armv6.asm',
-             'vp8/common/arm/bilinearfilter_arm.c',
-             'vp8/common/arm/dequantize_arm.c',
-             'vp8/common/arm/filter_arm.c',
-             'vp8/common/arm/loopfilter_arm.c',
-             'vp8/common/arm/neon/bilinearpredict16x16_neon.asm',
-             'vp8/common/arm/neon/bilinearpredict4x4_neon.asm',
-             'vp8/common/arm/neon/bilinearpredict8x4_neon.asm',
-             'vp8/common/arm/neon/bilinearpredict8x8_neon.asm',
-             'vp8/common/arm/neon/buildintrapredictorsmby_neon.asm',
-             'vp8/common/arm/neon/copymem16x16_neon.asm',
-             'vp8/common/arm/neon/copymem8x4_neon.asm',
-             'vp8/common/arm/neon/copymem8x8_neon.asm',
-             'vp8/common/arm/neon/dc_only_idct_add_neon.asm',
-             'vp8/common/arm/neon/dequant_idct_neon.asm',
-             'vp8/common/arm/neon/dequantizeb_neon.asm',
-             'vp8/common/arm/neon/idct_blk_neon.c',
-             'vp8/common/arm/neon/idct_dequant_0_2x_neon.asm',
-             'vp8/common/arm/neon/idct_dequant_full_2x_neon.asm',
-             'vp8/common/arm/neon/iwalsh_neon.asm',
-             'vp8/common/arm/neon/loopfilter_neon.asm',
-             'vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.asm',
-             'vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.asm',
-             'vp8/common/arm/neon/mbloopfilter_neon.asm',
-             'vp8/common/arm/neon/sad16_neon.asm',
-             'vp8/common/arm/neon/sad8_neon.asm',
-             'vp8/common/arm/neon/save_reg_neon.asm',
-             'vp8/common/arm/neon/shortidct4x4llm_neon.asm',
-             'vp8/common/arm/neon/sixtappredict16x16_neon.asm',
-             'vp8/common/arm/neon/sixtappredict4x4_neon.asm',
-             'vp8/common/arm/neon/sixtappredict8x4_neon.asm',
-             'vp8/common/arm/neon/sixtappredict8x8_neon.asm',
-             'vp8/common/arm/neon/variance_neon.asm',
-             'vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm',
-             'vp8/common/arm/neon/vp8_subpixelvariance16x16s_neon.asm',
-             'vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm',
-             'vp8/common/arm/reconintra_arm.c',
-             'vp8/common/arm/variance_arm.c',
-             'vp9/common/arm/neon/vp9_avg_neon.asm',
-             'vp9/common/arm/neon/vp9_convolve8_avg_neon.asm',
-             'vp9/common/arm/neon/vp9_convolve8_neon.asm',
-             'vp9/common/arm/neon/vp9_convolve_neon.c',
-             'vp9/common/arm/neon/vp9_copy_neon.asm',
-             'vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm',
-             'vp9/common/arm/neon/vp9_idct16x16_neon.c',
-             'vp9/common/arm/neon/vp9_loopfilter_neon.asm',
-             'vp9/common/arm/neon/vp9_mb_lpf_neon.asm',
-             'vp9/common/arm/neon/vp9_save_reg_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct16x16_1_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct32x32_1_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct32x32_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct4x4_1_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct4x4_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct8x8_1_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_idct8x8_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_iht4x4_add_neon.asm',
-             'vp9/common/arm/neon/vp9_short_iht8x8_add_neon.asm',
-             'vpx_ports/arm_cpudetect.c',
-             'vpx_scale/arm/neon/vp8_vpxyv12_copy_y_neon.asm',
-             'vpx_scale/arm/neon/vp8_vpxyv12_copyframe_func_neon.asm',
-             'vpx_scale/arm/neon/vp8_vpxyv12_copysrcframe_func_neon.asm',
-             'vpx_scale/arm/neon/vp8_vpxyv12_extendframeborders_neon.asm',
-             'vpx_scale/arm/neon/yv12extend_arm.c'],
- 'ARM_ASM_ENCODER': ['vp8/encoder/arm/armv5te/boolhuff_armv5te.asm',
-                     'vp8/encoder/arm/armv5te/vp8_packtokens_armv5.asm',
-                     'vp8/encoder/arm/armv5te/vp8_packtokens_mbrow_armv5.asm',
-                     'vp8/encoder/arm/armv5te/vp8_packtokens_partitions_armv5.asm',
-                     'vp8/encoder/arm/armv6/vp8_fast_quantize_b_armv6.asm',
-                     'vp8/encoder/arm/armv6/vp8_mse16x16_armv6.asm',
-                     'vp8/encoder/arm/armv6/vp8_short_fdct4x4_armv6.asm',
-                     'vp8/encoder/arm/armv6/vp8_subtract_armv6.asm',
-                     'vp8/encoder/arm/armv6/walsh_v6.asm',
-                     'vp8/encoder/arm/boolhuff_arm.c',
-                     'vp8/encoder/arm/dct_arm.c',
-                     'vp8/encoder/arm/neon/fastquantizeb_neon.asm',
-                     'vp8/encoder/arm/neon/picklpf_arm.c',
-                     'vp8/encoder/arm/neon/shortfdct_neon.asm',
-                     'vp8/encoder/arm/neon/subtract_neon.asm',
-                     'vp8/encoder/arm/neon/vp8_memcpy_neon.asm',
-                     'vp8/encoder/arm/neon/vp8_mse16x16_neon.asm',
-                     'vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm',
-                     'vp8/encoder/arm/quantize_arm.c'],
+ 'ARM_ASM': [
+    'vp8/common/arm/armv6/bilinearfilter_v6.asm',
+    'vp8/common/arm/armv6/copymem16x16_v6.asm',
+    'vp8/common/arm/armv6/copymem8x4_v6.asm',
+    'vp8/common/arm/armv6/copymem8x8_v6.asm',
+    'vp8/common/arm/armv6/dc_only_idct_add_v6.asm',
+    'vp8/common/arm/armv6/dequant_idct_v6.asm',
+    'vp8/common/arm/armv6/dequantize_v6.asm',
+    'vp8/common/arm/armv6/filter_v6.asm',
+    'vp8/common/arm/armv6/idct_blk_v6.c',
+    'vp8/common/arm/armv6/idct_v6.asm',
+    'vp8/common/arm/armv6/intra4x4_predict_v6.asm',
+    'vp8/common/arm/armv6/iwalsh_v6.asm',
+    'vp8/common/arm/armv6/loopfilter_v6.asm',
+    'vp8/common/arm/armv6/simpleloopfilter_v6.asm',
+    'vp8/common/arm/armv6/sixtappredict8x4_v6.asm',
+    'vp8/common/arm/armv6/vp8_sad16x16_armv6.asm',
+    'vp8/common/arm/armv6/vp8_variance16x16_armv6.asm',
+    'vp8/common/arm/armv6/vp8_variance8x8_armv6.asm',
+    'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_h_armv6.asm',
+    'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_hv_armv6.asm',
+    'vp8/common/arm/armv6/vp8_variance_halfpixvar16x16_v_armv6.asm',
+    'vp8/common/arm/bilinearfilter_arm.c',
+    'vp8/common/arm/dequantize_arm.c',
+    'vp8/common/arm/filter_arm.c',
+    'vp8/common/arm/loopfilter_arm.c',
+    'vp8/common/arm/neon/bilinearpredict16x16_neon.asm',
+    'vp8/common/arm/neon/bilinearpredict4x4_neon.asm',
+    'vp8/common/arm/neon/bilinearpredict8x4_neon.asm',
+    'vp8/common/arm/neon/bilinearpredict8x8_neon.asm',
+    'vp8/common/arm/neon/buildintrapredictorsmby_neon.asm',
+    'vp8/common/arm/neon/copymem16x16_neon.asm',
+    'vp8/common/arm/neon/copymem8x4_neon.asm',
+    'vp8/common/arm/neon/copymem8x8_neon.asm',
+    'vp8/common/arm/neon/dc_only_idct_add_neon.asm',
+    'vp8/common/arm/neon/dequant_idct_neon.asm',
+    'vp8/common/arm/neon/dequantizeb_neon.asm',
+    'vp8/common/arm/neon/idct_blk_neon.c',
+    'vp8/common/arm/neon/idct_dequant_0_2x_neon.asm',
+    'vp8/common/arm/neon/idct_dequant_full_2x_neon.asm',
+    'vp8/common/arm/neon/iwalsh_neon.asm',
+    'vp8/common/arm/neon/loopfilter_neon.asm',
+    'vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.asm',
+    'vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.asm',
+    'vp8/common/arm/neon/mbloopfilter_neon.asm',
+    'vp8/common/arm/neon/sad16_neon.asm',
+    'vp8/common/arm/neon/sad8_neon.asm',
+    'vp8/common/arm/neon/save_reg_neon.asm',
+    'vp8/common/arm/neon/shortidct4x4llm_neon.asm',
+    'vp8/common/arm/neon/sixtappredict16x16_neon.asm',
+    'vp8/common/arm/neon/sixtappredict4x4_neon.asm',
+    'vp8/common/arm/neon/sixtappredict8x4_neon.asm',
+    'vp8/common/arm/neon/sixtappredict8x8_neon.asm',
+    'vp8/common/arm/neon/variance_neon.asm',
+    'vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm',
+    'vp8/common/arm/neon/vp8_subpixelvariance16x16s_neon.asm',
+    'vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm',
+    'vp8/common/arm/reconintra_arm.c',
+    'vp8/common/arm/variance_arm.c',
+    'vp8/encoder/arm/armv5te/boolhuff_armv5te.asm',
+    'vp8/encoder/arm/armv5te/vp8_packtokens_armv5.asm',
+    'vp8/encoder/arm/armv5te/vp8_packtokens_mbrow_armv5.asm',
+    'vp8/encoder/arm/armv5te/vp8_packtokens_partitions_armv5.asm',
+    'vp8/encoder/arm/armv6/vp8_fast_quantize_b_armv6.asm',
+    'vp8/encoder/arm/armv6/vp8_mse16x16_armv6.asm',
+    'vp8/encoder/arm/armv6/vp8_short_fdct4x4_armv6.asm',
+    'vp8/encoder/arm/armv6/vp8_subtract_armv6.asm',
+    'vp8/encoder/arm/armv6/walsh_v6.asm',
+    'vp8/encoder/arm/boolhuff_arm.c',
+    'vp8/encoder/arm/dct_arm.c',
+    'vp8/encoder/arm/neon/fastquantizeb_neon.asm',
+    'vp8/encoder/arm/neon/picklpf_arm.c',
+    'vp8/encoder/arm/neon/shortfdct_neon.asm',
+    'vp8/encoder/arm/neon/subtract_neon.asm',
+    'vp8/encoder/arm/neon/vp8_memcpy_neon.asm',
+    'vp8/encoder/arm/neon/vp8_mse16x16_neon.asm',
+    'vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm',
+    'vp8/encoder/arm/quantize_arm.c',
+    'vp9/common/arm/neon/vp9_avg_neon.asm',
+    'vp9/common/arm/neon/vp9_convolve8_avg_neon.asm',
+    'vp9/common/arm/neon/vp9_convolve8_neon.asm',
+    'vp9/common/arm/neon/vp9_convolve_neon.c',
+    'vp9/common/arm/neon/vp9_copy_neon.asm',
+    'vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm',
+    'vp9/common/arm/neon/vp9_idct16x16_neon.c',
+    'vp9/common/arm/neon/vp9_loopfilter_neon.asm',
+    'vp9/common/arm/neon/vp9_mb_lpf_neon.asm',
+    'vp9/common/arm/neon/vp9_save_reg_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct16x16_1_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct32x32_1_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct32x32_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct4x4_1_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct4x4_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct8x8_1_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_idct8x8_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_iht4x4_add_neon.asm',
+    'vp9/common/arm/neon/vp9_short_iht8x8_add_neon.asm',
+    'vpx_ports/arm_cpudetect.c',
+    'vpx_scale/arm/neon/vp8_vpxyv12_copy_y_neon.asm',
+    'vpx_scale/arm/neon/vp8_vpxyv12_copyframe_func_neon.asm',
+    'vpx_scale/arm/neon/vp8_vpxyv12_copysrcframe_func_neon.asm',
+    'vpx_scale/arm/neon/vp8_vpxyv12_extendframeborders_neon.asm',
+    'vpx_scale/arm/neon/yv12extend_arm.c'
+ ],
  'AVX2': ['vp9/common/x86/vp9_loopfilter_intrin_avx2.c'],
- 'COMMON': ['vp8/common/alloccommon.c',
-            'vp8/common/blockd.c',
-            'vp8/common/debugmodes.c',
-            'vp8/common/dequantize.c',
-            'vp8/common/entropy.c',
-            'vp8/common/entropymode.c',
-            'vp8/common/entropymv.c',
-            'vp8/common/extend.c',
-            'vp8/common/filter.c',
-            'vp8/common/findnearmv.c',
-            'vp8/common/generic/systemdependent.c',
-            'vp8/common/idct_blk.c',
-            'vp8/common/idctllm.c',
-            'vp8/common/loopfilter.c',
-            'vp8/common/loopfilter_filters.c',
-            'vp8/common/mbpitch.c',
-            'vp8/common/modecont.c',
-            'vp8/common/quant_common.c',
-            'vp8/common/reconinter.c',
-            'vp8/common/reconintra.c',
-            'vp8/common/reconintra4x4.c',
-            'vp8/common/rtcd.c',
-            'vp8/common/sad_c.c',
-            'vp8/common/setupintrarecon.c',
-            'vp8/common/swapyv12buffer.c',
-            'vp8/common/treecoder.c',
-            'vp8/common/variance_c.c',
-            'vp8/decoder/dboolhuff.c',
-            'vp8/decoder/decodemv.c',
-            'vp8/decoder/decodframe.c',
-            'vp8/decoder/detokenize.c',
-            'vp8/decoder/onyxd_if.c',
-            'vp8/decoder/threading.c',
-            'vp8/vp8_dx_iface.c',
-            'vp9/common/generic/vp9_systemdependent.c',
-            'vp9/common/vp9_alloccommon.c',
-            'vp9/common/vp9_common_data.c',
-            'vp9/common/vp9_convolve.c',
-            'vp9/common/vp9_debugmodes.c',
-            'vp9/common/vp9_entropy.c',
-            'vp9/common/vp9_entropymode.c',
-            'vp9/common/vp9_entropymv.c',
-            'vp9/common/vp9_extend.c',
-            'vp9/common/vp9_filter.c',
-            'vp9/common/vp9_findnearmv.c',
-            'vp9/common/vp9_idct.c',
-            'vp9/common/vp9_loopfilter.c',
-            'vp9/common/vp9_loopfilter_filters.c',
-            'vp9/common/vp9_mvref_common.c',
-            'vp9/common/vp9_pred_common.c',
-            'vp9/common/vp9_quant_common.c',
-            'vp9/common/vp9_reconinter.c',
-            'vp9/common/vp9_reconintra.c',
-            'vp9/common/vp9_rtcd.c',
-            'vp9/common/vp9_scale.c',
-            'vp9/common/vp9_scan.c',
-            'vp9/common/vp9_seg_common.c',
-            'vp9/common/vp9_tile_common.c',
-            'vp9/common/vp9_treecoder.c',
-            'vp9/decoder/vp9_dboolhuff.c',
-            'vp9/decoder/vp9_decodemv.c',
-            'vp9/decoder/vp9_decodframe.c',
-            'vp9/decoder/vp9_detokenize.c',
-            'vp9/decoder/vp9_dsubexp.c',
-            'vp9/decoder/vp9_onyxd_if.c',
-            'vp9/decoder/vp9_thread.c',
-            'vp9/vp9_dx_iface.c',
-            'vpx/src/vpx_codec.c',
-            'vpx/src/vpx_decoder.c',
-            'vpx/src/vpx_encoder.c',
-            'vpx/src/vpx_image.c',
-            'vpx_mem/vpx_mem.c',
-            'vpx_scale/generic/gen_scalers.c',
-            'vpx_scale/generic/vpx_scale.c',
-            'vpx_scale/generic/yv12config.c',
-            'vpx_scale/generic/yv12extend.c',
-            'vpx_scale/vpx_scale_rtcd.c'],
- 'ENCODER': ['vp8/encoder/bitstream.c',
-             'vp8/encoder/dct.c',
-             'vp8/encoder/denoising.c',
-             'vp8/encoder/encodeframe.c',
-             'vp8/encoder/encodeintra.c',
-             'vp8/encoder/encodemb.c',
-             'vp8/encoder/encodemv.c',
-             'vp8/encoder/ethreading.c',
-             'vp8/encoder/firstpass.c',
-             'vp8/encoder/lookahead.c',
-             'vp8/encoder/mcomp.c',
-             'vp8/encoder/modecosts.c',
-             'vp8/encoder/mr_dissim.c',
-             'vp8/encoder/onyx_if.c',
-             'vp8/encoder/pickinter.c',
-             'vp8/encoder/picklpf.c',
-             'vp8/encoder/psnr.c',
-             'vp8/encoder/quantize.c',
-             'vp8/encoder/ratectrl.c',
-             'vp8/encoder/rdopt.c',
-             'vp8/encoder/segmentation.c',
-             'vp8/encoder/temporal_filter.c',
-             'vp8/encoder/tokenize.c',
-             'vp8/encoder/treewriter.c',
-             'vp8/vp8_cx_iface.c',
-             'vp9/encoder/vp9_bitstream.c',
-             'vp9/encoder/vp9_boolhuff.c',
-             'vp9/encoder/vp9_dct.c',
-             'vp9/encoder/vp9_encodeframe.c',
-             'vp9/encoder/vp9_encodeintra.c',
-             'vp9/encoder/vp9_encodemb.c',
-             'vp9/encoder/vp9_encodemv.c',
-             'vp9/encoder/vp9_firstpass.c',
-             'vp9/encoder/vp9_lookahead.c',
-             'vp9/encoder/vp9_mbgraph.c',
-             'vp9/encoder/vp9_mcomp.c',
-             'vp9/encoder/vp9_modecosts.c',
-             'vp9/encoder/vp9_onyx_if.c',
-             'vp9/encoder/vp9_picklpf.c',
-             'vp9/encoder/vp9_psnr.c',
-             'vp9/encoder/vp9_quantize.c',
-             'vp9/encoder/vp9_ratectrl.c',
-             'vp9/encoder/vp9_rdopt.c',
-             'vp9/encoder/vp9_sad_c.c',
-             'vp9/encoder/vp9_segmentation.c',
-             'vp9/encoder/vp9_subexp.c',
-             'vp9/encoder/vp9_temporal_filter.c',
-             'vp9/encoder/vp9_tokenize.c',
-             'vp9/encoder/vp9_treewriter.c',
-             'vp9/encoder/vp9_vaq.c',
-             'vp9/encoder/vp9_variance_c.c',
-             'vp9/vp9_cx_iface.c',
-             'vpx/src/svc_encodeframe.c'],
+ 'SOURCES': [
+    'vp8/common/alloccommon.c',
+    'vp8/common/blockd.c',
+    'vp8/common/debugmodes.c',
+    'vp8/common/dequantize.c',
+    'vp8/common/entropy.c',
+    'vp8/common/entropymode.c',
+    'vp8/common/entropymv.c',
+    'vp8/common/extend.c',
+    'vp8/common/filter.c',
+    'vp8/common/findnearmv.c',
+    'vp8/common/generic/systemdependent.c',
+    'vp8/common/idct_blk.c',
+    'vp8/common/idctllm.c',
+    'vp8/common/loopfilter.c',
+    'vp8/common/loopfilter_filters.c',
+    'vp8/common/mbpitch.c',
+    'vp8/common/modecont.c',
+    'vp8/common/quant_common.c',
+    'vp8/common/reconinter.c',
+    'vp8/common/reconintra.c',
+    'vp8/common/reconintra4x4.c',
+    'vp8/common/rtcd.c',
+    'vp8/common/sad_c.c',
+    'vp8/common/setupintrarecon.c',
+    'vp8/common/swapyv12buffer.c',
+    'vp8/common/treecoder.c',
+    'vp8/common/variance_c.c',
+    'vp8/decoder/dboolhuff.c',
+    'vp8/decoder/decodemv.c',
+    'vp8/decoder/decodframe.c',
+    'vp8/decoder/detokenize.c',
+    'vp8/decoder/onyxd_if.c',
+    'vp8/decoder/threading.c',
+    'vp8/encoder/bitstream.c',
+    'vp8/encoder/dct.c',
+    'vp8/encoder/denoising.c',
+    'vp8/encoder/encodeframe.c',
+    'vp8/encoder/encodeintra.c',
+    'vp8/encoder/encodemb.c',
+    'vp8/encoder/encodemv.c',
+    'vp8/encoder/ethreading.c',
+    'vp8/encoder/firstpass.c',
+    'vp8/encoder/lookahead.c',
+    'vp8/encoder/mcomp.c',
+    'vp8/encoder/modecosts.c',
+    'vp8/encoder/mr_dissim.c',
+    'vp8/encoder/onyx_if.c',
+    'vp8/encoder/pickinter.c',
+    'vp8/encoder/picklpf.c',
+    'vp8/encoder/psnr.c',
+    'vp8/encoder/quantize.c',
+    'vp8/encoder/ratectrl.c',
+    'vp8/encoder/rdopt.c',
+    'vp8/encoder/segmentation.c',
+    'vp8/encoder/temporal_filter.c',
+    'vp8/encoder/tokenize.c',
+    'vp8/encoder/treewriter.c',
+    'vp8/vp8_cx_iface.c',
+    'vp8/vp8_dx_iface.c',
+    'vp9/common/generic/vp9_systemdependent.c',
+    'vp9/common/vp9_alloccommon.c',
+    'vp9/common/vp9_common_data.c',
+    'vp9/common/vp9_convolve.c',
+    'vp9/common/vp9_debugmodes.c',
+    'vp9/common/vp9_entropy.c',
+    'vp9/common/vp9_entropymode.c',
+    'vp9/common/vp9_entropymv.c',
+    'vp9/common/vp9_extend.c',
+    'vp9/common/vp9_filter.c',
+    'vp9/common/vp9_findnearmv.c',
+    'vp9/common/vp9_idct.c',
+    'vp9/common/vp9_loopfilter.c',
+    'vp9/common/vp9_loopfilter_filters.c',
+    'vp9/common/vp9_mvref_common.c',
+    'vp9/common/vp9_pred_common.c',
+    'vp9/common/vp9_quant_common.c',
+    'vp9/common/vp9_reconinter.c',
+    'vp9/common/vp9_reconintra.c',
+    'vp9/common/vp9_rtcd.c',
+    'vp9/common/vp9_scale.c',
+    'vp9/common/vp9_scan.c',
+    'vp9/common/vp9_seg_common.c',
+    'vp9/common/vp9_tile_common.c',
+    'vp9/common/vp9_treecoder.c',
+    'vp9/decoder/vp9_dboolhuff.c',
+    'vp9/decoder/vp9_decodemv.c',
+    'vp9/decoder/vp9_decodframe.c',
+    'vp9/decoder/vp9_detokenize.c',
+    'vp9/decoder/vp9_dsubexp.c',
+    'vp9/decoder/vp9_onyxd_if.c',
+    'vp9/decoder/vp9_thread.c',
+    'vp9/encoder/vp9_bitstream.c',
+    'vp9/encoder/vp9_boolhuff.c',
+    'vp9/encoder/vp9_dct.c',
+    'vp9/encoder/vp9_encodeframe.c',
+    'vp9/encoder/vp9_encodeintra.c',
+    'vp9/encoder/vp9_encodemb.c',
+    'vp9/encoder/vp9_encodemv.c',
+    'vp9/encoder/vp9_firstpass.c',
+    'vp9/encoder/vp9_lookahead.c',
+    'vp9/encoder/vp9_mbgraph.c',
+    'vp9/encoder/vp9_mcomp.c',
+    'vp9/encoder/vp9_modecosts.c',
+    'vp9/encoder/vp9_onyx_if.c',
+    'vp9/encoder/vp9_picklpf.c',
+    'vp9/encoder/vp9_psnr.c',
+    'vp9/encoder/vp9_quantize.c',
+    'vp9/encoder/vp9_ratectrl.c',
+    'vp9/encoder/vp9_rdopt.c',
+    'vp9/encoder/vp9_sad_c.c',
+    'vp9/encoder/vp9_segmentation.c',
+    'vp9/encoder/vp9_subexp.c',
+    'vp9/encoder/vp9_temporal_filter.c',
+    'vp9/encoder/vp9_tokenize.c',
+    'vp9/encoder/vp9_treewriter.c',
+    'vp9/encoder/vp9_vaq.c',
+    'vp9/encoder/vp9_variance_c.c',
+    'vp9/vp9_cx_iface.c',
+    'vp9/vp9_dx_iface.c',
+    'vpx/src/svc_encodeframe.c',
+    'vpx/src/vpx_codec.c',
+    'vpx/src/vpx_decoder.c',
+    'vpx/src/vpx_encoder.c',
+    'vpx/src/vpx_image.c',
+    'vpx_mem/vpx_mem.c',
+    'vpx_scale/generic/gen_scalers.c',
+    'vpx_scale/generic/vpx_scale.c',
+    'vpx_scale/generic/yv12config.c',
+    'vpx_scale/generic/yv12extend.c',
+    'vpx_scale/vpx_scale_rtcd.c'
+    ],
  'ERROR_CONCEALMENT': ['vp8/decoder/error_concealment.c'],
  'EXPORTS': ['vpx/vp8.h',
              'vpx/vp8cx.h',
              'vpx/vp8dx.h',
              'vpx/vpx_codec.h',
              'vpx/vpx_decoder.h',
              'vpx/vpx_encoder.h',
              'vpx/vpx_image.h',
@@ -248,86 +252,88 @@ files = {
              'vpx_ports/mem.h',
              'vpx_ports/vpx_timer.h',
              'vpx_ports/x86.h',
              'vpx_scale/vpx_scale.h',
              'vpx_scale/yv12config.h'],
  'VP8_POSTPROC': ['vp8/common/mfqe.c', 'vp8/common/postproc.c'],
  'VP9_POSTPROC': ['vp9/common/vp9_postproc.c'],
  'X86-64_ASM': ['third_party/x86inc/x86inc.asm',
-                'vp8/common/x86/loopfilter_block_sse2.asm'],
- 'X86-64_ASM_ENCODER': ['vp9/encoder/x86/vp9_quantize_ssse3.asm'],
- 'X86_ASM': ['vp8/common/x86/dequantize_mmx.asm',
-             'vp8/common/x86/filter_x86.c',
-             'vp8/common/x86/idct_blk_mmx.c',
-             'vp8/common/x86/idct_blk_sse2.c',
-             'vp8/common/x86/idctllm_mmx.asm',
-             'vp8/common/x86/idctllm_sse2.asm',
-             'vp8/common/x86/iwalsh_mmx.asm',
-             'vp8/common/x86/iwalsh_sse2.asm',
-             'vp8/common/x86/loopfilter_mmx.asm',
-             'vp8/common/x86/loopfilter_sse2.asm',
-             'vp8/common/x86/loopfilter_x86.c',
-             'vp8/common/x86/mfqe_sse2.asm',
-             'vp8/common/x86/postproc_mmx.asm',
-             'vp8/common/x86/postproc_sse2.asm',
-             'vp8/common/x86/postproc_x86.c',
-             'vp8/common/x86/recon_mmx.asm',
-             'vp8/common/x86/recon_sse2.asm',
-             'vp8/common/x86/recon_wrapper_sse2.c',
-             'vp8/common/x86/sad_mmx.asm',
-             'vp8/common/x86/sad_sse2.asm',
-             'vp8/common/x86/sad_sse3.asm',
-             'vp8/common/x86/sad_sse4.asm',
-             'vp8/common/x86/sad_ssse3.asm',
-             'vp8/common/x86/subpixel_mmx.asm',
-             'vp8/common/x86/subpixel_sse2.asm',
-             'vp8/common/x86/subpixel_ssse3.asm',
-             'vp8/common/x86/variance_impl_mmx.asm',
-             'vp8/common/x86/variance_impl_sse2.asm',
-             'vp8/common/x86/variance_impl_ssse3.asm',
-             'vp8/common/x86/variance_mmx.c',
-             'vp8/common/x86/variance_sse2.c',
-             'vp8/common/x86/variance_ssse3.c',
-             'vp8/common/x86/vp8_asm_stubs.c',
-             'vp9/common/x86/vp9_asm_stubs.c',
-             'vp9/common/x86/vp9_copy_sse2.asm',
-             'vp9/common/x86/vp9_idct_intrin_sse2.c',
-             'vp9/common/x86/vp9_intrapred_sse2.asm',
-             'vp9/common/x86/vp9_intrapred_ssse3.asm',
-             'vp9/common/x86/vp9_loopfilter_intrin_sse2.c',
-             'vp9/common/x86/vp9_loopfilter_mmx.asm',
-             'vp9/common/x86/vp9_subpixel_8t_sse2.asm',
-             'vp9/common/x86/vp9_subpixel_8t_ssse3.asm',
-             'vpx_ports/emms.asm',
-             'vpx_ports/x86_cpuid.c'],
- 'X86_ASM_ENCODER': ['vp8/encoder/x86/dct_mmx.asm',
-                     'vp8/encoder/x86/dct_sse2.asm',
-                     'vp8/encoder/x86/denoising_sse2.c',
-                     'vp8/encoder/x86/encodeopt.asm',
-                     'vp8/encoder/x86/fwalsh_sse2.asm',
-                     'vp8/encoder/x86/quantize_mmx.asm',
-                     'vp8/encoder/x86/quantize_sse2.c',
-                     'vp8/encoder/x86/quantize_sse4.asm',
-                     'vp8/encoder/x86/quantize_ssse3.asm',
-                     'vp8/encoder/x86/subtract_mmx.asm',
-                     'vp8/encoder/x86/subtract_sse2.asm',
-                     'vp8/encoder/x86/temporal_filter_apply_sse2.asm',
-                     'vp8/encoder/x86/vp8_enc_stubs_mmx.c',
-                     'vp8/encoder/x86/vp8_enc_stubs_sse2.c',
-                     'vp9/encoder/x86/vp9_dct32x32_sse2.c',
-                     'vp9/encoder/x86/vp9_dct_sse2.c',
-                     'vp9/encoder/x86/vp9_error_sse2.asm',
-                     'vp9/encoder/x86/vp9_sad4d_sse2.asm',
-                     'vp9/encoder/x86/vp9_sad_mmx.asm',
-                     'vp9/encoder/x86/vp9_sad_sse2.asm',
-                     'vp9/encoder/x86/vp9_sad_sse3.asm',
-                     'vp9/encoder/x86/vp9_sad_sse4.asm',
-                     'vp9/encoder/x86/vp9_sad_ssse3.asm',
-                     'vp9/encoder/x86/vp9_subpel_variance.asm',
-                     'vp9/encoder/x86/vp9_subpel_variance_impl_sse2.asm',
-                     'vp9/encoder/x86/vp9_subtract_sse2.asm',
-                     'vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm',
-                     'vp9/encoder/x86/vp9_variance_impl_mmx.asm',
-                     'vp9/encoder/x86/vp9_variance_impl_sse2.asm',
-                     'vp9/encoder/x86/vp9_variance_mmx.c',
-                     'vp9/encoder/x86/vp9_variance_sse2.c']
+                'vp8/common/x86/loopfilter_block_sse2.asm',
+                'vp9/encoder/x86/vp9_quantize_ssse3.asm'],
+ 'X86_ASM': [
+    'vp8/common/x86/dequantize_mmx.asm',
+    'vp8/common/x86/filter_x86.c',
+    'vp8/common/x86/idct_blk_mmx.c',
+    'vp8/common/x86/idct_blk_sse2.c',
+    'vp8/common/x86/idctllm_mmx.asm',
+    'vp8/common/x86/idctllm_sse2.asm',
+    'vp8/common/x86/iwalsh_mmx.asm',
+    'vp8/common/x86/iwalsh_sse2.asm',
+    'vp8/common/x86/loopfilter_mmx.asm',
+    'vp8/common/x86/loopfilter_sse2.asm',
+    'vp8/common/x86/loopfilter_x86.c',
+    'vp8/common/x86/mfqe_sse2.asm',
+    'vp8/common/x86/postproc_mmx.asm',
+    'vp8/common/x86/postproc_sse2.asm',
+    'vp8/common/x86/postproc_x86.c',
+    'vp8/common/x86/recon_mmx.asm',
+    'vp8/common/x86/recon_sse2.asm',
+    'vp8/common/x86/recon_wrapper_sse2.c',
+    'vp8/common/x86/sad_mmx.asm',
+    'vp8/common/x86/sad_sse2.asm',
+    'vp8/common/x86/sad_sse3.asm',
+    'vp8/common/x86/sad_sse4.asm',
+    'vp8/common/x86/sad_ssse3.asm',
+    'vp8/common/x86/subpixel_mmx.asm',
+    'vp8/common/x86/subpixel_sse2.asm',
+    'vp8/common/x86/subpixel_ssse3.asm',
+    'vp8/common/x86/variance_impl_mmx.asm',
+    'vp8/common/x86/variance_impl_sse2.asm',
+    'vp8/common/x86/variance_impl_ssse3.asm',
+    'vp8/common/x86/variance_mmx.c',
+    'vp8/common/x86/variance_sse2.c',
+    'vp8/common/x86/variance_ssse3.c',
+    'vp8/common/x86/vp8_asm_stubs.c',
+    'vp8/encoder/x86/dct_mmx.asm',
+    'vp8/encoder/x86/dct_sse2.asm',
+    'vp8/encoder/x86/denoising_sse2.c',
+    'vp8/encoder/x86/encodeopt.asm',
+    'vp8/encoder/x86/fwalsh_sse2.asm',
+    'vp8/encoder/x86/quantize_mmx.asm',
+    'vp8/encoder/x86/quantize_sse2.c',
+    'vp8/encoder/x86/quantize_sse4.asm',
+    'vp8/encoder/x86/quantize_ssse3.asm',
+    'vp8/encoder/x86/subtract_mmx.asm',
+    'vp8/encoder/x86/subtract_sse2.asm',
+    'vp8/encoder/x86/temporal_filter_apply_sse2.asm',
+    'vp8/encoder/x86/vp8_enc_stubs_mmx.c',
+    'vp8/encoder/x86/vp8_enc_stubs_sse2.c',
+    'vp9/common/x86/vp9_asm_stubs.c',
+    'vp9/common/x86/vp9_copy_sse2.asm',
+    'vp9/common/x86/vp9_idct_intrin_sse2.c',
+    'vp9/common/x86/vp9_intrapred_sse2.asm',
+    'vp9/common/x86/vp9_intrapred_ssse3.asm',
+    'vp9/common/x86/vp9_loopfilter_intrin_sse2.c',
+    'vp9/common/x86/vp9_loopfilter_mmx.asm',
+    'vp9/common/x86/vp9_subpixel_8t_sse2.asm',
+    'vp9/common/x86/vp9_subpixel_8t_ssse3.asm',
+    'vp9/encoder/x86/vp9_dct32x32_sse2.c',
+    'vp9/encoder/x86/vp9_dct_sse2.c',
+    'vp9/encoder/x86/vp9_error_sse2.asm',
+    'vp9/encoder/x86/vp9_sad4d_sse2.asm',
+    'vp9/encoder/x86/vp9_sad_mmx.asm',
+    'vp9/encoder/x86/vp9_sad_sse2.asm',
+    'vp9/encoder/x86/vp9_sad_sse3.asm',
+    'vp9/encoder/x86/vp9_sad_sse4.asm',
+    'vp9/encoder/x86/vp9_sad_ssse3.asm',
+    'vp9/encoder/x86/vp9_subpel_variance.asm',
+    'vp9/encoder/x86/vp9_subpel_variance_impl_sse2.asm',
+    'vp9/encoder/x86/vp9_subtract_sse2.asm',
+    'vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm',
+    'vp9/encoder/x86/vp9_variance_impl_mmx.asm',
+    'vp9/encoder/x86/vp9_variance_impl_sse2.asm',
+    'vp9/encoder/x86/vp9_variance_mmx.c',
+    'vp9/encoder/x86/vp9_variance_sse2.c',
+    'vpx_ports/emms.asm',
+    'vpx_ports/x86_cpuid.c',
+    ]
 }
--- a/media/libvpx/update.py
+++ b/media/libvpx/update.py
@@ -35,60 +35,17 @@ mk_files = [
     'vpx_ports/vpx_ports.mk',
     'vpx_scale/vpx_scale.mk',
     'vpx/vpx_codec.mk',
 ]
 
 extensions = ['.asm', '.c', '.h']
 
 MODULES = {
-    'ENCODER': [
-        'API_DOC_SRCS-$(CONFIG_VP8_ENCODER)',
-        'API_SRCS-$(BUILD_LIBVPX)',
-        'API_SRCS-$(CONFIG_VP8_ENCODER)',
-        'API_SRCS-$(CONFIG_VP9_ENCODER)',
-        'VP8_CX_EXPORTS',
-        'VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING)',
-        'VP8_CX_SRCS-$(CONFIG_MULTITHREAD)',
-        'VP8_CX_SRCS-$(CONFIG_TEMPORAL_DENOISING)',
-        'VP8_CX_SRCS-no',
-        'VP8_CX_SRCS_REMOVE-no',
-        'VP8_CX_SRCS_REMOVE-yes',
-        'VP8_CX_SRCS-yes',
-        'VP9_CX_EXPORTS',
-        'VP9_CX_SRCS-no',
-        'VP9_CX_SRCS_REMOVE-no',
-        'VP9_CX_SRCS_REMOVE-yes',
-        'VP9_CX_SRCS-yes',
-    ],
-    'X86_ASM_ENCODER': [
-        'VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
-        'VP8_CX_SRCS-$(HAVE_MMX)',
-        'VP8_CX_SRCS-$(HAVE_SSE2)',
-        'VP8_CX_SRCS-$(HAVE_SSE4_1)',
-        'VP8_CX_SRCS-$(HAVE_SSSE3)',
-        'VP8_CX_SRCS_REMOVE-$(HAVE_SSE2)',
-        'VP9_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
-        'VP9_CX_SRCS-$(HAVE_MMX)',
-        'VP9_CX_SRCS-$(HAVE_SSE2)',
-        'VP9_CX_SRCS-$(HAVE_SSE3)',
-        'VP9_CX_SRCS-$(HAVE_SSE4_1)',
-        'VP9_CX_SRCS-$(HAVE_SSSE3)',
-    ],
-    'X86-64_ASM_ENCODER': [
-        'VP8_CX_SRCS-$(ARCH_X86_64)',
-        'VP9_CX_SRCS-$(ARCH_X86_64)',
-    ],
-    'ARM_ASM_ENCODER': [
-        'VP8_CX_SRCS-$(ARCH_ARM)',
-        'VP8_CX_SRCS-$(HAVE_EDSP)',
-        'VP8_CX_SRCS-$(HAVE_MEDIA)',
-        'VP8_CX_SRCS-$(HAVE_NEON)',
-    ],
-    'COMMON': [
+    'SOURCES': [
         'API_DOC_SRCS-$(CONFIG_VP8_DECODER)',
         'API_DOC_SRCS-yes',
         'API_EXPORTS',
         'API_SRCS-$(CONFIG_VP8_DECODER)',
         'API_SRCS-yes',
         'MEM_SRCS-yes',
         'PORTS_SRCS-yes',
         'SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING)',
@@ -102,45 +59,80 @@ MODULES = {
         'VP8_DX_SRCS_REMOVE-yes',
         'VP8_DX_SRCS-yes',
         'VP9_COMMON_SRCS-yes',
         'VP9_DX_EXPORTS',
         'VP9_DX_SRCS-no',
         'VP9_DX_SRCS_REMOVE-no',
         'VP9_DX_SRCS_REMOVE-yes',
         'VP9_DX_SRCS-yes',
-    ],
-    'ERROR_CONCEALMENT': [
-        'VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT)',
-    ],
-    'AVX2': [
-        'VP9_COMMON_SRCS-$(HAVE_AVX2)',
+        'API_DOC_SRCS-$(CONFIG_VP8_ENCODER)',
+        'API_SRCS-$(BUILD_LIBVPX)',
+        'API_SRCS-$(CONFIG_VP8_ENCODER)',
+        'API_SRCS-$(CONFIG_VP9_ENCODER)',
+        'VP8_CX_EXPORTS',
+        'VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING)',
+        'VP8_CX_SRCS-$(CONFIG_MULTITHREAD)',
+        'VP8_CX_SRCS-$(CONFIG_TEMPORAL_DENOISING)',
+        'VP8_CX_SRCS-no',
+        'VP8_CX_SRCS_REMOVE-no',
+        'VP8_CX_SRCS_REMOVE-yes',
+        'VP8_CX_SRCS-yes',
+        'VP9_CX_EXPORTS',
+        'VP9_CX_SRCS-no',
+        'VP9_CX_SRCS_REMOVE-no',
+        'VP9_CX_SRCS_REMOVE-yes',
+        'VP9_CX_SRCS-yes',
     ],
     'X86_ASM': [
         'PORTS_SRCS-$(BUILD_LIBVPX)',
         'VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
         'VP8_COMMON_SRCS-$(HAVE_MMX)',
         'VP8_COMMON_SRCS-$(HAVE_SSE2)',
         'VP8_COMMON_SRCS-$(HAVE_SSE3)',
         'VP8_COMMON_SRCS-$(HAVE_SSE4_1)',
         'VP8_COMMON_SRCS-$(HAVE_SSSE3)',
         'VP9_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
         'VP9_COMMON_SRCS-$(HAVE_MMX)',
         'VP9_COMMON_SRCS-$(HAVE_SSE2)',
         'VP9_COMMON_SRCS-$(HAVE_SSSE3)',
+        'VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
+        'VP8_CX_SRCS-$(HAVE_MMX)',
+        'VP8_CX_SRCS-$(HAVE_SSE2)',
+        'VP8_CX_SRCS-$(HAVE_SSE4_1)',
+        'VP8_CX_SRCS-$(HAVE_SSSE3)',
+        'VP8_CX_SRCS_REMOVE-$(HAVE_SSE2)',
+        'VP9_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64)',
+        'VP9_CX_SRCS-$(HAVE_MMX)',
+        'VP9_CX_SRCS-$(HAVE_SSE2)',
+        'VP9_CX_SRCS-$(HAVE_SSE3)',
+        'VP9_CX_SRCS-$(HAVE_SSE4_1)',
+        'VP9_CX_SRCS-$(HAVE_SSSE3)',
     ],
     'X86-64_ASM': [
+        'VP8_CX_SRCS-$(ARCH_X86_64)',
+        'VP9_CX_SRCS-$(ARCH_X86_64)',
     ],
     'ARM_ASM': [
         'PORTS_SRCS-$(ARCH_ARM)',
         'SCALE_SRCS-$(HAVE_NEON)',
         'VP8_COMMON_SRCS-$(ARCH_ARM)',
         'VP8_COMMON_SRCS-$(HAVE_MEDIA)',
         'VP8_COMMON_SRCS-$(HAVE_NEON)',
         'VP9_COMMON_SRCS-$(HAVE_NEON)',
+        'VP8_CX_SRCS-$(ARCH_ARM)',
+        'VP8_CX_SRCS-$(HAVE_EDSP)',
+        'VP8_CX_SRCS-$(HAVE_MEDIA)',
+        'VP8_CX_SRCS-$(HAVE_NEON)',
+    ],
+    'ERROR_CONCEALMENT': [
+        'VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT)',
+    ],
+    'AVX2': [
+        'VP9_COMMON_SRCS-$(HAVE_AVX2)',
     ],
     'VP8_POSTPROC': [
         'VP8_COMMON_SRCS-$(CONFIG_POSTPROC)',
     ],
     'VP9_POSTPROC': [
         'VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC)',
     ]
 }
@@ -248,17 +240,16 @@ manual = [
     # asm includes
     'vpx_ports/x86_abi_support.asm',
 ]
 
 platform_files = [
     'vp8_rtcd.h',
     'vp9_rtcd.h',
     'vpx_config.asm',
-    'vpx_config.c',
     'vpx_config.h',
     'vpx_scale_rtcd.h',
 ]
 
 def prepare_upstream(prefix, commit=None):
     if os.path.exists(prefix):
         print "Please remove '%s' folder before running %s" % (prefix, sys.argv[0])
         sys.exit(1)
@@ -273,17 +264,20 @@ def prepare_upstream(prefix, commit=None
         p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
         stdout, stderr = p.communicate()
         commit = stdout.strip()
 
     for target in PLATFORMS:
         target_objdir = os.path.join(prefix, 'objdir', target)
         os.makedirs(target_objdir)
         os.chdir(target_objdir)
-        configure = ['../../configure', '--target=%s' % target, '--disable-examples', '--disable-install-docs']
+        configure = ['../../configure', '--target=%s' % target,
+            '--disable-examples', '--disable-install-docs',
+            '--enable-multi-res-encoding',
+        ]
 
         if 'darwin9' in target:
             configure += ['--enable-pic']
         if 'linux' in target:
             configure += ['--enable-pic']
             # mozilla linux toolchain currently does not support avx2,
             # remove once gcc is updated
             configure += ['--disable-avx2']
--- a/media/libvpx/vpx_config.h
+++ b/media/libvpx/vpx_config.h
@@ -35,22 +35,12 @@
 
 #else
 /* Assume generic GNU/GCC configuration. */
 #include "vpx_config_generic-gnu.h"
 #endif
 
 /* Control error-concealment support using our own #define rather than
    hard-coding it. */
-#if defined(MOZ_VP8_ERROR_CONCEALMENT)
+#if defined(MOZ_VPX_ERROR_CONCEALMENT)
 #undef CONFIG_ERROR_CONCEALMENT
 #define CONFIG_ERROR_CONCEALMENT 1
 #endif
-
-/* Control encoder support using our own #define rather than hard-coding it. */
-#if defined(MOZ_VP8_ENCODER)
-#undef CONFIG_VP8_ENCODER
-#undef CONFIG_ENCODERS
-#undef CONFIG_MULTI_RES_ENCODING
-#define CONFIG_VP8_ENCODER 1
-#define CONFIG_ENCODERS 1
-#define CONFIG_MULTI_RES_ENCODING 1
-#endif
--- a/media/libvpx/vpx_config_armv7-android-gcc.asm
+++ b/media/libvpx/vpx_config_armv7-android-gcc.asm
@@ -69,17 +69,17 @@
 .equ CONFIG_ONTHEFLY_BITPACKING ,  0
 .equ CONFIG_ERROR_CONCEALMENT ,  0
 .equ CONFIG_SHARED ,  0
 .equ CONFIG_STATIC ,  1
 .equ CONFIG_SMALL ,  0
 .equ CONFIG_POSTPROC_VISUALIZER ,  0
 .equ CONFIG_OS_SUPPORT ,  1
 .equ CONFIG_UNIT_TESTS ,  0
-.equ CONFIG_MULTI_RES_ENCODING ,  0
+.equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_EXPERIMENTAL ,  0
 .equ CONFIG_DECRYPT ,  0
 .equ CONFIG_MULTIPLE_ARF ,  0
 .equ CONFIG_NON420 ,  0
 .equ CONFIG_ALPHA ,  0
 	.section	.note.GNU-stack,"",%progbits
 @ This file was created from a .asm file
deleted file mode 100644
--- a/media/libvpx/vpx_config_armv7-android-gcc.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=armv7-android-gcc --disable-examples --disable-install-docs --sdk-path=/opt/android-ndk-r9b/";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_armv7-android-gcc.h
+++ b/media/libvpx/vpx_config_armv7-android-gcc.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 0
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
deleted file mode 100644
--- a/media/libvpx/vpx_config_c.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#if defined(VPX_X86_ASM)
-
-#if defined(_WIN64)
-#include "vpx_config_x86_64-win64-vs8.c"
-
-#elif defined(WIN32)
-/* 32 bit Windows, MSVC. */
-#include "vpx_config_x86-win32-vs8.c"
-
-#elif defined(__APPLE__) && defined(__x86_64__)
-/* 64 bit MacOS. */
-#include "vpx_config_x86_64-darwin9-gcc.c"
-
-#elif defined(__APPLE__) && defined(__i386__)
-/* 32 bit MacOS. */
-#include "vpx_config_x86-darwin9-gcc.c"
-
-#elif defined(__ELF__) && (defined(__i386) || defined(__i386__))
-/* 32 bit ELF platforms. */
-#include "vpx_config_x86-linux-gcc.c"
-
-#elif defined(__ELF__) && (defined(__x86_64) || defined(__x86_64__))
-/* 64 bit ELF platforms. */
-#include "vpx_config_x86_64-linux-gcc.c"
-
-#else
-#error VPX_X86_ASM is defined, but assembly not supported on this platform!
-#endif
-
-#elif defined(VPX_ARM_ASM)
-
-#if defined(__linux__) && defined(__GNUC__)
-#include "vpx_config_arm-linux-gcc.c"
-
-#else
-#error VPX_ARM_ASM is defined, but assembly not supported on this platform!
-#endif
-
-#else
-/* Assume generic GNU/GCC configuration. */
-#include "vpx_config_generic-gnu.c"
-#endif
-
--- a/media/libvpx/vpx_config_generic-gnu.asm
+++ b/media/libvpx/vpx_config_generic-gnu.asm
@@ -69,17 +69,17 @@
 .equ CONFIG_ONTHEFLY_BITPACKING ,  0
 .equ CONFIG_ERROR_CONCEALMENT ,  0
 .equ CONFIG_SHARED ,  0
 .equ CONFIG_STATIC ,  1
 .equ CONFIG_SMALL ,  0
 .equ CONFIG_POSTPROC_VISUALIZER ,  0
 .equ CONFIG_OS_SUPPORT ,  1
 .equ CONFIG_UNIT_TESTS ,  1
-.equ CONFIG_MULTI_RES_ENCODING ,  0
+.equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_EXPERIMENTAL ,  0
 .equ CONFIG_DECRYPT ,  0
 .equ CONFIG_MULTIPLE_ARF ,  0
 .equ CONFIG_NON420 ,  0
 .equ CONFIG_ALPHA ,  0
 	.section	.note.GNU-stack,"",%progbits
 @ This file was created from a .asm file
deleted file mode 100644
--- a/media/libvpx/vpx_config_generic-gnu.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=generic-gnu --disable-examples --disable-install-docs";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_generic-gnu.h
+++ b/media/libvpx/vpx_config_generic-gnu.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86-darwin9-gcc.asm
+++ b/media/libvpx/vpx_config_x86-darwin9-gcc.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86-darwin9-gcc.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86-darwin9-gcc --disable-examples --disable-install-docs --enable-pic";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86-darwin9-gcc.h
+++ b/media/libvpx/vpx_config_x86-darwin9-gcc.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86-linux-gcc.asm
+++ b/media/libvpx/vpx_config_x86-linux-gcc.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86-linux-gcc.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86-linux-gcc --disable-examples --disable-install-docs --enable-pic --disable-avx2 --disable-use-x86inc";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86-linux-gcc.h
+++ b/media/libvpx/vpx_config_x86-linux-gcc.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86-win32-vs8.asm
+++ b/media/libvpx/vpx_config_x86-win32-vs8.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86-win32-vs8.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86-win32-vs8 --disable-examples --disable-install-docs";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86-win32-vs8.h
+++ b/media/libvpx/vpx_config_x86-win32-vs8.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86_64-darwin9-gcc.asm
+++ b/media/libvpx/vpx_config_x86_64-darwin9-gcc.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86_64-darwin9-gcc.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86_64-darwin9-gcc --disable-examples --disable-install-docs --enable-pic";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86_64-darwin9-gcc.h
+++ b/media/libvpx/vpx_config_x86_64-darwin9-gcc.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86_64-linux-gcc.asm
+++ b/media/libvpx/vpx_config_x86_64-linux-gcc.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86_64-linux-gcc.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86_64-linux-gcc --disable-examples --disable-install-docs --enable-pic --disable-avx2";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86_64-linux-gcc.h
+++ b/media/libvpx/vpx_config_x86_64-linux-gcc.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
--- a/media/libvpx/vpx_config_x86_64-win64-vs8.asm
+++ b/media/libvpx/vpx_config_x86_64-win64-vs8.asm
@@ -66,15 +66,15 @@ CONFIG_REALTIME_ONLY equ 0
 CONFIG_ONTHEFLY_BITPACKING equ 0
 CONFIG_ERROR_CONCEALMENT equ 0
 CONFIG_SHARED equ 0
 CONFIG_STATIC equ 1
 CONFIG_SMALL equ 0
 CONFIG_POSTPROC_VISUALIZER equ 0
 CONFIG_OS_SUPPORT equ 1
 CONFIG_UNIT_TESTS equ 1
-CONFIG_MULTI_RES_ENCODING equ 0
+CONFIG_MULTI_RES_ENCODING equ 1
 CONFIG_TEMPORAL_DENOISING equ 1
 CONFIG_EXPERIMENTAL equ 0
 CONFIG_DECRYPT equ 0
 CONFIG_MULTIPLE_ARF equ 0
 CONFIG_NON420 equ 0
 CONFIG_ALPHA equ 0
deleted file mode 100644
--- a/media/libvpx/vpx_config_x86_64-win64-vs8.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */
-/*  */
-/* Use of this source code is governed by a BSD-style license */
-/* that can be found in the LICENSE file in the root of the source */
-/* tree. An additional intellectual property rights grant can be found */
-/* in the file PATENTS.  All contributing project authors may */
-/* be found in the AUTHORS file in the root of the source tree. */
-static const char* const cfg = "--target=x86_64-win64-vs8 --disable-examples --disable-install-docs";
-const char *vpx_codec_build_config(void) {return cfg;}
--- a/media/libvpx/vpx_config_x86_64-win64-vs8.h
+++ b/media/libvpx/vpx_config_x86_64-win64-vs8.h
@@ -78,16 +78,16 @@
 #define CONFIG_ONTHEFLY_BITPACKING 0
 #define CONFIG_ERROR_CONCEALMENT 0
 #define CONFIG_SHARED 0
 #define CONFIG_STATIC 1
 #define CONFIG_SMALL 0
 #define CONFIG_POSTPROC_VISUALIZER 0
 #define CONFIG_OS_SUPPORT 1
 #define CONFIG_UNIT_TESTS 1
-#define CONFIG_MULTI_RES_ENCODING 0
+#define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_EXPERIMENTAL 0
 #define CONFIG_DECRYPT 0
 #define CONFIG_MULTIPLE_ARF 0
 #define CONFIG_NON420 0
 #define CONFIG_ALPHA 0
 #endif /* VPX_CONFIG_H */
deleted file mode 100644
--- a/media/libvpx/vpx_x86-darwin9-gcc.c
+++ /dev/null
@@ -1,15 +0,0 @@
-static const char* const cfg =
-"H4sIAFc23ksAA31WTXPaMBC991eo01sOTQsNzVXIi9FgfVSSHThpaDCpZyjMpOSQ"
-"f18Z27S21vjkee/tl3a98v0dcb+qP2RfHUqyfTuffm/P1fP2cHgnL+WxfN2eyx35"
-"+U6eT8d99fL2Wn4myYkcT2dS7qrzR3J3/+HTrtxXx5JwmXEJ5PJcwYUyDFrmChqw"
-"znDmekpq2NJTI8iXPiS4tkNs/TgjX68QSDrPYAB2Oj/7NrTWmk0nCNhTLmkBdTrF"
-"gwMMnmHg9yHIn4RYOxydDOG60mmMinVcax+86KyFWNcHO90EFU4Q5RRVTmPliBTR"
-"0szxAtiwTCUnXivjbOwGo5qwLuHS+SUSOWa64N4ZAJ/Rjcqjxmi3NEATzCNGNUls"
-"bGgHlWgaGMeUXPDUw9qBkTTz85xnyX+ZtDyX1tEs84lidpydh5c47gg7sM34/Ibt"
-"gB3YWsNu2A7Y1jaBeZ7GpaTaqAUCM1XEqCmYw7QsTqYPtkphC+Q0NUfs+2CrZCoB"
-"1tQXebnU15xbxC2odT4P7eaphCQONsp3eYPwYZBoCiZ2XpPOULYaI9kS2ArJSiQP"
-"yG7pgdfafuQ0fFFOrUBitTNvILzHjISnUSsoaD1ogiM9Nbl0XIBnOg/RHYS+R6ne"
-"1HS9VdaFCcMaHDMDG5+ChHBTISeXhzXWrATkBFGy820l0qVCP3qQ9XSNkGHsLmQU"
-"DCf/WaIWyDpqgqNj3TKRI4RpbcIacJzVXxszSG+tDnRoffgRoEKHn4MU2Z23NN2M"
-"QH2biPqKyDYhzF9rQkWwzggAAA=="
-;const char *on2_codec_build_config(void) {return cfg;}
--- a/media/webrtc/signaling/signaling.gyp
+++ b/media/webrtc/signaling/signaling.gyp
@@ -177,16 +177,17 @@
         'HAVE_UINT16_T=1',
         'HAVE_UINT32_T=1',
         'HAVE_UINT64_T=1',
       ],
 
       'cflags_mozilla': [
         '$(NSPR_CFLAGS)',
         '$(NSS_CFLAGS)',
+        '$(MOZ_PIXMAN_CFLAGS)',
       ],
 
       #
       # Conditionals
       #
       'conditions': [
         ['build_for_test==0', {
           'defines' : [
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -164,16 +164,17 @@ public class GeckoEvent {
     private double mY;
     private double mZ;
 
     private int mMetaState;
     private int mFlags;
     private int mKeyCode;
     private int mUnicodeChar;
     private int mBaseUnicodeChar; // mUnicodeChar without meta states applied
+    private int mDOMPrintableKeyValue;
     private int mRepeatCount;
     private int mCount;
     private int mStart;
     private int mEnd;
     private String mCharacters;
     private String mCharactersExtra;
     private String mData;
     private int mRangeType;
@@ -251,16 +252,27 @@ public class GeckoEvent {
         mFlags = k.getFlags();
         mKeyCode = k.getKeyCode();
         mUnicodeChar = k.getUnicodeChar(mMetaState);
         // e.g. for Ctrl+A, Android returns 0 for mUnicodeChar,
         // but Gecko expects 'a', so we return that in mBaseUnicodeChar
         mBaseUnicodeChar = k.getUnicodeChar(0);
         mRepeatCount = k.getRepeatCount();
         mCharacters = k.getCharacters();
+        if (mUnicodeChar >= ' ') {
+            mDOMPrintableKeyValue = mUnicodeChar;
+        } else {
+            int unmodifiedMetaState =
+                mMetaState & ~(KeyEvent.META_ALT_MASK |
+                               KeyEvent.META_CTRL_MASK |
+                               KeyEvent.META_META_MASK);
+            if (unmodifiedMetaState != mMetaState) {
+                mDOMPrintableKeyValue = k.getUnicodeChar(unmodifiedMetaState);
+            }
+        }
         mDomKeyLocation = isJoystickButton(mKeyCode) ? DomKeyLocation.DOM_KEY_LOCATION_JOYSTICK
                                                      : DomKeyLocation.DOM_KEY_LOCATION_MOBILE;
     }
 
     /**
      * This method tests if a key is one of the described in:
      * https://bugzilla.mozilla.org/show_bug.cgi?id=756504#c0
      * @param keyCode int with the key code (Android key constant from KeyEvent)
--- a/security/manager/pki/resources/content/editcerts.js
+++ b/security/manager/pki/resources/content/editcerts.js
@@ -101,17 +101,19 @@ function doLoadForEmailCert()
   var sslTrust = document.getElementById("sslTrustGroup");
   sslTrust.value = certdb.isCertTrusted(cert, nsIX509Cert.EMAIL_CERT,
                                         nsIX509CertDB.TRUSTED_EMAIL);
 }
 
 function doEmailOK()
 {
   var sslTrust = document.getElementById("sslTrustGroup");
-  var trustemail = sslTrust.value ? nsIX509CertDB.TRUSTED_EMAIL : 0;
+  var trustemail = sslTrust.value == "true"
+                   ? nsIX509CertDB.TRUSTED_EMAIL
+                   : nsIX509CertDB.UNTRUSTED;
   //
   //  Set the cert trust
   //
   certdb.setCertTrust(cert, nsIX509Cert.EMAIL_CERT, trustemail);
   return true;
 }
 
 function editCaTrust()
--- a/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -276,17 +276,17 @@ GetKeyUsagesString(CERTCertificate *cert
       return NS_OK;
     else
       return NS_ERROR_FAILURE;
   }
 
   unsigned char keyUsage = keyUsageItem.data[0];
   nsAutoString local;
   nsresult rv;
-  const PRUnichar *comma = NS_LITERAL_STRING(",").get();
+  const char16_t comma = ',';
 
   if (keyUsage & KU_DIGITAL_SIGNATURE) {
     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUSign", local);
     if (NS_SUCCEEDED(rv)) {
       if (!text.IsEmpty()) text.Append(comma);
       text.Append(local.get());
     }
   }
--- a/view/src/Makefile.in
+++ b/view/src/Makefile.in
@@ -1,8 +1,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 $(topsrcdir)/config/rules.mk
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -102,26 +102,32 @@ public:
   nsTArray<AlternativeCharCode> alternativeCharCodes;
   // Indicates whether the event signifies a printable character
   bool isChar;
   // Indicates whether the event is generated by auto repeat or not.
   // if this is keyup event, always false.
   bool mIsRepeat;
   // DOM KeyboardEvent.key
   KeyNameIndex mKeyNameIndex;
+  // DOM KeyboardEvent.key only when mKeyNameIndex is KEY_NAME_INDEX_USE_STRING.
+  nsString mKeyValue;
   // OS-specific native event can optionally be preserved
   void* mNativeKeyEvent;
   // Unique id associated with a keydown / keypress event. Used in identifing
   // keypress events for removal from async event dispatch queue in metrofx
   // after preventDefault is called on keydown events. It's ok if this wraps
   // over long periods.
   uint32_t mUniqueId;
 
   void GetDOMKeyName(nsAString& aKeyName)
   {
+    if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
+      aKeyName = mKeyValue;
+      return;
+    }
     GetDOMKeyName(mKeyNameIndex, aKeyName);
   }
 
   static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex,
                             nsAString& aKeyName)
   {
 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
       case KEY_NAME_INDEX_##aCPPName: \
@@ -142,16 +148,17 @@ public:
 
     keyCode = aEvent.keyCode;
     charCode = aEvent.charCode;
     location = aEvent.location;
     alternativeCharCodes = aEvent.alternativeCharCodes;
     isChar = aEvent.isChar;
     mIsRepeat = aEvent.mIsRepeat;
     mKeyNameIndex = aEvent.mKeyNameIndex;
+    mKeyValue = aEvent.mKeyValue;
     // Don't copy mNativeKeyEvent because it may be referred after its instance
     // is destroyed.
     mNativeKeyEvent = nullptr;
     mUniqueId = aEvent.mUniqueId;
   }
 };
 
 /******************************************************************************
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -30,16 +30,17 @@ jfieldID AndroidGeckoEvent::jYField = 0;
 jfieldID AndroidGeckoEvent::jZField = 0;
 jfieldID AndroidGeckoEvent::jDistanceField = 0;
 jfieldID AndroidGeckoEvent::jRectField = 0;
 jfieldID AndroidGeckoEvent::jNativeWindowField = 0;
 
 jfieldID AndroidGeckoEvent::jCharactersField = 0;
 jfieldID AndroidGeckoEvent::jCharactersExtraField = 0;
 jfieldID AndroidGeckoEvent::jDataField = 0;
+jfieldID AndroidGeckoEvent::jDOMPrintableKeyValueField = 0;
 jfieldID AndroidGeckoEvent::jKeyCodeField = 0;
 jfieldID AndroidGeckoEvent::jMetaStateField = 0;
 jfieldID AndroidGeckoEvent::jDomKeyLocationField = 0;
 jfieldID AndroidGeckoEvent::jFlagsField = 0;
 jfieldID AndroidGeckoEvent::jUnicodeCharField = 0;
 jfieldID AndroidGeckoEvent::jBaseUnicodeCharField = 0;
 jfieldID AndroidGeckoEvent::jRepeatCountField = 0;
 jfieldID AndroidGeckoEvent::jCountField = 0;
@@ -141,16 +142,17 @@ AndroidGeckoEvent::InitGeckoEventClass(J
     jCharactersExtraField = getField("mCharactersExtra", "Ljava/lang/String;");
     jDataField = getField("mData", "Ljava/lang/String;");
     jKeyCodeField = getField("mKeyCode", "I");
     jMetaStateField = getField("mMetaState", "I");
     jDomKeyLocationField = getField("mDomKeyLocation", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;");
     jFlagsField = getField("mFlags", "I");
     jUnicodeCharField = getField("mUnicodeChar", "I");
     jBaseUnicodeCharField = getField("mBaseUnicodeChar", "I");
+    jDOMPrintableKeyValueField = getField("mDOMPrintableKeyValue", "I");
     jRepeatCountField = getField("mRepeatCount", "I");
     jCountField = getField("mCount", "I");
     jStartField = getField("mStart", "I");
     jEndField = getField("mEnd", "I");
     jPointerIndexField = getField("mPointerIndex", "I");
     jRangeTypeField = getField("mRangeType", "I");
     jRangeStylesField = getField("mRangeStyles", "I");
     jRangeLineStyleField = getField("mRangeLineStyle", "I");
@@ -419,16 +421,18 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
         case IME_KEY_EVENT:
             mTime = jenv->GetLongField(jobj, jTimeField);
             mMetaState = jenv->GetIntField(jobj, jMetaStateField);
             mDomKeyLocation = ReadDomKeyLocation(jenv, jobj);
             mFlags = jenv->GetIntField(jobj, jFlagsField);
             mKeyCode = jenv->GetIntField(jobj, jKeyCodeField);
             mUnicodeChar = jenv->GetIntField(jobj, jUnicodeCharField);
             mBaseUnicodeChar = jenv->GetIntField(jobj, jBaseUnicodeCharField);
+            mDOMPrintableKeyValue =
+                jenv->GetIntField(jobj, jDOMPrintableKeyValueField);
             mRepeatCount = jenv->GetIntField(jobj, jRepeatCountField);
             ReadCharactersField(jenv);
             break;
 
         case NATIVE_GESTURE_EVENT:
             mTime = jenv->GetLongField(jobj, jTimeField);
             mMetaState = jenv->GetIntField(jobj, jMetaStateField);
             mCount = jenv->GetIntField(jobj, jCountField);
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -506,16 +506,17 @@ public:
     uint32_t DomKeyLocation() { return mDomKeyLocation; }
     bool IsAltPressed() const { return (mMetaState & AMETA_ALT_MASK) != 0; }
     bool IsShiftPressed() const { return (mMetaState & AMETA_SHIFT_MASK) != 0; }
     bool IsCtrlPressed() const { return (mMetaState & AMETA_CTRL_MASK) != 0; }
     bool IsMetaPressed() const { return (mMetaState & AMETA_META_MASK) != 0; }
     int Flags() { return mFlags; }
     int UnicodeChar() { return mUnicodeChar; }
     int BaseUnicodeChar() { return mBaseUnicodeChar; }
+    int DOMPrintableKeyValue() { return mDOMPrintableKeyValue; }
     int RepeatCount() const { return mRepeatCount; }
     int Count() { return mCount; }
     int Start() { return mStart; }
     int End() { return mEnd; }
     int PointerIndex() { return mPointerIndex; }
     int RangeType() { return mRangeType; }
     int RangeStyles() { return mRangeStyles; }
     int RangeLineStyle() { return mRangeLineStyle; }
@@ -547,17 +548,17 @@ protected:
     nsTArray<nsIntPoint> mPoints;
     nsTArray<nsIntPoint> mPointRadii;
     nsTArray<int> mPointIndicies;
     nsTArray<float> mOrientations;
     nsTArray<float> mPressures;
     nsIntRect mRect;
     int mFlags, mMetaState;
     uint32_t mDomKeyLocation;
-    int mKeyCode, mUnicodeChar, mBaseUnicodeChar;
+    int mKeyCode, mUnicodeChar, mBaseUnicodeChar, mDOMPrintableKeyValue;
     int mRepeatCount;
     int mCount;
     int mStart, mEnd;
     int mRangeType, mRangeStyles, mRangeLineStyle;
     bool mRangeBoldLine;
     int mRangeForeColor, mRangeBackColor, mRangeLineColor;
     double mX, mY, mZ;
     int mPointerIndex;
@@ -611,16 +612,17 @@ protected:
     static jfieldID jZField;
     static jfieldID jDistanceField;
     static jfieldID jRectField;
     static jfieldID jNativeWindowField;
 
     static jfieldID jCharactersField;
     static jfieldID jCharactersExtraField;
     static jfieldID jDataField;
+    static jfieldID jDOMPrintableKeyValueField;
     static jfieldID jKeyCodeField;
     static jfieldID jMetaStateField;
     static jfieldID jDomKeyLocationField;
     static jfieldID jFlagsField;
     static jfieldID jCountField;
     static jfieldID jStartField;
     static jfieldID jEndField;
     static jfieldID jPointerIndexField;
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1388,74 +1388,82 @@ static unsigned int ConvertAndroidKeyCod
 
         default:
             ALOG("ConvertAndroidKeyCodeToDOMKeyCode: "
                  "No DOM keycode for Android keycode %d", androidKeyCode);
         return 0;
     }
 }
 
-static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
+static KeyNameIndex
+ConvertAndroidKeyCodeToKeyNameIndex(AndroidGeckoEvent& aAndroidGeckoEvent)
 {
+    int keyCode = aAndroidGeckoEvent.KeyCode();
     // Special-case alphanumeric keycodes because they are most common.
-    if (aAndroidKeyCode >= AKEYCODE_A && aAndroidKeyCode <= AKEYCODE_Z) {
-        return KEY_NAME_INDEX_PrintableKey;
+    if (keyCode >= AKEYCODE_A && keyCode <= AKEYCODE_Z) {
+        return KEY_NAME_INDEX_USE_STRING;
     }
 
-    if (aAndroidKeyCode >= AKEYCODE_0 && aAndroidKeyCode <= AKEYCODE_9) {
-        return KEY_NAME_INDEX_PrintableKey;
+    if (keyCode >= AKEYCODE_0 && keyCode <= AKEYCODE_9) {
+        return KEY_NAME_INDEX_USE_STRING;
     }
 
-    switch (aAndroidKeyCode) {
+    switch (keyCode) {
 
 #define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex) \
         case aNativeKey: return aKeyNameIndex;
 
 #include "NativeKeyToDOMKeyName.h"
 
 #undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
 
         // KEYCODE_0 (7) ... KEYCODE_9 (16)
         case AKEYCODE_STAR:               // '*' key
         case AKEYCODE_POUND:              // '#' key
 
         // KEYCODE_A (29) ... KEYCODE_Z (54)
 
         case AKEYCODE_COMMA:              // ',' key
         case AKEYCODE_PERIOD:             // '.' key
+        case AKEYCODE_SPACE:
         case AKEYCODE_GRAVE:              // '`' key
         case AKEYCODE_MINUS:              // '-' key
         case AKEYCODE_EQUALS:             // '=' key
         case AKEYCODE_LEFT_BRACKET:       // '[' key
         case AKEYCODE_RIGHT_BRACKET:      // ']' key
         case AKEYCODE_BACKSLASH:          // '\' key
         case AKEYCODE_SEMICOLON:          // ';' key
         case AKEYCODE_APOSTROPHE:         // ''' key
         case AKEYCODE_SLASH:              // '/' key
         case AKEYCODE_AT:                 // '@' key
         case AKEYCODE_PLUS:               // '+' key
 
-        case AKEYCODE_UNKNOWN:
         case AKEYCODE_NUMPAD_0:
         case AKEYCODE_NUMPAD_1:
         case AKEYCODE_NUMPAD_2:
         case AKEYCODE_NUMPAD_3:
         case AKEYCODE_NUMPAD_4:
         case AKEYCODE_NUMPAD_5:
         case AKEYCODE_NUMPAD_6:
         case AKEYCODE_NUMPAD_7:
         case AKEYCODE_NUMPAD_8:
         case AKEYCODE_NUMPAD_9:
-
+        case AKEYCODE_NUMPAD_DIVIDE:
+        case AKEYCODE_NUMPAD_MULTIPLY:
+        case AKEYCODE_NUMPAD_SUBTRACT:
+        case AKEYCODE_NUMPAD_ADD:
+        case AKEYCODE_NUMPAD_DOT:
+        case AKEYCODE_NUMPAD_COMMA:
+        case AKEYCODE_NUMPAD_EQUALS:
         case AKEYCODE_NUMPAD_LEFT_PAREN:
         case AKEYCODE_NUMPAD_RIGHT_PAREN:
 
         case AKEYCODE_YEN:                // yen sign key
         case AKEYCODE_RO:                 // Japanese Ro key
-            return KEY_NAME_INDEX_PrintableKey;
+            return KEY_NAME_INDEX_USE_STRING;
 
         case AKEYCODE_SOFT_LEFT:
         case AKEYCODE_SOFT_RIGHT:
         case AKEYCODE_CALL:
         case AKEYCODE_ENDCALL:
         case AKEYCODE_SYM:                // Symbol modifier
         case AKEYCODE_NUM:                // XXX Not sure
         case AKEYCODE_HEADSETHOOK:
@@ -1516,19 +1524,28 @@ static KeyNameIndex ConvertAndroidKeyCod
         case AKEYCODE_CALENDAR:
         case AKEYCODE_MUSIC:
         case AKEYCODE_CALCULATOR:
 
         case AKEYCODE_ZENKAKU_HANKAKU:
         case AKEYCODE_KATAKANA_HIRAGANA:
             return KEY_NAME_INDEX_Unidentified;
 
+        case AKEYCODE_UNKNOWN:
+            MOZ_ASSERT(
+                aAndroidGeckoEvent.Action() != AKEY_EVENT_ACTION_MULTIPLE,
+                "Don't call this when action is AKEY_EVENT_ACTION_MULTIPLE!");
+            // It's actually an unknown key if the action isn't ACTION_MULTIPLE.
+            // However, it might cause text input.  So, let's check the value.
+            return aAndroidGeckoEvent.DOMPrintableKeyValue() ?
+                KEY_NAME_INDEX_USE_STRING : KEY_NAME_INDEX_Unidentified;
+
         default:
             ALOG("ConvertAndroidKeyCodeToKeyNameIndex: "
-                 "No DOM key name index for Android keycode %d", aAndroidKeyCode);
+                 "No DOM key name index for Android keycode %d", keyCode);
             return KEY_NAME_INDEX_Unidentified;
     }
 }
 
 static void InitPluginEvent(ANPEvent* pluginEvent, ANPKeyActions keyAction,
                             AndroidGeckoEvent& key)
 {
     int androidKeyCode = key.KeyCode();
@@ -1549,19 +1566,24 @@ static void InitPluginEvent(ANPEvent* pl
     pluginEvent->data.key.modifiers = modifiers;
     pluginEvent->data.key.repeatCount = key.RepeatCount();
 }
 
 void
 nsWindow::InitKeyEvent(WidgetKeyboardEvent& event, AndroidGeckoEvent& key,
                        ANPEvent* pluginEvent)
 {
-    int androidKeyCode = key.KeyCode();
-    event.mKeyNameIndex = ConvertAndroidKeyCodeToKeyNameIndex(androidKeyCode);
-    uint32_t domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(androidKeyCode);
+    event.mKeyNameIndex = ConvertAndroidKeyCodeToKeyNameIndex(key);
+    if (event.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
+        int keyValue = key.DOMPrintableKeyValue();
+        if (keyValue) {
+            event.mKeyValue = static_cast<PRUnichar>(keyValue);
+        }
+    }
+    uint32_t domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(key.KeyCode());
 
     if (event.message == NS_KEY_PRESS) {
         // Android gives us \n, so filter out some control characters.
         int charCode = key.UnicodeChar();
         if (!charCode) {
             charCode = key.BaseUnicodeChar();
         }
         event.isChar = (charCode >= ' ');
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -777,18 +777,19 @@ void
 TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
                                     WidgetKeyboardEvent& aKeyEvent,
                                     const nsAString *aInsertString)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   PR_LOG(gLog, PR_LOG_ALWAYS,
     ("%p TISInputSourceWrapper::InitKeyEvent, aNativeKeyEvent=%p, "
-     "aKeyEvent.message=%s, aInsertString=%p",
-     this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent), aInsertString));
+     "aKeyEvent.message=%s, aInsertString=%p, IsOpenedIMEMode()=%s",
+     this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent), aInsertString,
+     TrueOrFalse(IsOpenedIMEMode())));
 
   NS_ENSURE_TRUE(aNativeKeyEvent, );
 
   nsCocoaUtils::InitInputEvent(aKeyEvent, aNativeKeyEvent);
 
   // This is used only while dispatching the event (which is a synchronous
   // call), so there is no need to retain and release this data.
   aKeyEvent.mNativeKeyEvent = aNativeKeyEvent;
@@ -963,38 +964,74 @@ TISInputSourceWrapper::InitKeyEvent(NSEv
     aKeyEvent.charCode = 0;
     aKeyEvent.isChar = false; // XXX not used in XP level
 
     PR_LOG(gLog, PR_LOG_ALWAYS,
       ("%p TISInputSourceWrapper::InitKeyEvent, keyCode=0x%X charCode=0x0",
        this, aKeyEvent.keyCode));
   }
 
-  // Compute the key for non-printable keys and some special printable keys.
-  aKeyEvent.mKeyNameIndex = ComputeGeckoKeyNameIndex(nativeKeyCode);
-  if (isPrintableKey &&
-      aKeyEvent.mKeyNameIndex == KEY_NAME_INDEX_Unidentified) {
-    // If the key name isn't in the list and the key is a printable key but
-    // inserting no characters without control key nor command key, then,
-    // check if the key is dead key.
-    if (insertString.IsEmpty() &&
-        !aKeyEvent.IsControl() && !aKeyEvent.IsMeta()) {
+  if (isPrintableKey) {
+    aKeyEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
+    // If insertText calls this method, let's use the string.
+    if (aInsertString && !aInsertString->IsEmpty() &&
+        !IsControlChar((*aInsertString)[0])) {
+      aKeyEvent.mKeyValue = *aInsertString;
+    }
+    // If meta key is pressed, the printable key layout may be switched from
+    // non-ASCII capable layout to ASCII capable, or from Dvorak to QWERTY.
+    // KeyboardEvent.key value should be the switched layout's character.
+    else if (aKeyEvent.IsMeta()) {
+      nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters],
+                                         aKeyEvent.mKeyValue);
+    }
+    // If control key is pressed, some keys may produce printable character via
+    // [aNativeKeyEvent characters].  Otherwise, translate input character of
+    // the key without control key.
+    else if (aKeyEvent.IsControl()) {
+      nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters],
+                                         aKeyEvent.mKeyValue);
+      if (aKeyEvent.mKeyValue.IsEmpty() ||
+          IsControlChar(aKeyEvent.mKeyValue[0])) {
+        NSUInteger cocoaState =
+          [aNativeKeyEvent modifierFlags] & ~NSControlKeyMask;
+        UInt32 carbonState = nsCocoaUtils::ConvertToCarbonModifier(cocoaState);
+        aKeyEvent.mKeyValue =
+          TranslateToChar(nativeKeyCode, carbonState, kbType);
+      }
+    }
+    // Otherwise, KeyboardEvent.key expose
+    // [aNativeKeyEvent characters] value.  However, if IME is open and the
+    // keyboard layout isn't ASCII capable, exposing the non-ASCII character
+    // doesn't match with other platform's behavior.  For the compatibility
+    // with other platform's Gecko, we need to set a translated character.
+    else if (IsOpenedIMEMode()) {
       UInt32 state =
         nsCocoaUtils::ConvertToCarbonModifier([aNativeKeyEvent modifierFlags]);
-      uint32_t ch = TranslateToChar(nativeKeyCode, state, kbType);
-      if (ch) {
-        aKeyEvent.mKeyNameIndex =
-          WidgetUtils::GetDeadKeyNameIndex(static_cast<PRUnichar>(ch));
+      aKeyEvent.mKeyValue = TranslateToChar(nativeKeyCode, state, kbType);
+    } else {
+      nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters],
+                                         aKeyEvent.mKeyValue);
+    }
+
+    // Last resort.  If .key value becomes empty string, we should use
+    // charactersIgnoringModifiers, if it's available.
+    if (aKeyEvent.mKeyValue.IsEmpty() ||
+        IsControlChar(aKeyEvent.mKeyValue[0])) {
+      nsCocoaUtils::GetStringForNSString(
+        [aNativeKeyEvent charactersIgnoringModifiers], aKeyEvent.mKeyValue);
+      // But don't expose it if it's a control character.
+      if (!aKeyEvent.mKeyValue.IsEmpty() &&
+          IsControlChar(aKeyEvent.mKeyValue[0])) {
+        aKeyEvent.mKeyValue.Truncate();
       }
     }
-    // If the printable key isn't a dead key, we should set printable key name
-    // for now.
-    if (aKeyEvent.mKeyNameIndex == KEY_NAME_INDEX_Unidentified) {
-      aKeyEvent.mKeyNameIndex = KEY_NAME_INDEX_PrintableKey;
-    }
+  } else {
+    // Compute the key for non-printable keys and some special printable keys.
+    aKeyEvent.mKeyNameIndex = ComputeGeckoKeyNameIndex(nativeKeyCode);
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK
 }
 
 void
 TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
                                          PRUnichar aInsertChar,
--- a/widget/gonk/GonkKeyMapping.h
+++ b/widget/gonk/GonkKeyMapping.h
@@ -234,28 +234,48 @@ static KeyNameIndex GetKeyNameIndex(int 
     case AKEYCODE_U:
     case AKEYCODE_V:
     case AKEYCODE_W:
     case AKEYCODE_X:
     case AKEYCODE_Y:
     case AKEYCODE_Z:
     case AKEYCODE_COMMA:
     case AKEYCODE_PERIOD:
+    case AKEYCODE_SPACE:
     case AKEYCODE_GRAVE:
     case AKEYCODE_MINUS:
     case AKEYCODE_EQUALS:
     case AKEYCODE_LEFT_BRACKET:
     case AKEYCODE_RIGHT_BRACKET:
     case AKEYCODE_BACKSLASH:
     case AKEYCODE_SEMICOLON:
     case AKEYCODE_APOSTROPHE:
     case AKEYCODE_SLASH:
     case AKEYCODE_AT:
     case AKEYCODE_PLUS:
-        return KEY_NAME_INDEX_PrintableKey;
+    case AKEYCODE_NUMPAD_0:
+    case AKEYCODE_NUMPAD_1:
+    case AKEYCODE_NUMPAD_2:
+    case AKEYCODE_NUMPAD_3:
+    case AKEYCODE_NUMPAD_4:
+    case AKEYCODE_NUMPAD_5:
+    case AKEYCODE_NUMPAD_6:
+    case AKEYCODE_NUMPAD_7:
+    case AKEYCODE_NUMPAD_8:
+    case AKEYCODE_NUMPAD_9:
+    case AKEYCODE_NUMPAD_DIVIDE:
+    case AKEYCODE_NUMPAD_MULTIPLY:
+    case AKEYCODE_NUMPAD_SUBTRACT:
+    case AKEYCODE_NUMPAD_ADD:
+    case AKEYCODE_NUMPAD_DOT:
+    case AKEYCODE_NUMPAD_COMMA:
+    case AKEYCODE_NUMPAD_EQUALS:
+    case AKEYCODE_NUMPAD_LEFT_PAREN:
+    case AKEYCODE_NUMPAD_RIGHT_PAREN:
+        return KEY_NAME_INDEX_USE_STRING;
 
     default:
         return KEY_NAME_INDEX_Unidentified;
     }
 }
 
 } // namespace widget
 } // namespace mozilla
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -215,52 +215,149 @@ sendTouchEvent(UserInputData& data, bool
     } else {
         for (i = 0; i < data.motion.touchCount; ++i)
             addDOMTouch(data, event, i);
     }
 
     return nsWindow::DispatchInputEvent(event, captured);
 }
 
-static nsEventStatus
-sendKeyEventWithMsg(uint32_t keyCode,
-                    int16_t charCode,
-                    KeyNameIndex keyNameIndex,
-                    uint32_t msg,
-                    uint64_t timeMs,
-                    bool isRepeat)
+class MOZ_STACK_CLASS KeyEventDispatcher
+{
+public:
+    KeyEventDispatcher(const UserInputData& aData,
+                       KeyCharacterMap* aKeyCharMap);
+    void Dispatch();
+
+private:
+    const UserInputData& mData;
+    sp<KeyCharacterMap> mKeyCharMap;
+
+    uint32_t mDOMKeyCode;
+    KeyNameIndex mDOMKeyNameIndex;
+    PRUnichar mDOMPrintableKeyValue;
+
+    bool IsKeyPress() const
+    {
+        return mData.action == AKEY_EVENT_ACTION_DOWN;
+    }
+    bool IsRepeat() const
+    {
+        return IsKeyPress() && (mData.flags & AKEY_EVENT_FLAG_LONG_PRESS);
+    }
+
+    uint32_t CharCode() const;
+    PRUnichar PrintableKeyValue() const;
+
+    void DispatchKeyDownEvent();
+    void DispatchKeyUpEvent();
+    nsEventStatus DispatchKeyEventInternal(uint32_t aEventMessage);
+};
+
+KeyEventDispatcher::KeyEventDispatcher(const UserInputData& aData,
+                                       KeyCharacterMap* aKeyCharMap) :
+    mData(aData), mKeyCharMap(aKeyCharMap)
 {
-    WidgetKeyboardEvent event(true, msg, nullptr);
-    if (msg == NS_KEY_PRESS && charCode >= ' ') {
-        event.charCode = charCode;
-    } else {
-        event.keyCode = keyCode;
+    // XXX Printable key's keyCode value should be computed with actual
+    //     input character.
+    mDOMKeyCode = (mData.key.keyCode < ArrayLength(kKeyMapping)) ?
+        kKeyMapping[mData.key.keyCode] : 0;
+    mDOMKeyNameIndex = GetKeyNameIndex(mData.key.keyCode);
+    mDOMPrintableKeyValue = PrintableKeyValue();
+}
+
+uint32_t
+KeyEventDispatcher::CharCode() const
+{
+    if (!mKeyCharMap.get()) {
+        return 0;
+    }
+    // XXX If the charCode is not a printable character, the charCode should be
+    //     computed without Ctrl/Alt/Meta modifiers.
+    char16_t ch = mKeyCharMap->getCharacter(mData.key.keyCode, mData.metaState);
+    return (ch >= ' ') ? static_cast<uint32_t>(ch) : 0;
+}
+
+PRUnichar
+KeyEventDispatcher::PrintableKeyValue() const
+{
+    if (mDOMKeyNameIndex != KEY_NAME_INDEX_USE_STRING || !mKeyCharMap.get()) {
+        return 0;
+    }
+    char16_t ch = mKeyCharMap->getCharacter(mData.key.keyCode, mData.metaState);
+    if (ch >= ' ') {
+        return static_cast<PRUnichar>(ch);
+    }
+    int32_t unmodifiedMetaState = mData.metaState &
+        ~(AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON |
+          AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON |
+          AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
+    if (unmodifiedMetaState == mData.metaState) {
+        return 0;
+    }
+    ch = mKeyCharMap->getCharacter(mData.key.keyCode, unmodifiedMetaState);
+    return (ch >= ' ') ? static_cast<PRUnichar>(ch) : 0;
+}
+
+nsEventStatus
+KeyEventDispatcher::DispatchKeyEventInternal(uint32_t aEventMessage)
+{
+    WidgetKeyboardEvent event(true, aEventMessage, nullptr);
+    if (aEventMessage == NS_KEY_PRESS) {
+        event.charCode = CharCode();
+    }
+    if (!event.charCode) {
+        event.keyCode = mDOMKeyCode;
     }
     event.isChar = !!event.charCode;
-    event.mIsRepeat = isRepeat;
-    event.mKeyNameIndex = keyNameIndex;
+    event.mIsRepeat = IsRepeat();
+    event.mKeyNameIndex = mDOMKeyNameIndex;
+    if (mDOMPrintableKeyValue) {
+        event.mKeyValue = mDOMPrintableKeyValue;
+    }
     event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
-    event.time = timeMs;
+    event.time = mData.timeMs;
     return nsWindow::DispatchInputEvent(event);
 }
 
-static void
-sendKeyEvent(uint32_t keyCode, int16_t charCode, KeyNameIndex keyNameIndex,
-             bool down, uint64_t timeMs, bool isRepeat)
+void
+KeyEventDispatcher::Dispatch()
 {
-    EventFlags extraFlags;
-    nsEventStatus status =
-        sendKeyEventWithMsg(keyCode, charCode, keyNameIndex,
-                            down ? NS_KEY_DOWN : NS_KEY_UP, timeMs, isRepeat);
-    if (down && status != nsEventStatus_eConsumeNoDefault) {
-        sendKeyEventWithMsg(keyCode, charCode, keyNameIndex, NS_KEY_PRESS,
-                            timeMs, isRepeat);
+    // XXX Even if unknown key is pressed, DOM key event should be
+    //     dispatched since Gecko for the other platforms are implemented
+    //     as so.
+    if (!mDOMKeyCode && mDOMKeyNameIndex == KEY_NAME_INDEX_Unidentified) {
+        VERBOSE_LOG("Got unknown key event code. "
+                    "type 0x%04x code 0x%04x value %d",
+                    mData.action, mData.key.keyCode, IsKeyPress());
+        return;
+    }
+
+    if (IsKeyPress()) {
+        DispatchKeyDownEvent();
+    } else {
+        DispatchKeyUpEvent();
     }
 }
 
+void
+KeyEventDispatcher::DispatchKeyDownEvent()
+{
+    nsEventStatus status = DispatchKeyEventInternal(NS_KEY_DOWN);
+    if (status != nsEventStatus_eConsumeNoDefault) {
+        DispatchKeyEventInternal(NS_KEY_PRESS);
+    }
+}
+
+void
+KeyEventDispatcher::DispatchKeyUpEvent()
+{
+    DispatchKeyEventInternal(NS_KEY_UP);
+}
+
 class SwitchEventRunnable : public nsRunnable {
 public:
     SwitchEventRunnable(hal::SwitchEvent& aEvent) : mEvent(aEvent)
     {}
 
     NS_IMETHOD Run()
     {
         hal::NotifySwitchChange(mEvent);
@@ -540,45 +637,24 @@ GeckoInputDispatcher::dispatchOnce()
         sendMouseEvent(msg,
                        data.timeMs,
                        data.motion.touches[0].coords.getX(),
                        data.motion.touches[0].coords.getY(),
                        status != nsEventStatus_eConsumeNoDefault);
         break;
     }
     case UserInputData::KEY_DATA: {
-        uint32_t DOMKeyCode =
-            (data.key.keyCode < ArrayLength(kKeyMapping)) ?
-            kKeyMapping[data.key.keyCode] : 0;
-        KeyNameIndex DOMKeyNameIndex = GetKeyNameIndex(data.key.keyCode);
-        if (!DOMKeyCode && DOMKeyNameIndex == KEY_NAME_INDEX_Unidentified) {
-            VERBOSE_LOG("Got unknown key event code. "
-                        "type 0x%04x code 0x%04x value %d",
-                        keyCode, pressed);
-            break;
-        }
-
-        bool isPress = data.action == AKEY_EVENT_ACTION_DOWN;
-        bool isRepeat = isPress && (data.flags & AKEY_EVENT_FLAG_LONG_PRESS);
-        int16_t charCode = 0;
         sp<KeyCharacterMap> kcm = mEventHub->getKeyCharacterMap(data.deviceId);
-        if (kcm.get())
-            charCode = kcm->getCharacter(data.key.keyCode, data.metaState);
-        sendKeyEvent(DOMKeyCode,
-                     charCode,
-                     DOMKeyNameIndex,
-                     isPress,
-                     data.timeMs,
-                     isRepeat);
+        KeyEventDispatcher dispatcher(data, kcm.get());
+        dispatcher.Dispatch();
         break;
     }
     }
 }
 
-
 void
 GeckoInputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs*)
 {
 }
 
 static uint64_t
 nanosecsToMillisecs(nsecs_t nsecs)
 {
--- a/widget/gtk/Makefile.in
+++ b/widget/gtk/Makefile.in
@@ -1,14 +1,13 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS          += $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
-CXXFLAGS        += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) \
-		               $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
+CXXFLAGS        += $(MOZ_CAIRO_CFLAGS) $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
 
 CFLAGS          += $(TK_CFLAGS)
 CXXFLAGS        += $(TK_CFLAGS)
 
--- a/widget/gtk/nsGtkKeyUtils.cpp
+++ b/widget/gtk/nsGtkKeyUtils.cpp
@@ -838,28 +838,39 @@ KeymapWrapper::ComputeDOMKeyNameIndex(co
 #include "NativeKeyToDOMKeyName.h"
 
 #undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
 
         default:
             break;
     }
 
-    uint32_t ch = GetCharCodeFor(aGdkKeyEvent);
-    return ch ? KEY_NAME_INDEX_PrintableKey : KEY_NAME_INDEX_Unidentified;
+    return KEY_NAME_INDEX_Unidentified;
 }
 
 /* static */ void
 KeymapWrapper::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
                             GdkEventKey* aGdkKeyEvent)
 {
     KeymapWrapper* keymapWrapper = GetInstance();
 
     aKeyEvent.mKeyNameIndex =
         keymapWrapper->ComputeDOMKeyNameIndex(aGdkKeyEvent);
+    if (aKeyEvent.mKeyNameIndex == KEY_NAME_INDEX_Unidentified) {
+        uint32_t charCode = GetCharCodeFor(aGdkKeyEvent);
+        if (!charCode) {
+            charCode = keymapWrapper->GetUnmodifiedCharCodeFor(aGdkKeyEvent);
+        }
+        if (charCode) {
+            aKeyEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
+            MOZ_ASSERT(aKeyEvent.mKeyValue.IsEmpty(),
+                       "Uninitialized mKeyValue must be empty");
+            AppendUCS4ToUTF16(charCode, aKeyEvent.mKeyValue);
+        }
+    }
     aKeyEvent.keyCode = ComputeDOMKeyCode(aGdkKeyEvent);
 
     // NOTE: The state of given key event indicates adjacent state of
     // modifier keys.  E.g., even if the event is Shift key press event,
     // the bit for Shift is still false.  By the same token, even if the
     // event is Shift key release event, the bit for Shift is still true.
     // Unfortunately, gdk_keyboard_get_modifiers() returns current modifier
     // state.  It means if there're some pending modifier key press or
@@ -1038,16 +1049,39 @@ KeymapWrapper::GetCharCodeFor(const GdkE
     }
     GdkEventKey tmpEvent = *aGdkKeyEvent;
     tmpEvent.state = aModifierState;
     tmpEvent.keyval = keyval;
     tmpEvent.group = aGroup;
     return GetCharCodeFor(&tmpEvent);
 }
 
+uint32_t
+KeymapWrapper::GetUnmodifiedCharCodeFor(const GdkEventKey* aGdkKeyEvent)
+{
+    guint state = aGdkKeyEvent->state &
+        (GetModifierMask(SHIFT) | GetModifierMask(CAPS_LOCK) |
+         GetModifierMask(NUM_LOCK) | GetModifierMask(SCROLL_LOCK) |
+         GetModifierMask(LEVEL3) | GetModifierMask(LEVEL5));
+    uint32_t charCode = GetCharCodeFor(aGdkKeyEvent, GdkModifierType(state),
+                                       aGdkKeyEvent->group);
+    if (charCode) {
+        return charCode;
+    }
+    // If no character is mapped to the key when Level3 Shift or Level5 Shift
+    // is active, let's return a character which is inputted by the key without
+    // Level3 nor Level5 Shift.
+    guint stateWithoutAltGraph =
+        state & ~(GetModifierMask(LEVEL3) | GetModifierMask(LEVEL5));
+    if (state == stateWithoutAltGraph) {
+        return 0;
+    }
+    return GetCharCodeFor(aGdkKeyEvent, GdkModifierType(stateWithoutAltGraph),
+                          aGdkKeyEvent->group);
+}
 
 gint
 KeymapWrapper::GetKeyLevel(GdkEventKey *aGdkKeyEvent)
 {
     gint level;
     if (!gdk_keymap_translate_keyboard_state(mGdkKeymap,
              aGdkKeyEvent->hardware_keycode,
              GdkModifierType(aGdkKeyEvent->state),
--- a/widget/gtk/nsGtkKeyUtils.h
+++ b/widget/gtk/nsGtkKeyUtils.h
@@ -256,16 +256,28 @@ protected:
      *                          If failed, this returns 0.
      */
     static uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent);
     uint32_t GetCharCodeFor(const GdkEventKey *aGdkKeyEvent,
                             guint aModifierState,
                             gint aGroup);
 
     /**
+     * GetUnmodifiedCharCodeFor() computes what character is inputted by the
+     * key event without Ctrl/Alt/Meta/Super/Hyper modifiers.
+     * If Level3 or Level5 Shift causes no character input, this also ignores
+     * them.
+     *
+     * @param aGdkKeyEvent      Native key event, must not be nullptr.
+     * @return                  charCode which is computed without modifiers
+     *                          which prevent text input.
+     */
+    uint32_t GetUnmodifiedCharCodeFor(const GdkEventKey* aGdkKeyEvent);
+
+    /**
      * GetKeyLevel() returns level of the aGdkKeyEvent in mGdkKeymap.
      *
      * @param aGdkKeyEvent      Native key event, must not be nullptr.
      * @return                  Using level.  Typically, this is 0 or 1.
      *                          If failed, this returns -1.
      */
     gint GetKeyLevel(GdkEventKey *aGdkKeyEvent);
 
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -292,32 +292,34 @@ template<>
 struct ParamTraits<mozilla::WidgetKeyboardEvent>
 {
   typedef mozilla::WidgetKeyboardEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetInputEvent>(aParam));
     WriteParam(aMsg, static_cast<uint32_t>(aParam.mKeyNameIndex));
+    WriteParam(aMsg, aParam.mKeyValue);
     WriteParam(aMsg, aParam.keyCode);
     WriteParam(aMsg, aParam.charCode);
     WriteParam(aMsg, aParam.isChar);
     WriteParam(aMsg, aParam.mIsRepeat);
     WriteParam(aMsg, aParam.location);
     WriteParam(aMsg, aParam.mUniqueId);
     // An OS-specific native event might be attached in |mNativeKeyEvent|,  but
     // that cannot be copied across process boundaries.
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     uint32_t keyNameIndex = 0;
     if (ReadParam(aMsg, aIter,
                   static_cast<mozilla::WidgetInputEvent*>(aResult)) &&
         ReadParam(aMsg, aIter, &keyNameIndex) &&
+        ReadParam(aMsg, aIter, &aResult->mKeyValue) &&
         ReadParam(aMsg, aIter, &aResult->keyCode) &&
         ReadParam(aMsg, aIter, &aResult->charCode) &&
         ReadParam(aMsg, aIter, &aResult->isChar) &&
         ReadParam(aMsg, aIter, &aResult->mIsRepeat) &&
         ReadParam(aMsg, aIter, &aResult->location) &&
         ReadParam(aMsg, aIter, &aResult->mUniqueId))
     {
       aResult->mKeyNameIndex = static_cast<mozilla::KeyNameIndex>(keyNameIndex);
--- a/widget/os2/Makefile.in
+++ b/widget/os2/Makefile.in
@@ -2,17 +2,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 RESFILE		= widget.res
 
 include $(topsrcdir)/config/rules.mk
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
 
 install-readme:	README.$(MOZ_APP_NAME)
 ifneq (,$(filter-out xulrunner sunbird,$(MOZ_APP_NAME)))
 	cp -f $^ $(DIST)/bin/README.txt
 endif
 
 libs::	install-readme
 	$(INSTALL) $(srcdir)/MozSounds.cmd $(DIST)/bin/
--- a/widget/qt/Makefile.in
+++ b/widget/qt/Makefile.in
@@ -1,11 +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) \
-		$(MOZ_PIXMAN_CFLAGS)
-CFLAGS		+= $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS) \
-		$(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS	+= $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
+CFLAGS		+= $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
--- a/widget/shared/NativeKeyToDOMKeyName.h
+++ b/widget/shared/NativeKeyToDOMKeyName.h
@@ -455,66 +455,16 @@ KEY_MAP_ANDROID (Esc, AKEYCODE_ESCAPE)
 
 // Exit
 KEY_MAP_ANDROID (Exit, AKEYCODE_HOME)
 
 // Zoom
 KEY_MAP_WIN     (Zoom, VK_ZOOM)
 KEY_MAP_QT      (Zoom, Qt::Key_Zoom)
 
-// Separator
-KEY_MAP_WIN     (Separator, VK_SEPARATOR)
-KEY_MAP_WIN     (Separator, VK_ABNT_C2) // This is on Brazilian keyboard.
-KEY_MAP_COCOA   (Separator, kVK_JIS_KeypadComma)
-KEY_MAP_GTK     (Separator, GDK_KP_Separator)
-KEY_MAP_ANDROID (Separator, AKEYCODE_NUMPAD_COMMA)
-
-// Spacebar
-KEY_MAP_WIN     (Spacebar, VK_SPACE)
-KEY_MAP_COCOA   (Spacebar, kVK_Space)
-KEY_MAP_GTK     (Spacebar, GDK_space)
-KEY_MAP_GTK     (Spacebar, GDK_KP_Space)
-KEY_MAP_QT      (Spacebar, Qt::Key_Space)
-KEY_MAP_ANDROID (Spacebar, AKEYCODE_SPACE)
-
-// Add
-KEY_MAP_WIN     (Add, VK_ADD)
-KEY_MAP_COCOA   (Add, kVK_ANSI_KeypadPlus)
-KEY_MAP_GTK     (Add, GDK_KP_Add)
-KEY_MAP_ANDROID (Add, AKEYCODE_NUMPAD_ADD)
-
-// Subtract
-KEY_MAP_WIN     (Subtract, VK_SUBTRACT)
-KEY_MAP_COCOA   (Subtract, kVK_ANSI_KeypadMinus)
-KEY_MAP_GTK     (Subtract, GDK_KP_Subtract)
-KEY_MAP_ANDROID (Subtract, AKEYCODE_NUMPAD_SUBTRACT)
-
-// Multiply
-KEY_MAP_WIN     (Multiply, VK_MULTIPLY)
-KEY_MAP_COCOA   (Multiply, kVK_ANSI_KeypadMultiply)
-KEY_MAP_GTK     (Multiply, GDK_KP_Multiply)
-KEY_MAP_ANDROID (Multiply, AKEYCODE_NUMPAD_MULTIPLY)
-
-// Divide
-KEY_MAP_WIN     (Divide, VK_DIVIDE)
-KEY_MAP_COCOA   (Divide, kVK_ANSI_KeypadDivide)
-KEY_MAP_GTK     (Divide, GDK_KP_Divide)
-KEY_MAP_ANDROID (Divide, AKEYCODE_NUMPAD_DIVIDE)
-
-// Equals
-KEY_MAP_COCOA   (Equals, kVK_ANSI_KeypadEquals)
-KEY_MAP_GTK     (Equals, GDK_KP_Equal)
-KEY_MAP_ANDROID (Equals, AKEYCODE_NUMPAD_EQUALS)
-
-// Decimal
-KEY_MAP_WIN     (Decimal, VK_DECIMAL)
-KEY_MAP_COCOA   (Decimal, kVK_ANSI_KeypadDecimal)
-KEY_MAP_GTK     (Decimal, GDK_KP_Decimal)
-KEY_MAP_ANDROID (Decimal, AKEYCODE_NUMPAD_DOT)
-
 // BrightnessDown
 KEY_MAP_GTK     (BrightnessDown, GDK_MonBrightnessDown)
 KEY_MAP_QT      (BrightnessDown, Qt::Key_MonBrightnessDown)
 
 // BrightnessUp
 KEY_MAP_GTK     (BrightnessUp, GDK_MonBrightnessUp)
 KEY_MAP_QT      (BrightnessUp, Qt::Key_MonBrightnessUp)
 
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -942,16 +942,19 @@ NativeKey::InitKeyEvent(WidgetKeyboardEv
       aKeyEvent.mUniqueId = sUniqueKeyEventId;
       break;
     default:
       MOZ_CRASH("Invalid event message");
   }
 
   aKeyEvent.mIsRepeat = IsRepeat();
   aKeyEvent.mKeyNameIndex = mKeyNameIndex;
+  if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
+    aKeyEvent.mKeyValue = mCommittedCharsAndModifiers.ToString();
+  }
   aKeyEvent.location = GetKeyLocation();
   aModKeyState.InitInputEvent(aKeyEvent);
 }
 
 bool
 NativeKey::DispatchKeyEvent(WidgetKeyboardEvent& aKeyEvent,
                             const MSG* aMsgSentToPlugin) const
 {
@@ -1663,16 +1666,19 @@ KeyboardLayout::InitNativeKey(NativeKey&
   int32_t virtualKeyIndex = GetKeyIndex(virtualKey);
 
   if (virtualKeyIndex < 0) {
     // Does not produce any printable characters, but still preserves the
     // dead-key state.
     return;
   }
 
+  MOZ_ASSERT(aNativeKey.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING,
+    "Printable key's key name index must be KEY_NAME_INDEX_USE_STRING");
+
   bool isKeyDown = aNativeKey.IsKeyDownMessage();
   uint8_t shiftState =
     VirtualKey::ModifiersToShiftState(aModKeyState.GetModifiers());
 
   if (mVirtualKeys[virtualKeyIndex].IsDeadKey(shiftState)) {
     if ((isKeyDown && mActiveDeadKey < 0) ||
         (!isKeyDown && mActiveDeadKey == virtualKey)) {
       //  First dead key event doesn't generate characters.
@@ -2306,16 +2312,20 @@ KeyboardLayout::ConvertNativeKeyCodeToDO
   NS_WARNING(warning.get());
 #endif
   return 0;
 }
 
 KeyNameIndex
 KeyboardLayout::ConvertNativeKeyCodeToKeyNameIndex(uint8_t aVirtualKey) const
 {
+  if (IsPrintableCharKey(aVirtualKey)) {
+    return KEY_NAME_INDEX_USE_STRING;
+  }
+
 #define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
 #define NS_JAPANESE_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
 #define NS_KOREAN_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
 #define NS_OTHER_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
 
   switch (aVirtualKey) {
 
 #undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
@@ -2323,19 +2333,16 @@ KeyboardLayout::ConvertNativeKeyCodeToKe
     case aNativeKey: return aKeyNameIndex;
 
 #include "NativeKeyToDOMKeyName.h"
 
 #undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
 #define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
 
     default:
-      if (IsPrintableCharKey(aVirtualKey)) {
-        return KEY_NAME_INDEX_PrintableKey;
-      }
       break;
   }
 
   HKL layout = GetLayout();
   WORD langID = LOWORD(static_cast<HKL>(layout));
   WORD primaryLangID = PRIMARYLANGID(langID);
 
   if (primaryLangID == LANG_JAPANESE) {
--- a/widget/windows/Makefile.in
+++ b/widget/windows/Makefile.in
@@ -2,9 +2,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/.
 
 RESFILE		= widget.res
 
 include $(topsrcdir)/config/rules.mk
 
-CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
+CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -5490,18 +5490,20 @@ nsWindow::ProcessMessage(UINT msg, WPARA
         }
       }
     }
     break;
     case WM_SETTINGCHANGE:
       if (IsWin8OrLater() && lParam &&
           !wcsicmp(L"ConvertibleSlateMode", (wchar_t*)lParam)) {
         // If we're switching into slate mode, switch to Metro for hardware
-        // that supports this feature.
-        if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0) {
+        // that supports this feature if the pref is set.
+        if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0 &&
+            Preferences::GetBool("browser.shell.desktop-auto-switch-enabled",
+                                 false)) {
           nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
           if (appStartup) {
             appStartup->Quit(nsIAppStartup::eForceQuit |
                              nsIAppStartup::eRestartTouchEnvironment);
           }
         }
       }
     break;
--- a/widget/windows/winrt/MetroWidget.cpp
+++ b/widget/windows/winrt/MetroWidget.cpp
@@ -712,18 +712,20 @@ MetroWidget::StaticWindowProcedure(HWND 
 LRESULT
 MetroWidget::WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam)
 {
   if(sDefaultBrowserMsgId == aMsg) {
     CloseGesture();
   } else if (WM_SETTINGCHANGE == aMsg) {
     if (aLParam && !wcsicmp(L"ConvertibleSlateMode", (wchar_t*)aLParam)) {
       // If we're switching away from slate mode, switch to Desktop for
-      // hardware that supports this feature.
-      if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0) {
+      // hardware that supports this feature if the pref is set.
+      if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0 &&
+          Preferences::GetBool("browser.shell.metro-auto-switch-enabled",
+                               false)) {
         nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
         if (appStartup) {
           appStartup->Quit(nsIAppStartup::eForceQuit | nsIAppStartup::eRestart);
         }
       }
     }
   }
 
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -81,25 +81,30 @@ EXPORTS.mozilla += [
     'VisualEventTracer.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla += [
         'WindowsVersion.h',
     ]
 
+# nsDebugImpl isn't unified because we disable PGO so that NS_ABORT_OOM isn't
+# optimized away oddly.
+SOURCES += [
+    'nsDebugImpl.cpp',
+]
+
 UNIFIED_SOURCES += [
     'AvailableMemoryTracker.cpp',
     'ClearOnShutdown.cpp',
     'CycleCollectedJSRuntime.cpp',
     'Debug.cpp',
     'nsConsoleMessage.cpp',
     'nsConsoleService.cpp',
     'nsCycleCollector.cpp',
-    'nsDebugImpl.cpp',
     'nsErrorService.cpp',
     'nsGZFileWriter.cpp',
     'nsInterfaceRequestorAgg.cpp',
     'nsMemoryImpl.cpp',
     'nsMemoryInfoDumper.cpp',
     'nsMemoryReporterManager.cpp',
     'nsMessageLoop.cpp',
     'nsSecurityConsoleMessage.cpp',
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2310,16 +2310,17 @@ nsCycleCollector::MarkRoots(SliceBudget 
         mBuilder->Traverse(pi);
         if (mCurrNode->AtBlockEnd()) {
             mBuilder->SetLastChild();
         }
         aBudget.step(kStep);
     }
 
     if (!mCurrNode->IsDone()) {
+        timeLog.Checkpoint("MarkRoots()");
         return;
     }
 
     if (mGraph.mRootCount > 0) {
         mBuilder->SetLastChild();
     }
 
     if (mBuilder->RanOutOfMemory()) {