Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 22 Nov 2013 15:18:19 -0500
changeset 172648 e9796b650e93ade1f298c7e10209b3e5617a0bef
parent 172606 3c4fc4279e6a32d0a7f3b6ea7b753662aa0ed127 (current diff)
parent 172647 e05ba13f8bfa362a536da3ae4f3f5558bdc19b72 (diff)
child 172649 a5d40ddc8042a849b8869d47497310d974c66af5
child 172680 577cffd4656d0119ced36300b4ad7bc005387d8b
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
CLOBBER
mobile/android/base/GeckoApp.java
toolkit/library/StaticXULComponents.ld
toolkit/library/StaticXULComponentsEnd/StaticXULComponentsEnd.cpp
toolkit/library/StaticXULComponentsEnd/moz.build
toolkit/library/StaticXULComponentsStart.cpp
new file mode 100644
--- /dev/null
+++ b/.lldbinit
@@ -0,0 +1,7 @@
+# .lldbinit file for debugging Mozilla
+
+# Mozilla's use of UNIFIED_SOURCES to include multiple source files into a
+# single compiled file breaks lldb breakpoint setting. This works around that.
+# See http://lldb.llvm.org/troubleshooting.html for more info.
+settings set target.inline-breakpoint-strategy always
+
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,10 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-More Windows WebIDL changes. 
+Bug 942184 - Landing and subsequent backout of bug 941450 increased the
+             possibility of random build bustage.
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -595,16 +595,17 @@ pref("javascript.options.mem.gc_high_fre
 pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 0);
 pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
 pref("javascript.options.mem.high_water_mark", 6);
 pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
 pref("javascript.options.mem.gc_decommit_threshold_mb", 1);
 
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
+pref("ui.useOverlayScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
 pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
 
--- a/b2g/chrome/content/content.css
+++ b/b2g/chrome/content/content.css
@@ -279,15 +279,19 @@ button:active,
 input:active,
 option:active,
 select:active,
 label:active,
 textarea:active {
   background-color: rgba(141, 184, 216, 0.5);
 }
 
+input[type=number]::-moz-number-spin-box {
+  display: none;
+}
+
 %ifdef MOZ_WIDGET_GONK
 /* This binding only provide key shortcuts that we can't use on devices */
 input,
 textarea {
 -moz-binding: none !important;
 }
 %endif
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -762,16 +762,18 @@ var gPluginHandler = {
       }
     }
 
     // If there are no instances of the plugin on the page any more, what the
     // user probably needs is for us to allow and then refresh.
     if (aNewState != "block" && !pluginFound) {
       browser.reload();
     }
+
+    this._setPluginNotificationIcon(browser);
   },
 
   _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPlugin, aShowNow) {
     let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
     let plugins = [];
 
     // if aPlugin is null, that means the user has navigated back to a page with plugins, and we need
     // to collect all the plugins
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -99,16 +99,17 @@ support-files =
   test_no_mcb_on_http_site_font2.css
 
 [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_nonplugins.js]
 [browser_CTP_resize.js]
 [browser_URLBarSetURI.js]
 [browser_aboutHealthReport.js]
 [browser_aboutHome.js]
 [browser_aboutSyncProgress.js]
 [browser_addKeywordSearch.js]
 [browser_alltabslistener.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_CTP_hideBar.js
@@ -0,0 +1,98 @@
+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;
+
+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);
+
+  prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_small.html");
+}
+
+function finishTest() {
+  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 notification bar is getting dismissed when directly activating plugins
+// via the doorhanger.
+
+function test1() {
+  let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") !== null,
+    test2,
+    "Test 1, expected a notification bar for hidden plugins");
+}
+
+function test2() {
+  let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 2, Should have a click-to-play notification");
+  let plugin = gTestBrowser.contentDocument.getElementById("test");
+  ok(plugin, "Test 2, Found plugin in page");
+  let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
+     "Test 2, Plugin should be click-to-play");
+
+  // simulate "always allow"
+  notification.reshow();
+  PopupNotifications.panel.firstChild._primaryButton.click();
+
+  let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null,
+    test3,
+    "Test 2, expected the notification bar for hidden plugins to get dismissed");
+}
+
+function test3() {
+  let plugin = gTestBrowser.contentDocument.getElementById("test");
+  ok(plugin, "Test 3, Found plugin in page");
+  let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  waitForCondition(() => objLoadingContent.activated, finishTest,
+    "Test 3, Waited too long for plugin to activate");
+}
--- a/browser/base/content/test/general/browser_pluginnotification.js
+++ b/browser/base/content/test/general/browser_pluginnotification.js
@@ -855,21 +855,21 @@ function test26() {
 
   waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") !== null,
     () => {
       // Don't use setTestPluginEnabledState here because we already saved the
       // prior value
       getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
       prepareTest(test27, gTestRoot + "plugin_small.html");
     },
-    "Test 26, expected the plugin notification icon to be highlighted");
+    "Test 26, expected to have a plugin notification bar");
 }
 
 function test27() {
   let notification = PopupNotifications.getNotification("click-to-play-plugins");
   ok(notification, "Test 27: There should be a plugin notification");
 
   let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
 
   waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null,
     finishTest,
-    "Test 27, expected the plugin notification icon to not be highlighted");
+    "Test 27, expected to not have a plugin notification bar");
 }
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -71,16 +71,25 @@ endif
 
 # Put a useful .gdbinit in the bin directory, to be picked up automatically
 # by GDB when we debug executables there.
 # NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
 GDBINIT_FILES := $(topsrcdir)/.gdbinit
 GDBINIT_DEST = $(FINAL_TARGET)
 INSTALL_TARGETS += GDBINIT
 
+# Put a useful .lldbinit in the bin directory, to be picked up automatically
+# by LLDB when we debug executables using that directory as the current working
+# directory.
+# NOTE: Keep .lldbinit in the topsrcdir for people who run LLDB from the
+# topsrcdir rather than the bin directory.
+LLDBINIT_FILES := $(topsrcdir)/.lldbinit
+LLDBINIT_DEST = $(FINAL_TARGET)
+INSTALL_TARGETS += LLDBINIT
+
 include $(topsrcdir)/config/rules.mk
 
 # we install to _leaktest/
 TARGET_DEPTH = ..
 include $(srcdir)/automation-build.mk
 
 _LEAKTEST_DIR = $(DEPTH)/_leaktest
 
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -242,23 +242,16 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD
             if $CC -B $_objdir/build/unix/gold -Wl,--version 2>&1 | grep -q "GNU gold"; then
                 LDFLAGS="$LDFLAGS -B $_objdir/build/unix/gold"
             else
                 rm -rf $_objdir/build/unix/gold
             fi
         fi
     fi
 fi
-if test "$GNU_CC"; then
-    if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
-        LD_IS_BFD=1
-    fi
-fi
-
-AC_SUBST([LD_IS_BFD])
 
 if test "$GNU_CC"; then
     if test -z "$DEVELOPER_OPTIONS"; then
         CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
         CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
     fi
     CFLAGS="$CFLAGS -fno-math-errno"
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno"
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -772,17 +772,16 @@ endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 else # !WINNT || GNU_CC
 	$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -829,17 +828,16 @@ ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -932,17 +930,16 @@ ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
 endif
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 	@$(RM) $(DTRACE_PROBE_OBJ)
 else # ! DTRACE_LIB_DEPENDENT
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 endif # DTRACE_LIB_DEPENDENT
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
 	fi
@@ -1707,12 +1704,8 @@ default all:: $(PURGECACHES_FILES)
 
 #############################################################################
 # Derived targets and dependencies
 
 include $(topsrcdir)/config/makefiles/autotargets.mk
 ifneq ($(NULL),$(AUTO_DEPS))
   default all libs tools export:: $(AUTO_DEPS)
 endif
-
-export:: $(GENERATED_FILES)
-
-GARBAGE += $(GENERATED_FILES)
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1821,16 +1821,17 @@ GK_ATOM(imageControlFrame, "ImageControl
 GK_ATOM(inlineFrame, "InlineFrame")
 GK_ATOM(leafBoxFrame, "LeafBoxFrame")
 GK_ATOM(legendFrame, "LegendFrame")
 GK_ATOM(letterFrame, "LetterFrame")
 GK_ATOM(lineFrame, "LineFrame")
 GK_ATOM(listControlFrame,"ListControlFrame")
 GK_ATOM(menuFrame,"MenuFrame")
 GK_ATOM(menuPopupFrame,"MenuPopupFrame")
+GK_ATOM(numberControlFrame, "NumberControlFrame")
 GK_ATOM(objectFrame, "ObjectFrame")
 GK_ATOM(pageFrame, "PageFrame")
 GK_ATOM(pageBreakFrame, "PageBreakFrame")
 GK_ATOM(pageContentFrame, "PageContentFrame")
 GK_ATOM(placeholderFrame, "PlaceholderFrame")
 GK_ATOM(popupSetFrame, "PopupSetFrame")
 GK_ATOM(canvasFrame, "CanvasFrame")
 GK_ATOM(rangeFrame, "RangeFrame")
--- a/content/canvas/src/WebGLContextFramebufferOperations.cpp
+++ b/content/canvas/src/WebGLContextFramebufferOperations.cpp
@@ -149,16 +149,19 @@ WebGLContext::DepthMask(WebGLboolean b)
     MakeContextCurrent();
     mDepthWriteMask = b;
     gl->fDepthMask(b);
 }
 
 void
 WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
 {
+    if (IsContextLost())
+        return;
+
     const size_t buffersLength = buffers.Length();
 
     if (buffersLength == 0) {
         return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers must not be empty)");
     }
 
     if (mBoundFramebuffer == 0)
     {
--- a/content/events/test/mochitest.ini
+++ b/content/events/test/mochitest.ini
@@ -40,16 +40,17 @@ support-files =
 [test_bug448602.html]
 [test_bug450876.html]
 [test_bug456273.html]
 [test_bug457672.html]
 [test_bug489671.html]
 [test_bug493251.html]
 [test_bug502818.html]
 [test_bug508479.html]
+[test_bug822898.html]
 [test_bug517851.html]
 [test_bug534833.html]
 [test_bug545268.html]
 [test_bug547996-1.html]
 [test_bug547996-2.xhtml]
 [test_bug556493.html]
 [test_bug574663.html]
 [test_bug591815.html]
--- a/content/events/test/test_all_synthetic_events.html
+++ b/content/events/test/test_all_synthetic_events.html
@@ -293,16 +293,20 @@ const kEventConstructors = {
                                                        },
                                              },
   OfflineAudioCompletionEvent:               { create: null, // Cannot create untrusted event from JS.
                                              },
   PageTransitionEvent:                       { create: function (aName, aProps) {
                                                          return new PageTransitionEvent(aName, aProps);
                                                        },
                                              },
+  PointerEvent:                              { create: function (aName, aProps) {
+                                                         return new PointerEvent(aName, aProps);
+                                                       },
+                                             },
   PopStateEvent:                             { create: function (aName, aProps) {
                                                          return new PopStateEvent(aName, aProps);
                                                        },
                                              },
   PopupBlockedEvent:                         { create: function (aName, aProps) {
                                                          return new PopupBlockedEvent(aName, aProps);
                                                        },
                                              },
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug822898.html
@@ -0,0 +1,359 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822898
+-->
+<head>
+  <title>Test for Bug 822898</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822898">Mozilla Bug 822898</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe id="subFrame"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.8">
+
+/** Test for Bug 822898 - Pointer* Events **/
+
+let tests = [], testTarget, parent, iframeBody, gOnPointerPropHandled;
+
+function nextTest() {
+  if (tests.length)
+    SimpleTest.executeSoon(tests.shift());
+}
+
+function random() {
+  return Math.floor(Math.random() * 100);
+}
+
+function createTestEventValue(name) {
+
+  let detail = random();
+  let screenX = random();
+  let screenY = random();
+  let clientX = random();
+  let clientY = random();
+  let ctrlKey = random() % 2 ? true : false;
+  let altKey = random() % 2 ? true : false;
+  let shiftKey = random() % 2 ? true : false;
+  let metaKey = random() % 2 ? true : false;
+  let button = random();
+  let pointerId = random();
+
+  return function() {
+    let event = new PointerEvent("pointerdown", {
+      bubbles: true, cancelable: true, view: window,
+      detail: detail, screenX: screenX, screenY: screenY, clientX: clientX, clientY: clientY,
+      ctrlKey: ctrlKey, altKey: altKey, shiftKey: shiftKey, metaKey: metaKey,
+      button: button, relatedTarget: null, pointerId: pointerId
+    });
+
+
+    function check(ev) {
+      is(ev.detail, detail, "Correct detail");
+      is(ev.screenX, screenX, "Correct screenX");
+      is(ev.screenY, screenY, "Correct screenY");
+      is(ev.clientX, clientX, "Correct clientX");
+      is(ev.clientY, clientY, "Correct clientY");
+      is(ev.ctrlKey, ctrlKey, "Correct ctrlKey");
+      is(ev.altKey, altKey, "Correct altKey");
+      is(ev.shiftKey, shiftKey, "Correct shiftKey");
+      is(ev.metaKey, metaKey, "Correct metaKey");
+      is(ev.button, button, "Correct buttonArg");
+      is(ev.pointerId, pointerId, "Correct pointerId");
+    }
+
+    for each (let target in [document, window, testTarget, parent])
+      target.addEventListener(name, check, false);
+
+    testTarget.dispatchEvent(event);
+
+    for each (let target in [document, window, testTarget, parent])
+      target.removeEventListener(name, check, false);
+
+
+    nextTest();
+  }
+}
+
+function getDefaultArgEvent(eventname) {
+  return new PointerEvent(eventname, {
+    bubbles: true, cancelable: true, view: window,
+    detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+    ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+    button: 0, relatedTarget: null, pointerId: 0
+  });
+}
+
+function testDefaultArg() {
+  let event = getDefaultArgEvent("pointerdown");
+
+  testTarget.addEventListener("pointerdown", function(ev) {
+    testTarget.removeEventListener("pointerdown", arguments.callee, false);
+    is(ev.pointerId, 0, "Correct default pointerId");
+  }, false);
+  testTarget.dispatchEvent(event);
+
+  nextTest();
+}
+
+function testStopPropagation() {
+  let event = getDefaultArgEvent("pointerdown");
+
+  let unreachableListener = function () {
+    ok(false, "Event should have been stopped");
+  }
+
+  // Capturing phase
+  let captured = false;
+  parent.addEventListener("pointerdown", function() {
+    parent.removeEventListener("pointerdown", arguments.callee, true);
+    captured = true;
+  }, true); // Capturing phase
+
+  // Bubbling phase
+  parent.addEventListener("pointerdown", unreachableListener, false);
+
+  testTarget.addEventListener("pointerdown", function(ev) {
+    testTarget.removeEventListener("pointerdown", arguments.callee, false);
+    is(captured, true, "Event should have been captured");
+    ev.stopPropagation();
+  }, false);
+
+  testTarget.dispatchEvent(event);
+
+  parent.removeEventListener("pointerdown", unreachableListener, false);
+
+  nextTest();
+}
+
+function testPreventDefault() {
+  let event = getDefaultArgEvent("pointerdown");
+
+  parent.addEventListener("pointerdown", function(ev) {
+    parent.removeEventListener("pointerdown", arguments.callee, false);
+    is(ev.defaultPrevented, true, "preventDefault can be called");
+    nextTest();
+  }, false);
+
+  testTarget.addEventListener("pointerdown", function(ev) {
+    testTarget.removeEventListener("pointerdown", arguments.callee, false);
+    ev.preventDefault();
+  }, false);
+
+  testTarget.dispatchEvent(event);
+}
+
+function testBlockPreventDefault() {
+  let event = new PointerEvent("pointerdown", {
+    bubbles: true, cancelable: false, view: window,
+    detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+    ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+    button: 0, relatedTarget: null, pointerId: 0, pointerType: "pen"
+  });
+
+  parent.addEventListener("pointerdown", function(ev) {
+    parent.removeEventListener("pointerdown", arguments.callee, false);
+    is(ev.defaultPrevented, false, "aCancelableArg works");
+    nextTest();
+  }, false);
+
+  testTarget.addEventListener("pointerdown", function(ev) {
+    testTarget.removeEventListener("pointerdown", arguments.callee, false);
+    ev.preventDefault();
+  }, false);
+
+  testTarget.dispatchEvent(event);
+}
+
+function testBlockBubbling() {
+  let unreachableListener = function () {
+    ok(false, "aCanBubble doesn't work");
+  }
+
+  let event = new PointerEvent("pointerdown", {
+    bubbles: false, cancelable: true, view: window,
+    detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+    ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+    button: 0, relatedTarget: null, pointerId: 0
+  });
+
+  parent.addEventListener("pointerdown", unreachableListener, false);
+  testTarget.dispatchEvent(event);
+  parent.removeEventListener("pointerdown", unreachableListener, false);
+
+  nextTest();
+}
+
+function testOnPointerProperty()
+{
+  iframeBody.onpointerdown = function (e) { gOnPointerPropHandled["pointerdown"] = true; }
+  iframeBody.onpointerup = function (e) { gOnPointerPropHandled["pointerup"] = true; }
+  iframeBody.onpointermove = function (e) { gOnPointerPropHandled["pointermove"] = true; }
+  iframeBody.onpointerout = function (e) { gOnPointerPropHandled["pointerout"] = true; }
+  iframeBody.onpointerover = function (e) { gOnPointerPropHandled["pointerover"] = true; }
+  iframeBody.onpointerenter = function (e) { gOnPointerPropHandled["pointerenter"] = true; }
+  iframeBody.onpointerleave = function (e) { gOnPointerPropHandled["pointerleave"] = true; }
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerdown"));
+  is(gOnPointerPropHandled['pointerdown'], true, "pointerdown property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerup"));
+  is(gOnPointerPropHandled['pointerup'], true, "pointerup property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointermove"));
+  is(gOnPointerPropHandled['pointermove'], true, "pointermove property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerout"));
+  is(gOnPointerPropHandled['pointerout'], true, "pointerout property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerover"));
+  is(gOnPointerPropHandled['pointerover'], true, "pointerover property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerenter"));
+  is(gOnPointerPropHandled['pointerenter'], true, "pointerenter property is performed");
+
+  iframeBody.dispatchEvent(getDefaultArgEvent("pointerleave"));
+  is(gOnPointerPropHandled['pointerleave'], true, "pointerleave property is performed");
+
+  nextTest();
+}
+
+function testPointerEventCTORS()
+{
+  // TODO: This should go to test_eventctors.html, when PointerEvents enabled by default
+  var receivedEvent;
+  iframeBody.addEventListener("hello", function(e) { receivedEvent = e; }, true);
+
+  var e;
+  var ex = false;
+
+  try {
+    e = new PointerEvent();
+  } catch(exp) {
+    ex = true;
+  }
+  ok(ex, "PointerEvent: First parameter is required!");
+  ex = false;
+
+  e = new PointerEvent("hello");
+  ok(e.type, "hello", "PointerEvent: Wrong event type!");
+  ok(!e.isTrusted, "PointerEvent: Event shouldn't be trusted!");
+  ok(!e.bubbles, "PointerEvent: Event shouldn't bubble!");
+  ok(!e.cancelable, "PointerEvent: Event shouldn't be cancelable!");
+  iframeBody.dispatchEvent(e);
+  is(receivedEvent, e, "PointerEvent: Wrong event!");
+
+  var PointerEventProps =
+  [ { screenX: 0 },
+    { screenY: 0 },
+    { clientX: 0 },
+    { clientY: 0 },
+    { ctrlKey: false },
+    { shiftKey: false },
+    { altKey: false },
+    { metaKey: false },
+    { button: 0 },
+    { buttons: 0 },
+    { relatedTarget: null },
+    { pointerId: 0 },
+    { pointerType: "" }
+  ];
+
+  var testPointerProps =
+  [
+    { screenX: 1 },
+    { screenY: 2 },
+    { clientX: 3 },
+    { clientY: 4 },
+    { ctrlKey: true },
+    { shiftKey: true },
+    { altKey: true },
+    { metaKey: true },
+    { button: 5 },
+    { buttons: 6 },
+    { relatedTarget: window },
+    { pointerId: 5 },
+    { pointerType: "mouse" }
+  ];
+
+  var defaultPointerEventValues = {};
+  for (var i = 0; i < PointerEventProps.length; ++i) {
+    for (prop in PointerEventProps[i]) {
+      ok(prop in e, "PointerEvent: PointerEvent doesn't have property " + prop + "!");
+      defaultPointerEventValues[prop] = PointerEventProps[i][prop];
+    }
+  }
+
+  while (testPointerProps.length) {
+    var p = testPointerProps.shift();
+    e = new PointerEvent("foo", p);
+    for (var def in defaultPointerEventValues) {
+      if (!(def in p)) {
+        is(e[def], defaultPointerEventValues[def],
+           "PointerEvent: Wrong default value for " + def + "!");
+      } else {
+        is(e[def], p[def], "PointerEvent: Wrong event init value for " + def + "!");
+      }
+    }
+  }
+  nextTest();
+}
+
+function runTests() {
+  SpecialPowers.setBoolPref("dom.w3c_pointer_events.enabled", true);      // Enable Pointer Events
+  testTarget = document.getElementById("testTarget");
+  parent = testTarget.parentNode;
+  gOnPointerPropHandled = new Array;
+  iframeBody = document.getElementById("subFrame").contentWindow.document.body;
+
+  tests.push(createTestEventValue("pointerdown"));
+  tests.push(createTestEventValue("pointermove"));
+  tests.push(createTestEventValue("pointerup"));
+
+  tests.push(testDefaultArg);
+  tests.push(testStopPropagation);
+
+  tests.push(testPreventDefault);
+  tests.push(testBlockPreventDefault);
+
+  tests.push(testBlockBubbling);
+  tests.push(testOnPointerProperty());
+  tests.push(testPointerEventCTORS());
+
+  tests.push(function() {
+    clearPrefs();
+    SimpleTest.finish();
+  });
+
+  nextTest();
+}
+
+function initPrefs()
+{
+  SpecialPowers.setBoolPref("dom.w3c_pointer_events.enabled", true);      // Enable Pointer Events
+}
+
+function clearPrefs()
+{
+  SpecialPowers.clearUserPref("dom.w3c_pointer_events.enabled");      // Disable Pointer Events
+}
+
+window.onload = function () {
+  initPrefs();
+  SimpleTest.executeSoon(runTests);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+<div id="parent">
+  <span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</div>
+</body>
+</html>
--- a/content/html/content/public/nsIFormControl.h
+++ b/content/html/content/public/nsIFormControl.h
@@ -245,18 +245,16 @@ nsIFormControl::IsSingleLineTextControl(
 bool
 nsIFormControl::IsSingleLineTextControl(bool aExcludePassword, uint32_t aType)
 {
   return aType == NS_FORM_INPUT_TEXT ||
          aType == NS_FORM_INPUT_EMAIL ||
          aType == NS_FORM_INPUT_SEARCH ||
          aType == NS_FORM_INPUT_TEL ||
          aType == NS_FORM_INPUT_URL ||
-         // TODO: this is temporary until bug 635240 is fixed.
-         aType == NS_FORM_INPUT_NUMBER ||
          // TODO: those are temporary until bug 773205 is fixed.
          aType == NS_FORM_INPUT_DATE ||
          aType == NS_FORM_INPUT_TIME ||
          (!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
 }
 
 bool
 nsIFormControl::IsSubmittableControl() const
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/autofocus/input-number-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- In this case we're using reftest-wait to make sure the test doesn't         
+       get snapshotted before it's been focused. We're not testing                 
+       invalidation so we don't need to listen for MozReftestInvalidate.           
+  -->                                                                              
+  <head>
+    <meta charset="utf-8">
+  </head>
+  <body onload="document.getElementsByTagName('input')[0].focus();">
+    <input onfocus="document.documentElement.removeAttribute('class');"
+           style="-moz-appearance: none;">
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/autofocus/input-number.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- In this case we're using reftest-wait to make sure the test doesn't
+       get snapshotted before it's been focused. We're not testing
+       invalidation so we don't need to listen for MozReftestInvalidate.
+  -->
+  <head>
+    <meta charset="utf-8">
+    <script>
+
+function focusHandler() {
+  setTimeout(function() {
+    document.documentElement.removeAttribute('class');
+  }, 0);
+}
+
+    </script>
+  </head>
+  <body>
+    <input type="number" autofocus onfocus="focusHandler();"
+           style="-moz-appearance: none;">
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
+
--- a/content/html/content/reftests/autofocus/reftest.list
+++ b/content/html/content/reftests/autofocus/reftest.list
@@ -1,10 +1,11 @@
 needs-focus == input-load.html input-ref.html
 needs-focus == input-create.html input-ref.html
+fails-if(Android) needs-focus == input-number.html input-number-ref.html # bug 940764
 needs-focus == button-load.html button-ref.html
 needs-focus == button-create.html button-ref.html
 needs-focus == textarea-load.html textarea-ref.html
 needs-focus == textarea-create.html textarea-ref.html
 needs-focus == select-load.html select-ref.html
 needs-focus == select-create.html select-ref.html
 needs-focus == autofocus-after-load.html autofocus-after-load-ref.html
 needs-focus == autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -14,16 +14,17 @@
 #include "nsITextControlElement.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIRadioVisitor.h"
 #include "nsIPhonetic.h"
 
 #include "nsIControllers.h"
 #include "nsIStringBundle.h"
 #include "nsFocusManager.h"
+#include "nsNumberControlFrame.h"
 #include "nsPIDOMWindow.h"
 #include "nsContentCID.h"
 #include "nsIComponentManager.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
@@ -2138,16 +2139,24 @@ HTMLInputElement::StepDown(int32_t n, ui
 
 NS_IMETHODIMP
 HTMLInputElement::StepUp(int32_t n, uint8_t optional_argc)
 {
   return ApplyStep(optional_argc ? n : 1);
 }
 
 void
+HTMLInputElement::FlushFrames()
+{
+  if (GetCurrentDoc()) {
+    GetCurrentDoc()->FlushPendingNotifications(Flush_Frames);
+  }
+}
+
+void
 HTMLInputElement::MozGetFileNameArray(nsTArray< nsString >& aArray)
 {
   for (uint32_t i = 0; i < mFiles.Length(); i++) {
     nsString str;
     mFiles[i]->GetMozFullPathInternal(str);
     aArray.AppendElement(str);
   }
 }
@@ -2228,17 +2237,17 @@ HTMLInputElement::MozSetFileNameArray(co
 
   MozSetFileNameArray(list);
   return NS_OK;
 }
 
 bool
 HTMLInputElement::MozIsTextField(bool aExcludePassword)
 {
-  // TODO: temporary until bug 635240 and 773205 are fixed.
+  // TODO: temporary until bug 773205 is fixed.
   if (IsExperimentalMobileType(mType)) {
     return false;
   }
 
   return IsSingleLineTextControl(aExcludePassword);
 }
 
 HTMLInputElement*
@@ -2682,16 +2691,24 @@ HTMLInputElement::SetValueInternal(const
       if (IsSingleLineTextControl(false)) {
         mInputData.mState->SetValue(value, aUserInput, aSetValueChanged);
       } else {
         mInputData.mValue = ToNewUnicode(value);
         if (aSetValueChanged) {
           SetValueChanged(true);
         }
         OnValueChanged(!mParserCreating);
+
+        if (mType == NS_FORM_INPUT_NUMBER) {
+          nsNumberControlFrame* numberControlFrame =
+            do_QueryFrame(GetPrimaryFrame());
+          if (numberControlFrame) {
+            numberControlFrame->UpdateForValueChange(value);
+          }
+        }
       }
 
       // Call parent's SetAttr for color input so its control frame is notified
       // and updated
       if (mType == NS_FORM_INPUT_COLOR) {
         return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None,
                                                  nsGkAtoms::value, aValue,
                                                  true);
@@ -2948,18 +2965,50 @@ HTMLInputElement::SetCheckedInternal(boo
   UpdateAllValidityStates(aNotify);
 
   // Notify the document that the CSS :checked pseudoclass for this element
   // has changed state.
   UpdateState(aNotify);
 }
 
 void
+HTMLInputElement::Blur(ErrorResult& aError)
+{
+  if (mType == NS_FORM_INPUT_NUMBER) {
+    // Blur our anonymous text control, if we have one. (DOM 'change' event
+    // firing and other things depend on this.)
+    nsNumberControlFrame* numberControlFrame =
+      do_QueryFrame(GetPrimaryFrame());
+    if (numberControlFrame) {
+      HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
+      if (textControl) {
+        textControl->Blur(aError);
+        return;
+      }
+    }
+  }
+  nsGenericHTMLElement::Blur(aError);
+}
+
+void
 HTMLInputElement::Focus(ErrorResult& aError)
 {
+  if (mType == NS_FORM_INPUT_NUMBER) {
+    // Focus our anonymous text control, if we have one.
+    nsNumberControlFrame* numberControlFrame =
+      do_QueryFrame(GetPrimaryFrame());
+    if (numberControlFrame) {
+      HTMLInputElement* textControl = numberControlFrame->GetAnonTextControl();
+      if (textControl) {
+        textControl->Focus(aError);
+        return;
+      }
+    }
+  }
+
   if (mType != NS_FORM_INPUT_FILE) {
     nsGenericHTMLElement::Focus(aError);
     return;
   }
 
   // For file inputs, focus the button instead.
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
@@ -3220,17 +3269,55 @@ HTMLInputElement::PreHandleEvent(nsEvent
     // Just as nsGenericHTMLFormElementWithState::PreHandleEvent calls
     // nsIFormControlFrame::SetFocus, we handle focus here.
     nsIFrame* frame = GetPrimaryFrame();
     if (frame) {
       frame->InvalidateFrameSubtree();
     }
   }
 
-  return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+  nsresult rv = nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
+
+  // We do this after calling the base class' PreHandleEvent so that
+  // nsIContent::PreHandleEvent doesn't reset any change we make to mCanHandle.
+  if (mType == NS_FORM_INPUT_NUMBER &&
+      aVisitor.mEvent->mFlags.mIsTrusted  &&
+      aVisitor.mEvent->originalTarget != this) {
+    // <input type=number> has an anonymous <input type=text> descendant. If
+    // 'input' or 'change' events are fired at that text control then we need
+    // to do some special handling here.
+    HTMLInputElement* textControl = nullptr;
+    nsNumberControlFrame* numberControlFrame =
+      do_QueryFrame(GetPrimaryFrame());
+    if (numberControlFrame) {
+      textControl = numberControlFrame->GetAnonTextControl();
+    }
+    if (textControl && aVisitor.mEvent->originalTarget == textControl) {
+      if (aVisitor.mEvent->message == NS_FORM_INPUT) {
+        // Propogate the anon text control's new value to our HTMLInputElement:
+        numberControlFrame->HandlingInputEvent(true);
+        nsAutoString value;
+        textControl->GetValue(value);
+        SetValueInternal(value, false, true);
+        numberControlFrame->HandlingInputEvent(false);
+      }
+      else if (aVisitor.mEvent->message == NS_FORM_CHANGE) {
+        // We cancel the DOM 'change' event that is fired for any change to our
+        // anonymous text control since we fire our own 'change' events and
+        // content shouldn't be seeing two 'change' events. Besides that we
+        // (as a number) control have tighter restrictions on when our internal
+        // value changes than our anon text control does, so in some cases
+        // (if our text control's value doesn't parse as a number) we don't
+        // want to fire a 'change' event at all.
+        aVisitor.mCanHandle = false;
+      }
+    }
+  }
+
+  return rv;
 }
 
 void
 HTMLInputElement::StartRangeThumbDrag(WidgetGUIEvent* aEvent)
 {
   mIsDraggingRange = true;
   mRangeThumbDragStartValue = GetValueAsDecimal();
   nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED |
@@ -3416,17 +3503,18 @@ HTMLInputElement::PostHandleEvent(nsEven
   // Ideally we would make the default action for click and space just dispatch
   // DOMActivate, and the default action for DOMActivate flip the checkbox/
   // radio state and fire onchange.  However, for backwards compatibility, we
   // need to flip the state before firing click, and we need to fire click
   // when space is pressed.  So, we just nest the firing of DOMActivate inside
   // the click event handling, and allow cancellation of DOMActivate to cancel
   // the click.
   if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
-      !IsSingleLineTextControl(true)) {
+      !IsSingleLineTextControl(true) &&
+      mType != NS_FORM_INPUT_NUMBER) {
     WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
     if (mouseEvent && mouseEvent->IsLeftClickEvent() &&
         !ShouldPreventDOMActivateDispatch(aVisitor.mEvent->originalTarget)) {
       InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
                                NS_UI_ACTIVATE, 1);
 
       nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
       if (shell) {
@@ -5511,17 +5599,18 @@ HTMLInputElement::IsHTMLFocusable(bool a
   }
 
   if (IsDisabled()) {
     *aIsFocusable = false;
     return true;
   }
 
   if (IsSingleLineTextControl(false) ||
-      mType == NS_FORM_INPUT_RANGE) {
+      mType == NS_FORM_INPUT_RANGE ||
+      mType == NS_FORM_INPUT_NUMBER) {
     *aIsFocusable = true;
     return false;
   }
 
 #ifdef XP_MACOSX
   const bool defaultFocusable = !aWithMouse || nsFocusManager::sMouseFocusesFormControl;
 #else
   const bool defaultFocusable = true;
@@ -5722,17 +5811,17 @@ HTMLInputElement::PlaceholderApplies() c
   }
 
   return IsSingleLineTextControl(false);
 }
 
 bool
 HTMLInputElement::DoesPatternApply() const
 {
-  // TODO: temporary until bug 635240 and bug 773205 are fixed.
+  // TODO: temporary until bug 773205 is fixed.
   if (IsExperimentalMobileType(mType)) {
     return false;
   }
 
   return IsSingleLineTextControl(false);
 }
 
 bool
--- a/content/html/content/src/HTMLInputElement.h
+++ b/content/html/content/src/HTMLInputElement.h
@@ -103,16 +103,17 @@ public:
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLInputElement, input)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
   using nsGenericHTMLElement::Focus;
+  virtual void Blur(ErrorResult& aError) MOZ_OVERRIDE;
   virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIDOMHTMLInputElement
   NS_DECL_NSIDOMHTMLINPUTELEMENT
 
   // nsIPhonetic
   NS_DECL_NSIPHONETIC
 
@@ -569,16 +570,23 @@ public:
   {
     SetHTMLAttr(nsGkAtoms::step, aValue, aRv);
   }
 
   // XPCOM GetType() is OK
   void SetType(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
+    if (aValue.Equals(NS_LITERAL_STRING("number"))) {
+      // For NS_FORM_INPUT_NUMBER we rely on having frames to process key
+      // events. Make sure we have them in case someone changes the type of
+      // this element to "number" and then expects to be able to send key
+      // events to it (type changes are rare, so not a big perf issue):
+      FlushFrames();
+    }
   }
 
   // XPCOM GetDefaultValue() is OK
   void SetDefaultValue(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::value, aValue, aRv);
   }
 
@@ -1083,21 +1091,25 @@ protected:
    */
   nsresult ApplyStep(int32_t aStep);
 
   /**
    * Returns if the current type is an experimental mobile type.
    */
   static bool IsExperimentalMobileType(uint8_t aType)
   {
-    return aType == NS_FORM_INPUT_NUMBER || aType == NS_FORM_INPUT_DATE ||
-           aType == NS_FORM_INPUT_TIME;
+    return aType == NS_FORM_INPUT_DATE || aType == NS_FORM_INPUT_TIME;
   }
 
   /**
+   * Flushes the layout frame tree to make sure we have up-to-date frames.
+   */
+  void FlushFrames();
+
+  /**
    * Returns true if the element should prevent dispatching another DOMActivate.
    * This is used in situations where the anonymous subtree should already have
    * sent a DOMActivate and prevents firing more than once.
    */
   bool ShouldPreventDOMActivateDispatch(EventTarget* aOriginalTarget);
 
   /**
    * Some input type (color and file) let user choose a value using a picker:
@@ -1238,17 +1250,18 @@ private:
   bool SupportsSetRangeText() const {
     return mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_SEARCH ||
            mType == NS_FORM_INPUT_URL || mType == NS_FORM_INPUT_TEL ||
            mType == NS_FORM_INPUT_PASSWORD;
   }
 
   static bool MayFireChangeOnBlur(uint8_t aType) {
     return IsSingleLineTextControl(false, aType) ||
-           aType == NS_FORM_INPUT_RANGE;
+           aType == NS_FORM_INPUT_RANGE ||
+           aType == NS_FORM_INPUT_NUMBER;
   }
 
   struct nsFilePickerFilter {
     nsFilePickerFilter()
       : mFilterMask(0), mIsTrusted(false) {}
 
     nsFilePickerFilter(int32_t aFilterMask)
       : mFilterMask(aFilterMask), mIsTrusted(true) {}
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -153,17 +153,17 @@ public:
   {
     return GetIntAttr(nsGkAtoms::tabindex, TabIndexDefault());
   }
   void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError)
   {
     SetHTMLIntAttr(nsGkAtoms::tabindex, aTabIndex, aError);
   }
   virtual void Focus(mozilla::ErrorResult& aError);
-  void Blur(mozilla::ErrorResult& aError);
+  virtual void Blur(mozilla::ErrorResult& aError);
   void GetAccessKey(nsString& aAccessKey)
   {
     GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
   }
   void SetAccessKey(const nsAString& aAccessKey, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::accesskey, aAccessKey, aError);
   }
--- a/content/html/content/test/forms/test_change_event.html
+++ b/content/html/content/test/forms/test_change_event.html
@@ -24,32 +24,34 @@ https://bugzilla.mozilla.org/show_bug.cg
  
 <!-- "Non-text" inputs-->
 <input type="button" id="input_button" onchange="++NonTextInputChange[0];"></input>
 <input type="submit" id="input_submit" onchange="++NonTextInputChange[1];"></input>
 <input type="image" id="input_image" onchange="++NonTextInputChange[2];"></input>
 <input type="reset" id="input_reset" onchange="++NonTextInputChange[3];"></input>
 <input type="radio" id="input_radio" onchange="++NonTextInputChange[4];"></input>
 <input type="checkbox" id="input_checkbox" onchange="++NonTextInputChange[5];"></input>
+<input type="number" id="input_number" onchange="++numberChange;"></input>
 <input type="range" id="input_range" onchange="++rangeChange;"></input>
  
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
   /** Test for Bug 722599 **/
   var textareaChange = 0;
   var fileInputChange = 0;
 
   var textInputTypes = ["text", "email", "search", "telephone", "url", "password"];
   var textInputChange = [0, 0, 0, 0, 0, 0];
 
   var NonTextInputTypes = ["button", "submit", "image", "reset", "radio", "checkbox"];
   var NonTextInputChange = [0, 0, 0, 0, 0, 0];
 
+  var numberChange = 0;
   var rangeChange = 0;
 
   var blurTestCalled = false; //Sentinel to prevent infinite loop.
 
   SimpleTest.waitForExplicitFinish();
   var MockFilePicker = SpecialPowers.MockFilePicker;
   MockFilePicker.init(window);
 
@@ -159,16 +161,29 @@ https://bugzilla.mozilla.org/show_bug.cg
         input.focus();
         input.click();
         is(NonTextInputChange[i], 1, NonTextInputTypes[i] + " input element should have dispatched change event.");
         input.blur();
         is(NonTextInputChange[i], 1, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element");
       }
     }
 
+    // Special case type=number
+    var number = document.getElementById("input_number");
+    number.focus();
+    synthesizeKey("a", {});
+    number.blur();
+    is(numberChange, 0, "Change event shouldn't be dispatched on number input element for key changes that don't change its value");
+    number.value = "";
+    number.focus();
+    synthesizeKey("1", {});
+    is(numberChange, 0, "Change event shouldn't be dispatched on number input element for keyboard input until it is looses focus");
+    number.blur();
+    is(numberChange, 1, "Change event should be dispatched on number input element on blur");
+
     // Special case type=range
     var range = document.getElementById("input_range");
     range.focus();
     synthesizeKey("a", {});
     range.blur();
     is(rangeChange, 0, "Change event shouldn't be dispatched on range input element for key changes that don't change its value");
     range.focus();
     synthesizeKey("VK_HOME", {});
--- a/content/mathml/content/src/moz.build
+++ b/content/mathml/content/src/moz.build
@@ -1,15 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsMathMLElement.cpp',
     'nsMathMLElementFactory.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
--- a/content/media/fmp4/moz.build
+++ b/content/media/fmp4/moz.build
@@ -3,20 +3,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/.
 
 EXPORTS += [
     'MP4Decoder.h',
     'MP4Reader.h',
     'PlatformDecoderModule.h',
-    'wmf/MFTDecoder.h',
-    'wmf/WMFAudioDecoder.h',
-    'wmf/WMFDecoderModule.h',
-    'wmf/WMFVideoDecoder.h',
 ]
 
 EXPORTS.mp4_demuxer += [
     'demuxer/aac.h',
     'demuxer/audio_decoder_config.h',
     'demuxer/avc.h',
     'demuxer/basictypes.h',
     'demuxer/bit_reader.h',
@@ -48,17 +44,27 @@ SOURCES += [
     'demuxer/es_descriptor.cc',
     'demuxer/mp4_demuxer.cc',
     'demuxer/track_run_iterator.cc',
     'demuxer/video_decoder_config.cc',
     'demuxer/video_util.cc',
     'MP4Decoder.cpp',
     'MP4Reader.cpp',
     'PlatformDecoderModule.cpp',
-    'wmf/MFTDecoder.cpp',
-    'wmf/WMFAudioDecoder.cpp',
-    'wmf/WMFDecoderModule.cpp',
-    'wmf/WMFVideoDecoder.cpp',
 ]
 
+if CONFIG['MOZ_WMF']:
+  EXPORTS += [
+      'wmf/MFTDecoder.h',
+      'wmf/WMFAudioDecoder.h',
+      'wmf/WMFDecoderModule.h',
+      'wmf/WMFVideoDecoder.h',
+  ]
+  SOURCES += [
+      'wmf/MFTDecoder.cpp',
+      'wmf/WMFAudioDecoder.cpp',
+      'wmf/WMFDecoderModule.cpp',
+      'wmf/WMFVideoDecoder.cpp',
+  ]
+
 FINAL_LIBRARY = 'gklayout'
 
 FAIL_ON_WARNINGS = True
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -1774,17 +1774,17 @@ nsXULElement::HideWindowChrome(bool aSho
 }
 
 nsIWidget*
 nsXULElement::GetWindowWidget()
 {
     nsIDocument* doc = GetCurrentDoc();
 
     // only top level chrome documents can set the titlebar color
-    if (doc->IsRootDisplayDocument()) {
+    if (doc && doc->IsRootDisplayDocument()) {
         nsCOMPtr<nsISupports> container = doc->GetContainer();
         nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
         if (baseWindow) {
             nsCOMPtr<nsIWidget> mainWidget;
             baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
             return mainWidget;
         }
     }
--- a/dom/activities/src/ActivityProxy.js
+++ b/dom/activities/src/ActivityProxy.js
@@ -72,20 +72,22 @@ ActivityProxy.prototype = {
       return;
     debug("msg=" + JSON.stringify(msg));
 
     switch(aMessage.name) {
       case "Activity:FireSuccess":
         debug("FireSuccess");
         Services.DOMRequest.fireSuccess(this.activity,
                                         ObjectWrapper.wrap(msg.result, this.window));
+        Services.obs.notifyObservers(null, "Activity:Success", null);
         break;
       case "Activity:FireError":
         debug("FireError");
         Services.DOMRequest.fireError(this.activity, msg.error);
+        Services.obs.notifyObservers(null, "Activity:Error", null);
         break;
     }
     // We can only get one FireSuccess / FireError message, so cleanup as soon as possible.
     this.cleanup();
   },
 
   cleanup: function actProxy_cleanup() {
     debug("cleanup");
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -58,18 +58,20 @@ const ContentPanning = {
         els.addSystemEventListener(global, type,
                                    this.handleEvent.bind(this),
                                    /* useCapture = */ false);
       }.bind(this));
     }
 
     addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
     addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
-    addEventListener("visibilitychange", this._recvVisibilityChange.bind(this));
+    addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
     Services.obs.addObserver(this, "BEC:ShownModalPrompt", false);
+    Services.obs.addObserver(this, "Activity:Success", false);
+    Services.obs.addObserver(this, "Activity:Error", false);
   },
 
   handleEvent: function cp_handleEvent(evt) {
     if (evt.defaultPrevented || evt.multipleActionsPrevented) {
       // clean up panning state even if touchend/mouseup has been preventDefault.
       if(evt.type === 'touchend' || evt.type === 'mouseup') {
         if (this.dragging &&
             (this.watchedEventsType === 'mouse' ||
@@ -456,18 +458,20 @@ const ContentPanning = {
   _resetActive: function cp_resetActive() {
     let elt = this.pointerDownTarget || this.target;
     let root = elt.ownerDocument || elt.document;
     this._setActive(root.documentElement);
   },
 
   _resetHover: function cp_resetHover() {
     const kStateHover = 0x00000004;
-    let element = content.document.createElement('foo');
-    this._domUtils.setContentState(element, kStateHover);
+    try {
+      let element = content.document.createElement('foo');
+      this._domUtils.setContentState(element, kStateHover);
+    } catch(e) {}
   },
 
   _setActive: function cp_setActive(elt) {
     const kStateActive = 0x00000001;
     this._domUtils.setContentState(elt, kStateActive);
   },
 
   _recvViewportChange: function(data) {
@@ -541,17 +545,17 @@ const ContentPanning = {
         rect.y = cssTapY - (rect.h / 2);
       }
 
       var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
       os.notifyObservers(docShell, 'browser-zoom-to-rect', JSON.stringify(rect));
     }
   },
 
-  _recvVisibilityChange: function(evt) {
+  _handleVisibilityChange: function(evt) {
     if (!evt.target.hidden)
       return;
 
     this._resetHover();
   },
 
   _shouldZoomToElement: function(aElement) {
     let win = aElement.ownerDocument.defaultView;
--- a/dom/encoding/Makefile.in
+++ b/dom/encoding/Makefile.in
@@ -1,11 +1,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
 
+EncodingUtils.$(OBJ_SUFFIX): labelsencodings.properties.h
+FallbackEncoding.$(OBJ_SUFFIX): localesfallbacks.properties.h
+
 PROPS2ARRAYS = $(topsrcdir)/intl/locale/src/props2arrays.py
 labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties
 	$(PYTHON) $^ $@
 localesfallbacks.properties.h: $(PROPS2ARRAYS) localesfallbacks.properties
 	$(PYTHON) $^ $@
+
+GARBAGE += \
+	labelsencodings.properties.h \
+	localesfallbacks.properties.h \
+	$(NULL)
--- a/dom/encoding/moz.build
+++ b/dom/encoding/moz.build
@@ -25,12 +25,8 @@ UNIFIED_SOURCES += [
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '/intl/locale/src',
 ]
 
-GENERATED_FILES += [
-    'labelsencodings.properties.h',
-    'localesfallbacks.properties.h',
-]
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -569,42 +569,45 @@ AudioManager::SetFmRadioAudioEnabled(boo
     return NS_OK;
   } else {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 }
 
 NS_IMETHODIMP
 AudioManager::SetAudioChannelVolume(int32_t aChannel, int32_t aIndex) {
-  status_t status;
+  nsresult status;
 
   switch (aChannel) {
     case AUDIO_CHANNEL_CONTENT:
-      status = SetStreamVolumeIndex(AUDIO_STREAM_MUSIC, aIndex);
-      status += SetStreamVolumeIndex(AUDIO_STREAM_SYSTEM, aIndex);
       // sync FMRadio's volume with content channel.
       if (IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
-        status += SetStreamVolumeIndex(AUDIO_STREAM_FM, aIndex);
+        status = SetStreamVolumeIndex(AUDIO_STREAM_FM, aIndex);
+        NS_ENSURE_SUCCESS(status, status);
       }
+      status = SetStreamVolumeIndex(AUDIO_STREAM_MUSIC, aIndex);
+      NS_ENSURE_SUCCESS(status, status);
+      status = SetStreamVolumeIndex(AUDIO_STREAM_SYSTEM, aIndex);
       break;
     case AUDIO_CHANNEL_NOTIFICATION:
       status = SetStreamVolumeIndex(AUDIO_STREAM_NOTIFICATION, aIndex);
-      status += SetStreamVolumeIndex(AUDIO_STREAM_RING, aIndex);
+      NS_ENSURE_SUCCESS(status, status);
+      status = SetStreamVolumeIndex(AUDIO_STREAM_RING, aIndex);
       break;
     case AUDIO_CHANNEL_ALARM:
       status = SetStreamVolumeIndex(AUDIO_STREAM_ALARM, aIndex);
       break;
     case AUDIO_CHANNEL_TELEPHONY:
       status = SetStreamVolumeIndex(AUDIO_STREAM_VOICE_CALL, aIndex);
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
-  return status ? NS_ERROR_FAILURE : NS_OK;
+  return status;
 }
 
 NS_IMETHODIMP
 AudioManager::GetAudioChannelVolume(int32_t aChannel, int32_t* aIndex) {
   if (!aIndex) {
     return NS_ERROR_NULL_POINTER;
   }
 
@@ -659,69 +662,76 @@ AudioManager::GetMaxAudioChannelVolume(i
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   *aMaxIndex = sMaxStreamVolumeTbl[stream];
    return NS_OK;
 }
 
-status_t
+nsresult
 AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
   if (aIndex < 0 || aIndex > sMaxStreamVolumeTbl[aStream]) {
-    return BAD_VALUE;
+    return NS_ERROR_INVALID_ARG;
   }
 
   mCurrentStreamVolumeTbl[aStream] = aIndex;
+  status_t status;
 #if ANDROID_VERSION < 17
-  return AudioSystem::setStreamVolumeIndex(
-           static_cast<audio_stream_type_t>(aStream),
-           aIndex);
+   status = AudioSystem::setStreamVolumeIndex(
+              static_cast<audio_stream_type_t>(aStream),
+              aIndex);
+   return status ? NS_ERROR_FAILURE : NS_OK;
 #else
   int device = 0;
 
   if (aStream == AUDIO_STREAM_BLUETOOTH_SCO) {
     device = AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
   } else if (aStream == AUDIO_STREAM_FM) {
     device = AUDIO_DEVICE_OUT_FM;
   }
 
   if (device != 0) {
-    return AudioSystem::setStreamVolumeIndex(
+    status = AudioSystem::setStreamVolumeIndex(
+               static_cast<audio_stream_type_t>(aStream),
+               aIndex,
+               device);
+    return status ? NS_ERROR_FAILURE : NS_OK;
+  }
+
+  status = AudioSystem::setStreamVolumeIndex(
              static_cast<audio_stream_type_t>(aStream),
              aIndex,
-             device);
-  }
-
-  status_t status = AudioSystem::setStreamVolumeIndex(
-                      static_cast<audio_stream_type_t>(aStream),
-                      aIndex,
-                      AUDIO_DEVICE_OUT_SPEAKER);
+             AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
+  status += AudioSystem::setStreamVolumeIndex(
+              static_cast<audio_stream_type_t>(aStream),
+              aIndex,
+              AUDIO_DEVICE_OUT_SPEAKER);
   status += AudioSystem::setStreamVolumeIndex(
               static_cast<audio_stream_type_t>(aStream),
               aIndex,
               AUDIO_DEVICE_OUT_WIRED_HEADSET);
   status += AudioSystem::setStreamVolumeIndex(
               static_cast<audio_stream_type_t>(aStream),
               aIndex,
               AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
   status += AudioSystem::setStreamVolumeIndex(
               static_cast<audio_stream_type_t>(aStream),
               aIndex,
               AUDIO_DEVICE_OUT_EARPIECE);
-  return status;
+  return status ? NS_ERROR_FAILURE : NS_OK;
 #endif
 }
 
-status_t
+nsresult
 AudioManager::GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex) {
   if (!aIndex) {
-    return BAD_VALUE;
+    return NS_ERROR_INVALID_ARG;
   }
 
   if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
-    return BAD_VALUE;
+    return NS_ERROR_INVALID_ARG;
   }
 
   *aIndex = mCurrentStreamVolumeTbl[aStream];
 
-  return NO_ERROR;
+  return NS_OK;
 }
--- a/dom/system/gonk/AudioManager.h
+++ b/dom/system/gonk/AudioManager.h
@@ -55,18 +55,18 @@ public:
   // settings then set back into audio backend.
   friend class RecoverTask;
   friend class AudioChannelVolInitCallback;
 
 protected:
   int32_t mPhoneState;
   int mCurrentStreamVolumeTbl[AUDIO_STREAM_CNT];
 
-  android::status_t SetStreamVolumeIndex(int32_t aStream, int32_t aIndex);
-  android::status_t GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex);
+  nsresult SetStreamVolumeIndex(int32_t aStream, int32_t aIndex);
+  nsresult GetStreamVolumeIndex(int32_t aStream, int32_t *aIndex);
 
 private:
   nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
   nsCOMPtr<AudioChannelAgent>             mPhoneAudioAgent;
 
   void HandleBluetoothStatusChanged(nsISupports* aSubject,
                                     const char* aTopic,
                                     const nsCString aAddress);
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -400,16 +400,17 @@ var interfaceNamesInGlobalScope =
     "PannerNode",
     "Performance",
     "PerformanceNavigation",
     "PerformanceTiming",
     "PeriodicWave",
     "PhoneNumberService",
     "Plugin",
     "PluginArray",
+    {name: "PointerEvent", pref: "dom.w3c_pointer_events.enabled"},
     "PopStateEvent",
     "PopupBlockedEvent",
     "ProcessingInstruction",
     "ProgressEvent",
     {name: "Promise", b2g: false, release: false},
     "PropertyNodeList",
     "Range",
     "RecordErrorEvent",
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -74,8 +74,10 @@ endif
 
 ifdef SOLARIS_SUNPRO_CXX
 gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
 endif
 endif
 
 PremultiplyTables.h: $(srcdir)/genTables.py
 	$(PYTHON) $(srcdir)/genTables.py
+
+gfxUtils.$(OBJ_SUFFIX): PremultiplyTables.h
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -274,12 +274,8 @@ FAIL_ON_WARNINGS = not CONFIG['_MSC_VER'
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'thebes'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
-
-GENERATED_FILES = [
-    'PremultiplyTables.h',
-]
--- a/intl/locale/src/Makefile.in
+++ b/intl/locale/src/Makefile.in
@@ -14,13 +14,19 @@ EXPORT_RESOURCE = \
 
 
 LOCAL_INCLUDES = \
 	-I$(topsrcdir)/intl/uconv/src \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
+nsCharsetAlias.$(OBJ_SUFFIX): charsetalias.properties.h
+
 charsetalias.properties.h: props2arrays.py charsetalias.properties
 	$(PYTHON) $^ $@
 
+GARBAGE += \
+	charsetalias.properties.h \
+	$(NULL)
+
 libs::
 	$(INSTALL) $(EXPORT_RESOURCE) $(DIST)/bin/res
--- a/intl/locale/src/moz.build
+++ b/intl/locale/src/moz.build
@@ -29,12 +29,8 @@ SOURCES += [
 
 EXTRA_JS_MODULES += [
     'PluralForm.jsm',
 ]
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'i18n'
-
-GENERATED_FILES = [
-    'charsetalias.properties.h',
-]
--- a/intl/locale/src/os2/Makefile.in
+++ b/intl/locale/src/os2/Makefile.in
@@ -2,10 +2,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
 
 INCLUDES	+= -I$(srcdir)/..
 
+nsOS2Charset.$(OBJ_SUFFIX): os2charset.properties.h
+
 os2charset.properties.h: $(srcdir)/../props2arrays.py os2charset.properties
 	$(PYTHON) $^ $@
+
+GARBAGE += \
+	os2charset.properties.h \
+	$(NULL)
--- a/intl/locale/src/os2/moz.build
+++ b/intl/locale/src/os2/moz.build
@@ -7,12 +7,8 @@
 SOURCES += [
     'nsCollationOS2.cpp',
     'nsDateTimeFormatOS2.cpp',
     'nsOS2Charset.cpp',
     'nsOS2Locale.cpp',
 ]
 
 FINAL_LIBRARY = 'i18n'
-
-GENERATED_FILES = [
-    'os2charset.properties.h',
-]
--- a/intl/locale/src/unix/Makefile.in
+++ b/intl/locale/src/unix/Makefile.in
@@ -11,10 +11,16 @@ INCLUDES	+= -I$(srcdir)/..
 # Define _XOPEN_SOURCE so CODESET will get defined and thus allow
 # nl_langinfo(CODESET) to compile on these systems.
 ifeq ($(OS_ARCH), Linux)
 DEFINES		+= -D_XOPEN_SOURCE=500
 endif
 
 DEFINES += -DOSTYPE=\"$(OS_CONFIG)\"
 
+nsUNIXCharset.$(OBJ_SUFFIX): unixcharset.properties.h
+
 unixcharset.properties.h: $(srcdir)/../props2arrays.py unixcharset.properties
 	$(PYTHON) $^ $@
+
+GARBAGE += \
+	unixcharset.properties.h \
+	$(NULL)
--- a/intl/locale/src/unix/moz.build
+++ b/intl/locale/src/unix/moz.build
@@ -15,12 +15,8 @@ if CONFIG['OS_TARGET'] == 'Android':
         'nsAndroidCharset.cpp',
     ]
 else:
     SOURCES += [
         'nsUNIXCharset.cpp',
     ]
 
 FINAL_LIBRARY = 'i18n'
-
-GENERATED_FILES = [
-    'unixcharset.properties.h',
-]
--- a/intl/locale/src/windows/Makefile.in
+++ b/intl/locale/src/windows/Makefile.in
@@ -2,10 +2,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
 
 INCLUDES	+= -I$(srcdir)/..
 
+nsWinCharset.$(OBJ_SUFFIX): wincharset.properties.h
+
 wincharset.properties.h: $(srcdir)/../props2arrays.py wincharset.properties
 	$(PYTHON) $^ $@
+
+GARBAGE += \
+	wincharset.properties.h \
+	$(NULL)
--- a/intl/locale/src/windows/moz.build
+++ b/intl/locale/src/windows/moz.build
@@ -7,12 +7,8 @@
 SOURCES += [
     'nsCollationWin.cpp',
     'nsDateTimeFormatWin.cpp',
     'nsWin32Locale.cpp',
     'nsWinCharset.cpp',
 ]
 
 FINAL_LIBRARY = 'i18n'
-
-GENERATED_FILES = [
-    'wincharset.properties.h',
-]
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -601,16 +601,18 @@ endif
 
 # Force auto-header generation before compiling any source that may use them
 $(OBJS): $(CURDIR)/jsautokw.h $(CURDIR)/jsautooplen.h
 
 ifdef MOZ_ETW
 ETWProvider.h ETWProvider.rc ETWProvider.mof: ETWProvider.man
 	$(MC) -um -mof $^
 
+Probes.$(OBJ_SUFFIX): ETWProvider.h
+
 ETWProvider.res: ETWProvider.rc
 	$(RC) -r -i "$(SDKDIR)Include" $^
 
 export:: ETWProvider.res
 
 install:: ETWProvider.mof ETWProvider.man
 	$(SYSINSTALL) $^ $(DESTDIR)$(bindir)
 
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -242,23 +242,16 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD
             if $CC -B $_objdir/build/unix/gold -Wl,--version 2>&1 | grep -q "GNU gold"; then
                 LDFLAGS="$LDFLAGS -B $_objdir/build/unix/gold"
             else
                 rm -rf $_objdir/build/unix/gold
             fi
         fi
     fi
 fi
-if test "$GNU_CC"; then
-    if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
-        LD_IS_BFD=1
-    fi
-fi
-
-AC_SUBST([LD_IS_BFD])
 
 if test "$GNU_CC"; then
     if test -z "$DEVELOPER_OPTIONS"; then
         CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
         CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
     fi
     CFLAGS="$CFLAGS -fno-math-errno"
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno"
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -772,17 +772,16 @@ endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 else # !WINNT || GNU_CC
 	$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -829,17 +828,16 @@ ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -932,17 +930,16 @@ ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
 endif
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 	@$(RM) $(DTRACE_PROBE_OBJ)
 else # ! DTRACE_LIB_DEPENDENT
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 endif # DTRACE_LIB_DEPENDENT
 	@$(call CHECK_STDCXX,$@)
-	@$(call LOCAL_CHECKS,$@)
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
 	fi
@@ -1707,12 +1704,8 @@ default all:: $(PURGECACHES_FILES)
 
 #############################################################################
 # Derived targets and dependencies
 
 include $(topsrcdir)/config/makefiles/autotargets.mk
 ifneq ($(NULL),$(AUTO_DEPS))
   default all libs tools export:: $(AUTO_DEPS)
 endif
-
-export:: $(GENERATED_FILES)
-
-GARBAGE += $(GENERATED_FILES)
--- a/js/src/editline/moz.build
+++ b/js/src/editline/moz.build
@@ -1,14 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 LIBRARY_NAME = 'editline'
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'editline.c',
     'sysunix.c',
 ]
 
 FORCE_STATIC_LIB = True
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -429,57 +429,56 @@ class RelocatablePtr : public BarrieredP
     }
     RelocatablePtr(const RelocatablePtr<T> &v) : BarrieredPtr<T>(v) {
         if (this->value)
             post();
     }
 
     ~RelocatablePtr() {
         if (this->value)
-            relocate(this->value->runtimeFromAnyThread());
+            relocate();
     }
 
     RelocatablePtr<T> &operator=(T *v) {
         this->pre();
         JS_ASSERT(!IsPoisonedPtr<T>(v));
         if (v) {
             this->value = v;
             post();
         } else if (this->value) {
-            JSRuntime *rt = this->value->runtimeFromAnyThread();
+            relocate();
             this->value = v;
-            relocate(rt);
         }
         return *this;
     }
 
     RelocatablePtr<T> &operator=(const RelocatablePtr<T> &v) {
         this->pre();
         JS_ASSERT(!IsPoisonedPtr<T>(v.value));
         if (v.value) {
             this->value = v.value;
             post();
         } else if (this->value) {
-            JSRuntime *rt = this->value->runtimeFromAnyThread();
+            relocate();
             this->value = v;
-            relocate(rt);
         }
         return *this;
     }
 
   protected:
     void post() {
 #ifdef JSGC_GENERATIONAL
         JS_ASSERT(this->value);
         T::writeBarrierPostRelocate(this->value, &this->value);
 #endif
     }
 
-    void relocate(JSRuntime *rt) {
+    void relocate() {
 #ifdef JSGC_GENERATIONAL
+        JS_ASSERT(this->value);
         T::writeBarrierPostRemove(this->value, &this->value);
 #endif
     }
 };
 
 /*
  * This is a hack for RegExpStatics::updateFromMatch. It allows us to do two
  * barriers with only one branch to check if we're in an incremental GC.
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -48,27 +48,27 @@ gc::MapAlignedPages(JSRuntime *rt, size_
      * Windows requires that there be a 1:1 mapping between VM allocation
      * and deallocation operations.  Therefore, take care here to acquire the
      * final result via one mapping operation.  This means unmapping any
      * preliminary result that is not correctly aligned.
      */
     void *p = nullptr;
     while (!p) {
         /*
-         * Over-allocate in order to map a memory region that is
-         * definitely large enough then deallocate and allocate again the
-         * correct sizee, within the over-sized mapping.
+         * Over-allocate in order to map a memory region that is definitely
+         * large enough, then deallocate and allocate again the correct size,
+         * within the over-sized mapping.
          *
          * Since we're going to unmap the whole thing anyway, the first
          * mapping doesn't have to commit pages.
          */
         p = VirtualAlloc(nullptr, size * 2, MEM_RESERVE, PAGE_READWRITE);
         if (!p)
             return nullptr;
-        void *chunkStart = (void *)(uintptr_t(p) + (alignment - (uintptr_t(p) % alignment)));
+        void *chunkStart = (void *)AlignBytes(uintptr_t(p), alignment);
         UnmapPages(rt, p, size * 2);
         p = VirtualAlloc(chunkStart, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 
         /* Failure here indicates a race with another thread, so try again. */
     }
 
     JS_ASSERT(uintptr_t(p) % alignment == 0);
     return p;
@@ -324,17 +324,17 @@ MapMemory(size_t length, int prot, int f
      * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual
      * address space.
      *
      * See Bug 589735 for more information.
      */
     void *region = mmap((void*)0x0000070000000000, length, prot, flags, fd, offset);
     if (region == MAP_FAILED)
         return MAP_FAILED;
-    /* 
+    /*
      * If the allocated memory doesn't have its upper 17 bits clear, consider it
      * as out of memory.
      */
     if ((uintptr_t(region) + (length - 1)) & 0xffff800000000000) {
         JS_ALWAYS_TRUE(0 == munmap(region, length));
         return MAP_FAILED;
     }
     return region;
@@ -367,17 +367,17 @@ gc::MapAlignedPages(JSRuntime *rt, size_
     void *region = MapMemory(reqSize, prot, flags, -1, 0);
     if (region == MAP_FAILED)
         return nullptr;
 
     uintptr_t regionEnd = uintptr_t(region) + reqSize;
     uintptr_t offset = uintptr_t(region) % alignment;
     JS_ASSERT(offset < reqSize - size);
 
-    void *front = (void *)(uintptr_t(region) + (alignment - offset));
+    void *front = (void *)AlignBytes(uintptr_t(region), alignment);
     void *end = (void *)(uintptr_t(front) + size);
     if (front != region)
         JS_ALWAYS_TRUE(0 == munmap(region, alignment - offset));
     if (uintptr_t(end) != regionEnd)
         JS_ALWAYS_TRUE(0 == munmap(end, regionEnd - uintptr_t(end)));
 
     JS_ASSERT(uintptr_t(front) % alignment == 0);
     return front;
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -415,24 +415,20 @@ class StoreBuffer
     void putRelocatableCell(Cell **cellp) {
         CellPtrEdge edge(cellp);
         if (!edge.inRememberedSet(nursery_))
             return;
         bufferRelocCell.put(edge);
     }
     void removeRelocatableValue(JS::Value *valuep) {
         ValueEdge edge(valuep);
-        if (!edge.inRememberedSet(nursery_))
-            return;
         bufferRelocVal.unput(edge);
     }
     void removeRelocatableCell(Cell **cellp) {
         CellPtrEdge edge(cellp);
-        if (!edge.inRememberedSet(nursery_))
-            return;
         bufferRelocCell.unput(edge);
     }
 
     /* Insert an entry into the generic buffer. */
     template <typename T>
     void putGeneric(const T &t) {
         bufferGeneric.put(t);
     }
--- a/js/src/gdb/moz.build
+++ b/js/src/gdb/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 PROGRAM = 'gdb-tests'
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'gdb-tests.cpp',
     'tests/test-jsid.cpp',
     'tests/test-JSObject.cpp',
     'tests/test-JSString.cpp',
     'tests/test-jsval.cpp',
     'tests/test-prettyprinters.cpp',
     'tests/test-Root.cpp',
     'tests/typedef-printers.cpp',
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug939868-2.js
@@ -0,0 +1,47 @@
+function f(x,y,z) {
+    var z;
+    if (x) {
+        if (y) {
+            z = 0xfffffff;
+        } else {
+            z = 0xfffffff;
+        }
+        assertFloat32(z, false);
+    } else {
+        z = Math.fround(z);
+        assertFloat32(z, true);
+    }
+    assertFloat32(z, false);
+    return z;
+}
+
+function g(x,y,z) {
+    var z;
+    if (x) {
+        if (y) {
+            z = 3;
+        } else {
+            z = 6;
+        }
+        assertFloat32(z, false);
+    } else {
+        z = Math.fround(z);
+        assertFloat32(z, true);
+    }
+    assertFloat32(z, true);
+    return z;
+}
+
+setJitCompilerOption("ion.usecount.trigger", 50);
+
+for (var n = 100; n--; ) {
+    assertEq(f(0,1,2), 2);
+    assertEq(f(0,0,2), 2);
+    assertEq(f(1,0,2), 0xfffffff);
+    assertEq(f(1,1,2), 0xfffffff);
+
+    assertEq(g(0,1,2), 2);
+    assertEq(g(0,0,2), 2);
+    assertEq(g(1,0,2), 6);
+    assertEq(g(1,1,2), 3);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug939868.js
@@ -0,0 +1,3 @@
+function f(x, y) { return x || Math.fround(y); }
+assertEq(f(0, 0), 0);
+assertEq(f(0xfffffff, 0), 0xfffffff);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug940846.js
@@ -0,0 +1,15 @@
+function a(f, i) {
+    results = []
+    for (var k = 0; k < 10; ++k) {
+        gc();
+        try {
+            results.push(f(i[k]));
+        } catch (e) {
+            results.push(e);
+        }
+    }
+}
+g = (function(x, y) {
+    return Math.fround((x ? Math.f : m0) ? w : Math.fround())
+})
+a(g, [Number.MAX_VALUE])
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -447,36 +447,33 @@ GuessPhiType(MPhi *phi)
                 // 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;
             }
         }
         if (type == MIRType_None) {
             type = in->type();
-            if (in->isConstant())
+            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 (IsFloatType(type) && IsFloatType(in->type())) {
-                // Specialize phis with int32 and float32 operands as float32.
-                type = MIRType_Float32;
-            } else if (convertibleToFloat32 && in->type() == MIRType_Float32) {
-                // If we only saw constants before and encounter a Float32 value, promote previous
-                // constants to Float32
+            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->isConstant();
+                convertibleToFloat32 &= in->canProduceFloat32();
             } else {
                 return MIRType_Value;
             }
         }
     }
     return type;
 }
 
@@ -505,18 +502,20 @@ TypeAnalyzer::propagateSpecialization(MP
             // We tried to specialize this phi, but were unable to guess its
             // type. Now that we know the type of one of its operands, we can
             // specialize it.
             if (!respecialize(use, phi->type()))
                 return false;
             continue;
         }
         if (use->type() != phi->type()) {
-            // Specialize phis with int32 and float operands as floats.
-            if (IsFloatType(use->type()) && IsFloatType(phi->type())) {
+            // Specialize phis with int32 that can be converted to float and float operands as floats.
+            if ((use->type() == MIRType_Int32 && use->canProduceFloat32() && phi->type() == MIRType_Float32) ||
+                (phi->type() == MIRType_Int32 && phi->canProduceFloat32() && use->type() == MIRType_Float32))
+            {
                 if (!respecialize(use, MIRType_Float32))
                     return false;
                 continue;
             }
 
             // Specialize phis with int32 and double operands as double.
             if (IsNumberType(use->type()) && IsNumberType(phi->type())) {
                 if (!respecialize(use, MIRType_Double))
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -841,19 +841,17 @@ MakeMIRTypeSet(MIRType type)
 
 void
 jit::MergeTypes(MIRType *ptype, types::TemporaryTypeSet **ptypeSet,
                 MIRType newType, types::TemporaryTypeSet *newTypeSet)
 {
     if (newTypeSet && newTypeSet->empty())
         return;
     if (newType != *ptype) {
-        if (IsFloatType(newType) && IsFloatType(*ptype)) {
-            *ptype = MIRType_Float32;
-        } else if (IsNumberType(newType) && IsNumberType(*ptype)) {
+        if (IsNumberType(newType) && IsNumberType(*ptype)) {
             *ptype = MIRType_Double;
         } else if (*ptype != MIRType_Value) {
             if (!*ptypeSet)
                 *ptypeSet = MakeMIRTypeSet(*ptype);
             *ptype = MIRType_Value;
         } else if (*ptypeSet && (*ptypeSet)->empty()) {
             *ptype = newType;
         }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -5784,17 +5784,17 @@ class MArrayPopShift
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::Element | AliasSet::ObjectFields);
     }
 };
 
 // Array.prototype.push on a dense array. Returns the new array length.
 class MArrayPush
   : public MBinaryInstruction,
-    public SingleObjectPolicy
+    public MixPolicy<SingleObjectPolicy, NoFloatPolicy<1> >
 {
     MArrayPush(MDefinition *object, MDefinition *value)
       : MBinaryInstruction(object, value)
     {
         setResultType(MIRType_Int32);
     }
 
   public:
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -29,16 +29,17 @@ UNIFIED_SOURCES += [
     'testException.cpp',
     'testExternalStrings.cpp',
     'testFindSCCs.cpp',
     'testFuncCallback.cpp',
     'testFunctionProperties.cpp',
     'testGCExactRooting.cpp',
     'testGCFinalizeCallback.cpp',
     'testGCOutOfMemory.cpp',
+    'testGCStoreBufferRemoval.cpp',
     'testHashTable.cpp',
     'testHashTableInit.cpp',
     'testIndexToString.cpp',
     'testIntern.cpp',
     'testIntString.cpp',
     'testIntTypesABI.cpp',
     'testJSEvaluateScript.cpp',
     'testLookup.cpp',
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testGCStoreBufferRemoval.cpp
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+* vim: set ts=8 sts=4 et sw=4 tw=99:
+*/
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef JSGC_GENERATIONAL
+
+#include "gc/Barrier.h"
+#include "jsapi-tests/tests.h"
+
+using namespace JS;
+using namespace js;
+
+BEGIN_TEST(testGCStoreBufferRemoval)
+{
+    // Sanity check - objects start in the nursery and then become tenured.
+    JS_GC(cx->runtime());
+    JS::RootedObject obj(cx, NurseryObject());
+    CHECK(js::gc::IsInsideNursery(rt, obj.get()));
+    JS_GC(cx->runtime());
+    CHECK(!js::gc::IsInsideNursery(rt, obj.get()));
+    JS::RootedObject tenuredObject(cx, obj);
+
+    // Test removal of store buffer entries added by RelocatablePtr<T>.
+    {
+        JSObject *badObject = reinterpret_cast<JSObject*>(1);
+        JSObject *punnedPtr = nullptr;
+        RelocatablePtrObject* relocPtr =
+            reinterpret_cast<RelocatablePtrObject*>(&punnedPtr);
+        new (relocPtr) RelocatablePtrObject;
+        *relocPtr = NurseryObject();
+        relocPtr->~RelocatablePtrObject();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+
+        new (relocPtr) RelocatablePtrObject;
+        *relocPtr = NurseryObject();
+        *relocPtr = tenuredObject;
+        relocPtr->~RelocatablePtrObject();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+
+        new (relocPtr) RelocatablePtrObject;
+        *relocPtr = NurseryObject();
+        *relocPtr = nullptr;
+        relocPtr->~RelocatablePtrObject();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+    }
+
+    // Test removal of store buffer entries added by RelocatableValue.
+    {
+        Value punnedValue;
+        RelocatableValue *relocValue = reinterpret_cast<RelocatableValue*>(&punnedValue);
+        new (relocValue) RelocatableValue;
+        *relocValue = ObjectValue(*NurseryObject());
+        relocValue->~RelocatableValue();
+        punnedValue = ObjectValueCrashOnTouch();
+        JS_GC(cx->runtime());
+
+        new (relocValue) RelocatableValue;
+        *relocValue = ObjectValue(*NurseryObject());
+        *relocValue = ObjectValue(*tenuredObject);
+        relocValue->~RelocatableValue();
+        punnedValue = ObjectValueCrashOnTouch();
+        JS_GC(cx->runtime());
+
+        new (relocValue) RelocatableValue;
+        *relocValue = ObjectValue(*NurseryObject());
+        *relocValue = NullValue();
+        relocValue->~RelocatableValue();
+        punnedValue = ObjectValueCrashOnTouch();
+        JS_GC(cx->runtime());
+    }
+
+    // Test removal of store buffer entries added by Heap<T>.
+    {
+        JSObject *badObject = reinterpret_cast<JSObject*>(1);
+        JSObject *punnedPtr = nullptr;
+        Heap<JSObject*>* heapPtr =
+            reinterpret_cast<Heap<JSObject*>*>(&punnedPtr);
+        new (heapPtr) Heap<JSObject*>;
+        *heapPtr = NurseryObject();
+        heapPtr->~Heap<JSObject*>();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+
+        new (heapPtr) Heap<JSObject*>;
+        *heapPtr = NurseryObject();
+        *heapPtr = tenuredObject;
+        heapPtr->~Heap<JSObject*>();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+
+        new (heapPtr) Heap<JSObject*>;
+        *heapPtr = NurseryObject();
+        *heapPtr = nullptr;
+        heapPtr->~Heap<JSObject*>();
+        punnedPtr = badObject;
+        JS_GC(cx->runtime());
+    }
+
+    return true;
+}
+
+JSObject *NurseryObject()
+{
+    return JS_NewObject(cx, nullptr, nullptr, nullptr);
+}
+END_TEST(testGCStoreBufferRemoval)
+
+#endif
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -386,13 +386,8 @@ HOST_SIMPLE_PROGRAMS += [
 #
 # In fact, we now build both a static and a shared library, as the
 # JS shell would like to link to the static library.
 
 if CONFIG['JS_SHARED_LIBRARY']:
     FORCE_SHARED_LIB = True
 
 FORCE_STATIC_LIB = True
-
-if CONFIG['MOZ_ETW']:
-    GENERATED_FILES = [
-        'ETWProvider.h',
-    ]
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -1,13 +1,13 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 PROGRAM = CONFIG['JS_SHELL_NAME']
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'js.cpp',
     'jsheaptools.cpp',
     'jsoptparse.cpp',
 ]
--- a/js/xpconnect/loader/moz.build
+++ b/js/xpconnect/loader/moz.build
@@ -1,16 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# These files cannot be built in unified mode because they rely on plarena.h
-# and they want to force NSPR logging.
 SOURCES += [
     'mozJSComponentLoader.cpp',
     'mozJSLoaderUtils.cpp',
     'mozJSSubScriptLoader.cpp',
 ]
 
 EXTRA_JS_MODULES += [
     'ISO8601DateUtils.jsm',
--- a/js/xpconnect/src/Makefile.in
+++ b/js/xpconnect/src/Makefile.in
@@ -58,16 +58,20 @@ include $(topsrcdir)/config/rules.mk
 DEFINES += \
   -DJS_THREADSAFE \
   $(NULL)
 
 ifdef MOZ_JSDEBUGGER
 DEFINES += -DMOZ_JSDEBUGGER
 endif
 
+nsXPConnect.$(OBJ_SUFFIX): dom_quickstubs.h
+
+XPCJSRuntime.$(OBJ_SUFFIX): dom_quickstubs.h
+
 dom_quickstubs.h: dom_quickstubs.cpp
 
 dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
                     $(srcdir)/qsgen.py \
                     $(LIBXUL_DIST)/sdk/bin/header.py \
                     $(LIBXUL_DIST)/sdk/bin/xpidl.py
 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) \
@@ -75,16 +79,18 @@ dom_quickstubs.cpp: $(srcdir)/dom_quicks
 	  $(srcdir)/qsgen.py \
 	  --idlpath=$(DEPTH)/dist/idl \
 	  --header-output dom_quickstubs.h \
 	  --stub-output dom_quickstubs.cpp \
 	  --makedepend-output $(MDDEPDIR)/dom_qsgen.pp \
 	  $(ENABLE_TRACEABLE_FLAGS) \
 	  $(srcdir)/dom_quickstubs.qsconf
 
+DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.cpp
+
 DictionaryHelpers.h: DictionaryHelpers.cpp
 
 DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
                        event_impl_gen.conf \
                        $(srcdir)/dictionary_helper_gen.py \
                        $(LIBXUL_DIST)/sdk/bin/header.py \
                        $(LIBXUL_DIST)/sdk/bin/xpidl.py
 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
@@ -93,16 +99,19 @@ DictionaryHelpers.cpp: $(srcdir)/diction
 	  $(srcdir)/dictionary_helper_gen.py \
 	  -I $(DEPTH)/dist/idl \
 	  --header-output DictionaryHelpers.h \
 	  --stub-output DictionaryHelpers.cpp \
 	  --makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \
 	  $(srcdir)/dictionary_helper_gen.conf \
 	  event_impl_gen.conf
 
+GeneratedEvents.$(OBJ_SUFFIX): GeneratedEvents.h \
+                               GeneratedEvents.cpp
+
 event_impl_gen.conf : $(srcdir)/event_impl_gen.conf.in
 	$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $^ -o event_impl_gen.conf)
 
 GeneratedEvents.h: $(srcdir)/dictionary_helper_gen.conf \
                    event_impl_gen.conf \
                    $(srcdir)/dictionary_helper_gen.py \
                    $(srcdir)/event_impl_gen.py \
                    $(LIBXUL_DIST)/sdk/bin/header.py \
@@ -140,16 +149,23 @@ GeneratedEvents-webidl: event_impl_gen.c
 	  $(PLY_INCLUDE) \
 	  -I$(LIBXUL_DIST)/sdk/bin \
 	  $(srcdir)/event_impl_gen.py \
 	  -I $(DEPTH)/dist/idl \
 	  --webidltarget=$(top_srcdir)/dom/webidl \
 	  event_impl_gen.conf
 
 GARBAGE += \
+		dom_quickstubs.h \
+		dom_quickstubs.cpp \
+		DictionaryHelpers.h \
+		DictionaryHelpers.cpp \
+		GeneratedEvents.h \
+		GeneratedEvents.cpp \
+		GeneratedEventClasses.h \
 		event_impl_gen.conf \
 		xpidl_debug \
 		$(MDDEPDIR)/dom_qsgen.pp \
 		$(MDDEPDIR)/dombindingsgen.pp \
 		$(MDDEPDIR)/dictionary_helper_gen.pp \
 		$(MDDEPDIR)/event_impl_gen.pp \
 		$(wildcard $(topsrcdir)/other-licenses/ply/ply/*.pyc) \
 		$(NULL)
--- a/js/xpconnect/src/moz.build
+++ b/js/xpconnect/src/moz.build
@@ -8,22 +8,23 @@ EXPORTS += [
     'BackstagePass.h',
     'nsCxPusher.h',
     'qsObjectHelper.h',
     'XPCJSMemoryReporter.h',
     'xpcObjectHelper.h',
     'xpcpublic.h',
 ]
 
-UNIFIED_SOURCES += [
+SOURCES += [
     'nsCxPusher.cpp',
     'nsScriptError.cpp',
     'nsXPConnect.cpp',
     'Sandbox.cpp',
     'XPCCallContext.cpp',
+    'XPCComponents.cpp',
     'XPCContext.cpp',
     'XPCConvert.cpp',
     'XPCDebug.cpp',
     'XPCException.cpp',
     'XPCJSContextStack.cpp',
     'XPCJSID.cpp',
     'XPCJSRuntime.cpp',
     'XPCJSWeakReference.cpp',
@@ -42,35 +43,23 @@ UNIFIED_SOURCES += [
     'XPCWrappedNative.cpp',
     'XPCWrappedNativeInfo.cpp',
     'XPCWrappedNativeJSOps.cpp',
     'XPCWrappedNativeProto.cpp',
     'XPCWrappedNativeScope.cpp',
     'XPCWrapper.cpp',
 ]
 
-# XPCComponents.cpp cannot be built in unified mode because it uses plarena.h.
-SOURCES += [
-    'XPCComponents.cpp',
-]
-
 GENERATED_SOURCES += [
     'DictionaryHelpers.cpp',
     'dom_quickstubs.cpp',
     'GeneratedEvents.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'xpconnect_s'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
-
-GENERATED_FILES = [
-    'DictionaryHelpers.h',
-    'dom_quickstubs.h',
-    'GeneratedEventClasses.h',
-    'GeneratedEvents.h',
-]
--- a/js/xpconnect/tests/components/native/moz.build
+++ b/js/xpconnect/tests/components/native/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 NO_DIST_INSTALL = True
 
-UNIFIED_SOURCES += [
+SOURCES += [
     'xpctest_attributes.cpp',
     'xpctest_module.cpp',
     'xpctest_params.cpp',
 ]
 
 LIBRARY_NAME = 'xpctest'
 
 IS_COMPONENT = True
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -666,17 +666,17 @@ TransplantObject(JSContext *cx, JS::Hand
         return nullptr;
     return newIdentity;
 }
 
 nsIGlobalObject *
 GetNativeForGlobal(JSObject *obj)
 {
     MOZ_ASSERT(JS_IsGlobalObject(obj));
-    if (!EnsureCompartmentPrivate(obj)->scope)
+    if (!MaybeGetObjectScope(obj))
         return nullptr;
 
     // Every global needs to hold a native as its private.
     MOZ_ASSERT(GetObjectClass(obj)->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS |
                                              JSCLASS_HAS_PRIVATE));
     nsISupports *native =
         static_cast<nsISupports *>(js::GetObjectPrivate(obj));
     MOZ_ASSERT(native);
--- a/js/xpconnect/wrappers/moz.build
+++ b/js/xpconnect/wrappers/moz.build
@@ -3,26 +3,22 @@
 # 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/.
 
 EXPORTS += [
     'WrapperFactory.h',
 ]
 
-UNIFIED_SOURCES += [
+SOURCES += [
     'AccessCheck.cpp',
     'ChromeObjectWrapper.cpp',
     'FilteringWrapper.cpp',
     'WaiveXrayWrapper.cpp',
     'WrapperFactory.cpp',
-]
-
-# XrayWrapper needs to be built separately becaue of template instantiations.
-SOURCES += [
     'XrayWrapper.cpp',
 ]
 
 # warning C4661 for FilteringWrapper
 FAIL_ON_WARNINGS = not CONFIG['_MSC_VER']
 
 MSVC_ENABLE_PGO = True
 
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1709,16 +1709,31 @@ ElementForStyleContext(nsIContent* aPare
 
     nsIFrame* grandparentFrame = aFrame->GetParent()->GetParent();
     MOZ_ASSERT(grandparentFrame->GetType() == nsGkAtoms::colorControlFrame,
                "Color swatch's grandparent should be nsColorControlFrame");
 
     return grandparentFrame->GetContent()->AsElement();
   }
 
+  if (aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberText ||
+      aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberWrapper ||
+      aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox ||
+      aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp ||
+      aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown) {
+    // Get content for nearest nsNumberControlFrame:
+    nsIFrame* f = aFrame->GetParent();
+    MOZ_ASSERT(f);
+    while (f->GetType() != nsGkAtoms::numberControlFrame) {
+      f = f->GetParent();
+      MOZ_ASSERT(f);
+    }
+    return f->GetContent()->AsElement();
+  }
+
   nsIContent* content = aParentContent ? aParentContent : aFrame->GetContent();
   return content->AsElement();
 }
 
 /**
  * FIXME: Temporary.  Should merge with following function.
  */
 static nsIFrame*
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3388,17 +3388,17 @@ nsCSSFrameConstructor::FindInputData(Ele
     SIMPLE_INT_CREATE(NS_FORM_INPUT_TEL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_RANGE, NS_NewRangeFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame),
     { NS_FORM_INPUT_COLOR,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewColorControlFrame,
                                  nsCSSAnonBoxes::buttonContent) },
     // TODO: this is temporary until a frame is written: bug 635240.
-    SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame),
+    SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewNumberControlFrame),
     // TODO: this is temporary until a frame is written: bug 773205.
     SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame),
     // TODO: this is temporary until a frame is written: bug 773205
     SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewTextControlFrame),
     { NS_FORM_INPUT_SUBMIT,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
                                  nsCSSAnonBoxes::buttonContent) },
     { NS_FORM_INPUT_RESET,
--- a/layout/forms/moz.build
+++ b/layout/forms/moz.build
@@ -24,16 +24,17 @@ UNIFIED_SOURCES += [
     'nsGfxButtonControlFrame.cpp',
     'nsGfxCheckboxControlFrame.cpp',
     'nsGfxRadioControlFrame.cpp',
     'nsHTMLButtonControlFrame.cpp',
     'nsImageControlFrame.cpp',
     'nsLegendFrame.cpp',
     'nsListControlFrame.cpp',
     'nsMeterFrame.cpp',
+    'nsNumberControlFrame.cpp',
     'nsProgressFrame.cpp',
     'nsRangeFrame.cpp',
     'nsSelectsAreaFrame.cpp',
     'nsTextControlFrame.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
new file mode 100644
--- /dev/null
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsNumberControlFrame.h"
+
+#include "HTMLInputElement.h"
+#include "nsIFocusManager.h"
+#include "nsIPresShell.h"
+#include "nsFocusManager.h"
+#include "nsFontMetrics.h"
+#include "nsFormControlFrame.h"
+#include "nsGkAtoms.h"
+#include "nsINodeInfo.h"
+#include "nsINameSpaceManager.h"
+#include "nsContentUtils.h"
+#include "nsContentCreatorFunctions.h"
+#include "nsContentList.h"
+#include "nsStyleSet.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+nsIFrame*
+NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
+{
+  return new (aPresShell) nsNumberControlFrame(aContext);
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(nsNumberControlFrame)
+
+NS_QUERYFRAME_HEAD(nsNumberControlFrame)
+  NS_QUERYFRAME_ENTRY(nsNumberControlFrame)
+  NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
+NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
+
+nsNumberControlFrame::nsNumberControlFrame(nsStyleContext* aContext)
+  : nsContainerFrame(aContext)
+  , mHandlingInputEvent(false)
+{
+}
+
+void
+nsNumberControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
+               "nsNumberControlFrame should not have continuations; if it does we "
+               "need to call RegUnregAccessKey only for the first");
+  nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
+  nsContentUtils::DestroyAnonymousContent(&mOuterWrapper);
+  nsContainerFrame::DestroyFrom(aDestructRoot);
+}
+
+NS_IMETHODIMP
+nsNumberControlFrame::Reflow(nsPresContext* aPresContext,
+                             nsHTMLReflowMetrics& aDesiredSize,
+                             const nsHTMLReflowState& aReflowState,
+                             nsReflowStatus& aStatus)
+{
+  DO_GLOBAL_REFLOW_COUNT("nsNumberControlFrame");
+  DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
+
+  NS_ASSERTION(mOuterWrapper, "Outer wrapper div must exist!");
+
+  NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
+               "nsNumberControlFrame should not have continuations; if it does we "
+               "need to call RegUnregAccessKey only for the first");
+
+  NS_ASSERTION(!mFrames.FirstChild() ||
+               !mFrames.FirstChild()->GetNextSibling(),
+               "We expect at most one direct child frame");
+
+  if (mState & NS_FRAME_FIRST_REFLOW) {
+    nsFormControlFrame::RegUnRegAccessKey(this, true);
+  }
+
+  nsHTMLReflowMetrics wrappersDesiredSize;
+  nsIFrame* outerWrapperFrame = mOuterWrapper->GetPrimaryFrame();
+  if (outerWrapperFrame) { // display:none?
+    NS_ASSERTION(outerWrapperFrame == mFrames.FirstChild(), "huh?");
+    nsresult rv =
+      ReflowAnonymousContent(aPresContext, wrappersDesiredSize,
+                             aReflowState, outerWrapperFrame);
+    NS_ENSURE_SUCCESS(rv, rv);
+    ConsiderChildOverflow(aDesiredSize.mOverflowAreas, outerWrapperFrame);
+  }
+
+  nscoord computedHeight = aReflowState.ComputedHeight();
+  if (computedHeight == NS_AUTOHEIGHT) {
+    computedHeight =
+      outerWrapperFrame ? outerWrapperFrame->GetSize().height : 0;
+  }
+  aDesiredSize.width = aReflowState.ComputedWidth() +
+                         aReflowState.mComputedBorderPadding.LeftRight();
+  aDesiredSize.height = computedHeight +
+                          aReflowState.mComputedBorderPadding.TopBottom();
+
+  if (outerWrapperFrame) {
+    aDesiredSize.ascent = wrappersDesiredSize.ascent +
+                            outerWrapperFrame->GetPosition().y;
+  }
+
+  aDesiredSize.SetOverflowAreasToDesiredBounds();
+
+  FinishAndStoreOverflow(&aDesiredSize);
+
+  aStatus = NS_FRAME_COMPLETE;
+
+  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
+
+  return NS_OK;
+}
+
+nsresult
+nsNumberControlFrame::
+  ReflowAnonymousContent(nsPresContext* aPresContext,
+                         nsHTMLReflowMetrics& aWrappersDesiredSize,
+                         const nsHTMLReflowState& aParentReflowState,
+                         nsIFrame* aOuterWrapperFrame)
+{
+  MOZ_ASSERT(aOuterWrapperFrame);
+
+  // The width of our content box, which is the available width
+  // for our anonymous content:
+  nscoord inputFrameContentBoxWidth = aParentReflowState.ComputedWidth();
+
+  nsHTMLReflowState wrapperReflowState(aPresContext, aParentReflowState,
+                                       aOuterWrapperFrame,
+                                       nsSize(inputFrameContentBoxWidth,
+                                              NS_UNCONSTRAINEDSIZE));
+
+  nscoord xoffset = aParentReflowState.mComputedBorderPadding.left +
+                      wrapperReflowState.mComputedMargin.left;
+  nscoord yoffset = aParentReflowState.mComputedBorderPadding.top +
+                      wrapperReflowState.mComputedMargin.top;
+
+  nsReflowStatus childStatus;
+  nsresult rv = ReflowChild(aOuterWrapperFrame, aPresContext,
+                            aWrappersDesiredSize, wrapperReflowState,
+                            xoffset, yoffset, 0, childStatus);
+  NS_ENSURE_SUCCESS(rv, rv);
+  MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(childStatus),
+             "We gave our child unconstrained height, so it should be complete");
+  return FinishReflowChild(aOuterWrapperFrame, aPresContext,
+                           &wrapperReflowState, aWrappersDesiredSize,
+                           xoffset, yoffset, 0);
+}
+
+NS_IMETHODIMP
+nsNumberControlFrame::AttributeChanged(int32_t  aNameSpaceID,
+                                       nsIAtom* aAttribute,
+                                       int32_t  aModType)
+{
+  if (aNameSpaceID == kNameSpaceID_None) {
+    if (aAttribute == nsGkAtoms::placeholder ||
+        aAttribute == nsGkAtoms::readonly) {
+      if (aModType == nsIDOMMutationEvent::REMOVAL) {
+        mTextField->UnsetAttr(aNameSpaceID, aAttribute, true);
+      } else {
+        MOZ_ASSERT(aModType == nsIDOMMutationEvent::ADDITION ||
+                   aModType == nsIDOMMutationEvent::MODIFICATION);
+        nsAutoString value;
+        mContent->GetAttr(aNameSpaceID, aAttribute, value);
+        mTextField->SetAttr(aNameSpaceID, aAttribute, value, true);
+      }
+    }
+  }
+
+  return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
+                                            aModType);
+}
+
+nsresult
+nsNumberControlFrame::MakeAnonymousElement(nsIContent** aResult,
+                                           nsTArray<ContentInfo>& aElements,
+                                           nsIAtom* aTagName,
+                                           nsCSSPseudoElements::Type aPseudoType,
+                                           nsStyleContext* aParentContext)
+{
+  // Get the NodeInfoManager and tag necessary to create the anonymous divs.
+  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
+
+  nsCOMPtr<nsINodeInfo> nodeInfo;
+  nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTagName, nullptr,
+                                                 kNameSpaceID_XHTML,
+                                                 nsIDOMNode::ELEMENT_NODE);
+  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  nsresult rv = NS_NewHTMLElement(aResult, nodeInfo.forget(),
+                                  dom::NOT_FROM_PARSER);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // If we legitimately fail this assertion and need to allow
+  // non-pseudo-element anonymous children, then we'll need to add a branch
+  // that calls ResolveStyleFor((*aResult)->AsElement(), aParentContext)") to
+  // set newStyleContext.
+  NS_ASSERTION(aPseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement,
+               "Expecting anonymous children to all be pseudo-elements");
+  // Associate the pseudo-element with the anonymous child
+  nsRefPtr<nsStyleContext> newStyleContext =
+    PresContext()->StyleSet()->ResolvePseudoElementStyle(mContent->AsElement(),
+                                                         aPseudoType,
+                                                         aParentContext);
+
+  if (!aElements.AppendElement(ContentInfo(*aResult, newStyleContext))) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  return NS_OK;
+}
+
+nsresult
+nsNumberControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
+{
+  nsresult rv;
+
+  // We create an anonymous tree for our input element that is structured as
+  // follows:
+  //
+  // input
+  //   div      - outer wrapper with "display:flex" by default
+  //     input  - text input field
+  //     div    - spin box wrapping up/down arrow buttons
+  //       div  - spin up (up arrow button)
+  //       div  - spin down (down arrow button)
+  //
+  // If you change this, be careful to change the destruction order in
+  // nsNumberControlFrame::DestroyFrom.
+
+
+  // Create the anonymous outer wrapper:
+  rv = MakeAnonymousElement(getter_AddRefs(mOuterWrapper),
+                            aElements,
+                            nsGkAtoms::div,
+                            nsCSSPseudoElements::ePseudo_mozNumberWrapper,
+                            mStyleContext);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  ContentInfo& outerWrapperCI = aElements.LastElement();
+
+  // Create the ::-moz-number-text pseudo-element:
+  rv = MakeAnonymousElement(getter_AddRefs(mTextField),
+                            outerWrapperCI.mChildren,
+                            nsGkAtoms::input,
+                            nsCSSPseudoElements::ePseudo_mozNumberText,
+                            outerWrapperCI.mStyleContext);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
+                      NS_LITERAL_STRING("text"), PR_FALSE);
+
+  // Initialize the text field value:
+  nsAutoString value;
+  HTMLInputElement::FromContent(mContent)->GetValue(value);
+  mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::value, value, false);
+
+  // If we're readonly, make sure our anonymous text control is too:
+  nsAutoString readonly;
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::readonly, readonly)) {
+    mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::readonly, readonly, false);
+  }
+
+  // Initialize the text field's placeholder, if ours is set:
+  nsAutoString placeholder;
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholder)) {
+    mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholder, false);
+  }
+
+  if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS)) {
+    // We don't want to focus the frame but the text field.
+    nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mTextField);
+    NS_ASSERTION(element, "Really, this should be a nsIDOMElement!");
+    fm->SetFocus(element, 0);
+  }
+
+  // Create the ::-moz-number-spin-box pseudo-element:
+  rv = MakeAnonymousElement(getter_AddRefs(mSpinBox),
+                            outerWrapperCI.mChildren,
+                            nsGkAtoms::div,
+                            nsCSSPseudoElements::ePseudo_mozNumberSpinBox,
+                            outerWrapperCI.mStyleContext);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  ContentInfo& spinBoxCI = outerWrapperCI.mChildren.LastElement();
+
+  // Create the ::-moz-number-spin-up pseudo-element:
+  rv = MakeAnonymousElement(getter_AddRefs(mSpinUp),
+                            spinBoxCI.mChildren,
+                            nsGkAtoms::div,
+                            nsCSSPseudoElements::ePseudo_mozNumberSpinUp,
+                            spinBoxCI.mStyleContext);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Create the ::-moz-number-spin-down pseudo-element:
+  rv = MakeAnonymousElement(getter_AddRefs(mSpinDown),
+                            spinBoxCI.mChildren,
+                            nsGkAtoms::div,
+                            nsCSSPseudoElements::ePseudo_mozNumberSpinDown,
+                            spinBoxCI.mStyleContext);
+  return rv;
+}
+
+nsIAtom*
+nsNumberControlFrame::GetType() const
+{
+  return nsGkAtoms::numberControlFrame;
+}
+
+HTMLInputElement*
+nsNumberControlFrame::GetAnonTextControl()
+{
+  return mTextField ? HTMLInputElement::FromContent(mTextField) : nullptr;
+}
+
+void
+nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                               uint32_t aFilter)
+{
+  // Only one direct anonymous child:
+  aElements.MaybeAppendElement(mOuterWrapper);
+}
+
+void
+nsNumberControlFrame::UpdateForValueChange(const nsAString& aValue)
+{
+  if (mHandlingInputEvent) {
+    // We have been called while our HTMLInputElement is processing a DOM
+    // 'input' event targeted at our anonymous text control. Our
+    // HTMLInputElement has taken the value of our anon text control and
+    // called SetValueInternal on itself to keep its own value in sync. As a
+    // result SetValueInternal has called us. In this one case we do not want
+    // to update our anon text control, especially since aValue will be the
+    // sanitized value, and only the internal value should be sanitized (not
+    // the value shown to the user, and certainly we shouldn't change it as
+    // they type).
+    return;
+  }
+  // We need to update the value of our anonymous text control here. Note that
+  // this must be its value, and not its 'value' attribute (the default value),
+  // since the default value is ignored once a user types into the text
+  // control.
+  HTMLInputElement::FromContent(mTextField)->SetValue(aValue);
+}
new file mode 100644
--- /dev/null
+++ b/layout/forms/nsNumberControlFrame.h
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsNumberControlFrame_h__
+#define nsNumberControlFrame_h__
+
+#include "nsContainerFrame.h"
+#include "nsIFormControlFrame.h"
+#include "nsIAnonymousContentCreator.h"
+#include "nsCOMPtr.h"
+
+class nsPresContext;
+
+namespace mozilla {
+namespace dom {
+class HTMLInputElement;
+}
+}
+
+/**
+ * This frame type is used for <input type=number>.
+ */
+class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame
+                                     , public nsIAnonymousContentCreator
+{
+  friend nsIFrame*
+  NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+
+  typedef mozilla::dom::HTMLInputElement HTMLInputElement;
+
+  nsNumberControlFrame(nsStyleContext* aContext);
+
+public:
+  NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame)
+  NS_DECL_QUERYFRAME
+  NS_DECL_FRAMEARENA_HELPERS
+
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
+
+  virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
+
+  NS_IMETHOD Reflow(nsPresContext*           aPresContext,
+                    nsHTMLReflowMetrics&     aDesiredSize,
+                    const nsHTMLReflowState& aReflowState,
+                    nsReflowStatus&          aStatus) MOZ_OVERRIDE;
+
+  NS_IMETHOD AttributeChanged(int32_t  aNameSpaceID,
+                              nsIAtom* aAttribute,
+                              int32_t  aModType) MOZ_OVERRIDE;
+
+  // nsIAnonymousContentCreator
+  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
+  virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
+                                        uint32_t aFilter) MOZ_OVERRIDE;
+
+#ifdef NS_DEBUG
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
+    return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult);
+  }
+#endif
+
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
+
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
+  {
+    return nsContainerFrame::IsFrameOfType(aFlags &
+      ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
+  }
+
+  /**
+   * When our HTMLInputElement's value changes, it calls this method to tell
+   * us to sync up our anonymous text input field child.
+   */
+  void UpdateForValueChange(const nsAString& aValue);
+
+  /**
+   * Called to notify this frame that its HTMLInputElement is currently
+   * processing a DOM 'input' event.
+   */
+  void HandlingInputEvent(bool aHandlingEvent)
+  {
+    mHandlingInputEvent = aHandlingEvent;
+  }
+
+  HTMLInputElement* GetAnonTextControl();
+
+private:
+
+  nsresult MakeAnonymousElement(nsIContent** aResult,
+                                nsTArray<ContentInfo>& aElements,
+                                nsIAtom* aTagName,
+                                nsCSSPseudoElements::Type aPseudoType,
+                                nsStyleContext* aParentContext);
+
+  nsresult ReflowAnonymousContent(nsPresContext* aPresContext,
+                                  nsHTMLReflowMetrics& aWrappersDesiredSize,
+                                  const nsHTMLReflowState& aReflowState,
+                                  nsIFrame* aOuterWrapperFrame);
+
+  /**
+   * The text field used to edit and show the number.
+   * @see nsNumberControlFrame::CreateAnonymousContent.
+   */
+  nsCOMPtr<nsIContent> mOuterWrapper;
+  nsCOMPtr<nsIContent> mTextField;
+  nsCOMPtr<nsIContent> mSpinBox;
+  nsCOMPtr<nsIContent> mSpinUp;
+  nsCOMPtr<nsIContent> mSpinDown;
+  bool mHandlingInputEvent;
+};
+
+#endif // nsNumberControlFrame_h__
--- a/layout/generic/nsFrameIdList.h
+++ b/layout/generic/nsFrameIdList.h
@@ -97,16 +97,17 @@ FRAME_ID(nsMathMLmtrFrame)
 FRAME_ID(nsMathMLmunderFrame)
 FRAME_ID(nsMathMLmunderoverFrame)
 FRAME_ID(nsMathMLsemanticsFrame)
 FRAME_ID(nsMathMLTokenFrame)
 FRAME_ID(nsMenuBarFrame)
 FRAME_ID(nsMenuFrame)
 FRAME_ID(nsMenuPopupFrame)
 FRAME_ID(nsMeterFrame)
+FRAME_ID(nsNumberControlFrame)
 FRAME_ID(nsObjectFrame)
 FRAME_ID(nsPageBreakFrame)
 FRAME_ID(nsPageContentFrame)
 FRAME_ID(nsPageFrame)
 FRAME_ID(nsPlaceholderFrame)
 FRAME_ID(nsPopupSetFrame)
 FRAME_ID(nsProgressFrame)
 FRAME_ID(nsProgressMeterFrame)
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -188,16 +188,18 @@ NS_NewListControlFrame(nsIPresShell* aPr
 nsIFrame*
 NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, uint32_t aFlags);
 nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewRangeFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsIFrame*
+NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 // Table frame factories
 nsIFrame*
 NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1754,17 +1754,17 @@ skip-if(B2G) == 818276-1.html 818276-1-r
 == 827799-1.html about:blank
 == 829958.html 829958-ref.html
 == 836844-1.html 836844-1-ref.html
 == 841192-1.html 841192-1-ref.html
 == 844178.html 844178-ref.html
 == 846144-1.html 846144-1-ref.html
 == 847850-1.html 847850-1-ref.html
 == 848421-1.html 848421-1-ref.html
-== 849407-1.html 849407-1-ref.html
+random-if(B2G) == 849407-1.html 849407-1-ref.html
 == 849996-1.html 849996-1-ref.html
 == 858803-1.html 858803-1-ref.html
 == 860242-1.html 860242-1-ref.html
 != 860370.html 860370-notref.html
 == 871338-1.html 871338-1-ref.html
 == 875060-1.html 875060-1-ref.html
 == 883987-1a.html 883987-1-ref.html
 == 883987-1b.html 883987-1-ref.html
--- a/layout/reftests/forms/fieldset/reftest.list
+++ b/layout/reftests/forms/fieldset/reftest.list
@@ -1,8 +1,8 @@
 == dynamic-legend-scroll-1.html dynamic-legend-scroll-1-ref.html
 == fieldset-hidden-1.html fieldset-hidden-1-ref.html
 == fieldset-intrinsic-width-1.html fieldset-intrinsic-width-1-ref.html
 == fieldset-percentage-padding-1.html fieldset-percentage-padding-1-ref.html
 == fieldset-scroll-1.html fieldset-scroll-1-ref.html
 == fieldset-scrolled-1.html fieldset-scrolled-1-ref.html
-== fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
+random-if(B2G) == fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
 == positioned-container-1.html positioned-container-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/focus-handling-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- In this case we're using reftest-wait to make sure the test doesn't         
+       get snapshotted before it's been focused. We're not testing                 
+       invalidation so we don't need to listen for MozReftestInvalidate.           
+  -->
+  <head>
+    <meta charset="utf-8">
+    <script>
+
+function end() {
+  setTimeout(function() {
+    document.documentElement.className = "";
+  }, 0);
+}
+
+    </script>
+  </head>
+  <body>
+    <input style="-moz-appearance:none;"><br>
+    <input autofocus onfocus="end();"
+           style="-moz-appearance:none;">
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/focus-handling.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- In this case we're using reftest-wait to make sure the test doesn't         
+       get snapshotted before it's been focused. We're not testing                 
+       invalidation so we don't need to listen for MozReftestInvalidate.           
+  -->                                                                              
+  <head>
+    <meta charset="utf-8">
+    <script>
+
+function begin() {
+  document.getElementsByTagName('input')[1].focus();
+}
+
+function end() {
+  setTimeout(function() {
+    document.documentElement.className = "";
+  }, 0);
+}
+
+    </script>
+  </head>
+  <body>
+    <input type='number' autofocus onfocus="begin();"
+           style="-moz-appearance:none;"><br>
+    <input type='number' onfocus="end();"
+           style="-moz-appearance:none;">
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/from-number-to-other-type-unthemed-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="checkbox" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/from-number-to-other-type-unthemed-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- Test: when switching to another type, the input element should look
+             like that type (not like an input number element) -->
+  <script type="text/javascript">
+    function setToCheckbox()
+    {
+      document.getElementById('i').type='checkbox';
+      document.documentElement.className = '';
+    }
+    document.addEventListener("MozReftestInvalidate", setToCheckbox);
+  </script>
+  <body>
+    <input type='number' id='i' style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/not-other-type-unthemed-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="number" value="1" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/not-other-type-unthemed-1a-notref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="text" value="1" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/not-other-type-unthemed-1b-notref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="checkbox" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-pseudo-elements-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="number" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-pseudo-elements.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+
+/* None of these selectors should match from content */
+input[type=number]::-moz-number-wrapper,
+input[type=number]::-moz-number-text,
+input[type=number]::-moz-number-spin-box,
+input[type=number]::-moz-number-spin-up,
+input[type=number]::-moz-number-spin-down {
+  background-color: red;
+}
+
+    </style>
+  </head>
+  <body>
+    <input type="number" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-same-as-text-unthemed-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="text" style="-moz-appearance:none; width:200px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-same-as-text-unthemed.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="number" style="-moz-appearance:none; width:200px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="text" style="-moz-appearance:none; width:200px;">
+    <!-- div to cover spin box area -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/number-similar-to-text-unthemed.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="number" style="-moz-appearance:none; width:200px;">
+    <!-- div to cover spin box area -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/reftest.list
@@ -0,0 +1,25 @@
+default-preferences pref(dom.forms.number,true)
+
+# sanity checks:
+# not valid on Android/B2G where type=number looks like type=text
+skip-if(Android||B2G) != not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html
+skip-if(Android||B2G) != not-other-type-unthemed-1.html not-other-type-unthemed-1b-notref.html
+# only valid on Android/B2G where type=number looks the same as type=text
+skip-if(!Android&&!B2G) == number-same-as-text-unthemed.html number-same-as-text-unthemed-ref.html
+
+# should look the same as type=text, except for the spin box
+== number-similar-to-text-unthemed.html number-similar-to-text-unthemed-ref.html
+
+# dynamic type changes:
+fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63,4) == to-number-from-other-type-unthemed-1.html to-number-from-other-type-unthemed-1-ref.html
+== from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1-ref.html
+
+# dynamic value changes:
+== show-value.html show-value-ref.html
+
+# focus
+fails-if(B2G) needs-focus == focus-handling.html focus-handling-ref.html # bug 940760
+
+# pseudo-elements not usable from content:
+== number-pseudo-elements.html number-pseudo-elements-ref.html
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/show-value-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">                                                         
+    <style>                                                                        
+                                                                                   
+input {                                                                            
+  -moz-appearance: none;                                                           
+}                                                                                  
+                                                                                   
+    </style>                                                                       
+  </head>
+  <body>
+    <input value='42'><br>
+    <input value='42'><br>
+    <input value='42'><br>
+    <input value='42'><br>
+    <input value='42'><br>
+    <form>
+      <input value='42'>
+    </form>
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:400px; top:0px; left:100px;">
+  </body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/show-value.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class='reftest-wait'>
+  <head>
+    <meta charset="utf-8">
+    <style>
+
+input {
+  -moz-appearance: none;
+}
+
+    </style>
+    <script>
+
+function run() {
+  var numbers = document.getElementsByTagName('input');
+  numbers[2].style.display = 'inline-block'; // none -> inline-block
+  numbers[3].setAttribute('value', '42');
+  numbers[4].value = '42';
+  numbers[5].varue = '1337'; // deliberately misspelt - should not set value
+  document.forms[0].reset(); // numbers[5] value should be 42 again.
+  document.documentElement.className = '';
+}
+
+document.addEventListener("MozReftestInvalidate", run);
+
+    </script>
+  </head>
+  <body onload="run();">
+    <input type='number' value='42'><br>
+    <input value='42' type='number'><br>
+    <input type='number' value='42' style="display: none;"><br>
+    <input type='number' value='1337'><br>
+    <input type='number' value='1337'><br>
+    <form>
+      <input type='number' value='42'>
+    </form>
+    <!-- div to cover spin box area for type=number to type=text comparison -->
+    <div style="display:block; position:absolute; background-color:black; width:200px; height:400px; top:0px; left:100px;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/to-number-from-other-type-unthemed-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input type="number" style="-moz-appearance:none;">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/input/number/to-number-from-other-type-unthemed-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- Test: input element changed to number state doesn't look like checkbox state -->
+  <script type="text/javascript">
+    function setToNumber()
+    {
+      document.getElementById('i').type='number';
+      document.documentElement.className = '';
+    }
+    document.addEventListener("MozReftestInvalidate", setToNumber);
+  </script>
+  <body>
+    <input type='checkbox' id='i' style="-moz-appearance:none;">
+  </body>
+</html>
--- a/layout/reftests/forms/input/reftest.list
+++ b/layout/reftests/forms/input/reftest.list
@@ -1,12 +1,13 @@
 include checkbox/reftest.list
 include email/reftest.list
 include tel/reftest.list
 include search/reftest.list
 include url/reftest.list
+include number/reftest.list
 include file/reftest.list
 include radio/reftest.list
 include range/reftest.list
 include text/reftest.list
 include percentage/reftest.list
 include hidden/reftest.list
 include color/reftest.list
--- a/layout/reftests/position-sticky/reftest.list
+++ b/layout/reftests/position-sticky/reftest.list
@@ -18,17 +18,17 @@ fuzzy-if(Android,2,4) == left-1.html lef
 fuzzy-if(Android,2,4) == left-2.html left-2-ref.html
 == left-3.html left-3-ref.html
 == right-1.html right-1-ref.html
 fuzzy-if(Android,2,4) == right-2.html right-2-ref.html
 fuzzy-if(Android,2,4) == right-3.html right-3-ref.html
 == margin-1.html margin-1-ref.html
 == padding-1.html padding-1-ref.html
 == padding-2.html padding-2-ref.html
-== padding-3.html padding-3-ref.html
+random-if(B2G) == padding-3.html padding-3-ref.html
 == overcontain-1.html overcontain-1-ref.html
 == initial-1.html initial-1-ref.html
 == initial-scroll-1.html initial-scroll-1-ref.html
 == scrollframe-reflow-1.html scrollframe-reflow-1-ref.html
 == scrollframe-reflow-2.html scrollframe-reflow-2-ref.html
 == scrollframe-auto-1.html scrollframe-auto-1-ref.html
 fuzzy-if(Android,2,3) == stacking-context-1.html stacking-context-1-ref.html
 == top-bottom-1.html top-bottom-1-ref.html
--- a/layout/reftests/reftest-sanity/reftest.list
+++ b/layout/reftests/reftest-sanity/reftest.list
@@ -87,17 +87,17 @@ needs-focus load needs-focus.html
 
 # Bug 632636
 fails == data:text/plain,HELLO about:blank
 needs-focus == data:text/plain, about:blank
 
 # Sanity check of viewport+displayport overrides
 random-if(!browserIsRemote) == test-displayport.html test-displayport-ref.html # bug 593168
 skip-if(!browserIsRemote) != test-displayport-2.html test-displayport-ref.html # bug 593168
-skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) == 647192-1.html 647192-1-ref.html
+skip-if(!browserIsRemote) fails-if(OSX&&layersGPUAccelerated) fuzzy-if(layersOMTC,1,1390) random-if(Android&&AndroidVersion<15) random-if(B2G) == 647192-1.html 647192-1-ref.html
 skip-if(!browserIsRemote) == 656041-1.html 656041-1-ref.html
 skip-if(!browserIsRemote||layersOMTC) == test-displayport-bg.html test-displayport-ref.html # bug 694706
 
 # IPC Position-fixed frames/layers test
 # Fixed layers are temporarily disabled (bug 656167).
 #skip-if(!browserIsRemote) == test-pos-fixed.html test-pos-fixed-ref.html
 #skip-if(!browserIsRemote) == test-bg-attachment-fixed.html test-bg-attachment-fixed-ref.html
 skip-if(!browserIsRemote) == test-pos-fixed-transform.html test-pos-fixed-transform-ref.html
--- a/layout/style/forms.css
+++ b/layout/style/forms.css
@@ -876,16 +876,94 @@ input[type=range]::-moz-range-thumb {
   height: 1em;
   border: 0.1em solid grey;
   border-radius: 0.5em;
   background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><linearGradient id='g' x2='0' y2='100%'><stop stop-color='%23ddd'/><stop offset='100%' stop-color='white'/></linearGradient><rect fill='url(%23g)' width='100%' height='100%'/></svg>");
   /* Prevent nsFrame::HandlePress setting mouse capture to this element. */
   -moz-user-select: none ! important;
 }
 
+input[type="number"] {
+  /* Has to revert some properties applied by the generic input rule. */
+  -moz-binding: none;
+  width: 149px; /* to match type=text */
+}
+
+input[type=number]::-moz-number-wrapper {
+  /* Prevent styling that would change the type of frame we construct. */
+  display: flex;
+  float: none !important;
+  position: static !important;
+  -moz-box-sizing: border-box;
+  width: 100%;
+  height: 100%;
+}
+
+input[type=number]::-moz-number-text {
+  -moz-appearance: none;
+  /* work around autofocus bug 939248 on initial load */
+  -moz-user-modify: read-write;
+  /* This pseudo-element is also an 'input' element (nested inside and
+   * distinct from the <input type=number> element) so we need to prevent the
+   * explicit setting of 'text-align' by the general CSS rule for 'input'
+   * above. We want to inherit its value from its <input type=number>
+   * ancestor, not have that general CSS rule reset it.
+   */
+  text-align: inherit;
+  flex: 1;
+  padding: 0;
+  border: 0;
+  margin: 0;
+}
+
+input[type=number]::-moz-number-spin-box {
+  display: flex;
+  flex-direction: column;
+  flex: 0 8px;
+  cursor: default;
+  padding: 1px;
+}
+
+input[type=number]::-moz-number-spin-up {
+  /* We should be "display:block" so that we don't get wrapped in an anonymous
+   * flex item that will prevent the setting of the "flex" property below from
+   * working.
+   */
+  display: block;
+  flex: 1;
+  background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,4 L3,0 5,4" fill="dimgrey"/></svg>');
+  background-repeat: no-repeat;
+  background-position: center bottom;
+  border: 1px solid darkgray;
+  border-bottom: none;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+}
+
+input[type=number]::-moz-number-spin-down {
+  /* We should be "display:block" so that we don't get wrapped in an anonymous
+   * flex item that will prevent the setting of the "flex" property below from
+   * working.
+   */
+  display: block;
+  flex: 1;
+  background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="6" height="5"><path d="M1,1 L3,5 5,1" fill="dimgrey"/></svg>');
+  background-repeat: no-repeat;
+  background-position: center top;
+  border: 1px solid darkgray;
+  border-top: none;
+  border-bottom-left-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+
+input[type="number"] > div > div > div:hover {
+  /* give some indication of hover state for the up/down buttons */
+  background-color: lightblue;
+}
+
 %ifdef XP_OS2
 input {
   font: medium serif; font-family: inherit
 }
 
 select {
   font: medium serif; font-family: inherit
 }
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3656,16 +3656,28 @@ CSSParserImpl::ParsePseudoSelector(int32
 
   // stash away some info about this pseudo so we only have to get it once.
   bool isTreePseudo = false;
   nsCSSPseudoElements::Type pseudoElementType =
     nsCSSPseudoElements::GetPseudoType(pseudo);
   nsCSSPseudoClasses::Type pseudoClassType =
     nsCSSPseudoClasses::GetPseudoType(pseudo);
 
+  if (!mUnsafeRulesEnabled &&
+      (pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberWrapper ||
+       pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberText ||
+       pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox ||
+       pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp ||
+       pseudoElementType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown)) {
+    // Hide these pseudo-elements from content until we standardize them.
+    REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
+    UngetToken();
+    return eSelectorParsingStatus_Error;
+  }
+
   // We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
   // be a bit stricter regarding the pseudo-element parsing rules.
   if (pseudoElementType == nsCSSPseudoElements::ePseudo_mozPlaceholder &&
       pseudoClassType == nsCSSPseudoClasses::ePseudoClass_mozPlaceholder) {
     if (parsingPseudoElement) {
       pseudoClassType = nsCSSPseudoClasses::ePseudoClass_NotPseudoClass;
     } else {
       pseudoElementType = nsCSSPseudoElements::ePseudo_NotPseudoElement;
--- a/layout/style/nsCSSPseudoElementList.h
+++ b/layout/style/nsCSSPseudoElementList.h
@@ -47,16 +47,21 @@ CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz
 // use our flags to prevent that?
 CSS_PSEUDO_ELEMENT(mozListBullet, ":-moz-list-bullet", 0)
 CSS_PSEUDO_ELEMENT(mozListNumber, ":-moz-list-number", 0)
 
 CSS_PSEUDO_ELEMENT(mozMathStretchy, ":-moz-math-stretchy", 0)
 CSS_PSEUDO_ELEMENT(mozMathAnonymous, ":-moz-math-anonymous", 0)
 
 // HTML5 Forms pseudo elements
+CSS_PSEUDO_ELEMENT(mozNumberWrapper, ":-moz-number-wrapper", 0)
+CSS_PSEUDO_ELEMENT(mozNumberText, ":-moz-number-text", 0)
+CSS_PSEUDO_ELEMENT(mozNumberSpinBox, ":-moz-number-spin-box", 0)
+CSS_PSEUDO_ELEMENT(mozNumberSpinUp, ":-moz-number-spin-up", 0)
+CSS_PSEUDO_ELEMENT(mozNumberSpinDown, ":-moz-number-spin-down", 0)
 CSS_PSEUDO_ELEMENT(mozProgressBar, ":-moz-progress-bar", 0)
 CSS_PSEUDO_ELEMENT(mozRangeTrack, ":-moz-range-track", 0)
 CSS_PSEUDO_ELEMENT(mozRangeProgress, ":-moz-range-progress", 0)
 CSS_PSEUDO_ELEMENT(mozRangeThumb, ":-moz-range-thumb", 0)
 CSS_PSEUDO_ELEMENT(mozMeterBar, ":-moz-meter-bar", 0)
 CSS_PSEUDO_ELEMENT(mozPlaceholder, ":-moz-placeholder", 0)
 CSS_PSEUDO_ELEMENT(mozColorSwatch, ":-moz-color-swatch",
                    CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE)
--- a/media/libjpeg/Makefile.in
+++ b/media/libjpeg/Makefile.in
@@ -11,8 +11,10 @@ ifeq ($(AS),yasm)
   # yasm doesn't like -c
   AS_DASH_C_FLAG=
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 jpeg_nbits_table.h: $(srcdir)/genTables.py
 	$(PYTHON) $(srcdir)/genTables.py
+
+jchuff.$(OBJ_SUFFIX): jpeg_nbits_table.h
--- a/media/libjpeg/moz.build
+++ b/media/libjpeg/moz.build
@@ -145,12 +145,8 @@ else: # No SIMD support?
     ]
 
 MSVC_ENABLE_PGO = True
 
 if CONFIG['OS_TARGET'] == 'WINNT':
     NO_VISIBILITY_FLAGS = True
 
 FINAL_LIBRARY = 'gkmedias'
-
-GENERATED_FILES = [
-    'jpeg_nbits_table.h',
-]
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/device_info_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/device_info_android.cc
@@ -100,17 +100,17 @@ int32_t DeviceInfoAndroid::GetDeviceName
   jobject javaCmDevInfoObject = jniFrame.GetCmDevInfoObject();
 
   // get the method ID for the Android Java GetDeviceUniqueName name.
   jmethodID cid = env->GetMethodID(javaCmDevInfoClass, "GetDeviceUniqueName",
                                    "(I)Ljava/lang/String;");
   if (cid != NULL) {
     jobject javaDeviceNameObj = env->CallObjectMethod(javaCmDevInfoObject,
                                                       cid, deviceNumber);
-    if (javaDeviceNameObj == NULL) {
+    if (javaDeviceNameObj == NULL || jniFrame.CheckForException()) {
       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                    "%s: Failed to get device name for device %d.",
                    __FUNCTION__, (int) deviceNumber);
       result = -1;
     } else {
       jboolean isCopy;
       const char* javaDeviceNameChar = env->GetStringUTFChars(
           (jstring) javaDeviceNameObj
@@ -195,17 +195,17 @@ int32_t DeviceInfoAndroid::CreateCapabil
     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                  "%s: Can't create string for  method GetCapabilityArray.",
                  __FUNCTION__);
     return -1;
   }
   // Call the java class and get an array with capabilities back.
   jobject javaCapabilitiesObj = env->CallObjectMethod(javaCmDevInfoObject,
                                                       cid, capureIdString);
-  if (!javaCapabilitiesObj) {
+  if (!javaCapabilitiesObj || jniFrame.CheckForException()) {
     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                  "%s: Failed to call java GetCapabilityArray.",
                  __FUNCTION__);
     return -1;
   }
 
   jfieldID widthField = env->GetFieldID(javaCapClass, "width", "I");
   jfieldID heigtField = env->GetFieldID(javaCapClass, "height", "I");
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
@@ -149,17 +149,22 @@ int32_t VideoCaptureAndroid::SetAndroidO
     EARLY_WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                  "%s: construct static java device object", __FUNCTION__);
 
     // construct the object by calling the static constructor object
     jobject javaCameraDeviceInfoObjLocal =
         env->CallStaticObjectMethod(g_javaCmDevInfoClass,
                                     cid, (int) -1,
                                     javaContext);
-    if (!javaCameraDeviceInfoObjLocal) {
+    bool exceptionThrown = env->ExceptionCheck();
+    if (!javaCameraDeviceInfoObjLocal || exceptionThrown) {
+      if (exceptionThrown) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+      }
       EARLY_WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, -1,
                    "%s: could not create Java Capture Device info object",
                    __FUNCTION__);
       return -1;
     }
     // create a reference to the object (to tell JNI that
     // we are referencing it after this function has returned)
     g_javaCmDevInfoObject = env->NewGlobalRef(javaCameraDeviceInfoObjLocal);
@@ -303,18 +308,16 @@ int32_t VideoCaptureAndroid::Init(const 
   AutoLocalJNIFrame jniFrame;
   JNIEnv* env = jniFrame.GetEnv();
   if (!env)
       return -1;
 
   jclass javaCmDevInfoClass = jniFrame.GetCmDevInfoClass();
   jobject javaCmDevInfoObject = jniFrame.GetCmDevInfoObject();
 
-  int32_t rotation = 0;
-
   WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
                "get method id");
   // get the method ID for the Android Java
   // CaptureDeviceInfoClass AllocateCamera factory method.
   char signature[256];
   sprintf(signature, "(IJLjava/lang/String;)L%s;", AndroidJavaCaptureClass);
 
   jmethodID cid = env->GetMethodID(javaCmDevInfoClass, "AllocateCamera",
@@ -326,17 +329,17 @@ int32_t VideoCaptureAndroid::Init(const 
   }
 
   jstring capureIdString = env->NewStringUTF((char*) deviceUniqueIdUTF8);
   // construct the object by calling the static constructor object
   jobject javaCameraObjLocal = env->CallObjectMethod(javaCmDevInfoObject,
                                                      cid, (jint) id,
                                                      (jlong) this,
                                                      capureIdString);
-  if (!javaCameraObjLocal) {
+  if (!javaCameraObjLocal || jniFrame.CheckForException()) {
     WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                  "%s: could not create Java Capture object", __FUNCTION__);
     return -1;
   }
 
   // create a reference to the object (to tell JNI that we are referencing it
   // after this function has returned)
   _javaCaptureObj = env->NewGlobalRef(javaCameraObjLocal);
@@ -369,16 +372,17 @@ VideoCaptureAndroid::~VideoCaptureAndroi
     jmethodID cid = env->GetStaticMethodID(g_javaCmClass,
                                            "DeleteVideoCaptureAndroid",
                                            "(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
     if (cid != NULL) {
       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                    "%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
       // Close the camera by calling the static destruct function.
       env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
+      jniFrame.CheckForException();
 
       // Delete global object ref to the camera.
       env->DeleteGlobalRef(_javaCaptureObj);
       _javaCaptureObj = NULL;
     } else {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                      "%s: Failed to find DeleteVideoCaptureAndroid id",
                      __FUNCTION__);
@@ -388,17 +392,16 @@ VideoCaptureAndroid::~VideoCaptureAndroi
 
 int32_t VideoCaptureAndroid::StartCapture(
     const VideoCaptureCapability& capability) {
   CriticalSectionScoped cs(&_apiCs);
   WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
                "%s: ", __FUNCTION__);
 
   int32_t result = 0;
-  int32_t rotation = 0;
 
   AutoLocalJNIFrame jniFrame;
   JNIEnv* env = jniFrame.GetEnv();
   if (!env)
       return -1;
 
   if (_capInfo.GetBestMatchedCapability(_deviceUniqueId, capability,
                                         _frameInfo) < 0) {
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -922,17 +922,17 @@ abstract public class GeckoApp
 
         mFullScreenPluginContainer.removeView(mFullScreenPluginView);
 
         // We need do do this on the next iteration in order to avoid
         // a deadlock, see comment below in FullScreenHolder
         ThreadUtils.postToUiThread(new Runnable() {
             @Override
             public void run() {
-                mLayerView.show();
+                mLayerView.showSurface();
             }
         });
 
         FrameLayout decor = (FrameLayout)getWindow().getDecorView();
         decor.removeView(mFullScreenPluginContainer);
 
         mFullScreenPluginView = null;
 
@@ -2655,17 +2655,17 @@ abstract public class GeckoApp
              * processed. Simultaneously, however, Flash is waiting on a mutex so
              * the post() below is an attempt to avoid a deadlock.
              */
             super.addView(view, index);
 
             ThreadUtils.postToUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    mLayerView.hide();
+                    mLayerView.hideSurface();
                 }
             });
         }
 
         /**
          * The methods below are simply copied from what Android WebKit does.
          * It wasn't ever called in my testing, but might as well
          * keep it in case it is for some reason. The methods
--- a/mobile/android/base/gfx/LayerView.java
+++ b/mobile/android/base/gfx/LayerView.java
@@ -193,22 +193,22 @@ public class LayerView extends FrameLayo
                 }
 
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createMotionEvent(event, false));
                 return true;
             }
         });
     }
 
-    public void show() {
+    public void showSurface() {
         // Fix this if TextureView support is turned back on above
         mSurfaceView.setVisibility(View.VISIBLE);
     }
 
-    public void hide() {
+    public void hideSurface() {
         // Fix this if TextureView support is turned back on above
         mSurfaceView.setVisibility(View.INVISIBLE);
     }
 
     public void destroy() {
         if (mLayerClient != null) {
             mLayerClient.destroy();
         }
--- a/mobile/android/themes/core/content.css
+++ b/mobile/android/themes/core/content.css
@@ -303,8 +303,13 @@ button:not([disabled]):active,
 input:not([disabled]):active,
 select:not([disabled]):active,
 textarea:not([disabled]):active,
 option:active,
 label:active,
 xul|menulist:active {
   background-color: @color_background_highlight_overlay@;
 }
+
+input[type=number]::-moz-number-spin-box {
+  display: none;
+}
+
--- a/netwerk/base/src/nsLoadGroup.cpp
+++ b/netwerk/base/src/nsLoadGroup.cpp
@@ -1151,17 +1151,17 @@ NS_IMETHODIMP
 nsLoadGroupConnectionInfo::SetSpdyPushCache(mozilla::net::SpdyPushCache *aSpdyPushCache)
 {
     mSpdyCache = aSpdyPushCache;
     return NS_OK;
 }
 
 nsresult nsLoadGroup::Init()
 {
-    static PLDHashTableOps hash_table_ops =
+    static const PLDHashTableOps hash_table_ops =
     {
         PL_DHashAllocTable,
         PL_DHashFreeTable,
         PL_DHashVoidPtrKeyStub,
         RequestHashMatchEntry,
         PL_DHashMoveEntryStub,
         RequestHashClearEntry,
         PL_DHashFinalizeStub,
--- a/netwerk/cache/nsCacheEntry.cpp
+++ b/netwerk/cache/nsCacheEntry.cpp
@@ -369,17 +369,17 @@ nsCacheEntryInfo::IsStreamBased(bool * r
     return NS_OK;
 }
 
 
 /******************************************************************************
  *  nsCacheEntryHashTable
  *****************************************************************************/
 
-PLDHashTableOps
+const PLDHashTableOps
 nsCacheEntryHashTable::ops =
 {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     HashKey,
     MatchEntry,
     MoveEntry,
     ClearEntry,
--- a/netwerk/cache/nsCacheEntry.h
+++ b/netwerk/cache/nsCacheEntry.h
@@ -298,14 +298,14 @@ private:
                                            void *            arg);
     static
     PLDHashOperator       VisitEntry(PLDHashTable *         table,
                                      PLDHashEntryHdr *      hdr,
                                      uint32_t               number,
                                      void *                 arg);
                                      
     // member variables
-    static PLDHashTableOps ops;
-    PLDHashTable           table;
-    bool                   initialized;
+    static const PLDHashTableOps ops;
+    PLDHashTable                 table;
+    bool                         initialized;
 };
 
 #endif // _nsCacheEntry_h_
--- a/netwerk/cache/nsDiskCacheBinding.cpp
+++ b/netwerk/cache/nsDiskCacheBinding.cpp
@@ -117,17 +117,17 @@ nsDiskCacheBinding::EnsureStreamIO()
 
 /******************************************************************************
  *  nsDiskCacheBindery
  *
  *  Keeps track of bound disk cache entries to detect for collisions.
  *
  *****************************************************************************/
 
-PLDHashTableOps nsDiskCacheBindery::ops =
+const PLDHashTableOps nsDiskCacheBindery::ops =
 {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     HashKey,
     MatchEntry,
     MoveEntry,
     ClearEntry,
     PL_DHashFinalizeStub
--- a/netwerk/cache/nsDiskCacheBinding.h
+++ b/netwerk/cache/nsDiskCacheBinding.h
@@ -107,14 +107,14 @@ public:
     bool                    ActiveBindings();
 
     size_t                 SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 private:
     nsresult                AddBinding(nsDiskCacheBinding * binding);
 
     // member variables
-    static PLDHashTableOps ops;
+    static const PLDHashTableOps ops;
     PLDHashTable           table;
     bool                   initialized;
 };
 
 #endif /* _nsDiskCacheBinding_h_ */
--- a/netwerk/cache2/CacheFileIOManager.cpp
+++ b/netwerk/cache2/CacheFileIOManager.cpp
@@ -94,17 +94,17 @@ CacheFileHandle::~CacheFileHandle()
 
 class CacheFileHandlesEntry : public PLDHashEntryHdr
 {
 public:
   PRCList      *mHandles;
   SHA1Sum::Hash mHash;
 };
 
-PLDHashTableOps CacheFileHandles::mOps =
+const PLDHashTableOps CacheFileHandles::mOps =
 {
   PL_DHashAllocTable,
   PL_DHashFreeTable,
   HashKey,
   MatchEntry,
   MoveEntry,
   ClearEntry,
   PL_DHashFinalizeStub
--- a/netwerk/cache2/CacheFileIOManager.h
+++ b/netwerk/cache2/CacheFileIOManager.h
@@ -78,19 +78,19 @@ private:
   static bool          MatchEntry(PLDHashTable *table,
                                   const PLDHashEntryHdr *entry,
                                   const void *key);
   static void          MoveEntry(PLDHashTable *table,
                                  const PLDHashEntryHdr *from,
                                  PLDHashEntryHdr *to);
   static void          ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry);
 
-  static PLDHashTableOps mOps;
-  PLDHashTable           mTable;
-  bool                   mInitialized;
+  static const PLDHashTableOps mOps;
+  PLDHashTable                 mTable;
+  bool                         mInitialized;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class OpenFileEvent;
 class CloseFileEvent;
 class ReadEvent;
 class WriteEvent;
--- a/netwerk/dns/Makefile.in
+++ b/netwerk/dns/Makefile.in
@@ -8,10 +8,15 @@ LOCAL_INCLUDES = \
   -I$(srcdir)/../base/src \
   -I. \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # Generate the include file containing compact, static definitions
 # for effective TLD data.
+nsEffectiveTLDService.$(OBJ_SUFFIX): etld_data.inc
+nsEffectiveTLDService.h: etld_data.inc
+
 etld_data.inc: $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat
 	$(PYTHON) $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat > etld_data.inc
+
+GARBAGE += etld_data.inc
--- a/netwerk/dns/moz.build
+++ b/netwerk/dns/moz.build
@@ -15,30 +15,26 @@ XPIDL_SOURCES += [
 
 XPIDL_MODULE = 'necko_dns'
 
 EXPORTS.mozilla.net += [
     'DNS.h',
 ]
 
 SOURCES += [
-    'nameprep.c',
-    'punycode.c',
-    'race.c',
+    'nsEffectiveTLDService.cpp', # Excluded from UNIFIED_SOURCES due to special build flags.
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'DNS.cpp',
+    'nameprep.c',
     'nsDNSService2.cpp',
-    'nsEffectiveTLDService.cpp',
     'nsHostResolver.cpp',
     'nsIDNService.cpp',
+    'punycode.c',
+    'race.c',
 ]
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'necko'
-
-GENERATED_FILES = [
-    'etld_data.inc',
-]
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -26,16 +26,17 @@
 #include "prerror.h"
 #include "prtime.h"
 #include "prlog.h"
 #include "pldhash.h"
 #include "plstr.h"
 #include "nsURLHelper.h"
 #include "nsThreadUtils.h"
 
+#include "mozilla/DebugOnly.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/VisualEventTracer.h"
 
 using namespace mozilla;
 using namespace mozilla::net;
 
@@ -303,17 +304,17 @@ HostDB_MoveEntry(PLDHashTable *table,
 
 static void
 HostDB_ClearEntry(PLDHashTable *table,
                   PLDHashEntryHdr *entry)
 {
     nsHostDBEnt *he = static_cast<nsHostDBEnt*>(entry);
     MOZ_ASSERT(he, "nsHostDBEnt is null!");
 
-    nsHostRecord *hr = he->rec;
+    DebugOnly<nsHostRecord*> hr = he->rec;
     MOZ_ASSERT(hr, "nsHostDBEnt has null host record!");
 
     LOG(("Clearing cache db entry for host [%s].\n", hr->host));
 #if defined(DEBUG) && defined(PR_LOGGING)
     {
         MutexAutoLock lock(hr->addr_info_lock);
         if (!hr->addr_info) {
             LOG(("No address info for host [%s].\n", hr->host));
@@ -347,17 +348,17 @@ HostDB_InitEntry(PLDHashTable *table,
                  PLDHashEntryHdr *entry,
                  const void *key)
 {
     nsHostDBEnt *he = static_cast<nsHostDBEnt *>(entry);
     nsHostRecord::Create(static_cast<const nsHostKey *>(key), &he->rec);
     return true;
 }
 
-static PLDHashTableOps gHostDB_ops =
+static const PLDHashTableOps gHostDB_ops =
 {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     HostDB_HashKey,
     HostDB_MatchEntry,
     HostDB_MoveEntry,
     HostDB_ClearEntry,
     PL_DHashFinalizeStub,
--- a/netwerk/protocol/rtsp/moz.build
+++ b/netwerk/protocol/rtsp/moz.build
@@ -10,17 +10,18 @@ EXPORTS.mozilla.net += [
     'controller/RtspControllerChild.h',
     'controller/RtspControllerParent.h',
     'controller/RtspMetaData.h',
     'rtsp/RTSPSource.h',
     'RtspChannel.h',
     'RtspHandler.h',
 ]
 
-UNIFIED_SOURCES += [
+# These files cannot be built in unified mode because they force NSPR logging.
+SOURCES += [
     'controller/RtspController.cpp',
     'controller/RtspControllerChild.cpp',
     'controller/RtspControllerParent.cpp',
     'controller/RtspMetaData.cpp',
     'RtspChannel.cpp',
     'RtspHandler.cpp',
 ]
 
--- a/parser/expat/lib/Makefile.in
+++ b/parser/expat/lib/Makefile.in
@@ -1,7 +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
 
+xmltok.$(OBJ_SUFFIX): moz_extensions.c
+
 DEFINES += -DHAVE_EXPAT_CONFIG_H
--- a/parser/expat/lib/moz.build
+++ b/parser/expat/lib/moz.build
@@ -13,12 +13,8 @@ SOURCES += [
     'xmlparse.c',
     'xmlrole.c',
     'xmltok.c',
 ]
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'gkmedias'
-
-GENERATED_FILES = [
-    'moz_extensions.c',
-]
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -197,17 +197,16 @@ class TreeMetadataEmitter(LoggingMixin):
             EXTRA_COMPONENTS='EXTRA_COMPONENTS',
             EXTRA_JS_MODULES='EXTRA_JS_MODULES',
             EXTRA_PP_COMPONENTS='EXTRA_PP_COMPONENTS',
             EXTRA_PP_JS_MODULES='EXTRA_PP_JS_MODULES',
             FAIL_ON_WARNINGS='FAIL_ON_WARNINGS',
             FILES_PER_UNIFIED_FILE='FILES_PER_UNIFIED_FILE',
             FORCE_SHARED_LIB='FORCE_SHARED_LIB',
             FORCE_STATIC_LIB='FORCE_STATIC_LIB',
-            GENERATED_FILES='GENERATED_FILES',
             HOST_LIBRARY_NAME='HOST_LIBRARY_NAME',
             IS_COMPONENT='IS_COMPONENT',
             JS_MODULES_PATH='JS_MODULES_PATH',
             LIBS='LIBS',
             LIBXUL_LIBRARY='LIBXUL_LIBRARY',
             MSVC_ENABLE_PGO='MSVC_ENABLE_PGO',
             NO_DIST_INSTALL='NO_DIST_INSTALL',
             OS_LIBS='OS_LIBS',
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
@@ -103,24 +103,16 @@ VARIABLES = {
         """Generated source code files that can be compiled together.
 
         This variable contains a list of generated source code files to
         compile, that can be concatenated all together, with UNIFIED_SOURCES,
         and built as a single source file. This can help make the build faster
         and reduce the debug info size.
         """, 'compile'),
 
-    'GENERATED_FILES': (StrictOrderingOnAppendList, list, [],
-        """Generic generated files.
-
-        This variable contains a list of generate files for the build system
-        to generate at export time. The rules for those files still live in
-        Makefile.in.
-        """, 'export'),
-
     'DEFINES': (OrderedDict, dict, OrderedDict(),
         """Dictionary of compiler defines to declare.
 
         These are passed in to the compiler as ``-Dkey='value'`` for string
         values, ``-Dkey=value`` for numeric values, or ``-Dkey`` if the
         value is True. Note that for string values, the outer-level of
         single-quotes will be consumed by the shell. If you want to have
         a string-literal in the program, the value needs to have
--- a/toolkit/components/telemetry/Makefile.in
+++ b/toolkit/components/telemetry/Makefile.in
@@ -44,9 +44,11 @@ data_python_deps := \
   $(srcdir)/histogram_tools.py \
   $(NULL)
 
 $(histogram_enum_file): $(histograms_file) $(enum_python_deps)
 	$(PYTHON) $(srcdir)/gen-histogram-enum.py $< > $@
 $(histogram_data_file): $(histograms_file) $(data_python_deps)
 	$(PYTHON) $(srcdir)/gen-histogram-data.py $< > $@
 
-GARBAGE += $(histogram_enum_file)
+Telemetry.$(OBJ_SUFFIX): $(histogram_data_file)
+
+GARBAGE += $(histogram_data_file) $(histogram_enum_file)
--- a/toolkit/components/telemetry/moz.build
+++ b/toolkit/components/telemetry/moz.build
@@ -38,12 +38,8 @@ EXTRA_JS_MODULES += [
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
-
-GENERATED_FILES = [
-    'TelemetryHistogramData.inc',
-]
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -64,16 +64,59 @@ symverscript: symverscript.in
 	$(call py_action,preprocessor, \
 		-DVERSION="$(LIBRARY_NAME)$(MOZILLA_SYMBOLVERSION)" $< -o $@)
 
 EXTRA_DEPS += symverscript
 endif
 endif
 
 # component libraries
+ifdef MOZ_JSDEBUGGER
+DEFINES += -DMOZ_JSDEBUGGER
+endif
+
+ifdef MOZ_PREF_EXTENSIONS
+DEFINES += -DMOZ_PREF_EXTENSIONS
+endif
+
+ifdef MOZ_AUTH_EXTENSION
+DEFINES += -DMOZ_AUTH_EXTENSION
+endif
+
+ifdef MOZ_PERMISSIONS
+DEFINES += -DMOZ_PERMISSIONS
+endif
+
+ifdef MOZ_UNIVERSALCHARDET
+DEFINES += -DMOZ_UNIVERSALCHARDET
+endif
+
+ifeq (,$(filter android gonk qt os2 cocoa windows,$(MOZ_WIDGET_TOOLKIT)))
+ifdef MOZ_XUL
+DEFINES += -DMOZ_FILEVIEW
+endif
+endif
+
+# Platform-specific icon channel stuff - supported mostly-everywhere
+ifneq (,$(filter windows os2 mac cocoa gtk2 gtk3 qt android,$(MOZ_WIDGET_TOOLKIT)))
+DEFINES += -DICON_DECODER
+endif
+
+ifdef MOZ_SPELLCHECK
+DEFINES += -DMOZ_SPELLCHECK
+endif
+
+ifdef MOZ_ZIPWRITER
+DEFINES += -DMOZ_ZIPWRITER
+endif
+
+ifdef MOZ_GIO_COMPONENT
+DEFINES += -DMOZ_GIO_COMPONENT
+endif
+
 ifdef MOZ_APP_COMPONENT_LIBS
 COMPONENT_LIBS += $(MOZ_APP_COMPONENT_LIBS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 OS_LIBS += -framework OpenGL -lcups
 endif
 
@@ -352,16 +395,22 @@ OS_LIBS += $(LIBICONV)
 DEFINES += \
   -DIMPL_LIBXUL \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 OS_LIBS += $(call EXPAND_LIBNAME,usp10 oleaut32)
 endif
 
+ifdef MOZ_DEBUG
+ifdef ENABLE_TESTS
+DEFINES += -DENABLE_LAYOUTDEBUG
+endif
+endif
+
 ifeq (WINNT_1,$(OS_TARGET)_$(MOZ_PROFILE_USE))
 # Wrap linker to measure peak virtual memory usage.
 LD := $(PYTHON) $(topsrcdir)/build/link.py $(CURDIR)/linker-vsize $(LD)
 endif
 
 ifndef LINK_GTEST
 ifdef COMPILE_ENVIRONMENT
 libs:: $(FINAL_TARGET)/dependentlibs.list
@@ -390,37 +439,8 @@ COMPONENT_LIBS += \
   gtest \
   gfxtest \
   ssltest \
   $(NULL)
 endif
 
 $(FINAL_TARGET)/dependentlibs.list: dependentlibs.py $(SHARED_LIBRARY) $(wildcard $(if $(wildcard $(FINAL_TARGET)/dependentlibs.list),$(addprefix $(FINAL_TARGET)/,$(shell cat $(FINAL_TARGET)/dependentlibs.list))))
 	$(PYTHON) $< $(SHARED_LIBRARY) -L $(FINAL_TARGET) $(if $(TOOLCHAIN_PREFIX),$(addprefix -p ,$(TOOLCHAIN_PREFIX))) > $@
-
-EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,StaticXULComponentsEnd,$(CURDIR)/StaticXULComponentsEnd)
-
-# BFD ld doesn't create multiple PT_LOADs as usual when an unknown section
-# exists. Using an implicit linker script to make it fold that section in
-# .data.rel.ro makes it create multiple PT_LOADs. That implicit linker
-# script however makes gold misbehave, first because it doesn't like that
-# the linker script is given after crtbegin.o, and even past that, replaces
-# the default section rules with those from the script instead of
-# supplementing them. Which leads to a lib with a huge load of sections.
-ifdef LD_IS_BFD
-EXTRA_DSO_LDOPTS += $(srcdir)/StaticXULComponents.ld
-endif
-
-# This, combined with the fact the file is first, makes the start pointer
-# first in Windows PGO builds.
-NO_PROFILE_GUIDED_OPTIMIZE = StaticXULComponentsStart.cpp
-
-ifeq (WINNT,$(OS_TARGET))
-get_first_and_last = dumpbin -exports $1 | grep _NSModule@@ | sort -k 3 | sed -n 's/^.*?\([^@]*\)@@.*$$/\1/;1p;$$p'
-else
-get_first_and_last = $(TOOLCHAIN_PREFIX)nm -g $1 | grep _NSModule$$ | sort | sed -n 's/^.* _*\([^ ]*\)$$/\1/;1p;$$p'
-endif
-
-LOCAL_CHECKS = test "$$($(get_first_and_last) | xargs echo)" != "start_kPStaticModules_NSModule end_kPStaticModules_NSModule" && echo "NSModules are not ordered appropriately" && exit 1 || exit 0
-
-ifeq (Linux,$(OS_ARCH))
-LOCAL_CHECKS += ; test "$$($(TOOLCHAIN_PREFIX)readelf -l $1 | awk '$1 == "LOAD" { t += 1 } END { print t }')" -le 1 && echo "Only one PT_LOAD segment" && exit 1 || exit 0
-endif
deleted file mode 100644
--- a/toolkit/library/StaticXULComponents.ld
+++ /dev/null
@@ -1,5 +0,0 @@
-SECTIONS {
-  .data.rel.ro : {
-    *(.kPStaticModules)
-  }
-}
deleted file mode 100644
--- a/toolkit/library/StaticXULComponentsEnd/StaticXULComponentsEnd.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "mozilla/Module.h"
-#include "mozilla/NullPtr.h"
-
-/* Ensure end_kPStaticModules is at the end of the .kPStaticModules section
- * on Windows. Somehow, placing the object last is not enough with PGO/LTCG. */
-#ifdef _MSC_VER
-/* Sections on Windows are in two parts, separated with $. When linking,
- * sections with the same first part are all grouped, and ordered
- * alphabetically with the second part as sort key. */
-#  pragma section(".kPStaticModules$Z", read)
-#  undef NSMODULE_SECTION
-#  define NSMODULE_SECTION __declspec(allocate(".kPStaticModules$Z"), dllexport)
-#endif
-NSMODULE_DEFN(end_kPStaticModules) = nullptr;
deleted file mode 100644
--- a/toolkit/library/StaticXULComponentsEnd/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-SOURCES += [
-    'StaticXULComponentsEnd.cpp',
-]
-
-LIBRARY_NAME = 'StaticXULComponentsEnd'
-
-LIBXUL_LIBRARY = True
deleted file mode 100644
--- a/toolkit/library/StaticXULComponentsStart.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "mozilla/Module.h"
-#include "mozilla/NullPtr.h"
-
-NSMODULE_DEFN(start_kPStaticModules) = nullptr;
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['MOZ_METRO'] and CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['winvccorlib']
 
 LIBRARY_NAME = 'xul'
 
 SOURCES += [
-    'StaticXULComponentsStart.cpp',
+    'nsStaticXULComponents.cpp',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     SOURCES += [
         'nsDllMain.cpp',
     ]
 
 MSVC_ENABLE_PGO = True
new file mode 100644
--- /dev/null
+++ b/toolkit/library/nsStaticXULComponents.cpp
@@ -0,0 +1,267 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Module.h"
+#include "nsXPCOM.h"
+#include "nsMemory.h"
+
+#ifdef MOZ_AUTH_EXTENSION
+#define AUTH_MODULE    MODULE(nsAuthModule)
+#else
+#define AUTH_MODULE
+#endif
+
+#ifdef MOZ_PERMISSIONS
+#define PERMISSIONS_MODULES                  \
+    MODULE(nsCookieModule)                   \
+    MODULE(nsPermissionsModule)
+#else
+#define PERMISSIONS_MODULES
+#endif
+
+#ifdef MOZ_UNIVERSALCHARDET
+#define UNIVERSALCHARDET_MODULE MODULE(nsUniversalCharDetModule)
+#else
+#define UNIVERSALCHARDET_MODULE
+#endif
+
+#ifdef XP_WIN
+#  define WIDGET_MODULES MODULE(nsWidgetModule)
+#elif defined(XP_MACOSX)
+#  define WIDGET_MODULES MODULE(nsWidgetMacModule)
+#elif defined(XP_OS2)
+#  define WIDGET_MODULES MODULE(nsWidgetOS2Module)
+#elif defined(MOZ_WIDGET_GTK)
+#  define WIDGET_MODULES MODULE(nsWidgetGtk2Module)
+#elif defined(MOZ_WIDGET_QT)
+#  define WIDGET_MODULES MODULE(nsWidgetQtModule)
+#elif defined(MOZ_WIDGET_ANDROID)
+#  define WIDGET_MODULES MODULE(nsWidgetAndroidModule)
+#elif defined(MOZ_WIDGET_GONK)
+#  define WIDGET_MODULES MODULE(nsWidgetGonkModule)
+#else
+#  error Unknown widget module.
+#endif
+
+#ifdef ICON_DECODER
+#define ICON_MODULE MODULE(nsIconDecoderModule)
+#else
+#define ICON_MODULE
+#endif
+
+#ifdef MOZ_ENABLE_XREMOTE
+#define XREMOTE_MODULES MODULE(RemoteServiceModule)
+#else
+#define XREMOTE_MODULES
+#endif
+
+#ifdef MOZ_PREF_EXTENSIONS
+#define SYSTEMPREF_MODULES MODULE(nsAutoConfigModule)
+#else
+#define SYSTEMPREF_MODULES
+#endif
+
+#ifdef ENABLE_LAYOUTDEBUG
+#define LAYOUT_DEBUG_MODULE MODULE(nsLayoutDebugModule)
+#else
+#define LAYOUT_DEBUG_MODULE
+#endif
+
+#ifdef MOZ_JSDEBUGGER
+#define JSDEBUGGER_MODULES \
+    MODULE(JavaScript_Debugger)
+#else
+#define JSDEBUGGER_MODULES
+#endif
+
+#if defined(MOZ_FILEVIEW) && defined(MOZ_XUL)
+#define FILEVIEW_MODULE MODULE(nsFileViewModule)
+#else
+#define FILEVIEW_MODULE
+#endif
+
+#ifdef MOZ_ZIPWRITER
+#define ZIPWRITER_MODULE MODULE(ZipWriterModule)
+#else
+#define ZIPWRITER_MODULE
+#endif
+
+#ifdef MOZ_PLACES
+#define PLACES_MODULES \
+    MODULE(nsPlacesModule)
+#else
+#define PLACES_MODULES
+#endif
+
+#ifdef MOZ_XUL
+#define XULENABLED_MODULES                   \
+    MODULE(tkAutoCompleteModule)             \
+    MODULE(satchel)                          \
+    MODULE(PKI)
+#else
+#define XULENABLED_MODULES
+#endif
+
+#ifdef MOZ_SPELLCHECK
+#define SPELLCHECK_MODULE MODULE(mozSpellCheckerModule)
+#else
+#define SPELLCHECK_MODULE
+#endif
+
+#ifdef MOZ_XUL
+#ifdef MOZ_WIDGET_GTK
+#define UNIXPROXY_MODULE MODULE(nsUnixProxyModule)
+#endif
+#if defined(MOZ_WIDGET_QT)
+#define UNIXPROXY_MODULE MODULE(nsUnixProxyModule)
+#endif
+#endif
+#ifndef UNIXPROXY_MODULE
+#define UNIXPROXY_MODULE
+#endif
+
+#if defined(XP_MACOSX)
+#define OSXPROXY_MODULE MODULE(nsOSXProxyModule)
+#else
+#define OSXPROXY_MODULE
+#endif
+
+#if defined(XP_WIN)
+#define WINDOWSPROXY_MODULE MODULE(nsWindowsProxyModule)
+#else
+#define WINDOWSPROXY_MODULE
+#endif
+
+#if defined(MOZ_WIDGET_ANDROID)
+#define ANDROIDPROXY_MODULE MODULE(nsAndroidProxyModule)
+#else
+#define ANDROIDPROXY_MODULE
+#endif
+
+#if defined(BUILD_CTYPES)
+#define JSCTYPES_MODULE MODULE(jsctypes)
+#else
+#define JSCTYPES_MODULE
+#endif
+
+#ifndef MOZ_APP_COMPONENT_MODULES
+#if defined(MOZ_APP_COMPONENT_INCLUDE)
+#include MOZ_APP_COMPONENT_INCLUDE
+#define MOZ_APP_COMPONENT_MODULES APP_COMPONENT_MODULES
+#else
+#define MOZ_APP_COMPONENT_MODULES
+#endif
+#endif
+
+#if defined(MOZ_ENABLE_PROFILER_SPS)
+#define PROFILER_MODULE MODULE(nsProfilerModule)
+#else
+#define PROFILER_MODULE
+#endif
+
+#if defined(MOZ_WEBRTC)
+#define PEERCONNECTION_MODULE MODULE(peerconnection)
+#else
+#define PEERCONNECTION_MODULE
+#endif
+
+#if defined(MOZ_GIO_COMPONENT)
+#define GIO_MODULE MODULE(nsGIOModule)
+#else
+#define GIO_MODULE
+#endif
+
+#if defined(MOZ_SYNTH_PICO)
+#define SYNTH_PICO_MODULE MODULE(synthpico)
+#else
+#define SYNTH_PICO_MODULE
+#endif
+
+#define XUL_MODULES                          \
+    MODULE(nsUConvModule)                    \
+    MODULE(nsI18nModule)                     \
+    MODULE(nsChardetModule)                  \
+    UNIVERSALCHARDET_MODULE                  \
+    MODULE(necko)                            \
+    PERMISSIONS_MODULES                      \
+    AUTH_MODULE                              \
+    MODULE(nsJarModule)                      \
+    ZIPWRITER_MODULE                         \
+    MODULE(StartupCacheModule)               \
+    MODULE(nsPrefModule)                     \
+    MODULE(nsRDFModule)                      \
+    MODULE(nsWindowDataSourceModule)         \
+    MODULE(nsParserModule)                   \
+    MODULE(nsImageLib2Module)                \
+    MODULE(nsMediaSnifferModule)             \
+    MODULE(nsGfxModule)                      \
+    PROFILER_MODULE                          \
+    WIDGET_MODULES                           \
+    ICON_MODULE                              \
+    MODULE(nsPluginModule)                   \
+    MODULE(nsLayoutModule)                   \
+    MODULE(docshell_provider)                \
+    MODULE(embedcomponents)                  \
+    MODULE(Browser_Embedding_Module)         \
+    MODULE(appshell)                         \
+    MODULE(nsTransactionManagerModule)       \
+    MODULE(nsComposerModule)                 \
+    MODULE(application)                      \
+    MODULE(Apprunner)                        \
+    MODULE(CommandLineModule)                \
+    FILEVIEW_MODULE                          \
+    MODULE(mozStorageModule)                 \
+    PLACES_MODULES                           \
+    XULENABLED_MODULES                       \
+    MODULE(nsToolkitCompsModule)             \
+    XREMOTE_MODULES                          \
+    JSDEBUGGER_MODULES                       \
+    MODULE(BOOT)                             \
+    MODULE(NSS)                              \
+    SYSTEMPREF_MODULES                       \
+    SPELLCHECK_MODULE                        \
+    LAYOUT_DEBUG_MODULE                      \
+    UNIXPROXY_MODULE                         \
+    OSXPROXY_MODULE                          \
+    WINDOWSPROXY_MODULE                      \
+    ANDROIDPROXY_MODULE                      \
+    JSCTYPES_MODULE                          \
+    MODULE(jsreflect)                        \
+    MODULE(jsperf)                           \
+    MODULE(identity)                         \
+    MODULE(nsServicesCryptoModule)           \
+    MOZ_APP_COMPONENT_MODULES                \
+    MODULE(nsTelemetryModule)                \
+    MODULE(jsinspector)                      \
+    MODULE(jsdebugger)                       \
+    PEERCONNECTION_MODULE                    \
+    GIO_MODULE                               \
+    SYNTH_PICO_MODULE                        \
+    MODULE(DiskSpaceWatcherModule)           \
+    /* end of list */
+
+#define MODULE(_name) \
+  NSMODULE_DECL(_name);
+
+XUL_MODULES
+
+#ifdef MOZ_WIDGET_GONK
+MODULE(WifiProxyServiceModule)
+#endif
+
+#undef MODULE
+
+#define MODULE(_name) \
+    &NSMODULE_NAME(_name),
+
+extern const mozilla::Module *const *const kPStaticModules[] = {
+  XUL_MODULES
+#ifdef MOZ_WIDGET_GONK
+MODULE(WifiProxyServiceModule)
+#endif
+  nullptr
+};
+
+#undef MODULE
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -156,17 +156,16 @@ add_tier_dir('platform', 'other-licenses
 if CONFIG['MOZ_GIO_COMPONENT']:
     add_tier_dir('platform', 'extensions/gio')
 
 # Applications can cheat and ask for code to be
 # built before libxul so it can be linked into libxul.
 add_tier_dir('platform', app_libxul_dirs)
 add_tier_dir('platform', app_libxul_static_dirs, static=True)
 
-add_tier_dir('platform', 'toolkit/library/StaticXULComponentsEnd')
 add_tier_dir('platform', 'toolkit/library')
 
 if CONFIG['MOZ_REPLACE_MALLOC']:
     add_tier_dir('platform', 'memory/replace')
 
 if CONFIG['NS_TRACE_MALLOC']:
     add_tier_dir('platform', 'tools/trace-malloc')
 
--- a/xpcom/components/Module.h
+++ b/xpcom/components/Module.h
@@ -100,29 +100,16 @@ struct Module
   LoadFuncPtr loadProc;
   UnloadFuncPtr unloadProc;
 };
 
 } // namespace
 
 #if defined(MOZILLA_INTERNAL_API)
 #  define NSMODULE_NAME(_name) _name##_NSModule
-#  if defined(_MSC_VER)
-#    pragma section(".kPStaticModules$M", read)
-#    pragma comment(linker, "/merge:.kPStaticModules=.rdata")
-#    define NSMODULE_SECTION __declspec(allocate(".kPStaticModules$M"), dllexport)
-#  elif defined(__GNUC__)
-#    if defined(__ELF__)
-#      define NSMODULE_SECTION __attribute__((section(".kPStaticModules"), visibility("protected")))
-#    elif defined(__MACH__)
-#      define NSMODULE_SECTION __attribute__((section("__DATA, .kPStaticModules"), visibility("default")))
-#    endif
-#  endif
-#  if !defined(NSMODULE_SECTION)
-#    error Do not know how to define sections.
-#  endif
-#  define NSMODULE_DEFN(_name) extern NSMODULE_SECTION mozilla::Module const *const NSMODULE_NAME(_name)
+#  define NSMODULE_DECL(_name) extern mozilla::Module const *const NSMODULE_NAME(_name)
+#  define NSMODULE_DEFN(_name) NSMODULE_DECL(_name)
 #else
 #  define NSMODULE_NAME(_name) NSModule
 #  define NSMODULE_DEFN(_name) extern "C" NS_EXPORT mozilla::Module const *const NSModule
 #endif
 
 #endif // mozilla_Module_h
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -77,16 +77,20 @@
 #include "mozilla/Omnijar.h"
 
 #include "prlog.h"
 
 using namespace mozilla;
 
 PRLogModuleInfo* nsComponentManagerLog = nullptr;
 
+// defined in nsStaticXULComponents.cpp to contain all the components in
+// libxul.
+extern mozilla::Module const *const *const kPStaticModules[];
+
 #if 0 || defined (DEBUG_timeless)
  #define SHOW_DENIED_ON_SHUTDOWN
  #define SHOW_CI_ON_EXISTING_SERVICE
 #endif
 
 // Bloated registry buffer size to improve startup performance -- needs to
 // be big enough to fit the entire file into memory or it'll thrash.
 // 512K is big enough to allow for some future growth in the registry.
@@ -316,36 +320,26 @@ nsComponentManagerImpl::nsComponentManag
     , mContractIDs(CONTRACTID_HASHTABLE_INITIAL_SIZE)
     , mLock("nsComponentManagerImpl.mLock")
     , mStatus(NOT_INITIALIZED)
 {
 }
 
 nsTArray<const mozilla::Module*>* nsComponentManagerImpl::sStaticModules;
 
-NSMODULE_DEFN(start_kPStaticModules);
-NSMODULE_DEFN(end_kPStaticModules);
-
-/* The content between start_kPStaticModules and end_kPStaticModules is gathered
- * by the linker from various objects containing symbols in a specific section.
- * ASAN considers (rightfully) the use of this content as a global buffer
- * overflow. But this is a deliberate and well-considered choice, with no proper
- * way to make ASAN happy. */
-MOZ_ASAN_BLACKLIST
 /* static */ void
 nsComponentManagerImpl::InitializeStaticModules()
 {
     if (sStaticModules)
         return;
 
     sStaticModules = new nsTArray<const mozilla::Module*>;
-    for (const mozilla::Module *const *staticModules = &NSMODULE_NAME(start_kPStaticModules) + 1;
-         staticModules < &NSMODULE_NAME(end_kPStaticModules); ++staticModules)
-        if (*staticModules) // ASAN adds padding
-            sStaticModules->AppendElement(*staticModules);
+    for (const mozilla::Module *const *const *staticModules = kPStaticModules;
+         *staticModules; ++staticModules)
+        sStaticModules->AppendElement(**staticModules);
 }
 
 nsTArray<nsComponentManagerImpl::ComponentLocation>*
 nsComponentManagerImpl::sModuleLocations;
 
 /* static */ void
 nsComponentManagerImpl::InitializeModuleLocations()
 {
--- a/xpcom/reflect/xptcall/src/md/unix/Makefile.in
+++ b/xpcom/reflect/xptcall/src/md/unix/Makefile.in
@@ -159,13 +159,17 @@ ifndef GNU_CC
 xptcstubsdef_asm.solx86: $(DIST)/include/xptcstubsdef.inc
 	sed \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9]\))/\11\(\2\)/' \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9][0-9]\))/\12\(\2\)/' \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9][0-9][0-9]\))/\13\(\2\)/' \
 	$(DIST)/include/xptcstubsdef.inc > $@
 ifeq (x86_64,$(OS_TEST))
 ASFLAGS += -xarch=amd64
+
+xptcstubs_asm_x86_64_solaris_SUNW.$(OBJ_SUFFIX): xptcstubsdef_asm.solx86
+else
+xptcstubs_asm_x86_solaris_SUNW.$(OBJ_SUFFIX): xptcstubsdef_asm.solx86
 endif
 
 endif
 endif
 endif
--- a/xpcom/reflect/xptcall/src/md/unix/moz.build
+++ b/xpcom/reflect/xptcall/src/md/unix/moz.build
@@ -276,19 +276,16 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CO
     SOURCES += [
         'xptcinvoke_asm_sparc64_openbsd.s',
         'xptcinvoke_sparc64_openbsd.cpp',
         'xptcstubs_asm_sparc64_openbsd.s',
         'xptcstubs_sparc64_openbsd.cpp',
     ]
 
 if CONFIG['OS_ARCH'] == 'SunOS' and CONFIG['OS_TEST'].find('86') == -1:
-    GENERATED_FILES = [
-        'xptcstubsdef_asm.solx86',
-    ]
     if CONFIG['HAVE_64BIT_OS']:
         SOURCES += [
             'xptcinvoke_sparcv9_solaris.cpp',
             'xptcstubs_sparcv9_solaris.cpp',
         ]
     else:
         SOURCES += [
             'xptcinvoke_sparc_solaris.cpp',