Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Mon, 30 Jun 2014 18:00:36 -0700
changeset 191494 5f998c527a672e0f28ce60b4e9b10b4ffb37daa8
parent 191456 606848e8adfc4993ee9ed70bee27a439ad556561 (current diff)
parent 191493 cddd70c049644abf1c0d1fca3502d16e88df6981 (diff)
child 191510 a3af97c421d3851ca61fca42758ea7956d6461fe
push id27051
push userkwierso@gmail.com
push dateTue, 01 Jul 2014 01:00:57 +0000
treeherdermozilla-central@5f998c527a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone33.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 a=merge
js/src/tests/ecma_6/TypedObject/simd/float32x4bitstoint32x4.js
js/src/tests/ecma_6/TypedObject/simd/float32x4toint32x4.js
js/src/tests/ecma_6/TypedObject/simd/int32x4bitstofloat32x4.js
js/src/tests/ecma_6/TypedObject/simd/int32x4tofloat32x4.js
xpcom/reflect/xptcall/public/genstubs.pl
xpcom/reflect/xptcall/public/moz.build
xpcom/reflect/xptcall/public/xptcall.h
xpcom/reflect/xptcall/public/xptcstubsdecl.inc
xpcom/reflect/xptcall/public/xptcstubsdef.inc
xpcom/reflect/xptcall/src/md/moz.build
xpcom/reflect/xptcall/src/md/test/README
xpcom/reflect/xptcall/src/md/test/clean.bat
xpcom/reflect/xptcall/src/md/test/invoke_test.cpp
xpcom/reflect/xptcall/src/md/test/mk_invoke.bat
xpcom/reflect/xptcall/src/md/test/mk_stub.bat
xpcom/reflect/xptcall/src/md/test/moz.build
xpcom/reflect/xptcall/src/md/test/stub_test.cpp
xpcom/reflect/xptcall/src/md/unix/Makefile.in
xpcom/reflect/xptcall/src/md/unix/moz.build
xpcom/reflect/xptcall/src/md/unix/vtable_layout_x86.cpp
xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_alpha_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_aarch64.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf32.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips64.S
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_parisc_linux.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.S
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix64.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_linux.S
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_openbsd.S
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_rhapsody.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_openbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_netbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_openbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_x86_solaris_SUNW.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_darwin.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf32.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_alpha.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_m68k.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390x.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_netbsd_m68k.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_rhapsody.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparcv9_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_aarch64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_alpha_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_amd64_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_aarch64.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf32.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf64.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.m4
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips64.S
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_parisc_linux.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.S
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix.s.m4
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix64.s.m4
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_darwin.s.m4
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_linux.S
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_openbsd.S
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc64_openbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_netbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_openbsd.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_solaris.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparcv9_solaris.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_x86_64_solaris_SUNW.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_x86_solaris_SUNW.s
xpcom/reflect/xptcall/src/md/unix/xptcstubs_darwin.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_gcc_x86_unix.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf32.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_m68k.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390x.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_netbsd_m68k.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix64.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_netbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_openbsd.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparcv9_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_darwin.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_solaris.cpp
xpcom/reflect/xptcall/src/md/win32/moz.build
xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp
xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_x86_64.asm
xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_x86_64_gnu.s
xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_64.cpp
xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_gnu.cpp
xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp
xpcom/reflect/xptcall/src/md/win32/xptcstubs_asm_x86_64.asm
xpcom/reflect/xptcall/src/md/win32/xptcstubs_x86_64.cpp
xpcom/reflect/xptcall/src/md/win32/xptcstubs_x86_64_gnu.cpp
xpcom/reflect/xptcall/src/moz.build
xpcom/reflect/xptcall/src/xptcall.cpp
xpcom/reflect/xptcall/src/xptcprivate.h
xpcom/reflect/xptinfo/public/XPTInterfaceInfoManager.h
xpcom/reflect/xptinfo/public/moz.build
xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl
xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl
xpcom/reflect/xptinfo/public/xptinfo.h
xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
xpcom/reflect/xptinfo/src/ShimInterfaceInfo.h
xpcom/reflect/xptinfo/src/TODO
xpcom/reflect/xptinfo/src/moz.build
xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
xpcom/typelib/xpt/public/moz.build
xpcom/typelib/xpt/public/xpt_arena.h
xpcom/typelib/xpt/public/xpt_struct.h
xpcom/typelib/xpt/public/xpt_xdr.h
xpcom/typelib/xpt/src/Makefile.in
xpcom/typelib/xpt/src/moz.build
xpcom/typelib/xpt/src/xpt_arena.cpp
xpcom/typelib/xpt/src/xpt_struct.cpp
xpcom/typelib/xpt/src/xpt_xdr.cpp
--- a/browser/base/content/browser-loop.js
+++ b/browser/base/content/browser-loop.js
@@ -19,25 +19,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
      * @param {event} event The event opening the panel, used to anchor
      *                      the panel to the button which triggers it.
      */
     openCallPanel: function(event) {
       let callback = iframe => {
         iframe.addEventListener("DOMContentLoaded", function documentDOMLoaded() {
           iframe.removeEventListener("DOMContentLoaded", documentDOMLoaded, true);
           injectLoopAPI(iframe.contentWindow);
-
-          // We use loopPanelInitialized so that we know we've finished localising before
-          // sizing the panel.
-          iframe.contentWindow.addEventListener("loopPanelInitialized",
-            function documentLoaded() {
-              iframe.contentWindow.removeEventListener("loopPanelInitialized",
-                                                       documentLoaded, true);
-            }, true);
-
         }, true);
       };
 
       PanelFrame.showPopup(window, PanelUI, event.target, "loop", null,
                            "about:looppanel", null, callback);
     },
 
     /**
--- a/browser/base/content/socialmarks.xml
+++ b/browser/base/content/socialmarks.xml
@@ -207,17 +207,16 @@
       </method>
 
       <method name="openPanel">
         <parameter name="aResetOnClose"/>
         <body><![CDATA[
         let panel = this.panel;
         let frameId = this.getAttribute("notificationFrameId");
 
-        let wasAlive = SharedFrame.isGroupAlive(frameId);
         SharedFrame.setOwner(frameId, this.content);
 
         // Clear dimensions on all browsers so the panel size will
         // only use the selected browser.
         let frameIter = panel.firstElementChild;
         while (frameIter) {
           frameIter.collapsed = (frameIter != this.content);
           frameIter = frameIter.nextElementSibling;
--- a/browser/devtools/netmonitor/test/sjs_content-type-test-server.sjs
+++ b/browser/devtools/netmonitor/test/sjs_content-type-test-server.sjs
@@ -24,17 +24,20 @@ function handleRequest(request, response
     if (cachedCount % 2) {
       response.setHeader("Cache-Control", "max-age=" + cacheExpire, false);
     } else {
       response.setHeader("Expires", Date(Date.now() + cacheExpire * 1000), false);
     }
     cachedCount++;
   }
 
-  Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer).initWithCallback(() => {
+  let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  timer.initWithCallback(() => {
+    // to avoid garbage collection
+    timer = null;
     switch (format) {
       case "txt": {
         response.setStatusLine(request.httpVersion, status, "DA DA DA");
         response.setHeader("Content-Type", "text/plain", false);
         setCacheHeaders();
         response.write("Братан, ты вообще качаешься?");
         response.finish();
         break;
--- a/browser/devtools/netmonitor/test/sjs_sorting-test-server.sjs
+++ b/browser/devtools/netmonitor/test/sjs_sorting-test-server.sjs
@@ -4,17 +4,20 @@
 const { classes: Cc, interfaces: Ci } = Components;
 
 function handleRequest(request, response) {
   response.processAsync();
 
   let params = request.queryString.split("&");
   let index = params.filter((s) => s.contains("index="))[0].split("=")[1];
 
-  Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer).initWithCallback(() => {
+  let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  timer.initWithCallback(() => {
+    // to avoid garbage collection
+    timer = null;
     response.setStatusLine(request.httpVersion, index == 1 ? 101 : index * 100, "Meh");
 
     response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
     response.setHeader("Pragma", "no-cache");
     response.setHeader("Expires", "0");
 
     response.setHeader("Content-Type", "text/" + index, false);
     response.write(new Array(index * 10).join(index)); // + 0.01 KB
--- a/browser/devtools/netmonitor/test/sjs_status-codes-test-server.sjs
+++ b/browser/devtools/netmonitor/test/sjs_status-codes-test-server.sjs
@@ -4,17 +4,20 @@
 const { classes: Cc, interfaces: Ci } = Components;
 
 function handleRequest(request, response) {
   response.processAsync();
 
   let params = request.queryString.split("&");
   let status = params.filter((s) => s.contains("sts="))[0].split("=")[1];
 
-  Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer).initWithCallback(() => {
+  let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  timer.initWithCallback(() => {
+    // to avoid garbage collection
+    timer = null;
     switch (status) {
       case "100":
         response.setStatusLine(request.httpVersion, 101, "Switching Protocols");
         break;
       case "200":
         response.setStatusLine(request.httpVersion, 202, "Created");
         break;
       case "300":
--- a/browser/modules/PanelFrame.jsm
+++ b/browser/modules/PanelFrame.jsm
@@ -130,17 +130,16 @@ let PanelFrame = {
       panel = aWindow.document.getElementById(aType + "-notification-panel");
       PanelFrameInternal._attachNotificatonPanel(aWindow, panel, aToolbarButton, aType, aOrigin, aSrc, aSize);
       showingEvent = "popupshown";
       hidingEvent = "popuphidden";
     }
     let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
     let notificationFrame = aWindow.document.getElementById(notificationFrameId);
 
-    let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
     SharedFrame.setOwner(notificationFrameId, notificationFrame);
 
     // Clear dimensions on all browsers so the panel size will
     // only use the selected browser.
     let frameIter = panel.firstElementChild;
     while (frameIter) {
       frameIter.collapsed = (frameIter != notificationFrame);
       frameIter = frameIter.nextElementSibling;
@@ -179,17 +178,17 @@ let PanelFrame = {
         notificationFrame.docShell.isAppTab = true;
         if (dynamicResizer)
           dynamicResizer.start(panel, notificationFrame);
         dispatchPanelEvent(aType + "FrameShow");
       };
       if (!inMenuPanel)
         anchorBtn.setAttribute("open", "true");
       if (notificationFrame.contentDocument &&
-          notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
+          notificationFrame.contentDocument.readyState == "complete") {
         initFrameShow();
       } else {
         // first time load, wait for load and dispatch after load
         notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
           notificationFrame.removeEventListener("load", panelBrowserOnload, true);
           initFrameShow();
         }, true);
       }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2469,27 +2469,24 @@ nsDocShell::GetFullscreenAllowed(bool* a
         !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) &&
         !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) {
         return NS_OK;
     }
 
     // If we have no parent then we're the root docshell; no ancestor of the
     // original docshell doesn't have a allowfullscreen attribute, so
     // report fullscreen as allowed.
-    nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-    GetParent(getter_AddRefs(parentTreeItem));
-    if (!parentTreeItem) {
+    nsRefPtr<nsDocShell> parent = GetParentDocshell();
+    if (!parent) {
         *aFullscreenAllowed = true;
         return NS_OK;
     }
+
     // Otherwise, we have a parent, continue the checking for
     // mozFullscreenAllowed in the parent docshell's ancestors.
-    nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentTreeItem);
-    NS_ENSURE_TRUE(parent, NS_OK);
-    
     return parent->GetFullscreenAllowed(aFullscreenAllowed);
 }
 
 NS_IMETHODIMP
 nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed)
 {
     if (!nsIDocShell::GetIsBrowserOrApp()) {
         // Only allow setting of fullscreenAllowed on content/process boundaries.
@@ -3127,26 +3124,25 @@ nsDocShell::GetSameTypeParentIgnoreBrows
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)
 {
     NS_ENSURE_ARG_POINTER(aRootTreeItem);
-    *aRootTreeItem = static_cast<nsIDocShellTreeItem *>(this);
-
-    nsCOMPtr<nsIDocShellTreeItem> parent;
-    NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
+
+    nsRefPtr<nsDocShell> root = this;
+    nsRefPtr<nsDocShell> parent = root->GetParentDocshell();
     while (parent) {
-        *aRootTreeItem = parent;
-        NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)),
-                          NS_ERROR_FAILURE);
-    }
-    NS_ADDREF(*aRootTreeItem);
+        root = parent;
+        parent = root->GetParentDocshell();
+    }
+
+    root.forget(aRootTreeItem);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetSameTypeRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)
 {
     NS_ENSURE_ARG_POINTER(aRootTreeItem);
     *aRootTreeItem = static_cast<nsIDocShellTreeItem *>(this);
@@ -5551,25 +5547,22 @@ nsDocShell::GetVisibility(bool * aVisibi
     // if our root view is hidden, we are not visible
     if (view->GetVisibility() == nsViewVisibility_kHide)
         return NS_OK;
 
     // otherwise, we must walk up the document and view trees checking
     // for a hidden view, unless we're an off screen browser, which 
     // would make this test meaningless.
 
-    nsCOMPtr<nsIDocShellTreeItem> treeItem = this;
-    nsCOMPtr<nsIDocShellTreeItem> parentItem;
-    treeItem->GetParent(getter_AddRefs(parentItem));
+    nsRefPtr<nsDocShell> docShell = this;
+    nsRefPtr<nsDocShell> parentItem = docShell->GetParentDocshell();
     while (parentItem) {
-        nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(treeItem));
         presShell = docShell->GetPresShell();
 
-        nsCOMPtr<nsIDocShell> parentDS = do_QueryInterface(parentItem);
-        nsCOMPtr<nsIPresShell> pPresShell = parentDS->GetPresShell();
+        nsCOMPtr<nsIPresShell> pPresShell = parentItem->GetPresShell();
 
         // Null-check for crash in bug 267804
         if (!pPresShell) {
             NS_NOTREACHED("parent docshell has null pres shell");
             return NS_OK;
         }
 
         vm = presShell->GetViewManager();
@@ -5588,18 +5581,18 @@ nsDocShell::GetVisibility(bool * aVisibi
         bool isDocShellOffScreen = false;
         docShell->GetIsOffScreenBrowser(&isDocShellOffScreen);
         if (frame &&
             !frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) &&
             !isDocShellOffScreen) {
             return NS_OK;
         }
 
-        treeItem = parentItem;
-        treeItem->GetParent(getter_AddRefs(parentItem));
+        docShell = parentItem;
+        parentItem = docShell->GetParentDocshell();
     }
 
     nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(mTreeOwner));
     if (!treeOwnerAsWin) {
         *aVisibility = true;
         return NS_OK;
     }
 
@@ -8014,18 +8007,17 @@ nsDocShell::RestoreFromHistory()
         newMUDV->SetTextZoom(textZoom);
         newMUDV->SetFullZoom(pageZoom);
         newMUDV->SetAuthorStyleDisabled(styleDisabled);
     }
 
     nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
     uint32_t parentSuspendCount = 0;
     if (document) {
-        nsCOMPtr<nsIDocShellTreeItem> parent;
-        GetParent(getter_AddRefs(parent));
+        nsRefPtr<nsDocShell> parent = GetParentDocshell();
         if (parent) {
           nsCOMPtr<nsIDocument> d = parent->GetDocument();
           if (d) {
             if (d->EventHandlingSuppressed()) {
                 document->SuppressEventHandling(nsIDocument::eEvents,
                                                 d->EventHandlingSuppressed());
             }
 
@@ -9220,18 +9212,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     // If a source docshell has been passed, check to see if we are sandboxed
     // from it as the result of an iframe or CSP sandbox.
     if (aSourceDocShell && aSourceDocShell->IsSandboxedFrom(this)) {
         return NS_ERROR_DOM_INVALID_ACCESS_ERR;
     }
 
     // If this docshell is owned by a frameloader, make sure to cancel
     // possible frameloader initialization before loading a new page.
-    nsCOMPtr<nsIDocShellTreeItem> parent;
-    GetParent(getter_AddRefs(parent));
+    nsCOMPtr<nsIDocShellTreeItem> parent = GetParentDocshell();
     if (parent) {
         nsCOMPtr<nsIDocument> doc = do_GetInterface(parent);
         if (doc) {
             doc->TryCancelFrameLoaderInitialization(this);
         }
     }
 
     // Before going any further vet loads initiated by external programs.
@@ -12297,28 +12288,25 @@ nsDocShell::GetNestedFrameId(uint64_t* a
 {
     *aId = 0;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::IsAppOfType(uint32_t aAppType, bool *aIsOfType)
 {
-    nsCOMPtr<nsIDocShell> shell = this;
+    nsRefPtr<nsDocShell> shell = this;
     while (shell) {
         uint32_t type;
         shell->GetAppType(&type);
         if (type == aAppType) {
             *aIsOfType = true;
             return NS_OK;
         }
-        nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(shell);
-        nsCOMPtr<nsIDocShellTreeItem> parent;
-        item->GetParent(getter_AddRefs(parent));
-        shell = do_QueryInterface(parent);
+        shell = shell->GetParentDocshell();
     }
 
     *aIsOfType = false;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetIsContent(bool *aIsContent)
@@ -13071,29 +13059,24 @@ nsDocShell::GetAsyncPanZoomEnabled(bool*
     }
     *aOut = false;
     return NS_OK;
 }
 
 bool
 nsDocShell::HasUnloadedParent()
 {
-    nsCOMPtr<nsIDocShellTreeItem> currentTreeItem = this;
-    while (currentTreeItem) {
-        nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-        currentTreeItem->GetParent(getter_AddRefs(parentTreeItem));
-        nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentTreeItem);
-        if (parent) {
-            bool inUnload = false;
-            parent->GetIsInUnload(&inUnload);
-            if (inUnload) {
-                return true;
-            }
-        }
-        currentTreeItem.swap(parentTreeItem);
+    nsRefPtr<nsDocShell> parent = GetParentDocshell();
+    while (parent) {
+        bool inUnload = false;
+        parent->GetIsInUnload(&inUnload);
+        if (inUnload) {
+            return true;
+        }
+        parent = parent->GetParentDocshell();
     }
     return false;
 }
 
 bool
 nsDocShell::IsInvisible()
 {
     return mInvisible;
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -6,16 +6,17 @@
 
 #ifndef nsPluginArray_h___
 #define nsPluginArray_h___
 
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "nsWrapperCache.h"
+#include "nsMimeTypeArray.h"
 #include "nsPluginTags.h"
 #include "nsPIDOMWindow.h"
 
 class nsPluginElement;
 class nsMimeType;
 
 class nsPluginArray MOZ_FINAL : public nsIObserver,
                                 public nsSupportsWeakReference,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -61,16 +61,17 @@ namespace dom {
 struct FontListEntry {
     nsString  familyName;
     nsString  faceName;
     nsCString filepath;
     uint16_t  weight;
     int16_t   stretch;
     uint8_t   italic;
     uint8_t   index;
+    bool      isHidden;
 };
 
 struct DeviceStorageFreeSpaceParams
 {
   nsString type;
   nsString storageName;
 };
 
--- a/dom/network/tests/mochitest.ini
+++ b/dom/network/tests/mochitest.ini
@@ -2,17 +2,17 @@
 skip-if = toolkit == "gonk" || toolkit == 'android'
 [test_tcpsocket_default_permissions.html]
 skip-if = toolkit == "gonk"
 [test_tcpsocket_enabled_no_perm.html]
 skip-if = toolkit == "gonk"
 [test_tcpsocket_enabled_with_perm.html]
 skip-if = toolkit == "gonk" || e10s
 [test_networkstats_alarms.html]
-skip-if = toolkit != "gonk" || true # Intermittent failures (bug 1023341)
+skip-if = toolkit != "gonk"
 [test_networkstats_basics.html]
 skip-if = toolkit != "gonk" || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(Will be fixed in bug 858005) b2g-desktop(Will be fixed in bug 858005)
 [test_networkstats_disabled.html]
 skip-if = toolkit != "gonk"
 [test_networkstats_enabled_no_perm.html]
 skip-if = toolkit != "gonk"
 [test_networkstats_enabled_perm.html]
 skip-if = toolkit != "gonk"
--- a/dom/network/tests/test_networkstats_alarms.html
+++ b/dom/network/tests/test_networkstats_alarms.html
@@ -87,17 +87,17 @@ var steps = [
       ok(req.error.name == "InvalidThresholdValue", "Get InvalidThresholdValue error");
       next();
     }
   },
   function () {
     ok(true, "Calling addAlarm()");
 
     req = navigator.mozNetworkStats
-                   .addAlarm(new window.MozNetworkStatsInterface(wifi), 1000000);
+                   .addAlarm(new window.MozNetworkStatsInterface(wifi), 100000000);
 
     req.onsuccess = function () {
       ok(true, "Succeeded to add alarm. AlarmId: " + req.result);
       next();
     };
     req.onerror = function () {
       ok(false, "addAlarm() shouldn't fail.");
     };
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -241,17 +241,17 @@ GLContextEGL::GLContextEGL(
 #ifdef DEBUG
     printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
 #endif
 #if defined(MOZ_WIDGET_GONK)
     if (!mIsOffscreen) {
         mHwc = HwcComposer2D::GetInstance();
         MOZ_ASSERT(!mHwc->Initialized());
 
-        if (mHwc->Init(EGL_DISPLAY(), mSurface)) {
+        if (mHwc->Init(EGL_DISPLAY(), mSurface, this)) {
             NS_WARNING("HWComposer initialization failed!");
             mHwc = nullptr;
         }
     }
 #endif
 }
 
 GLContextEGL::~GLContextEGL()
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/Base64.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "gfxAndroidPlatform.h"
 #include "mozilla/Omnijar.h"
 #include "nsAutoPtr.h"
 #include "nsIInputStream.h"
 #include "nsNetUtil.h"
@@ -38,16 +39,18 @@
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIMemory.h"
 #include "gfxFontConstants.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/scache/StartupCache.h"
+#include <fcntl.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 
 using namespace mozilla;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *
 GetFontInfoLog()
 {
@@ -577,30 +580,32 @@ FT2FontEntry::AddSizeOfIncludingThis(Mal
 
 /*
  * FT2FontFamily
  * A standard gfxFontFamily; just adds a method used to support sending
  * the font list from chrome to content via IPC.
  */
 
 void
-FT2FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList)
+FT2FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList,
+                                  Visibility aVisibility)
 {
     for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) {
         const FT2FontEntry *fe =
             static_cast<const FT2FontEntry*>(mAvailableFonts[i].get());
         if (!fe) {
             continue;
         }
         
         aFontList->AppendElement(FontListEntry(Name(), fe->Name(),
                                                fe->mFilename,
                                                fe->Weight(), fe->Stretch(),
                                                fe->IsItalic(),
-                                               fe->mFTFontIndex));
+                                               fe->mFTFontIndex,
+                                               aVisibility == kHidden));
     }
 }
 
 /*
  * Startup cache support for the font list:
  * We store the list of families and faces, with their style attributes and the
  * corresponding font files, in the startup cache.
  * This allows us to recreate the gfxFT2FontList collection of families and
@@ -822,19 +827,21 @@ private:
 // For Mobile, we use gfxFT2Fonts, and we build the font list by directly
 // scanning the system's Fonts directory for OpenType and TrueType files.
 
 gfxFT2FontList::gfxFT2FontList()
 {
 }
 
 void
-gfxFT2FontList::AppendFacesFromCachedFaceList(const nsCString& aFileName,
-                                              bool aStdFile,
-                                              const nsCString& aFaceList)
+gfxFT2FontList::AppendFacesFromCachedFaceList(
+    const nsCString& aFileName,
+    const nsCString& aFaceList,
+    StandardFile aStdFile,
+    FT2FontFamily::Visibility aVisibility)
 {
     const char *beginning = aFaceList.get();
     const char *end = strchr(beginning, ',');
     while (end) {
         nsString familyName =
             NS_ConvertUTF8toUTF16(beginning, end - beginning);
         ToLowerCase(familyName);
         beginning = end + 1;
@@ -860,17 +867,18 @@ gfxFT2FontList::AppendFacesFromCachedFac
         uint32_t weight = strtoul(beginning, nullptr, 10);
         beginning = end + 1;
         if (!(end = strchr(beginning, ','))) {
             break;
         }
         int32_t stretch = strtol(beginning, nullptr, 10);
 
         FontListEntry fle(familyName, faceName, aFileName,
-                          weight, stretch, italic, index);
+                          weight, stretch, italic, index,
+                          aVisibility == FT2FontFamily::kHidden);
         AppendFaceFromFontListEntry(fle, aStdFile);
 
         beginning = end + 1;
         end = strchr(beginning, ',');
     }
 }
 
 static void
@@ -918,48 +926,50 @@ FT2FontEntry::CheckForBrokenFont(gfxFont
                 mIgnoreGSUB = true;
             }
         }
     }
 }
 
 void
 gfxFT2FontList::AppendFacesFromFontFile(const nsCString& aFileName,
-                                        bool aStdFile,
-                                        FontNameCache *aCache)
+                                        FontNameCache *aCache,
+                                        StandardFile aStdFile,
+                                        FT2FontFamily::Visibility aVisibility)
 {
     nsCString faceList;
     uint32_t filesize = 0, timestamp = 0;
     if (aCache) {
         aCache->GetInfoForFile(aFileName, faceList, &timestamp, &filesize);
     }
 
     struct stat s;
     int statRetval = stat(aFileName.get(), &s);
     if (!faceList.IsEmpty() && 0 == statRetval &&
         s.st_mtime == timestamp && s.st_size == filesize)
     {
         LOG(("using cached font info for %s", aFileName.get()));
-        AppendFacesFromCachedFaceList(aFileName, aStdFile, faceList);
+        AppendFacesFromCachedFaceList(aFileName, faceList, aStdFile,
+                                      aVisibility);
         return;
     }
 
     FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary();
     FT_Face dummy;
     if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName.get(), -1, &dummy)) {
         LOG(("reading font info via FreeType for %s", aFileName.get()));
         nsCString faceList;
         timestamp = s.st_mtime;
         filesize = s.st_size;
         for (FT_Long i = 0; i < dummy->num_faces; i++) {
             FT_Face face;
             if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName.get(), i, &face)) {
                 continue;
             }
-            AddFaceToList(aFileName, i, aStdFile, face, faceList);
+            AddFaceToList(aFileName, i, aStdFile, aVisibility, face, faceList);
             FT_Done_Face(face);
         }
         FT_Done_Face(dummy);
         if (aCache && 0 == statRetval && !faceList.IsEmpty()) {
             aCache->CacheFileInfo(aFileName, faceList, timestamp, filesize);
         }
     }
 }
@@ -1012,44 +1022,50 @@ gfxFT2FontList::FindFontsInOmnijar(FontN
                          sizeof(jarModifiedTime));
     }
 }
 
 // Given the freetype face corresponding to an entryName and face index,
 // add the face to the available font list and to the faceList string
 void
 gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
-                              bool aStdFile, FT_Face aFace,
+                              StandardFile aStdFile,
+                              FT2FontFamily::Visibility aVisibility,
+                              FT_Face aFace,
                               nsCString& aFaceList)
 {
     if (FT_Err_Ok != FT_Select_Charmap(aFace, FT_ENCODING_UNICODE)) {
         // ignore faces that don't support a Unicode charmap
         return;
     }
 
     // build the font entry name and create an FT2FontEntry,
     // but do -not- keep a reference to the FT_Face
     FT2FontEntry* fe =
         CreateNamedFontEntry(aFace, aEntryName.get(), aIndex);
 
+    auto& fontFamilies =
+        (aVisibility == FT2FontFamily::kHidden) ? mHiddenFontFamilies :
+                                                  mFontFamilies;
+
     if (fe) {
         NS_ConvertUTF8toUTF16 name(aFace->family_name);
         BuildKeyNameFromFontName(name);
-        gfxFontFamily *family = mFontFamilies.GetWeak(name);
+        gfxFontFamily *family = fontFamilies.GetWeak(name);
         if (!family) {
             family = new FT2FontFamily(name);
-            mFontFamilies.Put(name, family);
+            fontFamilies.Put(name, family);
             if (mSkipSpaceLookupCheckFamilies.Contains(name)) {
                 family->SetSkipSpaceFeatureCheck(true);
             }
             if (mBadUnderlineFamilyNames.Contains(name)) {
                 family->SetBadUnderlineFamily();
             }
         }
-        fe->mStandardFace = aStdFile;
+        fe->mStandardFace = (aStdFile == kStandard);
         family->AddFontEntry(fe);
 
         fe->CheckForBrokenFont(family);
 
         AppendToFaceList(aFaceList, name, fe);
 #ifdef PR_LOGGING
         if (LOG_ENABLED()) {
             LOG(("(fontinit) added (%s) to family (%s)"
@@ -1069,17 +1085,17 @@ gfxFT2FontList::AppendFacesFromOmnijarEn
                                             FontNameCache *aCache,
                                             bool aJarChanged)
 {
     nsCString faceList;
     if (aCache && !aJarChanged) {
         uint32_t filesize, timestamp;
         aCache->GetInfoForFile(aEntryName, faceList, &timestamp, &filesize);
         if (faceList.Length() > 0) {
-            AppendFacesFromCachedFaceList(aEntryName, true, faceList);
+            AppendFacesFromCachedFaceList(aEntryName, faceList);
             return;
         }
     }
 
     nsZipItem *item = aArchive->GetItem(aEntryName.get());
     NS_ASSERTION(item, "failed to find zip entry");
 
     uint32_t bufSize = item->RealSize();
@@ -1106,17 +1122,18 @@ gfxFT2FontList::AppendFacesFromOmnijarEn
         return;
     }
 
     for (FT_Long i = 0; i < dummy->num_faces; i++) {
         FT_Face face;
         if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf, bufSize, i, &face)) {
             continue;
         }
-        AddFaceToList(aEntryName, i, true, face, faceList);
+        AddFaceToList(aEntryName, i, kStandard, FT2FontFamily::kVisible,
+                      face, faceList);
         FT_Done_Face(face);
     }
 
     FT_Done_Face(dummy);
 
     if (aCache && !faceList.IsEmpty()) {
         aCache->CacheFileInfo(aEntryName, faceList, 0, bufSize);
     }
@@ -1155,24 +1172,29 @@ gfxFT2FontList::FindFonts()
     mCodepointsWithNoFonts.SetRange(0,0x1f);     // C0 controls
     mCodepointsWithNoFonts.SetRange(0x7f,0x9f);  // C1 controls
 
     if (XRE_GetProcessType() != GeckoProcessType_Default) {
         // Content process: ask the Chrome process to give us the list
         InfallibleTArray<FontListEntry> fonts;
         mozilla::dom::ContentChild::GetSingleton()->SendReadFontList(&fonts);
         for (uint32_t i = 0, n = fonts.Length(); i < n; ++i) {
-            AppendFaceFromFontListEntry(fonts[i], false);
+            // We don't need to identify "standard" font files here,
+            // as the faces are already sorted.
+            AppendFaceFromFontListEntry(fonts[i], kUnknown);
         }
         // Passing null for userdata tells Finalize that it does not need
         // to sort faces (because they were already sorted by chrome,
         // so we just maintain the existing order)
         mFontFamilies.Enumerate(FinalizeFamilyMemberList, nullptr);
-        LOG(("got font list from chrome process: %d faces in %d families",
-            fonts.Length(), mFontFamilies.Count()));
+        mHiddenFontFamilies.Enumerate(FinalizeFamilyMemberList, nullptr);
+        LOG(("got font list from chrome process: %d faces in %d families "
+             "and %d in hidden families",
+            fonts.Length(), mFontFamilies.Count(),
+            mHiddenFontFamilies.Count()));
         return;
     }
 
     // Chrome process: get the cached list (if any)
     FontNameCache fnc;
 
     // ANDROID_ROOT is the root of the android system, typically /system;
     // font files are in /$ANDROID_ROOT/fonts/
@@ -1180,23 +1202,30 @@ gfxFT2FontList::FindFonts()
     char *androidRoot = PR_GetEnv("ANDROID_ROOT");
     if (androidRoot) {
         root = androidRoot;
     } else {
         root = NS_LITERAL_CSTRING("/system");
     }
     root.AppendLiteral("/fonts");
 
-    FindFontsInDir(root, &fnc);
+    FindFontsInDir(root, &fnc, FT2FontFamily::kVisible);
 
     if (mFontFamilies.Count() == 0) {
         // if we can't find/read the font directory, we are doomed!
         NS_RUNTIMEABORT("Could not read the system fonts directory");
     }
 
+#ifdef MOZ_WIDGET_GONK
+    // Look for fonts in /system/fonts/hidden and preload them to the
+    // user-font cache as data: URIs
+    root.AppendLiteral("/hidden");
+    FindFontsInDir(root, &fnc, FT2FontFamily::kHidden);
+#endif
+
     // Look for fonts stored in omnijar, unless we're on a low-memory
     // device where we don't want to spend the RAM to decompress them.
     // (Prefs may disable this, or force-enable it even with low memory.)
     bool lowmem;
     nsCOMPtr<nsIMemory> mem = nsMemory::GetGlobalMemoryService();
     if ((NS_SUCCEEDED(mem->IsLowMemoryPlatform(&lowmem)) && !lowmem &&
          Preferences::GetBool("gfx.bundled_fonts.enabled")) ||
         Preferences::GetBool("gfx.bundled_fonts.force-enabled")) {
@@ -1207,28 +1236,31 @@ gfxFT2FontList::FindFonts()
     nsCOMPtr<nsIFile> localDir;
     nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
                                          getter_AddRefs(localDir));
     if (NS_SUCCEEDED(rv) &&
         NS_SUCCEEDED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
         nsCString localPath;
         rv = localDir->GetNativePath(localPath);
         if (NS_SUCCEEDED(rv)) {
-            FindFontsInDir(localPath, &fnc);
+            FindFontsInDir(localPath, &fnc, FT2FontFamily::kVisible);
         }
     }
 
     // Finalize the families by sorting faces into standard order
     // and marking "simple" families.
     // Passing non-null userData here says that we want faces to be sorted.
     mFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
+    mHiddenFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
 }
 
 void
-gfxFT2FontList::FindFontsInDir(const nsCString& aDir, FontNameCache *aFNC)
+gfxFT2FontList::FindFontsInDir(const nsCString& aDir,
+                               FontNameCache *aFNC,
+                               FT2FontFamily::Visibility aVisibility)
 {
     static const char* sStandardFonts[] = {
         "DroidSans.ttf",
         "DroidSans-Bold.ttf",
         "DroidSerif-Regular.ttf",
         "DroidSerif-Bold.ttf",
         "DroidSerif-Italic.ttf",
         "DroidSerif-BoldItalic.ttf",
@@ -1267,35 +1299,38 @@ gfxFT2FontList::FindFontsInDir(const nsC
             nsCString s(aDir);
             s.Append('/');
             s.Append(ent->d_name);
 
             // Add the face(s) from this file to our font list;
             // note that if we have cached info for this file in fnc,
             // and the file is unchanged, we won't actually need to read it.
             // If the file is new/changed, this will update the FontNameCache.
-            AppendFacesFromFontFile(s, isStdFont, aFNC);
+            AppendFacesFromFontFile(s, aFNC, isStdFont ? kStandard : kUnknown,
+                                    aVisibility);
         }
     }
 
     closedir(d);
 }
 
 void
 gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
-                                            bool aStdFile)
+                                            StandardFile aStdFile)
 {
     FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(aFLE);
     if (fe) {
-        fe->mStandardFace = aStdFile;
+        auto& fontFamilies =
+            aFLE.isHidden() ? mHiddenFontFamilies : mFontFamilies;
+        fe->mStandardFace = (aStdFile == kStandard);
         nsAutoString name(aFLE.familyName());
-        gfxFontFamily *family = mFontFamilies.GetWeak(name);
+        gfxFontFamily *family = fontFamilies.GetWeak(name);
         if (!family) {
             family = new FT2FontFamily(name);
-            mFontFamilies.Put(name, family);
+            fontFamilies.Put(name, family);
             if (mSkipSpaceLookupCheckFamilies.Contains(name)) {
                 family->SetSkipSpaceFeatureCheck(true);
             }
             if (mBadUnderlineFamilyNames.Contains(name)) {
                 family->SetBadUnderlineFamily();
             }
         }
         family->AddFontEntry(fe);
@@ -1308,51 +1343,143 @@ static PLDHashOperator
 AddFamilyToFontList(nsStringHashKey::KeyType aKey,
                     nsRefPtr<gfxFontFamily>& aFamily,
                     void* aUserArg)
 {
     InfallibleTArray<FontListEntry>* fontlist =
         reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
 
     FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
-    family->AddFacesToFontList(fontlist);
+    family->AddFacesToFontList(fontlist, FT2FontFamily::kVisible);
+
+    return PL_DHASH_NEXT;
+}
+
+static PLDHashOperator
+AddHiddenFamilyToFontList(nsStringHashKey::KeyType aKey,
+                          nsRefPtr<gfxFontFamily>& aFamily,
+                          void* aUserArg)
+{
+    InfallibleTArray<FontListEntry>* fontlist =
+        reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
+
+    FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
+    family->AddFacesToFontList(fontlist, FT2FontFamily::kHidden);
 
     return PL_DHASH_NEXT;
 }
 
 void
 gfxFT2FontList::GetFontList(InfallibleTArray<FontListEntry>* retValue)
 {
     mFontFamilies.Enumerate(AddFamilyToFontList, retValue);
+    mHiddenFontFamilies.Enumerate(AddHiddenFamilyToFontList, retValue);
 }
 
 static void
 LoadSkipSpaceLookupCheck(nsTHashtable<nsStringHashKey>& aSkipSpaceLookupCheck)
 {
     nsAutoTArray<nsString, 5> skiplist;
     gfxFontUtils::GetPrefsFontList(
         "font.whitelist.skip_default_features_space_check",
         skiplist);
     uint32_t numFonts = skiplist.Length();
     for (uint32_t i = 0; i < numFonts; i++) {
         ToLowerCase(skiplist[i]);
         aSkipSpaceLookupCheck.PutEntry(skiplist[i]);
     }
 }
 
+static PLDHashOperator
+PreloadAsUserFontFaces(nsStringHashKey::KeyType aKey,
+                       nsRefPtr<gfxFontFamily>& aFamily,
+                       void* aUserArg)
+{
+    gfxFontFamily *family = aFamily.get();
+
+    auto& faces = family->GetFontList();
+    size_t count = faces.Length();
+    for (size_t i = 0; i < count; ++i) {
+        FT2FontEntry* fe = static_cast<FT2FontEntry*>(faces[i].get());
+        if (fe->mFTFontIndex != 0) {
+            NS_NOTREACHED("don't try to preload a multi-face font");
+            continue;
+        }
+
+        // XXX Should we move the i/o here off the main thread?
+
+        // Map the font data in fe->mFilename, so we can generate a data: URI.
+        int fd = open(fe->mFilename.get(), O_RDONLY);
+        if (fd < 0) {
+            continue;
+        }
+        struct stat buf;
+        if (fstat(fd, &buf) != 0 || buf.st_size < 12) {
+            close(fd);
+            continue;
+        }
+        char* data = static_cast<char*>(
+            mmap(0, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
+        close(fd);
+        if (data == MAP_FAILED) {
+            continue;
+        }
+
+        // First byte is sufficient to distinguish WOFF from uncompressed
+        // OpenType (either TrueType or CFF).
+        bool isWoff = (data[0] == 'w');
+
+        // Generate a corresponding data: URI that apps could use.
+        nsCString encodedData;
+        nsresult rv = Base64Encode(Substring(data, buf.st_size), encodedData);
+        munmap(data, buf.st_size);
+        if (NS_FAILED(rv)) {
+            continue;
+        }
+        nsCString spec("data:font/");
+        spec.Append(isWoff ? "woff" : "opentype");
+        spec.Append(";base64,");
+        spec.Append(encodedData);
+#if 0
+        ALOG("\n**** Preloading family [%s] face [%s]:\n%s\n\n",
+             NS_ConvertUTF16toUTF8(family->Name()).get(),
+             fe->mFilename.get(),
+             spec.get());
+#endif
+
+        // Record the URI in gfxUserFontData on the entry.
+        nsCOMPtr<nsIURI> uri;
+        if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), spec))) {
+            continue;
+        }
+        fe->mUserFontData = new gfxUserFontData;
+        fe->mUserFontData->mURI = uri;
+        fe->mUserFontData->mRealName = fe->Name();
+
+        // Stash it persistently in the user-font cache.
+        gfxUserFontSet::UserFontCache::CacheFont(
+            fe, gfxUserFontSet::UserFontCache::kPersistent);
+    }
+
+    return PL_DHASH_NEXT;
+}
+
 nsresult
 gfxFT2FontList::InitFontList()
 {
     // reset font lists
     gfxPlatformFontList::InitFontList();
+    mHiddenFontFamilies.Clear();
     
     LoadSkipSpaceLookupCheck(mSkipSpaceLookupCheckFamilies);
 
     FindFonts();
 
+    mHiddenFontFamilies.Enumerate(PreloadAsUserFontFaces, this);
+
     return NS_OK;
 }
 
 struct FullFontNameSearch {
     FullFontNameSearch(const nsAString& aFullName)
         : mFullName(aFullName), mFontEntry(nullptr)
     { }
 
@@ -1397,16 +1524,18 @@ FindFullName(nsStringHashKey::KeyType aK
 
 gfxFontEntry* 
 gfxFT2FontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
                                 const nsAString& aFontName)
 {
     // walk over list of names
     FullFontNameSearch data(aFontName);
 
+    // Note that we only check mFontFamilies here, not mHiddenFontFamilies;
+    // hence @font-face { src:local(...) } will not find hidden fonts.
     mFontFamilies.Enumerate(FindFullName, &data);
 
     if (!data.mFontEntry) {
         return nullptr;
     }
 
     // Clone the font entry so that we can then set its style descriptors
     // from the proxy rather than the actual font.
@@ -1454,8 +1583,26 @@ gfxFT2FontList::MakePlatformFont(const g
                                  uint32_t aLength)
 {
     // The FT2 font needs the font data to persist, so we do NOT free it here
     // but instead pass ownership to the font entry.
     // Deallocation will happen later, when the font face is destroyed.
     return FT2FontEntry::CreateFontEntry(*aProxyEntry, aFontData, aLength);
 }
 
+static PLDHashOperator
+AppendFamily(nsStringHashKey::KeyType aKey,
+             nsRefPtr<gfxFontFamily>& aFamily,
+             void* aUserArg)
+{
+    nsTArray<nsRefPtr<gfxFontFamily> > * familyArray =
+        reinterpret_cast<nsTArray<nsRefPtr<gfxFontFamily>>*>(aUserArg);
+
+    familyArray->AppendElement(aFamily);
+    return PL_DHASH_NEXT;
+}
+
+void
+gfxFT2FontList::GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray)
+{
+    mFontFamilies.Enumerate(AppendFamily, &aFamilyArray);
+    mHiddenFontFamilies.Enumerate(AppendFamily, &aFamilyArray);
+}
--- a/gfx/thebes/gfxFT2FontList.h
+++ b/gfx/thebes/gfxFT2FontList.h
@@ -90,21 +90,30 @@ public:
 
     nsCString mFilename;
     uint8_t   mFTFontIndex;
 };
 
 class FT2FontFamily : public gfxFontFamily
 {
 public:
+    // Flags to indicate whether a font should be "visible" in the global
+    // font list (available for use in font-family), or "hidden" (available
+    // only to support a matching data: URI used in @font-face).
+    typedef enum {
+        kVisible,
+        kHidden
+    } Visibility;
+
     FT2FontFamily(const nsAString& aName) :
         gfxFontFamily(aName) { }
 
     // Append this family's faces to the IPC fontlist
-    void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList);
+    void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList,
+                            Visibility aVisibility);
 };
 
 class gfxFT2FontList : public gfxPlatformFontList
 {
 public:
     gfxFT2FontList();
 
     virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
@@ -117,40 +126,57 @@ public:
                                            uint32_t aLength);
 
     void GetFontList(InfallibleTArray<FontListEntry>* retValue);
 
     static gfxFT2FontList* PlatformFontList() {
         return static_cast<gfxFT2FontList*>(gfxPlatformFontList::PlatformFontList());
     }
 
+    virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
+
 protected:
+    typedef enum {
+        kUnknown,
+        kStandard
+    } StandardFile;
+
     virtual nsresult InitFontList();
 
     void AppendFaceFromFontListEntry(const FontListEntry& aFLE,
-                                     bool isStdFile);
+                                     StandardFile aStdFile);
 
     void AppendFacesFromFontFile(const nsCString& aFileName,
-                                 bool isStdFile = false,
-                                 FontNameCache *aCache = nullptr);
+                                 FontNameCache *aCache,
+                                 StandardFile aStdFile,
+                                 FT2FontFamily::Visibility aVisibility);
 
     void AppendFacesFromOmnijarEntry(nsZipArchive *aReader,
                                      const nsCString& aEntryName,
                                      FontNameCache *aCache,
                                      bool aJarChanged);
 
+    // the defaults here are suitable for reading bundled fonts from omnijar
     void AppendFacesFromCachedFaceList(const nsCString& aFileName,
-                                       bool isStdFile,
-                                       const nsCString& aFaceList);
+                                       const nsCString& aFaceList,
+                                       StandardFile aStdFile = kStandard,
+                                       FT2FontFamily::Visibility aVisibility =
+                                           FT2FontFamily::kVisible);
 
     void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
-                       bool aStdFile, FT_Face aFace, nsCString& aFaceList);
+                       StandardFile aStdFile,
+                       FT2FontFamily::Visibility aVisibility,
+                       FT_Face aFace, nsCString& aFaceList);
 
     void FindFonts();
 
     void FindFontsInOmnijar(FontNameCache *aCache);
 
-    void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC);
+    void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC,
+                        FT2FontFamily::Visibility aVisibility);
 
     nsTHashtable<nsStringHashKey> mSkipSpaceLookupCheckFamilies;
+
+private:
+    nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mHiddenFontFamilies;
 };
 
 #endif /* GFX_FT2FONTLIST_H */
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -824,16 +824,24 @@ gfxUserFontSet::FindFamilyFor(gfxFontEnt
 ///////////////////////////////////////////////////////////////////////////////
 
 nsTHashtable<gfxUserFontSet::UserFontCache::Entry>*
     gfxUserFontSet::UserFontCache::sUserFonts = nullptr;
 
 NS_IMPL_ISUPPORTS(gfxUserFontSet::UserFontCache::Flusher, nsIObserver)
 
 PLDHashOperator
+gfxUserFontSet::UserFontCache::Entry::RemoveUnlessPersistent(Entry* aEntry,
+                                                             void* aUserData)
+{
+    return aEntry->mPersistence == kPersistent ? PL_DHASH_NEXT :
+                                                 PL_DHASH_REMOVE;
+}
+
+PLDHashOperator
 gfxUserFontSet::UserFontCache::Entry::RemoveIfPrivate(Entry* aEntry,
                                                       void* aUserData)
 {
     return aEntry->mPrivate ? PL_DHASH_REMOVE : PL_DHASH_NEXT;
 }
 
 PLDHashOperator
 gfxUserFontSet::UserFontCache::Entry::RemoveIfMatches(Entry* aEntry,
@@ -856,17 +864,17 @@ gfxUserFontSet::UserFontCache::Flusher::
                                                 const char* aTopic,
                                                 const char16_t* aData)
 {
     if (!sUserFonts) {
         return NS_OK;
     }
 
     if (!strcmp(aTopic, "cacheservice:empty-cache")) {
-        sUserFonts->Clear();
+        sUserFonts->EnumerateEntries(Entry::RemoveUnlessPersistent, nullptr);
     } else if (!strcmp(aTopic, "last-pb-context-exited")) {
         sUserFonts->EnumerateEntries(Entry::RemoveIfPrivate, nullptr);
     } else if (!strcmp(aTopic, "xpcom-shutdown")) {
         sUserFonts->EnumerateEntries(Entry::DisconnectSVG, nullptr);
     } else {
         NS_NOTREACHED("unexpected topic");
     }
 
@@ -914,17 +922,18 @@ gfxUserFontSet::UserFontCache::Entry::Ke
         mFontEntry->mFamilyName       != fe->mFamilyName) {
         return false;
     }
 
     return true;
 }
 
 void
-gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry)
+gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
+                                         EntryPersistence aPersistence)
 {
     NS_ASSERTION(aFontEntry->mFamilyName.Length() != 0,
                  "caching a font associated with no family yet");
     if (!sUserFonts) {
         sUserFonts = new nsTHashtable<Entry>;
 
         nsCOMPtr<nsIObserverService> obs =
             mozilla::services::GetObserverService();
@@ -943,17 +952,17 @@ gfxUserFontSet::UserFontCache::CacheFont
     // Otherwise, the principal is used as part of the cache key.
     nsIPrincipal *principal;
     if (IgnorePrincipal(data->mURI)) {
         principal = nullptr;
     } else {
         principal = data->mPrincipal;
     }
     sUserFonts->PutEntry(Key(data->mURI, principal, aFontEntry,
-                             data->mPrivate));
+                             data->mPrivate, aPersistence));
 
 #ifdef DEBUG_USERFONT_CACHE
     printf("userfontcache added fontentry: %p\n", aFontEntry);
     Dump();
 #endif
 }
 
 void
--- a/gfx/thebes/gfxUserFontSet.h
+++ b/gfx/thebes/gfxUserFontSet.h
@@ -56,17 +56,17 @@ operator==(const gfxFontFaceSrc& a, cons
 // deleted.
 // Lifetime: from when platform font is created until it is deactivated.
 // If the platform does not need to add any platform-specific code/data here,
 // then the gfxUserFontSet will allocate a base gfxUserFontData and attach
 // to the entry to track the basic user font info fields here.
 class gfxUserFontData {
 public:
     gfxUserFontData()
-        : mSrcIndex(0), mFormat(0), mMetaOrigLen(0)
+        : mSrcIndex(0), mFormat(0), mMetaOrigLen(0), mPrivate(false)
     { }
     virtual ~gfxUserFontData() { }
 
     nsTArray<uint8_t> mMetadata;  // woff metadata block (compressed), if any
     nsCOMPtr<nsIURI>  mURI;       // URI of the source, if it was url()
     nsCOMPtr<nsIPrincipal> mPrincipal; // principal for the download, if url()
     nsString          mLocalName; // font name used for the source, if local()
     nsString          mRealName;  // original fullname from the font resource
@@ -243,20 +243,31 @@ public:
     // increment the generation on font load
     void IncrementGeneration();
 
     // rebuild if local rules have been used
     void RebuildLocalRules();
 
     class UserFontCache {
     public:
+        // Flag passed when caching a font entry, to specify whether the entry
+        // should persist in the cache or be discardable.
+        typedef enum {
+            kDiscardable,
+            kPersistent
+        } EntryPersistence;
+
         // Record a loaded user-font in the cache. This requires that the
         // font-entry's userFontData has been set up already, as it relies
         // on the URI and Principal recorded there.
-        static void CacheFont(gfxFontEntry *aFontEntry);
+        // If aPersistence is Persistent, the entry will remain in the cache
+        // across cacheservice:empty-cache notifications. This is used for
+        // "preloaded hidden fonts" on FxOS.
+        static void CacheFont(gfxFontEntry *aFontEntry,
+                              EntryPersistence aPersistence = kDiscardable);
 
         // The given gfxFontEntry is being destroyed, so remove any record that
         // refers to it.
         static void ForgetFont(gfxFontEntry *aFontEntry);
 
         // Return the gfxFontEntry corresponding to a given URI and principal,
         // and the features of the given proxy, or nullptr if none is available.
         // The aPrivate flag is set for requests coming from private windows,
@@ -293,43 +304,48 @@ public:
         // (weight/width/style/features) that could affect font selection
         // or rendering, and that must match between a font-set's proxy
         // entry and the corresponding "real" font entry.
         struct Key {
             nsCOMPtr<nsIURI>        mURI;
             nsCOMPtr<nsIPrincipal>  mPrincipal; // use nullptr with data: URLs
             gfxFontEntry           *mFontEntry;
             bool                    mPrivate;
+            EntryPersistence        mPersistence;
 
             Key(nsIURI* aURI, nsIPrincipal* aPrincipal,
-                gfxFontEntry* aFontEntry, bool aPrivate)
+                gfxFontEntry* aFontEntry, bool aPrivate,
+                EntryPersistence aPersistence = kDiscardable)
                 : mURI(aURI),
                   mPrincipal(aPrincipal),
                   mFontEntry(aFontEntry),
-                  mPrivate(aPrivate)
+                  mPrivate(aPrivate),
+                  mPersistence(aPersistence)
             { }
         };
 
         class Entry : public PLDHashEntryHdr {
         public:
             typedef const Key& KeyType;
             typedef const Key* KeyTypePointer;
 
             Entry(KeyTypePointer aKey)
                 : mURI(aKey->mURI),
                   mPrincipal(aKey->mPrincipal),
                   mFontEntry(aKey->mFontEntry),
-                  mPrivate(aKey->mPrivate)
+                  mPrivate(aKey->mPrivate),
+                  mPersistence(aKey->mPersistence)
             { }
 
             Entry(const Entry& aOther)
                 : mURI(aOther.mURI),
                   mPrincipal(aOther.mPrincipal),
                   mFontEntry(aOther.mFontEntry),
-                  mPrivate(aOther.mPrivate)
+                  mPrivate(aOther.mPrivate),
+                  mPersistence(aOther.mPersistence)
             { }
 
             ~Entry() { }
 
             bool KeyEquals(const KeyTypePointer aKey) const;
 
             static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
 
@@ -347,19 +363,24 @@ public:
                                              (aKey->mFontEntry->mStretch << 10) ) ^
                                              aKey->mFontEntry->mLanguageOverride);
             }
 
             enum { ALLOW_MEMMOVE = false };
 
             gfxFontEntry* GetFontEntry() const { return mFontEntry; }
 
-            static PLDHashOperator RemoveIfPrivate(Entry* aEntry, void* aUserData);
-            static PLDHashOperator RemoveIfMatches(Entry* aEntry, void* aUserData);
-            static PLDHashOperator DisconnectSVG(Entry* aEntry, void* aUserData);
+            static PLDHashOperator
+            RemoveUnlessPersistent(Entry* aEntry, void* aUserData);
+            static PLDHashOperator
+            RemoveIfPrivate(Entry* aEntry, void* aUserData);
+            static PLDHashOperator
+            RemoveIfMatches(Entry* aEntry, void* aUserData);
+            static PLDHashOperator
+            DisconnectSVG(Entry* aEntry, void* aUserData);
 
 #ifdef DEBUG_USERFONT_CACHE
             static PLDHashOperator DumpEntry(Entry* aEntry, void* aUserData);
 #endif
 
         private:
             static uint32_t
             HashFeatures(const nsTArray<gfxFontFeature>& aFeatures) {
@@ -372,16 +393,19 @@ public:
 
             // The "real" font entry corresponding to this downloaded font.
             // The font entry MUST notify the cache when it is destroyed
             // (by calling Forget()).
             gfxFontEntry          *mFontEntry;
 
             // Whether this font was loaded from a private window.
             bool                   mPrivate;
+
+            // Whether this entry should survive cache-flushing.
+            EntryPersistence       mPersistence;
         };
 
         static nsTHashtable<Entry> *sUserFonts;
     };
 
 protected:
     // Protected destructor, to discourage deletion outside of Release():
     virtual ~gfxUserFontSet();
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -18,24 +18,24 @@
  * https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
  */
 
 #define FLOAT32X4_NULLARY_FUNCTION_LIST(V)                                                                        \
   V(zero, (FuncZero<Float32x4>), 0, 0, Zero)
 
 #define FLOAT32X4_UNARY_FUNCTION_LIST(V)                                                                          \
   V(abs, (Func<Float32x4, Abs<float, Float32x4>, Float32x4>), 1, 0, Abs)                                          \
-  V(bitsToInt32x4, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, BitsToInt32x4)                                    \
+  V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, FromInt32x4Bits)                                \
   V(neg, (Func<Float32x4, Neg<float, Float32x4>, Float32x4>), 1, 0, Neg)                                          \
   V(not, (CoercedFunc<Float32x4, Int32x4, Not<int32_t, Int32x4>, Float32x4>), 1, 0, Not)                          \
   V(reciprocal, (Func<Float32x4, Rec<float, Float32x4>, Float32x4>), 1, 0, Reciprocal)                            \
   V(reciprocalSqrt, (Func<Float32x4, RecSqrt<float, Float32x4>, Float32x4>), 1, 0, ReciprocalSqrt)                \
   V(splat, (FuncSplat<Float32x4>), 1, 0, Splat)                                                                   \
   V(sqrt, (Func<Float32x4, Sqrt<float, Float32x4>, Float32x4>), 1, 0, Sqrt)                                       \
-  V(toInt32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0, ToInt32x4)
+  V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1, 0, FromInt32x4)
 
 #define FLOAT32X4_BINARY_FUNCTION_LIST(V)                                                                         \
   V(add, (Func<Float32x4, Add<float, Float32x4>, Float32x4>), 2, 0, Add)                                          \
   V(and, (CoercedFunc<Float32x4, Int32x4, And<int32_t, Int32x4>, Float32x4>), 2, 0, And)                          \
   V(div, (Func<Float32x4, Div<float, Float32x4>, Float32x4>), 2, 0, Div)                                          \
   V(equal, (Func<Float32x4, Equal<float, Int32x4>, Int32x4>), 2, 0, Equal)                                        \
   V(greaterThan, (Func<Float32x4, GreaterThan<float, Int32x4>, Int32x4>), 2, 0, GreaterThan)                      \
   V(greaterThanOrEqual, (Func<Float32x4, GreaterThanOrEqual<float, Int32x4>, Int32x4>), 2, 0, GreaterThanOrEqual) \
@@ -64,21 +64,21 @@
   FLOAT32X4_UNARY_FUNCTION_LIST(V)                                                                                \
   FLOAT32X4_BINARY_FUNCTION_LIST(V)                                                                               \
   FLOAT32X4_TERNARY_FUNCTION_LIST(V)
 
 #define INT32X4_NULLARY_FUNCTION_LIST(V)                                                                          \
   V(zero, (FuncZero<Int32x4>), 0, 0, Zero)
 
 #define INT32X4_UNARY_FUNCTION_LIST(V)                                                                            \
-  V(bitsToFloat32x4, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, BitsToFloat32x4)                                \
+  V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, FromFloat32x4Bits)                            \
   V(neg, (Func<Int32x4, Neg<int32_t, Int32x4>, Int32x4>), 1, 0, Neg)                                              \
   V(not, (Func<Int32x4, Not<int32_t, Int32x4>, Int32x4>), 1, 0, Not)                                              \
   V(splat, (FuncSplat<Int32x4>), 0, 0, Splat)                                                                     \
-  V(toFloat32x4, (FuncConvert<Int32x4, Float32x4>), 1, 0, ToFloat32x4)
+  V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0, FromFloat32x4)
 
 #define INT32X4_BINARY_FUNCTION_LIST(V)                                                                           \
   V(add, (Func<Int32x4, Add<int32_t, Int32x4>, Int32x4>), 2, 0, Add)                                              \
   V(and, (Func<Int32x4, And<int32_t, Int32x4>, Int32x4>), 2, 0, And)                                              \
   V(equal, (Func<Int32x4, Equal<int32_t, Int32x4>, Int32x4>), 2, 0, Equal)                                        \
   V(greaterThan, (Func<Int32x4, GreaterThan<int32_t, Int32x4>, Int32x4>), 2, 0, GreaterThan)                      \
   V(lessThan, (Func<Int32x4, LessThan<int32_t, Int32x4>, Int32x4>), 2, 0, LessThan)                               \
   V(mul, (Func<Int32x4, Mul<int32_t, Int32x4>, Int32x4>), 2, 0, Mul)                                              \
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -138,32 +138,16 @@ function ToNumber(v) {
 
 
 /* Spec: ECMAScript Language Specification, 5.1 edition, 9.10 */
 function CheckObjectCoercible(v) {
     if (v === undefined || v === null)
         ThrowError(JSMSG_CANT_CONVERT_TO, ToString(v), "object");
 }
 
-
-/********** Various utility functions **********/
-
-
-/** Returns true iff Type(v) is Object; see ES5 8.6. */
-function IsObject(v) {
-    // Watch out for |typeof null === "object"| as the most obvious pitfall.
-    // But also be careful of SpiderMonkey's objects that emulate undefined
-    // (i.e. |document.all|), which have bogus |typeof| behavior.  Detect
-    // these objects using strict equality, which said bogosity doesn't affect.
-    return (typeof v === "object" && v !== null) ||
-           typeof v === "function" ||
-           (typeof v === "undefined" && v !== undefined);
-}
-
-
 /********** Testing code **********/
 
 #ifdef ENABLE_PARALLEL_JS
 
 /**
  * Internal debugging tool: checks that the given `mode` permits
  * sequential execution
  */
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1027510.js
@@ -0,0 +1,96 @@
+setJitCompilerOption("baseline.usecount.trigger", 10);
+setJitCompilerOption("ion.usecount.trigger", 20);
+
+function myCeil(x) {
+    if(x >= 0) {
+        var r = Math.abs(x % 1);
+        if(r != 0)
+            return (x + 1) - r;
+        else
+            return x;
+    }
+    else
+        return x + Math.abs(x % 1);
+}
+
+function ceilRangeTest(x) {
+    if(10 < x) {
+        if(x < 100) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if(-100 < x) {
+        if(x < -10) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (-(4294967296 - 1) < x) {
+        if(x < 10) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (-10 < x) {
+        if(x < 4294967296) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (-2147483648 < x) {
+        if(x < 10) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if ((-2147483648 -1) < x) {
+        if(x < 10) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (10 < x) {
+        if(x < 2147483648) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (10 < x) {
+        if(x < 2147483649) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+
+    if (Math.pow(2,31) < x) {
+        if(x < Math.pow(2,33)) {
+            assertEq(Math.ceil(x), myCeil(x));
+        }
+    }
+}
+
+var a = [Math.pow(2,31), Math.pow(2,33), -4294967296.4, 214748364.2, -50.4, 50.4];
+
+for(var i = 0; i < 10; i++) {
+    for (var j = 0; j < a.length; j++) {
+        ceilRangeTest(a[j]);
+    }
+}
+
+for (var j = 0; j < 30; j++) {
+    (function() {
+        Math.ceil(1.5);
+    })()
+}
+
+for (var j = 0; j < 30; j++) {
+    (function() {
+        Math.ceil(-1.5);
+    })()
+}
+
+for (var j = 0; j < 30; j++) {
+    (function() {
+        Math.ceil(-127.5);
+    })()
+}
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -291,16 +291,24 @@ function rconcat_string(i) {
 var uceFault_concat_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_concat_number'));
 function rconcat_number(i) {
     var x = "s" + i;
     if (uceFault_concat_number(i) || uceFault_concat_number(i))
         assertEq(x, "s99");
     return i;
 }
 
+var uceFault_string_length = eval(uneval(uceFault).replace('uceFault', 'uceFault_string_length'));
+function rstring_length(i) {
+    var x = i.toString().length;
+    if (uceFault_string_length(i) || uceFault_string_length(i))
+        assertEq(x, 2);
+    return i;
+}
+
 var uceFault_floor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_floor_number'));
 function rfloor_number(i) {
     var x = Math.floor(i + 0.1111);
     if (uceFault_floor_number(i) || uceFault_floor_number(i))
         assertEq(x, i);
     return i;
 }
 
@@ -420,16 +428,17 @@ for (i = 0; i < 100; i++) {
     rmul_object(i);
     rdiv_number(i);
     rdiv_float(i);
     rdiv_object(i);
     rmod_number(i);
     rmod_object(i);
     rconcat_string(i);
     rconcat_number(i);
+    rstring_length(i);
     rfloor_number(i);
     rfloor_object(i);
     rround_number(i);
     rround_double(i);
     rcharCodeAt(i);
     rfrom_char_code(i);
     rfrom_char_code_non_ascii(i);
     rpow_number(i);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -8479,16 +8479,25 @@ CodeGenerator::visitIsCallable(LIsCallab
 
     masm.bind(&notFunction);
     masm.cmpPtrSet(Assembler::NonZero, Address(output, offsetof(js::Class, call)), ImmPtr(nullptr), output);
     masm.bind(&done);
 
     return true;
 }
 
+bool
+CodeGenerator::visitIsObject(LIsObject *ins)
+{
+    Register output = ToRegister(ins->output());
+    ValueOperand value = ToValue(ins, LIsObject::Input);
+    masm.testObjectSet(Assembler::Equal, value, output);
+    return true;
+}
+
 void
 CodeGenerator::loadOutermostJSScript(Register reg)
 {
     // The "outermost" JSScript means the script that we are compiling
     // basically; this is not always the script associated with the
     // current basic block, which might be an inlined script.
 
     MIRGraph &graph = current->mir()->graph();
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -285,16 +285,17 @@ class CodeGenerator : public CodeGenerat
     bool visitCallInstanceOf(LCallInstanceOf *ins);
     bool visitProfilerStackOp(LProfilerStackOp *lir);
     bool visitGetDOMProperty(LGetDOMProperty *lir);
     bool visitGetDOMMember(LGetDOMMember *lir);
     bool visitSetDOMProperty(LSetDOMProperty *lir);
     bool visitCallDOMNative(LCallDOMNative *lir);
     bool visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir);
     bool visitIsCallable(LIsCallable *lir);
+    bool visitIsObject(LIsObject *lir);
     bool visitHaveSameClass(LHaveSameClass *lir);
     bool visitHasClass(LHasClass *lir);
     bool visitAsmJSCall(LAsmJSCall *lir);
     bool visitAsmJSParameter(LAsmJSParameter *lir);
     bool visitAsmJSReturn(LAsmJSReturn *ret);
     bool visitAsmJSVoidReturn(LAsmJSVoidReturn *ret);
 
     bool visitCheckOverRecursed(LCheckOverRecursed *lir);
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -725,16 +725,17 @@ class IonBuilder : public MIRGenerator
     // TypedObject intrinsics.
     InliningStatus inlineObjectIsTypeDescr(CallInfo &callInfo);
     InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo);
     bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id,
                                                      ScalarTypeDescr::Type *arrayType);
 
     // Utility intrinsics.
     InliningStatus inlineIsCallable(CallInfo &callInfo);
+    InliningStatus inlineIsObject(CallInfo &callInfo);
     InliningStatus inlineHaveSameClass(CallInfo &callInfo);
     InliningStatus inlineToObject(CallInfo &callInfo);
     InliningStatus inlineToInteger(CallInfo &callInfo);
     InliningStatus inlineToString(CallInfo &callInfo);
     InliningStatus inlineDump(CallInfo &callInfo);
     InliningStatus inlineHasClass(CallInfo &callInfo, const Class *clasp) {
         return inlineHasClasses(callInfo, clasp, nullptr);
     }
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -5784,16 +5784,26 @@ class LIsCallable : public LInstructionH
     const LAllocation *object() {
         return getOperand(0);
     }
     MIsCallable *mir() const {
         return mir_->toIsCallable();
     }
 };
 
+class LIsObject : public LInstructionHelper<1, BOX_PIECES, 0>
+{
+  public:
+    LIR_HEADER(IsObject);
+    static const size_t Input = 0;
+    MIsObject *mir() const {
+        return mir_->toIsObject();
+    }
+};
+
 class LHaveSameClass : public LInstructionHelper<1, 2, 1>
 {
   public:
     LIR_HEADER(HaveSameClass);
     LHaveSameClass(const LAllocation &left, const LAllocation &right,
                    const LDefinition &temp) {
         setOperand(0, left);
         setOperand(1, right);
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -277,16 +277,17 @@
     _(InterruptCheck)               \
     _(InterruptCheckImplicit)       \
     _(ProfilerStackOp)              \
     _(GetDOMProperty)               \
     _(GetDOMMember)                 \
     _(SetDOMProperty)               \
     _(CallDOMNative)                \
     _(IsCallable)                   \
+    _(IsObject)                     \
     _(HaveSameClass)                \
     _(HasClass)                     \
     _(AsmJSLoadHeap)                \
     _(AsmJSStoreHeap)               \
     _(AsmJSLoadGlobalVar)           \
     _(AsmJSStoreGlobalVar)          \
     _(AsmJSLoadFFIFunc)             \
     _(AsmJSParameter)               \
--- a/js/src/jit/Label.h
+++ b/js/src/jit/Label.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_Label_h
 #define jit_Label_h
 
+#include "jit/Ion.h"
+
 namespace js {
 namespace jit {
 
 struct LabelBase
 {
   protected:
     // offset_ >= 0 means that the label is either bound or has incoming
     // uses and needs to be bound.
@@ -20,20 +22,16 @@ struct LabelBase
 
     // Disallow assignment.
     void operator =(const LabelBase &label);
   public:
     static const int32_t INVALID_OFFSET = -1;
 
     LabelBase() : offset_(INVALID_OFFSET), bound_(false)
     { }
-    LabelBase(const LabelBase &label)
-      : offset_(label.offset_),
-        bound_(label.bound_)
-    { }
 
     // If the label is bound, all incoming edges have been patched and any
     // future incoming edges will be immediately patched.
     bool bound() const {
         return bound_;
     }
     int32_t offset() const {
         JS_ASSERT(bound() || used());
@@ -74,24 +72,42 @@ struct LabelBase
 // is not yet known.
 //
 // A jump to an unbound label adds that jump to the label's incoming queue. A
 // jump to a bound label automatically computes the jump distance. The process
 // of binding a label automatically corrects all incoming jumps.
 class Label : public LabelBase
 {
   public:
-    Label()
-    { }
-    Label(const Label &label) : LabelBase(label)
-    { }
+    ~Label()
+    {
+#ifdef DEBUG
+        // The assertion below doesn't hold if an error occurred.
+        if (OOM_counter > OOM_maxAllocations)
+            return;
+        if (IonContext *context = MaybeGetIonContext()) {
+            if (context->runtime->hadOutOfMemory())
+                return;
+        }
+
+        MOZ_ASSERT(!used());
+#endif
+    }
 };
 
 // Label's destructor asserts that if it has been used it has also been bound.
 // In the case long-lived labels, however, failed compilation (e.g. OOM) will
 // trigger this failure innocuously. This Label silences the assertion.
 class NonAssertingLabel : public Label
 {
+  public:
+    ~NonAssertingLabel()
+    {
+#ifdef DEBUG
+        if (used())
+            bind(0);
+#endif
+    }
 };
 
 } } // namespace js::jit
 
 #endif // jit_Label_h
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -617,37 +617,68 @@ ReorderComparison(JSOp op, MDefinition *
     if (lhs->isConstant()) {
         *rhsp = lhs;
         *lhsp = rhs;
         return ReverseCompareOp(op);
     }
     return op;
 }
 
+static bool
+ShouldReorderCommutative(MDefinition *lhs, MDefinition *rhs, MInstruction *ins)
+{
+    // lhs and rhs are used by the commutative operator.
+    JS_ASSERT(lhs->hasDefUses());
+    JS_ASSERT(rhs->hasDefUses());
+
+    // Ensure that if there is a constant, then it is in rhs.
+    if (rhs->isConstant())
+        return false;
+    if (lhs->isConstant())
+        return true;
+
+    // Since clobbering binary operations clobber the left operand, prefer a
+    // non-constant lhs operand with no further uses. To be fully precise, we
+    // should check whether this is the *last* use, but checking hasOneDefUse()
+    // is a decent approximation which doesn't require any extra analysis.
+    bool rhsSingleUse = rhs->hasOneDefUse();
+    bool lhsSingleUse = lhs->hasOneDefUse();
+    if (rhsSingleUse) {
+        if (!lhsSingleUse)
+            return true;
+    } else {
+        if (lhsSingleUse)
+            return false;
+    }
+
+    // If this is a reduction-style computation, such as
+    //
+    //   sum = 0;
+    //   for (...)
+    //      sum += ...;
+    //
+    // put the phi on the left to promote coalescing. This is fairly specific.
+    if (rhsSingleUse &&
+        rhs->isPhi() &&
+        rhs->block()->isLoopHeader() &&
+        ins == rhs->toPhi()->getLoopBackedgeOperand())
+    {
+        return true;
+    }
+
+    return false;
+}
+
 static void
-ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp)
+ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp, MInstruction *ins)
 {
     MDefinition *lhs = *lhsp;
     MDefinition *rhs = *rhsp;
 
-    // Ensure that if there is a constant, then it is in rhs.
-    // In addition, since clobbering binary operations clobber the left
-    // operand, prefer a non-constant lhs operand with no further uses.
-
-    if (rhs->isConstant())
-        return;
-
-    // lhs and rhs are used by the commutative operator. If they have any
-    // *other* uses besides, try to reorder to avoid clobbering them. To
-    // be fully precise, we should check whether this is the *last* use,
-    // but checking hasOneDefUse() is a decent approximation which doesn't
-    // require any extra analysis.
-    JS_ASSERT(lhs->hasDefUses());
-    JS_ASSERT(rhs->hasDefUses());
-    if (lhs->isConstant() || (rhs->hasOneDefUse() && !lhs->hasOneDefUse())) {
+    if (ShouldReorderCommutative(lhs, rhs, ins)) {
         *rhsp = lhs;
         *lhsp = rhs;
     }
 }
 
 bool
 LIRGenerator::visitTest(MTest *test)
 {
@@ -823,17 +854,17 @@ LIRGenerator::visitTest(MTest *test)
     }
 
     // Check if the operand for this test is a bitand operation. If it is, we want
     // to emit an LBitAndAndBranch rather than an LTest*AndBranch.
     if (opd->isBitAnd() && opd->isEmittedAtUses()) {
         MDefinition *lhs = opd->getOperand(0);
         MDefinition *rhs = opd->getOperand(1);
         if (lhs->type() == MIRType_Int32 && rhs->type() == MIRType_Int32) {
-            ReorderCommutative(&lhs, &rhs);
+            ReorderCommutative(&lhs, &rhs, test);
             return lowerForBitAndAndBranch(new(alloc()) LBitAndAndBranch(ifTrue, ifFalse), test, lhs, rhs);
         }
     }
 
     if (opd->type() == MIRType_Double)
         return add(new(alloc()) LTestDAndBranch(useRegister(opd), ifTrue, ifFalse));
 
     if (opd->type() == MIRType_Float32)
@@ -1006,17 +1037,17 @@ LIRGenerator::visitCompare(MCompare *com
 
 bool
 LIRGenerator::lowerBitOp(JSOp op, MInstruction *ins)
 {
     MDefinition *lhs = ins->getOperand(0);
     MDefinition *rhs = ins->getOperand(1);
 
     if (lhs->type() == MIRType_Int32 && rhs->type() == MIRType_Int32) {
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
         return lowerForALU(new(alloc()) LBitOpI(op), ins, lhs, rhs);
     }
 
     LBitOpV *lir = new(alloc()) LBitOpV(op);
     if (!useBoxAtStart(lir, LBitOpV::LhsInput, lhs))
         return false;
     if (!useBoxAtStart(lir, LBitOpV::RhsInput, rhs))
         return false;
@@ -1223,17 +1254,17 @@ LIRGenerator::visitRound(MRound *ins)
 }
 
 bool
 LIRGenerator::visitMinMax(MMinMax *ins)
 {
     MDefinition *first = ins->getOperand(0);
     MDefinition *second = ins->getOperand(1);
 
-    ReorderCommutative(&first, &second);
+    ReorderCommutative(&first, &second, ins);
 
     if (ins->specialization() == MIRType_Int32) {
         LMinMaxI *lir = new(alloc()) LMinMaxI(useRegisterAtStart(first), useRegisterOrConstant(second));
         return defineReuseInput(lir, ins, 0);
     }
 
     LMinMaxD *lir = new(alloc()) LMinMaxD(useRegisterAtStart(first), useRegister(second));
     return defineReuseInput(lir, ins, 0);
@@ -1385,38 +1416,38 @@ LIRGenerator::visitAdd(MAdd *ins)
 {
     MDefinition *lhs = ins->getOperand(0);
     MDefinition *rhs = ins->getOperand(1);
 
     JS_ASSERT(lhs->type() == rhs->type());
 
     if (ins->specialization() == MIRType_Int32) {
         JS_ASSERT(lhs->type() == MIRType_Int32);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
         LAddI *lir = new(alloc()) LAddI;
 
         if (ins->fallible() && !assignSnapshot(lir, Bailout_OverflowInvalidate))
             return false;
 
         if (!lowerForALU(lir, ins, lhs, rhs))
             return false;
 
         MaybeSetRecoversInput(ins, lir);
         return true;
     }
 
     if (ins->specialization() == MIRType_Double) {
         JS_ASSERT(lhs->type() == MIRType_Double);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
         return lowerForFPU(new(alloc()) LMathD(JSOP_ADD), ins, lhs, rhs);
     }
 
     if (ins->specialization() == MIRType_Float32) {
         JS_ASSERT(lhs->type() == MIRType_Float32);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
         return lowerForFPU(new(alloc()) LMathF(JSOP_ADD), ins, lhs, rhs);
     }
 
     return lowerBinaryV(JSOP_ADD, ins);
 }
 
 bool
 LIRGenerator::visitSub(MSub *ins)
@@ -1455,38 +1486,38 @@ bool
 LIRGenerator::visitMul(MMul *ins)
 {
     MDefinition *lhs = ins->lhs();
     MDefinition *rhs = ins->rhs();
     JS_ASSERT(lhs->type() == rhs->type());
 
     if (ins->specialization() == MIRType_Int32) {
         JS_ASSERT(lhs->type() == MIRType_Int32);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
 
         // If our RHS is a constant -1 and we don't have to worry about
         // overflow, we can optimize to an LNegI.
         if (!ins->fallible() && rhs->isConstant() && rhs->toConstant()->value() == Int32Value(-1))
             return defineReuseInput(new(alloc()) LNegI(useRegisterAtStart(lhs)), ins, 0);
 
         return lowerMulI(ins, lhs, rhs);
     }
     if (ins->specialization() == MIRType_Double) {
         JS_ASSERT(lhs->type() == MIRType_Double);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
 
         // If our RHS is a constant -1.0, we can optimize to an LNegD.
         if (rhs->isConstant() && rhs->toConstant()->value() == DoubleValue(-1.0))
             return defineReuseInput(new(alloc()) LNegD(useRegisterAtStart(lhs)), ins, 0);
 
         return lowerForFPU(new(alloc()) LMathD(JSOP_MUL), ins, lhs, rhs);
     }
     if (ins->specialization() == MIRType_Float32) {
         JS_ASSERT(lhs->type() == MIRType_Float32);
-        ReorderCommutative(&lhs, &rhs);
+        ReorderCommutative(&lhs, &rhs, ins);
 
         // We apply the same optimizations as for doubles
         if (rhs->isConstant() && rhs->toConstant()->value() == Float32Value(-1.0f))
             return defineReuseInput(new(alloc()) LNegF(useRegisterAtStart(lhs)), ins, 0);
 
         return lowerForFPU(new(alloc()) LMathF(JSOP_MUL), ins, lhs, rhs);
     }
 
@@ -3425,16 +3456,27 @@ bool
 LIRGenerator::visitIsCallable(MIsCallable *ins)
 {
     JS_ASSERT(ins->object()->type() == MIRType_Object);
     JS_ASSERT(ins->type() == MIRType_Boolean);
     return define(new(alloc()) LIsCallable(useRegister(ins->object())), ins);
 }
 
 bool
+LIRGenerator::visitIsObject(MIsObject *ins)
+{
+    MDefinition *opd = ins->input();
+    JS_ASSERT(opd->type() == MIRType_Value);
+    LIsObject *lir = new(alloc()) LIsObject();
+    if (!useBoxAtStart(lir, LIsObject::Input, opd))
+        return false;
+    return define(lir, ins);
+}
+
+bool
 LIRGenerator::visitHaveSameClass(MHaveSameClass *ins)
 {
     MDefinition *lhs = ins->lhs();
     MDefinition *rhs = ins->rhs();
 
     JS_ASSERT(lhs->type() == MIRType_Object);
     JS_ASSERT(rhs->type() == MIRType_Object);
 
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -240,16 +240,17 @@ class LIRGenerator : public LIRGenerator
     bool visitRestPar(MRestPar *ins);
     bool visitThrow(MThrow *ins);
     bool visitIn(MIn *ins);
     bool visitInArray(MInArray *ins);
     bool visitInstanceOf(MInstanceOf *ins);
     bool visitCallInstanceOf(MCallInstanceOf *ins);
     bool visitProfilerStackOp(MProfilerStackOp *ins);
     bool visitIsCallable(MIsCallable *ins);
+    bool visitIsObject(MIsObject *ins);
     bool visitHaveSameClass(MHaveSameClass *ins);
     bool visitHasClass(MHasClass *ins);
     bool visitAsmJSLoadGlobalVar(MAsmJSLoadGlobalVar *ins);
     bool visitAsmJSStoreGlobalVar(MAsmJSStoreGlobalVar *ins);
     bool visitAsmJSLoadFFIFunc(MAsmJSLoadFFIFunc *ins);
     bool visitAsmJSParameter(MAsmJSParameter *ins);
     bool visitAsmJSReturn(MAsmJSReturn *ins);
     bool visitAsmJSVoidReturn(MAsmJSVoidReturn *ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -158,16 +158,18 @@ IonBuilder::inlineNativeCall(CallInfo &c
 
     // Utility intrinsics.
     if (native == intrinsic_IsCallable)
         return inlineIsCallable(callInfo);
     if (native == intrinsic_HaveSameClass)
         return inlineHaveSameClass(callInfo);
     if (native == intrinsic_ToObject)
         return inlineToObject(callInfo);
+    if (native == intrinsic_IsObject)
+        return inlineIsObject(callInfo);
     if (native == intrinsic_ToInteger)
         return inlineToInteger(callInfo);
     if (native == intrinsic_ToString)
         return inlineToString(callInfo);
 
     // TypedObject intrinsics.
     if (native == intrinsic_ObjectIsTypedObject)
         return inlineHasClasses(callInfo,
@@ -1898,16 +1900,31 @@ IonBuilder::inlineIsCallable(CallInfo &c
     MIsCallable *isCallable = MIsCallable::New(alloc(), callInfo.getArg(0));
     current->add(isCallable);
     current->push(isCallable);
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
+IonBuilder::inlineIsObject(CallInfo &callInfo)
+{
+    if (callInfo.argc() != 1 || callInfo.constructing())
+        return InliningStatus_NotInlined;
+    if (getInlineReturnType() != MIRType_Boolean)
+        return InliningStatus_NotInlined;
+
+    callInfo.setImplicitlyUsedUnchecked();
+    MIsObject *isObject = MIsObject::New(alloc(), callInfo.getArg(0));
+    current->add(isObject);
+    current->push(isObject);
+    return InliningStatus_Inlined;
+}
+
+IonBuilder::InliningStatus
 IonBuilder::inlineToObject(CallInfo &callInfo)
 {
     if (callInfo.argc() != 1 || callInfo.constructing())
         return InliningStatus_NotInlined;
 
     // If we know the input type is an object, nop ToObject.
     if (getInlineReturnType() != MIRType_Object)
         return InliningStatus_NotInlined;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -904,16 +904,33 @@ MUnbox::printOpcode(FILE *fp) const
 void
 MTypeBarrier::printOpcode(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
     fprintf(fp, " ");
     getOperand(0)->printName(fp);
 }
 
+#ifdef DEBUG
+void
+MPhi::assertLoopPhi() const
+{
+    // getLoopPredecessorOperand and getLoopBackedgeOperand rely on these
+    // predecessors being at indices 0 and 1.
+    MBasicBlock *pred = block()->getPredecessor(0);
+    MBasicBlock *back = block()->getPredecessor(1);
+    JS_ASSERT(pred == block()->loopPredecessor());
+    JS_ASSERT(pred->successorWithPhis() == block());
+    JS_ASSERT(pred->positionInPhiSuccessor() == 0);
+    JS_ASSERT(back == block()->backedge());
+    JS_ASSERT(back->successorWithPhis() == block());
+    JS_ASSERT(back->positionInPhiSuccessor() == 1);
+}
+#endif
+
 void
 MPhi::removeOperand(size_t index)
 {
     JS_ASSERT(index < numOperands());
     JS_ASSERT(getUseFor(index)->index() == index);
     JS_ASSERT(getUseFor(index)->consumer() == this);
 
     // If we have phi(..., a, b, c, d, ..., z) and we plan
@@ -3060,16 +3077,29 @@ MSqrt::trySpecializeFloat32(TempAllocato
             ConvertDefinitionToDouble<0>(alloc, input(), this);
         return;
     }
 
     setResultType(MIRType_Float32);
     setPolicyType(MIRType_Float32);
 }
 
+MDefinition *
+MBoundsCheck::foldsTo(TempAllocator &alloc)
+{
+    if (index()->isConstant() && length()->isConstant()) {
+       uint32_t len = length()->toConstant()->value().toInt32();
+       uint32_t idx = index()->toConstant()->value().toInt32();
+       if (idx + uint32_t(minimum()) < len && idx + uint32_t(maximum()) < len)
+           return index();
+    }
+
+    return this;
+}
+
 bool
 jit::ElementAccessIsDenseNative(MDefinition *obj, MDefinition *id)
 {
     if (obj->mightBeType(MIRType_String))
         return false;
 
     if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
         return false;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -5021,16 +5021,38 @@ class MPhi MOZ_FINAL : public MDefinitio
         return triedToSpecialize_;
     }
     void specialize(MIRType type) {
         triedToSpecialize_ = true;
         setResultType(type);
     }
     bool specializeType();
 
+#ifdef DEBUG
+    // Assert that this is a phi in a loop header with a unique predecessor and
+    // a unique backedge.
+    void assertLoopPhi() const;
+#else
+    void assertLoopPhi() const {}
+#endif
+
+    // Assuming this phi is in a loop header with a unique loop entry, return
+    // the phi operand along the loop entry.
+    MDefinition *getLoopPredecessorOperand() const {
+        assertLoopPhi();
+        return getOperand(0);
+    }
+
+    // Assuming this phi is in a loop header with a unique loop entry, return
+    // the phi operand along the loop backedge.
+    MDefinition *getLoopBackedgeOperand() const {
+        assertLoopPhi();
+        return getOperand(1);
+    }
+
     // Whether this phi's type already includes information for def.
     bool typeIncludes(MDefinition *def);
 
     // Add types for this phi which speculate about new inputs that may come in
     // via a loop backedge.
     bool addBackedgeType(MIRType type, types::TemporaryTypeSet *typeSet);
 
     // Initializes the operands vector to the given capacity,
@@ -6265,16 +6287,17 @@ class MBoundsCheck
         minimum_ = n;
     }
     int32_t maximum() const {
         return maximum_;
     }
     void setMaximum(int32_t n) {
         maximum_ = n;
     }
+    MDefinition *foldsTo(TempAllocator &alloc);
     bool congruentTo(const MDefinition *ins) const {
         if (!ins->isBoundsCheck())
             return false;
         const MBoundsCheck *other = ins->toBoundsCheck();
         if (minimum() != other->minimum() || maximum() != other->maximum())
             return false;
         return congruentIfOperandsEqual(other);
     }
@@ -8892,16 +8915,21 @@ class MStringLength
     }
     AliasSet getAliasSet() const {
         // The string |length| property is immutable, so there is no
         // implicit dependency.
         return AliasSet::None();
     }
 
     void computeRange(TempAllocator &alloc);
+
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return true;
+    }
 };
 
 // Inlined version of Math.floor().
 class MFloor
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>
 {
     explicit MFloor(MDefinition *num)
@@ -8983,16 +9011,17 @@ class MCeil
 #ifdef DEBUG
     bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
     bool congruentTo(const MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
+    void computeRange(TempAllocator &alloc);
 };
 
 // Inlined version of Math.round().
 class MRound
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>
 {
     explicit MRound(MDefinition *num)
@@ -10088,17 +10117,42 @@ class MIsCallable
     }
 
   public:
     INSTRUCTION_HEADER(IsCallable);
 
     static MIsCallable *New(TempAllocator &alloc, MDefinition *obj) {
         return new(alloc) MIsCallable(obj);
     }
-
+    TypePolicy *typePolicy() {
+        return this;
+    }
+    MDefinition *object() const {
+        return getOperand(0);
+    }
+    AliasSet getAliasSet() const {
+        return AliasSet::None();
+    }
+};
+
+class MIsObject
+  : public MUnaryInstruction,
+    public BoxInputsPolicy
+{
+    explicit MIsObject(MDefinition *object)
+    : MUnaryInstruction(object)
+    {
+        setResultType(MIRType_Boolean);
+        setMovable();
+    }
+  public:
+    INSTRUCTION_HEADER(IsObject);
+    static MIsObject *New(TempAllocator &alloc, MDefinition *obj) {
+        return new(alloc) MIsObject(obj);
+    }
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -192,16 +192,17 @@ namespace jit {
     _(InstanceOf)                                                           \
     _(CallInstanceOf)                                                       \
     _(InterruptCheck)                                                       \
     _(ProfilerStackOp)                                                      \
     _(GetDOMProperty)                                                       \
     _(GetDOMMember)                                                         \
     _(SetDOMProperty)                                                       \
     _(IsCallable)                                                           \
+    _(IsObject)                                                             \
     _(HaveSameClass)                                                        \
     _(HasClass)                                                             \
     _(AsmJSNeg)                                                             \
     _(AsmJSUnsignedToDouble)                                                \
     _(AsmJSUnsignedToFloat32)                                               \
     _(AsmJSLoadHeap)                                                        \
     _(AsmJSStoreHeap)                                                       \
     _(AsmJSLoadGlobalVar)                                                   \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -301,16 +301,17 @@ class ParallelSafetyVisitor : public MIn
     UNSAFE_OP(In)
     UNSAFE_OP(InArray)
     SAFE_OP(GuardThreadExclusive)
     SAFE_OP(InterruptCheckPar)
     SAFE_OP(CheckOverRecursedPar)
     SAFE_OP(FunctionDispatch)
     SAFE_OP(TypeObjectDispatch)
     SAFE_OP(IsCallable)
+    SAFE_OP(IsObject)
     SAFE_OP(HaveSameClass)
     SAFE_OP(HasClass)
     UNSAFE_OP(EffectiveAddress)
     UNSAFE_OP(AsmJSUnsignedToDouble)
     UNSAFE_OP(AsmJSUnsignedToFloat32)
     UNSAFE_OP(AsmJSNeg)
     UNSAFE_OP(AsmJSLoadHeap)
     UNSAFE_OP(AsmJSStoreHeap)
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -558,17 +558,17 @@ Range::setDouble(double l, double h)
     if (l >= INT32_MIN && l <= INT32_MAX) {
         lower_ = int32_t(::floor(l));
         hasInt32LowerBound_ = true;
     } else {
         lower_ = INT32_MIN;
         hasInt32LowerBound_ = false;
     }
     if (h >= INT32_MIN && h <= INT32_MAX) {
-        upper_ = int32_t(ceil(h));
+        upper_ = int32_t(::ceil(h));
         hasInt32UpperBound_ = true;
     } else {
         upper_ = INT32_MAX;
         hasInt32UpperBound_ = false;
     }
 
     // Infer max_exponent_.
     uint16_t lExp = ExponentImpliedByDouble(l);
@@ -974,16 +974,35 @@ Range::floor(TempAllocator &alloc, const
     else if(copy->max_exponent_ < MaxFiniteExponent)
         copy->max_exponent_++;
 
     copy->canHaveFractionalPart_ = false;
     copy->assertInvariants();
     return copy;
 }
 
+Range *
+Range::ceil(TempAllocator &alloc, const Range *op)
+{
+    Range *copy = new(alloc) Range(*op);
+
+    // We need to refine max_exponent_ because ceil may have incremented the int value.
+    // If we have got int32 bounds defined, just deduce it using the defined bounds.
+    // Else we can just increment its value,
+    // as we are looking to maintain an over estimation.
+    if (copy->hasInt32Bounds())
+        copy->max_exponent_ = copy->exponentImpliedByInt32Bounds();
+    else if (copy->max_exponent_ < MaxFiniteExponent)
+        copy->max_exponent_++;
+
+    copy->canHaveFractionalPart_ = false;
+    copy->assertInvariants();
+    return copy;
+}
+
 bool
 Range::negativeZeroMul(const Range *lhs, const Range *rhs)
 {
     // The result can only be negative zero if both sides are finite and they
     // have differing signs.
     return (lhs->canBeFiniteNegative() && rhs->canBeFiniteNonNegative()) ||
            (rhs->canBeFiniteNegative() && lhs->canBeFiniteNonNegative());
 }
@@ -1203,16 +1222,23 @@ MAbs::computeRange(TempAllocator &alloc)
 void
 MFloor::computeRange(TempAllocator &alloc)
 {
     Range other(getOperand(0));
     setRange(Range::floor(alloc, &other));
 }
 
 void
+MCeil::computeRange(TempAllocator &alloc)
+{
+    Range other(getOperand(0));
+    setRange(Range::ceil(alloc, &other));
+}
+
+void
 MMinMax::computeRange(TempAllocator &alloc)
 {
     if (specialization_ != MIRType_Int32 && specialization_ != MIRType_Double)
         return;
 
     Range left(getOperand(0));
     Range right(getOperand(1));
     setRange(isMax() ? Range::max(alloc, &left, &right) : Range::min(alloc, &left, &right));
@@ -1692,23 +1718,23 @@ RangeAnalysis::analyzeLoopIterationCount
     // the start of the iteration.
 
     if (lhs.term->toPhi()->numOperands() != 2)
         return nullptr;
 
     // The first operand of the phi should be the lhs' value at the start of
     // the first executed iteration, and not a value written which could
     // replace the second operand below during the middle of execution.
-    MDefinition *lhsInitial = lhs.term->toPhi()->getOperand(0);
+    MDefinition *lhsInitial = lhs.term->toPhi()->getLoopPredecessorOperand();
     if (lhsInitial->block()->isMarked())
         return nullptr;
 
     // The second operand of the phi should be a value written by an add/sub
     // in every loop iteration, i.e. in a block which dominates the backedge.
-    MDefinition *lhsWrite = lhs.term->toPhi()->getOperand(1);
+    MDefinition *lhsWrite = lhs.term->toPhi()->getLoopBackedgeOperand();
     if (lhsWrite->isBeta())
         lhsWrite = lhsWrite->getOperand(0);
     if (!lhsWrite->isAdd() && !lhsWrite->isSub())
         return nullptr;
     if (!lhsWrite->block()->isMarked())
         return nullptr;
     MBasicBlock *bb = header->backedge();
     for (; bb != lhsWrite->block() && bb != header; bb = bb->immediateDominator()) {}
@@ -1778,27 +1804,21 @@ RangeAnalysis::analyzeLoopPhi(MBasicBloc
     // lower bound for a phi node that may change by a constant amount each
     // iteration. Unlike for the case when computing the iteration bound
     // itself, the phi does not need to change the same amount every iteration,
     // but is required to change at most N and be either nondecreasing or
     // nonincreasing.
 
     JS_ASSERT(phi->numOperands() == 2);
 
-    MBasicBlock *preLoop = header->loopPredecessor();
-    JS_ASSERT(!preLoop->isMarked() && preLoop->successorWithPhis() == header);
-
-    MBasicBlock *backedge = header->backedge();
-    JS_ASSERT(backedge->isMarked() && backedge->successorWithPhis() == header);
-
-    MDefinition *initial = phi->getOperand(preLoop->positionInPhiSuccessor());
+    MDefinition *initial = phi->getLoopPredecessorOperand();
     if (initial->block()->isMarked())
         return;
 
-    SimpleLinearSum modified = ExtractLinearSum(phi->getOperand(backedge->positionInPhiSuccessor()));
+    SimpleLinearSum modified = ExtractLinearSum(phi->getLoopBackedgeOperand());
 
     if (modified.term != phi || modified.constant == 0)
         return;
 
     if (!phi->range())
         phi->setRange(new(alloc()) Range());
 
     LinearSum initialSum(alloc());
--- a/js/src/jit/RangeAnalysis.h
+++ b/js/src/jit/RangeAnalysis.h
@@ -410,16 +410,17 @@ class Range : public TempObject {
     static Range *ursh(TempAllocator &alloc, const Range *lhs, int32_t c);
     static Range *lsh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
     static Range *rsh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
     static Range *ursh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
     static Range *abs(TempAllocator &alloc, const Range *op);
     static Range *min(TempAllocator &alloc, const Range *lhs, const Range *rhs);
     static Range *max(TempAllocator &alloc, const Range *lhs, const Range *rhs);
     static Range *floor(TempAllocator &alloc, const Range *op);
+    static Range *ceil(TempAllocator &alloc, const Range *op);
 
     static bool negativeZeroMul(const Range *lhs, const Range *rhs);
 
     bool isUnknownInt32() const {
         return isInt32() && lower() == INT32_MIN && upper() == INT32_MAX;
     }
 
     bool isUnknown() const {
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -505,16 +505,41 @@ RConcat::recover(JSContext *cx, Snapshot
     MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
     if (!js::AddValues(cx, &lhs, &rhs, &result))
         return false;
 
     iter.storeInstructionResult(result);
     return true;
 }
 
+RStringLength::RStringLength(CompactBufferReader &reader)
+{}
+
+bool
+RStringLength::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue operand(cx, iter.read());
+    RootedValue result(cx);
+
+    MOZ_ASSERT(!operand.isObject());
+    if (!js::GetLengthProperty(operand, &result))
+        return false;
+
+    iter.storeInstructionResult(result);
+    return true;
+}
+
+bool
+MStringLength::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_StringLength));
+    return true;
+}
+
 bool
 MFloor::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_Floor));
     return true;
 }
 
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -26,16 +26,17 @@ namespace jit {
     _(Rsh)                                      \
     _(Ursh)                                     \
     _(Add)                                      \
     _(Sub)                                      \
     _(Mul)                                      \
     _(Div)                                      \
     _(Mod)                                      \
     _(Concat)                                   \
+    _(StringLength)                             \
     _(Floor)                                    \
     _(Round)                                    \
     _(CharCodeAt)                               \
     _(FromCharCode)                             \
     _(Pow)                                      \
     _(PowHalf)                                  \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
@@ -269,16 +270,28 @@ class RConcat MOZ_FINAL : public RInstru
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RStringLength MOZ_FINAL : public RInstruction
+{
+public:
+    RINSTRUCTION_HEADER_(StringLength)
+
+    virtual uint32_t numOperands() const {
+        return 1;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RFloor MOZ_FINAL : public RInstruction
 {
   public:
     RINSTRUCTION_HEADER_(Floor)
 
     virtual uint32_t numOperands() const {
         return 1;
     }
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -1503,16 +1503,22 @@ class MacroAssemblerARMCompat : public M
         cmp32(lhs, rhs);
         emitSet(cond, dest);
     }
 
     void testNullSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testNull(cond, value);
         emitSet(cond, dest);
     }
+
+    void testObjectSet(Condition cond, const ValueOperand &value, Register dest) {
+        cond = testObject(cond, value);
+        emitSet(cond, dest);
+    }
+
     void testUndefinedSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testUndefined(cond, value);
         emitSet(cond, dest);
     }
 
     // Setup a call to C/C++ code, given the number of general arguments it
     // takes. Note that this only supports cdecl.
     //
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -2293,16 +2293,22 @@ MacroAssemblerMIPSCompat::branchTestObje
 void
 MacroAssemblerMIPSCompat::branchTestObject(Condition cond, const BaseIndex &src, Label *label)
 {
     MOZ_ASSERT(cond == Equal || cond == NotEqual);
     extractTag(src, SecondScratchReg);
     ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_OBJECT), label, cond);
 }
 
+void
+MacroAssemblerMIPSCompat::testObjectSet(Condition cond, const ValueOperand &value, Register dest)
+{
+    MOZ_ASSERT(cond == Equal || cond == NotEqual);
+    ma_cmp_set(dest, value.typeReg(), ImmType(JSVAL_TYPE_OBJECT), cond);
+}
 
 void
 MacroAssemblerMIPSCompat::branchTestString(Condition cond, const ValueOperand &value, Label *label)
 {
     branchTestString(cond, value.typeReg(), label);
 }
 
 void
--- a/js/src/jit/mips/MacroAssembler-mips.h
+++ b/js/src/jit/mips/MacroAssembler-mips.h
@@ -681,16 +681,17 @@ class MacroAssemblerMIPSCompat : public 
     void branchTestNull(Condition cond, const ValueOperand &value, Label *label);
     void branchTestNull(Condition cond, Register tag, Label *label);
     void branchTestNull(Condition cond, const BaseIndex &src, Label *label);
     void testNullSet(Condition cond, const ValueOperand &value, Register dest);
 
     void branchTestObject(Condition cond, const ValueOperand &value, Label *label);
     void branchTestObject(Condition cond, Register tag, Label *label);
     void branchTestObject(Condition cond, const BaseIndex &src, Label *label);
+    void testObjectSet(Condition cond, const ValueOperand &value, Register dest);
 
     void branchTestString(Condition cond, const ValueOperand &value, Label *label);
     void branchTestString(Condition cond, Register tag, Label *label);
     void branchTestString(Condition cond, const BaseIndex &src, Label *label);
 
     void branchTestSymbol(Condition cond, const ValueOperand &value, Label *label);
     void branchTestSymbol(Condition cond, const Register &tag, Label *label);
     void branchTestSymbol(Condition cond, const BaseIndex &src, Label *label);
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -1024,16 +1024,22 @@ class MacroAssemblerX64 : public MacroAs
         JS_ASSERT(cond == Equal || cond == NotEqual);
         branchPtr(cond, valaddr, value.valueReg(), label);
     }
 
     void testNullSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testNull(cond, value);
         emitSet(cond, dest);
     }
+
+    void testObjectSet(Condition cond, const ValueOperand &value, Register dest) {
+        cond = testObject(cond, value);
+        emitSet(cond, dest);
+    }
+
     void testUndefinedSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testUndefined(cond, value);
         emitSet(cond, dest);
     }
 
     void boxDouble(FloatRegister src, const ValueOperand &dest) {
         movq(src, dest.valueReg());
     }
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -481,16 +481,22 @@ class MacroAssemblerX86 : public MacroAs
             bind(&fallthrough);
         }
     }
 
     void testNullSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testNull(cond, value);
         emitSet(cond, dest);
     }
+
+    void testObjectSet(Condition cond, const ValueOperand &value, Register dest) {
+        cond = testObject(cond, value);
+        emitSet(cond, dest);
+    }
+
     void testUndefinedSet(Condition cond, const ValueOperand &value, Register dest) {
         cond = testUndefined(cond, value);
         emitSet(cond, dest);
     }
 
     void cmpPtr(Register lhs, const ImmWord rhs) {
         cmpl(lhs, Imm32(rhs.value));
     }
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -475,16 +475,21 @@ js::AtomizeString(ExclusiveContext *cx, 
 JSAtom *
 js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavior ib)
 {
     CHECK_REQUEST(cx);
 
     if (!JSString::validateLength(cx, length))
         return nullptr;
 
+    if (EnableLatin1Strings) {
+        const Latin1Char *chars = reinterpret_cast<const Latin1Char*>(bytes);
+        return AtomizeAndCopyChars(cx, chars, length, ib);
+    }
+
     static const unsigned ATOMIZE_BUF_MAX = 32;
     if (length < ATOMIZE_BUF_MAX) {
         /*
          * Avoiding the malloc in InflateString on shorter strings saves us
          * over 20,000 malloc calls on mozilla browser startup. This compares to
          * only 131 calls where the string is longer than a 31 char (net) buffer.
          * The vast majority of atomized strings are already in the hashtable. So
          * js::AtomizeString rarely has to copy the temp string we make.
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1002,16 +1002,17 @@ class ContextAllocPolicy
     void *calloc_(size_t bytes) { return cx_->calloc_(bytes); }
     void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx_->realloc_(p, oldBytes, bytes); }
     void free_(void *p) { js_free(p); }
     void reportAllocOverflow() const { js_ReportAllocationOverflow(cx_); }
 };
 
 /* Exposed intrinsics so that Ion may inline them. */
 bool intrinsic_ToObject(JSContext *cx, unsigned argc, Value *vp);
+bool intrinsic_IsObject(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_ToInteger(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_ToString(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_IsCallable(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_ThrowError(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_NewDenseArray(JSContext *cx, unsigned argc, Value *vp);
 
 bool intrinsic_UnsafePutElements(JSContext *cx, unsigned argc, Value *vp);
 bool intrinsic_DefineDataProperty(JSContext *cx, unsigned argc, Value *vp);
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -303,17 +303,17 @@ CopyStringPure(JSContext *cx, JSString *
 
         return NewString<CanGC>(cx, copiedChars.forget(), len);
     }
 
     ScopedJSFreePtr<jschar> copiedChars;
     if (!str->asRope().copyTwoByteCharsZ(cx, copiedChars))
         return nullptr;
 
-    return NewString<CanGC>(cx, copiedChars.forget(), len);
+    return NewStringDontDeflate<CanGC>(cx, copiedChars.forget(), len);
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, JSString **strp)
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(this));
     JS_ASSERT(cx->compartment() == this);
 
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -1535,17 +1535,16 @@ ScriptedDirectProxyHandler::getOwnProper
 
         if (!targetDesc.isPermanent()) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_C_AS_NC);
             return false;
         }
     }
 
     // step 22
-    // FIXME: This is incorrect with respect to [[Origin]]. See bug 999156.
     resultDesc.populatePropertyDescriptor(proxy, desc);
     return true;
 }
 
 // ES6 (5 April 2014) Proxy.[[DefineOwnProperty]](O,P)
 bool
 ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                            MutableHandle<PropertyDescriptor> desc)
@@ -1562,18 +1561,17 @@ ScriptedDirectProxyHandler::defineProper
     RootedValue trap(cx);
     if (!JSObject::getProperty(cx, handler, handler, cx->names().defineProperty, &trap))
          return false;
 
     // step 7
     if (trap.isUndefined())
         return DirectProxyHandler::defineProperty(cx, proxy, id, desc);
 
-    // step 8-9, with 9 blatantly defied.
-    // FIXME: This is incorrect with respect to [[Origin]]. See bug 601379.
+    // step 8-9
     RootedValue descObj(cx);
     if (!NewPropertyDescriptorObject(cx, desc, &descObj))
         return false;
 
     // step 10, 12
     RootedValue propKey(cx);
     if (!IdToStringOrSymbol(cx, id, &propKey))
         return false;
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -714,17 +714,17 @@ ToLowerCase(JSContext *cx, JSLinearStrin
         for (size_t i = 0; i < length; i++) {
             jschar c = unicode::ToLowerCase(chars[i]);
             MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= 0xff);
             newChars[i] = c;
         }
         newChars[length] = 0;
     }
 
-    JSString *res = NewString<CanGC>(cx, newChars.get(), length);
+    JSString *res = NewStringDontDeflate<CanGC>(cx, newChars.get(), length);
     if (!res)
         return nullptr;
 
     newChars.forget();
     return res;
 }
 
 static inline bool
@@ -4200,26 +4200,20 @@ js::str_fromCharCode_one_arg(JSContext *
     if (!ToUint16(cx, code, &ucode))
         return false;
 
     if (StaticStrings::hasUnit(ucode)) {
         rval.setString(cx->staticStrings().getUnit(ucode));
         return true;
     }
 
-    jschar *chars = cx->pod_malloc<jschar>(2);
-    if (!chars)
+    jschar c = jschar(ucode);
+    JSString *str = NewStringCopyN<CanGC>(cx, &c, 1);
+    if (!str)
         return false;
-    chars[0] = jschar(ucode);
-    chars[1] = 0;
-    JSString *str = NewString<CanGC>(cx, chars, 1);
-    if (!str) {
-        js_free(chars);
-        return false;
-    }
 
     rval.setString(str);
     return true;
 }
 
 static const JSFunctionSpec string_static_methods[] = {
     JS_FN("fromCharCode", js::str_fromCharCode, 1, 0),
     JS_SELF_HOSTED_FN("fromCodePoint", "String_static_fromCodePoint", 0,0),
@@ -4276,45 +4270,16 @@ js_InitStringClass(JSContext *cx, Handle
      * uneval on the global object.
      */
     if (!JS_DefineFunctions(cx, global, string_functions))
         return nullptr;
 
     return proto;
 }
 
-template <AllowGC allowGC, typename CharT>
-JSFlatString *
-js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
-{
-    if (length == 1) {
-        jschar c = chars[0];
-        if (StaticStrings::hasUnit(c)) {
-            // Free |chars| because we're taking possession of it, but it's no
-            // longer needed because we use the static string instead.
-            js_free(chars);
-            return cx->staticStrings().getUnit(c);
-        }
-    }
-
-    return JSFlatString::new_<allowGC>(cx, chars, length);
-}
-
-template JSFlatString *
-js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
-
-template JSFlatString *
-js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
-
-template JSFlatString *
-js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
-
-template JSFlatString *
-js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
-
 JSLinearString *
 js::NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t length)
 {
     if (length == 0)
         return cx->emptyString();
 
     JSLinearString *base = baseArg->ensureLinear(cx);
     if (!base)
@@ -4410,31 +4375,97 @@ NewStringDeflated(ThreadSafeContext *cx,
         return nullptr;
 
     for (size_t i = 0; i < n; i++) {
         MOZ_ASSERT(s[i] <= JSString::MAX_LATIN1_CHAR);
         news.get()[i] = Latin1Char(s[i]);
     }
     news[n] = '\0';
 
-    JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
+    JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
     if (!str)
         return nullptr;
 
     news.forget();
     return str;
 }
 
 template <AllowGC allowGC>
 static JSFlatString *
 NewStringDeflated(ThreadSafeContext *cx, const Latin1Char *s, size_t n)
 {
     MOZ_CRASH("Shouldn't be called for Latin1 chars");
 }
 
+template <AllowGC allowGC, typename CharT>
+JSFlatString *
+js::NewStringDontDeflate(ThreadSafeContext *cx, CharT *chars, size_t length)
+{
+    if (length == 1) {
+        jschar c = chars[0];
+        if (StaticStrings::hasUnit(c)) {
+            // Free |chars| because we're taking possession of it, but it's no
+            // longer needed because we use the static string instead.
+            js_free(chars);
+            return cx->staticStrings().getUnit(c);
+        }
+    }
+
+    return JSFlatString::new_<allowGC>(cx, chars, length);
+}
+
+template JSFlatString *
+js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
+
+template JSFlatString *
+js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
+
+template JSFlatString *
+js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
+
+template JSFlatString *
+js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
+
+template <AllowGC allowGC, typename CharT>
+JSFlatString *
+js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
+{
+    if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(chars, length)) {
+        if (length == 1) {
+            jschar c = chars[0];
+            if (StaticStrings::hasUnit(c)) {
+                js_free(chars);
+                return cx->staticStrings().getUnit(c);
+            }
+        }
+
+        JSFlatString *s = NewStringDeflated<allowGC>(cx, chars, length);
+        if (!s)
+            return nullptr;
+
+        // Free |chars| because we're taking possession of it but not using it.
+        js_free(chars);
+        return s;
+    }
+
+    return NewStringDontDeflate<allowGC>(cx, chars, length);
+}
+
+template JSFlatString *
+js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
+
+template JSFlatString *
+js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
+
+template JSFlatString *
+js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
+
+template JSFlatString *
+js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
+
 namespace js {
 
 template <AllowGC allowGC, typename CharT>
 JSFlatString *
 NewStringCopyNDontDeflate(ThreadSafeContext *cx, const CharT *s, size_t n)
 {
     if (EnableLatin1Strings) {
         if (JSFatInlineString::lengthFits<CharT>(n))
@@ -4442,17 +4473,17 @@ NewStringCopyNDontDeflate(ThreadSafeCont
 
         ScopedJSFreePtr<CharT> news(cx->pod_malloc<CharT>(n + 1));
         if (!news)
             return nullptr;
 
         PodCopy(news.get(), s, n);
         news[n] = 0;
 
-        JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
+        JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
         if (!str)
             return nullptr;
 
         news.forget();
         return str;
     }
 
     if (JSFatInlineString::twoByteLengthFits(n))
@@ -4460,17 +4491,17 @@ NewStringCopyNDontDeflate(ThreadSafeCont
 
     ScopedJSFreePtr<jschar> news(cx->pod_malloc<jschar>(n + 1));
     if (!news)
         return nullptr;
 
     CopyCharsMaybeInflate(news.get(), s, n);
     news[n] = 0;
 
-    JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
+    JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
     if (!str)
         return nullptr;
 
     news.forget();
     return str;
 }
 
 template JSFlatString *
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -126,16 +126,21 @@ js_strdup(js::ThreadSafeContext *cx, con
 
 namespace js {
 
 /* GC-allocate a string descriptor for the given malloc-allocated chars. */
 template <js::AllowGC allowGC, typename CharT>
 extern JSFlatString *
 NewString(js::ThreadSafeContext *cx, CharT *chars, size_t length);
 
+/* Like NewString, but doesn't try to deflate to Latin1. */
+template <js::AllowGC allowGC, typename CharT>
+extern JSFlatString *
+NewStringDontDeflate(js::ThreadSafeContext *cx, CharT *chars, size_t length);
+
 extern JSLinearString *
 NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
 
 /* Copy a counted string and GC-allocate a descriptor for it. */
 template <js::AllowGC allowGC, typename CharT>
 extern JSFlatString *
 NewStringCopyN(js::ThreadSafeContext *cx, const CharT *s, size_t n);
 
--- a/js/src/tests/ecma_6/TypedObject/simd/bug953270.js
+++ b/js/src/tests/ecma_6/TypedObject/simd/bug953270.js
@@ -8,20 +8,20 @@
 var BUGNUMBER = 953270;
 var summary = 'Handles';
 
 // Check that NaN normalization is applied when extracting the x lane
 // out, after bit conversion has occurred.
 
 var int32x4 = SIMD.int32x4;
 var a = int32x4((4294967295), 200, 300, 400);
-var c = SIMD.int32x4.bitsToFloat32x4(a);
+var c = SIMD.float32x4.fromInt32x4Bits(a);
 
 // NaN canonicalization occurs when extracting out x lane:
 assertEq(c.x, NaN);
 
 // but underlying bits are faithfully transmitted
 // (though reinterpreted as a signed integer):
-var d = SIMD.float32x4.bitsToInt32x4(c);
+var d = SIMD.int32x4.fromFloat32x4Bits(c);
 assertEq(d.x, -1);
 
 reportCompare(true, true);
 print("Tests complete");
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedObject/simd/float32x4bitstoint32x4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 946042;
-var float32x4 = SIMD.float32x4;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'float32x4 bitsToInt32x4';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
-
-  var a = float32x4(1, 2, 3, 4);
-  var c = SIMD.float32x4.bitsToInt32x4(a);
-  assertEq(c.x, 1065353216);
-  assertEq(c.y, 1073741824);
-  assertEq(c.z, 1077936128);
-  assertEq(c.w, 1082130432);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
-
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/float32x4fromint32x4.js
@@ -0,0 +1,25 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 946042;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'float32x4 fromInt32x4';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  var a = int32x4(1, 2, 3, 4);
+  var c = SIMD.float32x4.fromInt32x4(a);
+  assertEq(c.x, 1);
+  assertEq(c.y, 2);
+  assertEq(c.z, 3);
+  assertEq(c.w, 4);
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/float32x4fromint32x4bits.js
@@ -0,0 +1,25 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 946042;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'float32x4 fromInt32x4Bits';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  var a = int32x4(100, 200, 300, 400);
+  var c = SIMD.float32x4.fromInt32x4Bits(a);
+  assertEq(c.x, 1.401298464324817e-43);
+  assertEq(c.y, 2.802596928649634e-43);
+  assertEq(c.z, 4.203895392974451e-43);
+  assertEq(c.w, 5.605193857299268e-43);
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedObject/simd/float32x4toint32x4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 946042;
-var float32x4 = SIMD.float32x4;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'float32x4 toInt32x4';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
-
-  var a = float32x4(1.1, 2.2, 3.3, 4.6);
-  var c = SIMD.float32x4.toInt32x4(a);
-  assertEq(c.x, 1);
-  assertEq(c.y, 2);
-  assertEq(c.z, 3);
-  assertEq(c.w, 4);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
-
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedObject/simd/int32x4bitstofloat32x4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 946042;
-var float32x4 = SIMD.float32x4;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'int32x4 bitsToFloat32x4';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
-
-  var a = int32x4(100, 200, 300, 400);
-  var c = SIMD.int32x4.bitsToFloat32x4(a);
-  assertEq(c.x, 1.401298464324817e-43);
-  assertEq(c.y, 2.802596928649634e-43);
-  assertEq(c.z, 4.203895392974451e-43);
-  assertEq(c.w, 5.605193857299268e-43);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
-
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/int32x4fromfloat32x4.js
@@ -0,0 +1,25 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 946042;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'int32x4 fromFloat32x4';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  var a = float32x4(1.1, 2.2, 3.3, 4.6);
+  var c = SIMD.int32x4.fromFloat32x4(a);
+  assertEq(c.x, 1);
+  assertEq(c.y, 2);
+  assertEq(c.z, 3);
+  assertEq(c.w, 4);
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/int32x4fromfloat32x4bits.js
@@ -0,0 +1,25 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 946042;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'int32x4 fromFloat32x4Bits';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  var a = float32x4(1, 2, 3, 4);
+  var c = SIMD.int32x4.fromFloat32x4Bits(a);
+  assertEq(c.x, 1065353216);
+  assertEq(c.y, 1073741824);
+  assertEq(c.z, 1077936128);
+  assertEq(c.w, 1082130432);
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
deleted file mode 100644
--- a/js/src/tests/ecma_6/TypedObject/simd/int32x4tofloat32x4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 946042;
-var float32x4 = SIMD.float32x4;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'int32x4 toFloat32x4';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
-
-  var a = int32x4(1, 2, 3, 4);
-  var c = SIMD.int32x4.toFloat32x4(a);
-  assertEq(c.x, 1);
-  assertEq(c.y, 2);
-  assertEq(c.z, 3);
-  assertEq(c.w, 4);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
-
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -59,16 +59,26 @@ js::intrinsic_ToObject(JSContext *cx, un
     RootedObject obj(cx, ToObject(cx, val));
     if (!obj)
         return false;
     args.rval().setObject(*obj);
     return true;
 }
 
 bool
+js::intrinsic_IsObject(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    Value val = args[0];
+    bool isObject = val.isObject();
+    args.rval().setBoolean(isObject);
+    return true;
+}
+
+bool
 js::intrinsic_ToInteger(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     double result;
     if (!ToInteger(cx, args[0], &result))
         return false;
     args.rval().setNumber(result);
     return true;
@@ -761,16 +771,17 @@ intrinsic_RuntimeDefaultLocale(JSContext
         return false;
 
     args.rval().setString(jslocale);
     return true;
 }
 
 static const JSFunctionSpec intrinsic_functions[] = {
     JS_FN("ToObject",                intrinsic_ToObject,                1,0),
+    JS_FN("IsObject",                intrinsic_IsObject,                1,0),
     JS_FN("ToInteger",               intrinsic_ToInteger,               1,0),
     JS_FN("ToString",                intrinsic_ToString,                1,0),
     JS_FN("IsCallable",              intrinsic_IsCallable,              1,0),
     JS_FN("IsConstructor",           intrinsic_IsConstructor,           1,0),
     JS_FN("ThrowError",              intrinsic_ThrowError,              4,0),
     JS_FN("AssertionFailed",         intrinsic_AssertionFailed,         1,0),
     JS_FN("SetScriptHints",          intrinsic_SetScriptHints,          2,0),
     JS_FN("MakeConstructible",       intrinsic_MakeConstructible,       1,0),
--- a/js/src/vm/StringBuffer.cpp
+++ b/js/src/vm/StringBuffer.cpp
@@ -72,17 +72,17 @@ FinishStringFlat(ExclusiveContext *cx, S
     size_t len = sb.length();
     if (!sb.append('\0'))
         return nullptr;
 
     ScopedJSFreePtr<CharT> buf(ExtractWellSized<CharT>(cx, cb));
     if (!buf)
         return nullptr;
 
-    JSFlatString *str = NewString<CanGC>(cx, buf.get(), len);
+    JSFlatString *str = NewStringDontDeflate<CanGC>(cx, buf.get(), len);
     if (!str)
         return nullptr;
 
     buf.forget();
     return str;
 }
 
 JSFlatString *
--- a/js/xpconnect/src/moz.build
+++ b/js/xpconnect/src/moz.build
@@ -85,15 +85,15 @@ LOCAL_INCLUDES += [
     '/content/html/content/src',
     '/content/html/document/src',
     '/content/svg/content/src',
     '/dom/base',
     '/dom/workers',
     '/js/ipc',
     '/layout/base',
     '/layout/style',
-    '/xpcom/reflect/xptinfo/src',
+    '/xpcom/reflect/xptinfo',
 ]
 
 if CONFIG['MOZ_B2G_BT']:
     LOCAL_INCLUDES += [
         '/dom/bluetooth',
     ]
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4132,16 +4132,18 @@ PresShell::FlushPendingNotifications(moz
   if (mDocument->GetScriptHandlingObject(hasHadScriptObject) ||
       hasHadScriptObject) {
     isSafeToFlush = isSafeToFlush && nsContentUtils::IsSafeToRunScript();
   }
 
   NS_ASSERTION(!isSafeToFlush || mViewManager, "Must have view manager");
   // Make sure the view manager stays alive.
   nsRefPtr<nsViewManager> viewManagerDeathGrip = mViewManager;
+  bool didStyleFlush = false;
+  bool didLayoutFlush = false;
   if (isSafeToFlush && mViewManager) {
     // Processing pending notifications can kill us, and some callers only
     // hold weak refs when calling FlushPendingNotifications().  :(
     nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
 
     if (mResizeEvent.IsPending()) {
       FireResizeEvent();
       if (mIsDestroying) {
@@ -4221,46 +4223,57 @@ PresShell::FlushPendingNotifications(moz
     // happen during reflow, might suddenly pick up the new rules and
     // we'll end up with frames whose style doesn't match the frame
     // type.
     if (!mIsDestroying) {
       nsAutoScriptBlocker scriptBlocker;
       mPresContext->RestyleManager()->ProcessPendingRestyles();
     }
 
+    didStyleFlush = true;
+
 
     // There might be more pending constructors now, but we're not going to
     // worry about them.  They can't be triggered during reflow, so we should
     // be good.
 
     if (flushType >= (mSuppressInterruptibleReflows ? Flush_Layout : Flush_InterruptibleLayout) &&
         !mIsDestroying) {
+      didLayoutFlush = true;
       mFrameConstructor->RecalcQuotesAndCounters();
       mViewManager->FlushDelayedResize(true);
       if (ProcessReflowCommands(flushType < Flush_Layout) && mContentToScrollTo) {
         // We didn't get interrupted.  Go ahead and scroll to our content
         DoScrollContentIntoView();
         if (mContentToScrollTo) {
           mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
           mContentToScrollTo = nullptr;
         }
       }
-    } else if (!mIsDestroying && mSuppressInterruptibleReflows &&
-               flushType == Flush_InterruptibleLayout) {
-      // We suppressed this flush, but the document thinks it doesn't
-      // need to flush anymore.  Let it know what's really going on.
-      mDocument->SetNeedLayoutFlush();
     }
 
     if (flushType >= Flush_Layout) {
       if (!mIsDestroying) {
         mViewManager->UpdateWidgetGeometry();
       }
     }
   }
+
+  if (!didStyleFlush && flushType >= Flush_Style && !mIsDestroying) {
+    mDocument->SetNeedStyleFlush();
+  }
+
+  if (!didLayoutFlush && !mIsDestroying &&
+      (flushType >=
+       (mSuppressInterruptibleReflows ? Flush_Layout : Flush_InterruptibleLayout))) {
+    // We suppressed this flush due to mSuppressInterruptibleReflows or
+    // !isSafeToFlush, but the document thinks it doesn't
+    // need to flush anymore.  Let it know what's really going on.
+    mDocument->SetNeedLayoutFlush();
+  }
 }
 
 void
 PresShell::CharacterDataWillChange(nsIDocument *aDocument,
                                    nsIContent*  aContent,
                                    CharacterDataChangeInfo* aInfo)
 {
   NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged");
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -175,32 +175,32 @@ public:
   // mContentArea.IStart == BorderPadding().IStart and
   // mContentArea.BStart == BorderPadding().BStart.
   // The block size may be NS_UNCONSTRAINEDSIZE, which indicates that there
   // is no page/column boundary below (the common case).
   // mContentArea.BEnd() should only be called after checking that
   // mContentArea.BSize is not NS_UNCONSTRAINEDSIZE; otherwise
   // coordinate overflow may occur.
   mozilla::LogicalRect mContentArea;
-  nscoord ContentIStart() {
+  nscoord ContentIStart() const {
     return mContentArea.IStart(mReflowState.GetWritingMode());
   }
-  nscoord ContentISize() {
+  nscoord ContentISize() const {
     return mContentArea.ISize(mReflowState.GetWritingMode());
   }
-  nscoord ContentIEnd() {
+  nscoord ContentIEnd() const {
     return mContentArea.IEnd(mReflowState.GetWritingMode());
   }
-  nscoord ContentBStart() {
+  nscoord ContentBStart() const {
     return mContentArea.BStart(mReflowState.GetWritingMode());
   }
-  nscoord ContentBSize() {
+  nscoord ContentBSize() const {
     return mContentArea.BSize(mReflowState.GetWritingMode());
   }
-  nscoord ContentBEnd() {
+  nscoord ContentBEnd() const {
     return mContentArea.BEnd(mReflowState.GetWritingMode());
   }
   nscoord mContainerWidth;
 
   // Continuation out-of-flow float frames that need to move to our
   // next in flow are placed here during reflow.  It's a pointer to
   // a frame list stored in the block's property table.
   nsFrameList *mPushedFloats;
--- a/layout/xul/tree/crashtests/730441-1.xul
+++ b/layout/xul/tree/crashtests/730441-1.xul
@@ -3,17 +3,17 @@
 Program received signal SIGSEGV, Segmentation fault.
 0xb6457185 in nsIContent::SetAttr (this=0x0, aNameSpaceID=0, aName=0xb0cb064c, aValue=..., aNotify=1) at ../../dist/include/nsIContent.h:285
 285	    return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
 (gdb) p this
 $6 = (nsIContent * const) 0x0
 (gdb) bt 3
 #0  0xb6457185 in nsIContent::SetAttr (this=0x0, aNameSpaceID=0, aName=0xb0cb064c, aValue=..., aNotify=1) at ../../dist/include/nsIContent.h:285
 #1  0xb6b72072 in nsTreeColumns::RestoreNaturalOrder (this=0xaaf83cc0) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:605
-#2  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
+#2  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
 (More stack frames follow...)
 (gdb) frame 1
 #1  0xb6b72072 in nsTreeColumns::RestoreNaturalOrder (this=0xaaf83cc0) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:605
 605	    child->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal, PR_TRUE);
 (gdb) list
 600	  PRUint32 numChildren = colsContent->GetChildCount();
 601	  for (PRUint32 i = 0; i < numChildren; ++i) {
 602	    nsIContent *child = colsContent->GetChildAt(i);
--- a/layout/xul/tree/crashtests/730441-2.xul
+++ b/layout/xul/tree/crashtests/730441-2.xul
@@ -1,16 +1,16 @@
 <?xml version="1.0"?>
 <!--
 Program received signal SIGSEGV, Segmentation fault.
 0xb6b720a6 in nsTreeColumns::RestoreNaturalOrder (this=0xa947a580) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:610
 610	  mTree->Invalidate();
 (gdb) bt 3
 #0  0xb6b720a6 in nsTreeColumns::RestoreNaturalOrder (this=0xa947a580) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:610
-#1  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
+#1  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
 #2  0xb6171901 in XPCWrappedNative::CallMethod (ccx=..., mode=XPCWrappedNative::CALL_METHOD)
     at js/src/xpconnect/src/xpcwrappednative.cpp:2722
 (More stack frames follow...)
 (gdb) list
 605	    child->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal, PR_TRUE);
 606	  }
 607	
 608	  nsTreeColumns::InvalidateColumns();
--- a/layout/xul/tree/crashtests/730441-3.xul
+++ b/layout/xul/tree/crashtests/730441-3.xul
@@ -2,17 +2,17 @@
 <!--
 ###!!! ASSERTION: You can't dereference a NULL nsCOMPtr with operator->().: 'mRawPtr != 0', file ../../../../dist/include/nsCOMPtr.h, line 796
 
 Program received signal SIGSEGV, Segmentation fault.
 0xb6b7463a in nsTreeContentView::SetTree (this=0xb0ba2510, aTree=0xaaecece0) at layout/xul/base/src/tree/src/nsTreeContentView.cpp:571
 571        boxObject->GetElement(getter_AddRefs(element));
 (gdb) bt 3
 #0  0xb6b7463a in nsTreeContentView::SetTree (this=0xb0ba2510, aTree=0xaaecece0) at layout/xul/base/src/tree/src/nsTreeContentView.cpp:571
-#1  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
+#1  0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69
 #2  0xb6171901 in XPCWrappedNative::CallMethod (ccx=..., mode=XPCWrappedNative::CALL_METHOD)
     at js/src/xpconnect/src/xpcwrappednative.cpp:2722
 (More stack frames follow...)
 (gdb) list 566
 561    nsTreeContentView::SetTree(nsITreeBoxObject* aTree)
 562    {
 563      ClearRows();
 564
--- a/media/libmkv/EbmlBufferWriter.c
+++ b/media/libmkv/EbmlBufferWriter.c
@@ -9,31 +9,31 @@
 #include <string.h>
 
 void
 Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len)
 {
   /* buffer_size:
    * 1 - int8_t;
    * 2 - int16_t;
-   * 3 - int32_t;
-   * 4 - int64_t;
+   * 4 - int32_t;
+   * 8 - int64_t;
    */
   long i;
   for(i = len-1; i >= 0; i--) {
     unsigned char x;
     if (buffer_size == 1) {
       x = (char)(*(const int8_t *)buffer_in >> (i * 8));
-	} else if (buffer_size == 2) {
+    } else if (buffer_size == 2) {
       x = (char)(*(const int16_t *)buffer_in >> (i * 8));
-	} else if (buffer_size == 4) {
+    } else if (buffer_size == 4) {
       x = (char)(*(const int32_t *)buffer_in >> (i * 8));
-	} else if (buffer_size == 8) {
+    } else if (buffer_size == 8) {
       x = (char)(*(const int64_t *)buffer_in >> (i * 8));
-	}
+    }
     Ebml_Write(glob, &x, 1);
   }
 }
 
 void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) {
   unsigned char *src = glob->buf;
   src += glob->offset;
   memcpy(src, buffer_in, len);
@@ -60,17 +60,17 @@ void Ebml_Serialize(EbmlGlobal *glob, co
 }
 */
 
 void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id) {
   unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLL;
   Ebml_WriteID(glob, class_id);
   ebmlLoc->offset = glob->offset;
   // todo this is always taking 8 bytes, this may need later optimization
-  Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says lenght unknown
+  Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says length unknown
 }
 
 void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
   unsigned long long size = glob->offset - ebmlLoc->offset - 8;
   unsigned long long curOffset = glob->offset;
   glob->offset = ebmlLoc->offset;
   size |=  0x0100000000000000LL;
   Ebml_Serialize(glob, &size,sizeof(size), 8);
new file mode 100644
--- /dev/null
+++ b/media/libmkv/cleanup.patch
@@ -0,0 +1,41 @@
+diff --git a/media/libmkv/EbmlBufferWriter.c b/media/libmkv/EbmlBufferWriter.c
+index 8c26e80..5925504 100644
+--- a/media/libmkv/EbmlBufferWriter.c
++++ b/media/libmkv/EbmlBufferWriter.c
+@@ -14,21 +14,21 @@ Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigne
+   /* buffer_size:
+    * 1 - int8_t;
+    * 2 - int16_t;
+-   * 3 - int32_t;
+-   * 4 - int64_t;
++   * 4 - int32_t;
++   * 8 - int64_t;
+    */
+   long i;
+   for(i = len-1; i >= 0; i--) {
+     unsigned char x;
+     if (buffer_size == 1) {
+       x = (char)(*(const int8_t *)buffer_in >> (i * 8));
+-	} else if (buffer_size == 2) {
++    } else if (buffer_size == 2) {
+       x = (char)(*(const int16_t *)buffer_in >> (i * 8));
+-	} else if (buffer_size == 4) {
++    } else if (buffer_size == 4) {
+       x = (char)(*(const int32_t *)buffer_in >> (i * 8));
+-	} else if (buffer_size == 8) {
++    } else if (buffer_size == 8) {
+       x = (char)(*(const int64_t *)buffer_in >> (i * 8));
+-	}
++    }
+     Ebml_Write(glob, &x, 1);
+   }
+ }
+@@ -65,7 +65,7 @@ void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long clas
+   Ebml_WriteID(glob, class_id);
+   ebmlLoc->offset = glob->offset;
+   // todo this is always taking 8 bytes, this may need later optimization
+-  Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says lenght unknown
++  Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says length unknown
+ }
+ 
+ void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
--- a/media/libmkv/update.sh
+++ b/media/libmkv/update.sh
@@ -31,8 +31,9 @@ else
 fi
 
 # Apply any patches against upstream here.
 patch -p1 < source_fix.patch
 patch -p1 < gecko_fix.patch
 patch -p1 < const_fix.patch
 patch -p3 < bock_fix.patch
 patch -p3 < bug970774.patch
+patch -p3 < cleanup.patch
--- a/netwerk/test/unit/test_cookiejars_safebrowsing.js
+++ b/netwerk/test/unit/test_cookiejars_safebrowsing.js
@@ -97,30 +97,28 @@ function run_test() {
 // rather we only set the cookies in the header of response.
 add_test(function test_safebrowsing_update() {
 
   var dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"]
                   .getService(Ci.nsIUrlClassifierDBService);
   var streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"]
                      .getService(Ci.nsIUrlClassifierStreamUpdater);
 
-  streamUpdater.updateUrl = URL + safebrowsingUpdatePath;
-
   function onSuccess() {
     run_next_test();
   }
   function onUpdateError() {
     do_throw("ERROR: received onUpdateError!");
   }
   function onDownloadError() {
     do_throw("ERROR: received onDownloadError!");
   }
 
   streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "",
-    onSuccess, onUpdateError, onDownloadError);
+    URL + safebrowsingUpdatePath, onSuccess, onUpdateError, onDownloadError);
 });
 
 add_test(function test_non_safebrowsing_cookie() {
 
   var cookieName = 'regCookie_id0';
   var loadContext = new LoadContextCallback(0, false, false, false);
 
   function setNonSafeBrowsingCookie() {
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
@@ -2,27 +2,28 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from telnetlib import Telnet
 import datetime
 import os
 import shutil
 import subprocess
+import sys
 import tempfile
 import time
 
 from mozprocess import ProcessHandler
 
 from .base import Device
 from .emulator_battery import EmulatorBattery
 from .emulator_geo import EmulatorGeo
 from .emulator_screen import EmulatorScreen
 from ..utils import uses_marionette
-from ..errors import TimeoutException, ScriptTimeoutException
+from ..errors import TimeoutException
 
 class ArchContext(object):
     def __init__(self, arch, context, binary=None):
         kernel = os.path.join(context.homedir, 'prebuilts', 'qemu-kernel', '%s', '%s')
         sysdir = os.path.join(context.homedir, 'out', 'target', 'product', '%s')
         if arch == 'x86':
             self.binary = os.path.join(context.bindir, 'emulator-x86')
             self.kernel = kernel % ('x86', 'kernel-qemu')
@@ -202,17 +203,23 @@ class Emulator(Device):
         print 'waiting for system-message-listener-ready...'
         try:
             marionette.execute_async_script("""
 waitFor(
     function() { marionetteScriptFinished(true); },
     function() { return isSystemMessageListenerReady(); }
 );
             """)
-        except ScriptTimeoutException:
+        except:
+            # Look for ScriptTimeoutException this way to avoid a
+            # dependency on the marionette python client.
+            exc_name = sys.exc_info()[0].__name__
+            if exc_name != 'ScriptTimeoutException':
+                raise
+
             print 'timed out'
             # We silently ignore the timeout if it occurs, since
             # isSystemMessageListenerReady() isn't available on
             # older emulators.  45s *should* be enough of a delay
             # to allow telephony API's to work.
             pass
         print '...done'
 
--- a/testing/mozbase/mozrunner/mozrunner/errors.py
+++ b/testing/mozbase/mozrunner/mozrunner/errors.py
@@ -6,11 +6,8 @@
 class RunnerException(Exception):
     """Base exception handler for mozrunner related errors"""
 
 class RunnerNotStartedError(RunnerException):
     """Exception handler in case the runner hasn't been started"""
 
 class TimeoutException(RunnerException):
     """Raised on timeout waiting for targets to start."""
-
-class ScriptTimeoutException(RunnerException):
-    """Raised on timeout waiting for execute_script to finish."""
--- a/toolkit/components/build/nsToolkitCompsCID.h
+++ b/toolkit/components/build/nsToolkitCompsCID.h
@@ -145,19 +145,19 @@
 // {3d8579f0-75fa-4e00-ba41-38661d5b5d17}
  #define NS_URLCLASSIFIERPREFIXSET_CID \
 { 0x3d8579f0, 0x75fa, 0x4e00, { 0xba, 0x41, 0x38, 0x66, 0x1d, 0x5b, 0x5d, 0x17} }
 
 // {8a389f21-f821-4e29-9c6b-3de6f33cd7cf}
 #define NS_URLCLASSIFIERDBSERVICE_CID \
 { 0x8a389f21, 0xf821, 0x4e29, { 0x9c, 0x6b, 0x3d, 0xe6, 0xf3, 0x3c, 0xd7, 0xcf} }
 
-// {79e6b710-ce68-4639-ac6b-7d293af424a1}
+// e1797597-f4d6-4dd3-a1e1-745ad352cd80
 #define NS_URLCLASSIFIERSTREAMUPDATER_CID \
-{ 0x79e6b710, 0xce68, 0x4639, { 0xac, 0x6b, 0x7d, 0x29, 0x3a, 0xf4, 0x24, 0xa1} }
+{ 0xe1797597, 0xf4d6, 0x4dd3, { 0xa1, 0xe1, 0x74, 0x5a, 0xd3, 0x52, 0xcd, 0x80 }}
 
 // {b7b2ccec-7912-4ea6-a548-b038447004bd}
 #define NS_URLCLASSIFIERUTILS_CID \
 { 0xb7b2ccec, 0x7912, 0x4ea6, { 0xa5, 0x48, 0xb0, 0x38, 0x44, 0x70, 0x04, 0xbd} }
 
 #define NS_NAVHISTORYSERVICE_CID \
 { 0x88cecbb7, 0x6c63, 0x4b3b, { 0x8c, 0xd4, 0x84, 0xf3, 0xb8, 0x22, 0x8c, 0x69 } }
 
--- a/toolkit/components/downloads/test/unit/test_app_rep.js
+++ b/toolkit/components/downloads/test/unit/test_app_rep.js
@@ -200,17 +200,16 @@ add_test(function test_local_list() {
     response.setHeader("Content-Type",
                        "application/vnd.google.safebrowsing-update", false);
     response.setStatusLine(request.httpVersion, 200, "OK");
     response.bodyOutputStream.write(blob, blob.length);
   });
 
   let streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"]
     .getService(Ci.nsIUrlClassifierStreamUpdater);
-  streamUpdater.updateUrl = "http://localhost:4444/downloads";
 
   // Load up some update chunks for the safebrowsing server to serve.
   // This chunk contains the hash of blocklisted.com/.
   registerTableUpdate("goog-badbinurl-shavar", "data/block_digest.chunk");
   // This chunk contains the hash of whitelisted.com/.
   registerTableUpdate("goog-downloadwhite-digest256", "data/digest.chunk");
 
   // Download some updates, and don't continue until the downloads are done.
@@ -223,16 +222,17 @@ add_test(function test_local_list() {
   }
   // Just throw if we ever get an update or download error.
   function handleError(aEvent) {
     do_throw("We didn't download or update correctly: " + aEvent);
   }
   streamUpdater.downloadUpdates(
     "goog-downloadwhite-digest256,goog-badbinurl-shavar",
     "goog-downloadwhite-digest256,goog-badbinurl-shavar;\n",
+    "http://localhost:4444/downloads",
     updateSuccess, handleError, handleError);
 });
 
 add_test(function test_unlisted() {
   Services.prefs.setCharPref("browser.safebrowsing.appRepURL",
                              "http://localhost:4444/download");
   let counts = get_telemetry_counts();
   let listCounts = counts.listCounts;
--- a/toolkit/components/downloads/test/unit/test_app_rep_windows.js
+++ b/toolkit/components/downloads/test/unit/test_app_rep_windows.js
@@ -252,17 +252,16 @@ function waitForUpdates() {
     response.setHeader("Content-Type",
                        "application/vnd.google.safebrowsing-update", false);
     response.setStatusLine(request.httpVersion, 200, "OK");
     response.bodyOutputStream.write(blob, blob.length);
   });
 
   let streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"]
     .getService(Ci.nsIUrlClassifierStreamUpdater);
-  streamUpdater.updateUrl = "http://localhost:4444/downloads";
 
   // Load up some update chunks for the safebrowsing server to serve. This
   // particular chunk contains the hash of whitelisted.com/ and
   // sb-ssl.google.com/safebrowsing/csd/certificate/.
   registerTableUpdate("goog-downloadwhite-digest256", "data/digest.chunk");
 
   // Resolve the promise once processing the updates is complete.
   function updateSuccess(aEvent) {
@@ -275,16 +274,17 @@ function waitForUpdates() {
   // Just throw if we ever get an update or download error.
   function handleError(aEvent) {
     do_throw("We didn't download or update correctly: " + aEvent);
     deferred.reject();
   }
   streamUpdater.downloadUpdates(
     "goog-downloadwhite-digest256",
     "goog-downloadwhite-digest256;\n",
+    "http://localhost:4444/downloads",
     updateSuccess, handleError, handleError);
   return deferred.promise;
 }
 
 function promiseQueryReputation(query, expectedShouldBlock) {
   let deferred = Promise.defer();
   function onComplete(aShouldBlock, aStatus) {
     do_check_eq(Cr.NS_OK, aStatus);
--- a/toolkit/components/url-classifier/Classifier.cpp
+++ b/toolkit/components/url-classifier/Classifier.cpp
@@ -313,17 +313,17 @@ Classifier::ApplyUpdates(nsTArray<TableU
   }
 #endif
 
   LOG(("Backup before update."));
 
   nsresult rv = BackupTables();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  LOG(("Applying table updates."));
+  LOG(("Applying %d table updates.", aUpdates->Length()));
 
   for (uint32_t i = 0; i < aUpdates->Length(); i++) {
     // Previous ApplyTableUpdates() may have consumed this update..
     if ((*aUpdates)[i]) {
       // Run all updates for one table
       nsCString updateTable(aUpdates->ElementAt(i)->TableName());
       rv = ApplyTableUpdates(aUpdates, updateTable);
       if (NS_FAILED(rv)) {
@@ -571,18 +571,19 @@ Classifier::RecoverBackups()
 nsresult
 Classifier::ApplyTableUpdates(nsTArray<TableUpdate*>* aUpdates,
                               const nsACString& aTable)
 {
   LOG(("Classifier::ApplyTableUpdates(%s)", PromiseFlatCString(aTable).get()));
 
   nsAutoPtr<HashStore> store(new HashStore(aTable, mStoreDirectory));
 
-  if (!store)
+  if (!store) {
     return NS_ERROR_FAILURE;
+  }
 
   // take the quick exit if there is no valid update for us
   // (common case)
   uint32_t validupdates = 0;
 
   for (uint32_t i = 0; i < aUpdates->Length(); i++) {
     TableUpdate *update = aUpdates->ElementAt(i);
     if (!update || !update->TableName().Equals(store->TableName()))
--- a/toolkit/components/url-classifier/SafeBrowsing.jsm
+++ b/toolkit/components/url-classifier/SafeBrowsing.jsm
@@ -49,26 +49,26 @@ this.SafeBrowsing = {
 
     Services.prefs.addObserver("browser.safebrowsing", this.readPrefs.bind(this), false);
     this.readPrefs();
 
     // Register our two types of tables, and add custom Mozilla entries
     let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"].
                       getService(Ci.nsIUrlListManager);
     for (let i = 0; i < phishingLists.length; ++i) {
-      listManager.registerTable(phishingLists[i], false);
+      listManager.registerTable(phishingLists[i], this.updateURL, this.gethashURL);
     }
     for (let i = 0; i < malwareLists.length; ++i) {
-      listManager.registerTable(malwareLists[i], false);
+      listManager.registerTable(malwareLists[i], this.updateURL, this.gethashURL);
     }
     for (let i = 0; i < downloadBlockLists.length; ++i) {
-      listManager.registerTable(downloadBlockLists[i], false);
+      listManager.registerTable(downloadBlockLists[i], this.updateURL, this.gethashURL);
     }
     for (let i = 0; i < downloadAllowLists.length; ++i) {
-      listManager.registerTable(downloadAllowLists[i], false);
+      listManager.registerTable(downloadAllowLists[i], this.updateURL, this.gethashURL);
     }
     this.addMozEntries();
 
     this.controlUpdateChecking();
     this.initialized = true;
 
     log("init() finished");
   },
@@ -129,25 +129,18 @@ this.SafeBrowsing = {
     this.reportMalwareErrorURL = Services.urlFormatter.formatURLPref(basePref + "reportMalwareErrorURL");
 
     // Urls used to update DB
     this.updateURL  = Services.urlFormatter.formatURLPref(basePref + "updateURL");
     this.gethashURL = Services.urlFormatter.formatURLPref(basePref + "gethashURL");
 
     this.updateURL  = this.updateURL.replace("SAFEBROWSING_ID", clientID);
     this.gethashURL = this.gethashURL.replace("SAFEBROWSING_ID", clientID);
-
-    let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"].
-                      getService(Ci.nsIUrlListManager);
-
-    listManager.setUpdateUrl(this.updateURL);
-    listManager.setGethashUrl(this.gethashURL);
   },
 
-
   controlUpdateChecking: function() {
     log("phishingEnabled:", this.phishingEnabled, "malwareEnabled:", this.malwareEnabled);
 
     let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"].
                       getService(Ci.nsIUrlListManager);
 
     for (let i = 0; i < phishingLists.length; ++i) {
       if (this.phishingEnabled) {
--- a/toolkit/components/url-classifier/content/listmanager.js
+++ b/toolkit/components/url-classifier/content/listmanager.js
@@ -1,467 +1,431 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-
 // This is the only implementation of nsIUrlListManager.
 // A class that manages lists, namely white and black lists for
 // phishing or malware protection. The ListManager knows how to fetch,
 // update, and store lists.
 //
 // There is a single listmanager for the whole application.
 //
 // TODO more comprehensive update tests, for example add unittest check 
 //      that the listmanagers tables are properly written on updates
 
+// Log only if browser.safebrowsing.debug is true
+var debug = false;
+function log(...stuff) {
+  if (!debug) {
+    return;
+  }
+
+  let msg = "listmanager: " + stuff.join(" ");
+  dump(msg + "\n");
+}
+
 function QueryAdapter(callback) {
   this.callback_ = callback;
 };
 
 QueryAdapter.prototype.handleResponse = function(value) {
   this.callback_.handleEvent(value);
 }
 
 /**
  * A ListManager keeps track of black and white lists and knows
  * how to update them.
  *
  * @constructor
  */
 function PROT_ListManager() {
-  this.debugZone = "listmanager";
-  G_debugService.enableZone(this.debugZone);
-
-  this.currentUpdateChecker_ = null;   // set when we toggle updates
   this.prefs_ = new G_Preferences();
   this.updateInterval = this.prefs_.getPref("urlclassifier.updateinterval", 30 * 60) * 1000;
 
-  this.updateserverURL_ = null;
-  this.gethashURL_ = null;
-
-  this.isTesting_ = false;
-
+  // A map of tableNames to objects of type
+  // { updateUrl: <updateUrl>, gethashUrl: <gethashUrl> }
   this.tablesData = {};
+  // A map of updateUrls to maps of tables requiring updates, e.g.
+  // { safebrowsing-update-url: { goog-phish-shavar: true,
+  //                              goog-malware-shavar: true }
+  this.needsUpdate_ = {};
 
   this.observerServiceObserver_ = new G_ObserverServiceObserver(
                                           'quit-application',
                                           BindToObject(this.shutdown_, this),
                                           true /*only once*/);
 
-  this.cookieObserver_ = new G_ObserverServiceObserver(
-                                          'cookie-changed',
-                                          BindToObject(this.cookieChanged_, this),
-                                          false);
-
-  /* Backoff interval should be between 30 and 60 minutes. */
-  var backoffInterval = 30 * 60 * 1000;
-  backoffInterval += Math.floor(Math.random() * (30 * 60 * 1000));
-
-  this.requestBackoff_ = new RequestBackoff(2 /* max errors */,
-                                      60*1000 /* retry interval, 1 min */,
-                                            4 /* num requests */,
-                                   60*60*1000 /* request time, 60 min */,
-                              backoffInterval /* backoff interval, 60 min */,
-                                 8*60*60*1000 /* max backoff, 8hr */);
-
+  this.updateCheckers_ = {};
+  this.requestBackoffs_ = {};
   this.dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
                    .getService(Ci.nsIUrlClassifierDBService);
 
+
   this.hashCompleter_ = Cc["@mozilla.org/url-classifier/hashcompleter;1"]
                         .getService(Ci.nsIUrlClassifierHashCompleter);
+  debug = this.prefs_.getPref("browser.safebrowsing.debug");
 }
 
 /**
  * xpcom-shutdown callback
  * Delete all of our data tables which seem to leak otherwise.
  */
 PROT_ListManager.prototype.shutdown_ = function() {
   for (var name in this.tablesData) {
     delete this.tablesData[name];
   }
 }
 
 /**
- * Set the url we check for updates.  If the new url is valid and different,
- * update our table list.
- * 
- * After setting the update url, the caller is responsible for registering
- * tables and then toggling update checking.  All the code for this logic is
- * currently in browser/components/safebrowsing.  Maybe it should be part of
- * the listmanger?
+ * Register a new table table
+ * @param tableName - the name of the table
+ * @param updateUrl - the url for updating the table
+ * @param gethashUrl - the url for fetching hash completions
+ * @returns true if the table could be created; false otherwise
  */
-PROT_ListManager.prototype.setUpdateUrl = function(url) {
-  G_Debug(this, "Set update url: " + url);
-  if (url != this.updateserverURL_) {
-    this.updateserverURL_ = url;
-    this.requestBackoff_.reset();
-    
-    // Remove old tables which probably aren't valid for the new provider.
-    for (var name in this.tablesData) {
-      delete this.tablesData[name];
-    }
+PROT_ListManager.prototype.registerTable = function(tableName,
+                                                    updateUrl,
+                                                    gethashUrl) {
+  log("registering " + tableName + " with " + updateUrl);
+  if (!updateUrl) {
+    log("Can't register table " + tableName + " without updateUrl");
+    return false;
   }
+  this.tablesData[tableName] = {};
+  this.tablesData[tableName].updateUrl = updateUrl;
+  this.tablesData[tableName].gethashUrl = gethashUrl;
+
+  // Keep track of all of our update URLs.
+  if (!this.needsUpdate_[updateUrl]) {
+    this.needsUpdate_[updateUrl] = {};
+    /* Backoff interval should be between 30 and 60 minutes. */
+    var backoffInterval = 30 * 60 * 1000;
+    backoffInterval += Math.floor(Math.random() * (30 * 60 * 1000));
+
+    log("Creating request backoff for " + updateUrl);
+    this.requestBackoffs_[updateUrl] = new RequestBackoff(2 /* max errors */,
+                                      60*1000 /* retry interval, 1 min */,
+                                            4 /* num requests */,
+                                   60*60*1000 /* request time, 60 min */,
+                              backoffInterval /* backoff interval, 60 min */,
+                                 8*60*60*1000 /* max backoff, 8hr */);
+
+  }
+  this.needsUpdate_[updateUrl][tableName] = false;
+
+  return true;
 }
 
-/**
- * Set the gethash url.
- */
-PROT_ListManager.prototype.setGethashUrl = function(url) {
-  G_Debug(this, "Set gethash url: " + url);
-  if (url != this.gethashURL_) {
-    this.gethashURL_ = url;
-    this.hashCompleter_.gethashUrl = url;
+PROT_ListManager.prototype.getGethashUrl = function(tableName) {
+  if (this.tablesData[tableName] && this.tablesData[tableName].gethashUrl) {
+    return this.tablesData[tableName].gethashUrl;
   }
-}
-
-/**
- * Register a new table table
- * @param tableName - the name of the table
- * @param opt_requireMac true if a mac is required on update, false otherwise
- * @returns true if the table could be created; false otherwise
- */
-PROT_ListManager.prototype.registerTable = function(tableName, 
-                                                    opt_requireMac) {
-  this.tablesData[tableName] = {};
-  this.tablesData[tableName].needsUpdate = false;
-
-  return true;
+  return "";
 }
 
 /**
  * Enable updates for some tables
  * @param tables - an array of table names that need updating
  */
 PROT_ListManager.prototype.enableUpdate = function(tableName) {
   var changed = false;
   var table = this.tablesData[tableName];
   if (table) {
-    G_Debug(this, "Enabling table updates for " + tableName);
-    table.needsUpdate = true;
+    log("Enabling table updates for " + tableName);
+    this.needsUpdate_[table.updateUrl][tableName] = true;
     changed = true;
   }
 
-  if (changed === true)
+  if (changed) {
     this.maybeToggleUpdateChecking();
+  }
 }
 
 /**
  * Disables updates for some tables
  * @param tables - an array of table names that no longer need updating
  */
 PROT_ListManager.prototype.disableUpdate = function(tableName) {
   var changed = false;
   var table = this.tablesData[tableName];
   if (table) {
-    G_Debug(this, "Disabling table updates for " + tableName);
-    table.needsUpdate = false;
+    log("Disabling table updates for " + tableName);
+    this.needsUpdate_[table.updateUrl][tableName] = false;
     changed = true;
   }
 
-  if (changed === true)
+  if (changed) {
     this.maybeToggleUpdateChecking();
+  }
 }
 
 /**
  * Determine if we have some tables that need updating.
  */
 PROT_ListManager.prototype.requireTableUpdates = function() {
-  for (var type in this.tablesData) {
-    // Tables that need updating even if other tables dont require it
-    if (this.tablesData[type].needsUpdate)
+  for (var name in this.tablesData) {
+    // Tables that need updating even if other tables don't require it
+    if (this.needsUpdate_[this.tablesData[name].updateUrl][name]) {
       return true;
+    }
   }
 
   return false;
 }
 
 /**
- * Start managing the lists we know about. We don't do this automatically
- * when the listmanager is instantiated because their profile directory
- * (where we store the lists) might not be available.
- */
-PROT_ListManager.prototype.maybeStartManagingUpdates = function() {
-  if (this.isTesting_)
-    return;
-
-  // We might have been told about tables already, so see if we should be
-  // actually updating.
-  this.maybeToggleUpdateChecking();
-}
-
-/**
  * Acts as a nsIUrlClassifierCallback for getTables.
  */
 PROT_ListManager.prototype.kickoffUpdate_ = function (onDiskTableData)
 {
   this.startingUpdate_ = false;
   var initialUpdateDelay = 3000;
 
   // Check if any table registered for updates has ever been downloaded.
-  var diskTablesAreUpdating = false;
+  var updatingExisting = false;
   for (var tableName in this.tablesData) {
-    if (this.tablesData[tableName].needsUpdate) {
+    if (this.needsUpdate_[this.tablesData[tableName].updateUrl][tableName]) {
       if (onDiskTableData.indexOf(tableName) != -1) {
-        diskTablesAreUpdating = true;
+        updatingExisting = true;
       }
     }
   }
 
   // If the user has never downloaded tables, do the check now.
-  // If the user has tables, add a fuzz of a few minutes.
-  if (diskTablesAreUpdating) {
-    // Add a fuzz of 0-5 minutes.
-    initialUpdateDelay += Math.floor(Math.random() * (5 * 60 * 1000));
+  log("needsUpdate: " + JSON.stringify(this.needsUpdate_, undefined, 2));
+  for (var url in this.needsUpdate_) {
+    // If the user has tables, add a fuzz of a few minutes.
+    if (updatingExisting) {
+      // Add a fuzz of 0-5 minutes.
+      initialUpdateDelay += Math.floor(Math.random() * (5 * 60 * 1000));
+    }
+    // If we haven't already kicked off updates for this updateUrl, set a
+    // repeating timer for it. The delay will be reset either on updateSuccess
+    // to this.updateinterval, or backed off on downloadError.
+    if (!this.updateCheckers_[url]) {
+      this.updateCheckers_[url] =
+        new G_Alarm(BindToObject(this.checkForUpdates, this, url),
+                    initialUpdateDelay, true /* repeating */);
+    }
   }
+}
 
-  this.currentUpdateChecker_ =
-    new G_Alarm(BindToObject(this.checkForUpdates, this),
-                initialUpdateDelay);
+PROT_ListManager.prototype.stopUpdateCheckers = function() {
+  log("Stopping updates");
+  for (var updateUrl in this.updateCheckers_) {
+    this.updateCheckers_[updateUrl].cancel();
+    this.updateCheckers_[updateUrl] = null;
+  }
 }
 
 /**
  * Determine if we have any tables that require updating.  Different
  * Wardens may call us with new tables that need to be updated.
  */ 
 PROT_ListManager.prototype.maybeToggleUpdateChecking = function() {
-  // If we are testing or dont have an application directory yet, we should
-  // not start reading tables from disk or schedule remote updates
-  if (this.isTesting_)
-    return;
-
   // We update tables if we have some tables that want updates.  If there
   // are no tables that want to be updated - we dont need to check anything.
-  if (this.requireTableUpdates() === true) {
-    G_Debug(this, "Starting managing lists");
-    this.startUpdateChecker();
+  if (this.requireTableUpdates()) {
+    log("Starting managing lists");
 
-    // Multiple warden can ask us to reenable updates at the same time, but we
-    // really just need to schedule a single update.
-    if (!this.currentUpdateChecker && !this.startingUpdate_) {
+    // Get the list of existing tables from the DBService before making any
+    // update requests.
+    if (!this.startingUpdate_) {
       this.startingUpdate_ = true;
       // check the current state of tables in the database
       this.dbService_.getTables(BindToObject(this.kickoffUpdate_, this));
     }
   } else {
-    G_Debug(this, "Stopping managing lists (if currently active)");
-    this.stopUpdateChecker();                    // Cancel pending updates
-  }
-}
-
-/**
- * Start periodic checks for updates. Idempotent.
- * We want to distribute update checks evenly across the update period (an
- * hour).  The first update is scheduled for a random time between 0.5 and 1.5
- * times the update interval.
- */
-PROT_ListManager.prototype.startUpdateChecker = function() {
-  this.stopUpdateChecker();
-
-  // Schedule the first check for between 15 and 45 minutes.
-  var repeatingUpdateDelay = this.updateInterval / 2;
-  repeatingUpdateDelay += Math.floor(Math.random() * this.updateInterval);
-  this.updateChecker_ = new G_Alarm(BindToObject(this.initialUpdateCheck_,
-                                                 this),
-                                    repeatingUpdateDelay);
-}
-
-/**
- * Callback for the first update check.
- * We go ahead and check for table updates, then start a regular timer (once
- * every update interval).
- */
-PROT_ListManager.prototype.initialUpdateCheck_ = function() {
-  this.checkForUpdates();
-  this.updateChecker_ = new G_Alarm(BindToObject(this.checkForUpdates, this), 
-                                    this.updateInterval, true /* repeat */);
-}
-
-/**
- * Stop checking for updates. Idempotent.
- */
-PROT_ListManager.prototype.stopUpdateChecker = function() {
-  if (this.updateChecker_) {
-    this.updateChecker_.cancel();
-    this.updateChecker_ = null;
-  }
-  // Cancel the oneoff check from maybeToggleUpdateChecking.
-  if (this.currentUpdateChecker_) {
-    this.currentUpdateChecker_.cancel();
-    this.currentUpdateChecker_ = null;
+    log("Stopping managing lists (if currently active)");
+    this.stopUpdateCheckers();                    // Cancel pending updates
   }
 }
 
 /**
  * Provides an exception free way to look up the data in a table. We
  * use this because at certain points our tables might not be loaded,
  * and querying them could throw.
  *
  * @param table String Name of the table that we want to consult
  * @param key Principal being used to lookup the database
  * @param callback nsIUrlListManagerCallback (ie., Function) given false or the
  *        value in the table corresponding to key.  If the table name does not
  *        exist, we return false, too.
  */
 PROT_ListManager.prototype.safeLookup = function(key, callback) {
   try {
-    G_Debug(this, "safeLookup: " + key);
+    log("safeLookup: " + key);
     var cb = new QueryAdapter(callback);
     this.dbService_.lookup(key,
                            BindToObject(cb.handleResponse, cb),
                            true);
   } catch(e) {
-    G_Debug(this, "safeLookup masked failure for key " + key + ": " + e);
+    log("safeLookup masked failure for key " + key + ": " + e);
     callback.handleEvent("");
   }
 }
 
 /**
  * Updates our internal tables from the update server
  *
- * @returns true when a new request was scheduled, false if an old request
- *          was still pending.
+ * @param updateUrl: request updates for tables associated with that url, or
+ * for all tables if the url is empty.
  */
-PROT_ListManager.prototype.checkForUpdates = function() {
-  // Allow new updates to be scheduled from maybeToggleUpdateChecking()
-  this.currentUpdateChecker_ = null;
-
-  if (!this.updateserverURL_) {
-    G_Debug(this, 'checkForUpdates: no update server url');
+PROT_ListManager.prototype.checkForUpdates = function(updateUrl) {
+  log("checkForUpdates with " + updateUrl);
+  // See if we've triggered the request backoff logic.
+  if (!updateUrl) {
     return false;
   }
-
-  // See if we've triggered the request backoff logic.
-  if (!this.requestBackoff_.canMakeRequest())
+  if (!this.requestBackoffs_[updateUrl] ||
+      !this.requestBackoffs_[updateUrl].canMakeRequest()) {
     return false;
-
+  }
   // Grab the current state of the tables from the database
-  this.dbService_.getTables(BindToObject(this.makeUpdateRequest_, this));
+  this.dbService_.getTables(BindToObject(this.makeUpdateRequest_, this,
+                            updateUrl));
   return true;
 }
 
 /**
  * Method that fires the actual HTTP update request.
  * First we reset any tables that have disappeared.
  * @param tableData List of table data already in the database, in the form
  *        tablename;<chunk ranges>\n
  */
-PROT_ListManager.prototype.makeUpdateRequest_ = function(tableData) {
-  var tableList;
-  var tableNames = {};
+PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
+  log("this.tablesData: " + JSON.stringify(this.tablesData, undefined, 2));
+  log("existing chunks: " + tableData + "\n");
+  // Disallow blank updateUrls
+  if (!updateUrl) {
+    return;
+  }
+  // An object of the form
+  // { tableList: comma-separated list of tables to request,
+  //   tableNames: map of tables that need updating,
+  //   request: list of tables and existing chunk ranges from tableData
+  // }
+  var streamerMap = { tableList: null, tableNames: {}, request: "" };
   for (var tableName in this.tablesData) {
-    if (this.tablesData[tableName].needsUpdate)
-      tableNames[tableName] = true;
-    if (!tableList) {
-      tableList = tableName;
+    // Skip tables not matching this update url
+    if (this.tablesData[tableName].updateUrl != updateUrl) {
+      continue;
+    }
+    if (this.needsUpdate_[this.tablesData[tableName].updateUrl][tableName]) {
+      streamerMap.tableNames[tableName] = true;
+    }
+    if (!streamerMap.tableList) {
+      streamerMap.tableList = tableName;
     } else {
-      tableList += "," + tableName;
+      streamerMap.tableList += "," + tableName;
     }
   }
-
-  var request = "";
-
-  // For each table already in the database, include the chunk data from
-  // the database
+  // Build the request. For each table already in the database, include the
+  // chunk data from the database
   var lines = tableData.split("\n");
   for (var i = 0; i < lines.length; i++) {
     var fields = lines[i].split(";");
-    if (tableNames[fields[0]]) {
-      request += lines[i] + "\n";
-      delete tableNames[fields[0]];
+    var name = fields[0];
+    if (streamerMap.tableNames[name]) {
+      streamerMap.request += lines[i] + "\n";
+      delete streamerMap.tableNames[name];
     }
   }
+  // For each requested table that didn't have chunk data in the database,
+  // request it fresh
+  for (let tableName in streamerMap.tableNames) {
+    streamerMap.request += tableName + ";\n";
+  }
 
-  // For each requested table that didn't have chunk data in the database,
-  // request it fresh
-  for (var tableName in tableNames) {
-    request += tableName + ";\n";
+  log("update request: " + JSON.stringify(streamerMap, undefined, 2) + "\n");
+
+  if (Object.keys(streamerMap.tableNames).length > 0) {
+    this.makeUpdateRequestForEntry_(updateUrl, streamerMap.tableList,
+                                    streamerMap.request);
   }
+}
 
-  G_Debug(this, 'checkForUpdates: scheduling request..');
+PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl,
+                                                                 tableList,
+                                                                 request) {
+  log("makeUpdateRequestForEntry_: request " + request + " update: " +
+      updateUrl + " tablelist: " + tableList + "\n");
   var streamer = Cc["@mozilla.org/url-classifier/streamupdater;1"]
                  .getService(Ci.nsIUrlClassifierStreamUpdater);
-  try {
-    streamer.updateUrl = this.updateserverURL_;
-  } catch (e) {
-    G_Debug(this, 'invalid url');
-    return;
-  }
+
+  this.requestBackoffs_[updateUrl].noteRequest();
 
-  this.requestBackoff_.noteRequest();
-
-  if (!streamer.downloadUpdates(tableList,
-                                request,
-                                BindToObject(this.updateSuccess_, this),
-                                BindToObject(this.updateError_, this),
-                                BindToObject(this.downloadError_, this))) {
-    G_Debug(this, "pending update, wait until later");
+  if (!streamer.downloadUpdates(
+        tableList,
+        request,
+        updateUrl,
+        BindToObject(this.updateSuccess_, this, tableList, updateUrl),
+        BindToObject(this.updateError_, this, tableList, updateUrl),
+        BindToObject(this.downloadError_, this, tableList, updateUrl))) {
+    log("pending update, wait until later");
   }
 }
 
 /**
  * Callback function if the update request succeeded.
  * @param waitForUpdate String The number of seconds that the client should
  *        wait before requesting again.
  */
-PROT_ListManager.prototype.updateSuccess_ = function(waitForUpdate) {
-  G_Debug(this, "update success: " + waitForUpdate);
+PROT_ListManager.prototype.updateSuccess_ = function(tableList, updateUrl,
+                                                     waitForUpdate) {
+  log("update success for " + tableList + " from " + updateUrl + ": " +
+      waitForUpdate + "\n");
   if (waitForUpdate) {
     var delay = parseInt(waitForUpdate, 10);
     // As long as the delay is something sane (5 minutes or more), update
-    // our delay time for requesting updates
-    if (delay >= (5 * 60) && this.updateChecker_)
-      this.updateChecker_.setDelay(delay * 1000);
+    // our delay time for requesting updates. Setting the delay requires a
+    // repeating timer, so always use one.
+    if (delay >= (5 * 60) && this.updateCheckers_[updateUrl]) {
+      log("Waiting " + delay);
+      this.updateCheckers_[updateUrl].setDelay(delay * 1000);
+    } else {
+      log("Ignoring delay from server, waiting " + this.updateInterval);
+      this.updateCheckers_[updateUrl].setDelay(this.updateInterval);
+    }
   }
 
   // Let the backoff object know that we completed successfully.
-  this.requestBackoff_.noteServerResponse(200);
+  this.requestBackoffs_[updateUrl].noteServerResponse(200);
 }
 
 /**
  * Callback function if the update request succeeded.
  * @param result String The error code of the failure
  */
-PROT_ListManager.prototype.updateError_ = function(result) {
-  G_Debug(this, "update error: " + result);
+PROT_ListManager.prototype.updateError_ = function(table, updateUrl, result) {
+  log("update error for " + table + " from " + updateUrl + ": " + result + "\n");
   // XXX: there was some trouble applying the updates.
 }
 
 /**
  * Callback function when the download failed
  * @param status String http status or an empty string if connection refused.
  */
-PROT_ListManager.prototype.downloadError_ = function(status) {
-  G_Debug(this, "download error: " + status);
+PROT_ListManager.prototype.downloadError_ = function(table, updateUrl, status) {
+  log("download error for " + table + ": " + status + "\n");
   // If status is empty, then we assume that we got an NS_CONNECTION_REFUSED
   // error.  In this case, we treat this is a http 500 error.
   if (!status) {
     status = 500;
   }
   status = parseInt(status, 10);
-  this.requestBackoff_.noteServerResponse(status);
-
-  if (this.requestBackoff_.isErrorStatus(status)) {
+  this.requestBackoffs_[updateUrl].noteServerResponse(status);
+  if (this.requestBackoffs_[updateUrl].isErrorStatus(status)) {
     // Schedule an update for when our backoff is complete
-    this.currentUpdateChecker_ =
-      new G_Alarm(BindToObject(this.checkForUpdates, this),
-                  this.requestBackoff_.nextRequestDelay());
+    this.updateCheckers_[updateUrl].setDelay(
+      this.requestBackoffs_[updateUrl].nextRequestDelay());
   }
 }
 
-/**
- * Called when cookies are cleared
- */
-PROT_ListManager.prototype.cookieChanged_ = function(subject, topic, data) {
-  if (data != "cleared")
-    return;
-
-  G_Debug(this, "cookies cleared");
-}
-
 PROT_ListManager.prototype.QueryInterface = function(iid) {
   if (iid.equals(Ci.nsISupports) ||
       iid.equals(Ci.nsIUrlListManager) ||
       iid.equals(Ci.nsITimerCallback))
     return this;
 
   throw Components.results.NS_ERROR_NO_INTERFACE;
 }
--- a/toolkit/components/url-classifier/content/request-backoff.js
+++ b/toolkit/components/url-classifier/content/request-backoff.js
@@ -16,17 +16,17 @@ const HTTP_FOUND                 = 302;
 const HTTP_SEE_OTHER             = 303;
 const HTTP_TEMPORARY_REDIRECT    = 307;
 
 /**
  * @param maxErrors Number of times to request before backing off.
  * @param retryIncrement Time (ms) for each retry before backing off.
  * @param maxRequests Number the number of requests needed to trigger backoff
  * @param requestPeriod Number time (ms) in which maxRequests have to occur to
- *     trigger the backoff behavior
+ *     trigger the backoff behavior (0 to disable maxRequests)
  * @param timeoutIncrement Number time (ms) the starting timeout period
  *     we double this time for consecutive errors
  * @param maxTimeout Number time (ms) maximum timeout period
  */
 function RequestBackoff(maxErrors, retryIncrement,
                         maxRequests, requestPeriod,
                         timeoutIncrement, maxTimeout) {
   this.MAX_ERRORS_ = maxErrors;
@@ -40,17 +40,17 @@ function RequestBackoff(maxErrors, retry
   this.requestTimes_ = [];
 
   this.numErrors_ = 0;
   this.errorTimeout_ = 0;
   this.nextRequestTime_ = 0;
 }
 
 /**
- * Reset the object for reuse.
+ * Reset the object for reuse. This deliberately doesn't clear requestTimes_.
  */
 RequestBackoff.prototype.reset = function() {
   this.numErrors_ = 0;
   this.errorTimeout_ = 0;
   this.nextRequestTime_ = 0;
 }
 
 /**
--- a/toolkit/components/url-classifier/nsIUrlClassifierHashCompleter.idl
+++ b/toolkit/components/url-classifier/nsIUrlClassifierHashCompleter.idl
@@ -41,26 +41,25 @@ interface nsIUrlClassifierHashCompleterC
  * Clients updating the url-classifier database have the option of sending
  * partial (32-bit) hashes of URL fragments to be blacklisted.  If the
  * url-classifier encounters one of these truncated hashes, it will ask an
  * nsIUrlClassifierCompleter instance to asynchronously provide the complete
  * hash, along with some associated metadata.
  * This is only ever used for testing and should absolutely be deleted (I
  * think).
  */
-[scriptable, uuid(ade9b72b-3562-44f5-aba6-e63246be53ae)]
+[scriptable, uuid(231fb2ad-ea8a-4e63-a331-eafc3b434811)]
 interface nsIUrlClassifierHashCompleter : nsISupports
 {
   /**
-   * Request a completed hash.
+   * Request a completed hash from the given gethash url.
    *
    * @param partialHash
    *        The 32-bit hash encountered by the url-classifier.
+   * @param gethashUrl
+   *        The gethash url to use.
    * @param callback
    *        An nsIUrlClassifierCompleterCallback instance.
    */
   void complete(in ACString partialHash,
+                in ACString gethashUrl,
                 in nsIUrlClassifierHashCompleterCallback callback);
-  /**
-   * The URL for the gethash request
-   */
-  attribute ACString gethashUrl;
 };
--- a/toolkit/components/url-classifier/nsIUrlClassifierStreamUpdater.idl
+++ b/toolkit/components/url-classifier/nsIUrlClassifierStreamUpdater.idl
@@ -6,35 +6,31 @@
 #include "nsISupports.idl"
 #include "nsIUrlClassifierDBService.idl"
 
 /**
  * This is a class to manage large table updates from the server.  Rather than
  * downloading the whole update and then updating the sqlite database, we
  * update tables as the data is streaming in.
  */
-[scriptable, uuid(79e6b710-ce68-4639-ac6b-7d293af424a1)]
+[scriptable, uuid(e1797597-f4d6-4dd3-a1e1-745ad352cd80)]
 interface nsIUrlClassifierStreamUpdater : nsISupports
 {
   /**
-   * The Url to download from.  Should be plain ascii text.
-   */
-  attribute ACString updateUrl;
-
-  /**
-   * Try to download updates from updateUrl.  Only one instance of this
-   * runs at a time, so we return false if another instance is already
-   * running.
-   * This is used in nsIUrlListManager as well as in testing.
+   * Try to download updates from updateUrl. If an update is already in
+   * progress, queues the requested update. This is used in nsIUrlListManager
+   * as well as in testing.
    * @param aRequestTables Comma-separated list of tables included in this
    *        update.
    * @param aRequestBody The body for the request.
+   * @param aUpdateUrl The plaintext url from which to request updates.
    * @param aSuccessCallback Called after a successful update.
    * @param aUpdateErrorCallback Called for problems applying the update
    * @param aDownloadErrorCallback Called if we get an http error or a
    *        connection refused error.
    */
   boolean downloadUpdates(in ACString aRequestTables,
                           in ACString aRequestBody,
+                          in ACString aUpdateUrl,
                           in nsIUrlClassifierCallback aSuccessCallback,
                           in nsIUrlClassifierCallback aUpdateErrorCallback,
                           in nsIUrlClassifierCallback aDownloadErrorCallback);
 };
--- a/toolkit/components/url-classifier/nsIUrlListManager.idl
+++ b/toolkit/components/url-classifier/nsIUrlListManager.idl
@@ -13,50 +13,48 @@ interface nsIPrincipal;
 
 // Interface for JS function callbacks
 [scriptable, function, uuid(fa4caf12-d057-4e7e-81e9-ce066ceee90b)]
 interface nsIUrlListManagerCallback : nsISupports {
   void handleEvent(in ACString value);
 };
 
 
-[scriptable, uuid(62484bb5-bf7e-4988-9055-8803b16b48a1)]
+[scriptable, uuid(653afdc4-ad4e-4ee0-8375-c576e85ebc40)]
 interface nsIUrlListManager : nsISupports
 {
     /**
-     * Set the URL we check for updates.
+     * Get the gethash url for this table
      */
-    void setUpdateUrl(in ACString url);
+    ACString getGethashUrl(in ACString tableName);
 
     /**
-     * Set the URL that we will query for complete hashes after a partial
-     * hash match.
+     * Add a table to the list of tables we are managing. The name is a
+     * string of the format provider_name-semantic_type-table_type.  For
+     * @param tableName A string of the format
+     *        provider_name-semantic_type-table_type.  For example,
+     *        goog-white-enchash or goog-black-url.
+     * @param updateUrl The URL from which to fetch updates.
+     * @param gethashUrl The URL from which to fetch hash completions.
      */
-    void setGethashUrl(in ACString url);
+    boolean registerTable(in ACString tableName,
+                          in ACString updateUrl,
+                          in ACString gethashUrl);
 
     /**
-     * Add a table to the list of tables we are managing.  The name is a
-     * string of the format provider_name-semantic_type-table_type.  For
-     * example, goog-white-enchash or goog-black-url.
-     */
-    boolean registerTable(in ACString tableName);
-
-    /**
-     * Turn on update checking for a table.  I.e., during the next server
+     * Turn on update checking for a table. I.e., during the next server
      * check, download updates for this table.
      */
     void enableUpdate(in ACString tableName);
 
     /**
      * Turn off update checking for a table.
      */
     void disableUpdate(in ACString tableName);
 
     /**
      * Lookup a key.  Should not raise exceptions.  Calls the callback
      * function with a comma-separated list of tables to which the key
      * belongs.
      */
     void safeLookup(in nsIPrincipal key,
                     in nsIUrlListManagerCallback cb);
-
-    void checkForUpdates();
 };
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -89,17 +89,17 @@ nsIThread* nsUrlClassifierDBService::gDb
 
 // Once we've committed to shutting down, don't do work in the background
 // thread.
 static bool gShuttingDownThread = false;
 
 static mozilla::Atomic<int32_t> gFreshnessGuarantee(CONFIRM_AGE_DEFAULT_SEC);
 
 // -------------------------------------------------------------------------
-// Actual worker implemenatation
+// Actual worker implementation
 class nsUrlClassifierDBServiceWorker MOZ_FINAL :
   public nsIUrlClassifierDBServiceWorker
 {
 public:
   nsUrlClassifierDBServiceWorker();
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURLCLASSIFIERDBSERVICE
@@ -423,18 +423,19 @@ nsUrlClassifierDBServiceWorker::SetHashC
 }
 
 NS_IMETHODIMP
 nsUrlClassifierDBServiceWorker::BeginUpdate(nsIUrlClassifierUpdateObserver *observer,
                                             const nsACString &tables)
 {
   LOG(("nsUrlClassifierDBServiceWorker::BeginUpdate [%s]", PromiseFlatCString(tables).get()));
 
-  if (gShuttingDownThread)
+  if (gShuttingDownThread) {
     return NS_ERROR_NOT_INITIALIZED;
+  }
 
   NS_ENSURE_STATE(!mUpdateObserver);
 
   nsresult rv = OpenDb();
   if (NS_FAILED(rv)) {
     NS_ERROR("Unable to open SafeBrowsing database");
     return NS_ERROR_FAILURE;
   }
@@ -518,18 +519,20 @@ nsUrlClassifierDBServiceWorker::UpdateSt
 
   // Feed the chunk to the parser.
   return mProtocolParser->AppendStream(chunk);
 }
 
 NS_IMETHODIMP
 nsUrlClassifierDBServiceWorker::FinishStream()
 {
-  if (gShuttingDownThread)
+  if (gShuttingDownThread) {
+    LOG(("shutting down"));
     return NS_ERROR_NOT_INITIALIZED;
+  }
 
   NS_ENSURE_STATE(mInStream);
   NS_ENSURE_STATE(mUpdateObserver);
 
   mInStream = false;
 
   if (NS_SUCCEEDED(mProtocolParser->Status())) {
     if (mProtocolParser->UpdateWait()) {
@@ -817,23 +820,36 @@ nsUrlClassifierLookupCallback::LookupCom
 
   // Check the results entries that need to be completed.
   for (uint32_t i = 0; i < results->Length(); i++) {
     LookupResult& result = results->ElementAt(i);
 
     // We will complete partial matches and matches that are stale.
     if (!result.Confirmed()) {
       nsCOMPtr<nsIUrlClassifierHashCompleter> completer;
+      nsCString gethashUrl;
+      nsresult rv;
+      nsCOMPtr<nsIUrlListManager> listManager = do_GetService(
+        "@mozilla.org/url-classifier/listmanager;1", &rv);
+      NS_ENSURE_SUCCESS(rv, rv);
+      rv = listManager->GetGethashUrl(result.mTableName, gethashUrl);
+      NS_ENSURE_SUCCESS(rv, rv);
+      // We only allow empty gethashUrls for test- tables
+      if (gethashUrl.IsEmpty()) {
+        MOZ_ASSERT(
+          StringBeginsWith(result.mTableName, NS_LITERAL_CSTRING("test-")),
+          "Only test tables may have empty gethash urls");
+      }
       if (mDBService->GetCompleter(result.mTableName,
                                    getter_AddRefs(completer))) {
         nsAutoCString partialHash;
         partialHash.Assign(reinterpret_cast<char*>(&result.hash.prefix),
                            PREFIX_SIZE);
 
-        nsresult rv = completer->Complete(partialHash, this);
+        nsresult rv = completer->Complete(partialHash, gethashUrl, this);
         if (NS_SUCCEEDED(rv)) {
           mPendingCompletions++;
         }
       } else {
         // For tables with no hash completer, a complete hash match is
         // good enough, we'll consider it fresh.
         if (result.Complete()) {
           result.mFresh = true;
@@ -1337,18 +1353,20 @@ nsUrlClassifierDBService::SetHashComplet
 }
 
 NS_IMETHODIMP
 nsUrlClassifierDBService::BeginUpdate(nsIUrlClassifierUpdateObserver *observer,
                                       const nsACString &updateTables)
 {
   NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
 
-  if (mInUpdate)
+  if (mInUpdate) {
+    LOG(("Already updating, not available"));
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
   mInUpdate = true;
 
   // The proxy observer uses the current thread
   nsCOMPtr<nsIUrlClassifierUpdateObserver> proxyObserver =
     new UrlClassifierUpdateObserverProxy(observer);
 
   return mWorkerProxy->BeginUpdate(proxyObserver, updateTables);
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.h
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.h
@@ -8,16 +8,17 @@
 
 #include <nsISupportsUtils.h>
 
 #include "nsID.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIObserver.h"
 #include "nsUrlClassifierPrefixSet.h"
 #include "nsIUrlClassifierHashCompleter.h"
+#include "nsIUrlListManager.h"
 #include "nsIUrlClassifierDBService.h"
 #include "nsIURIClassifier.h"
 #include "nsToolkitCompsCID.h"
 #include "nsICryptoHash.h"
 #include "nsICryptoHMAC.h"
 #include "mozilla/Attributes.h"
 
 #include "LookupCache.h"
--- a/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
@@ -9,197 +9,164 @@ const Cu = Components.utils;
 
 // COMPLETE_LENGTH and PARTIAL_LENGTH copied from nsUrlClassifierDBService.h,
 // they correspond to the length, in bytes, of a hash prefix and the total
 // hash.
 const COMPLETE_LENGTH = 32;
 const PARTIAL_LENGTH = 4;
 
 // These backoff related constants are taken from v2 of the Google Safe Browsing
-// API.
+// API. All times are in milliseconds.
 // BACKOFF_ERRORS: the number of errors incurred until we start to back off.
-// BACKOFF_INTERVAL: the initial time, in seconds, to wait once we start backing
+// BACKOFF_INTERVAL: the initial time to wait once we start backing
 //                   off.
 // BACKOFF_MAX: as the backoff time doubles after each failure, this is a
-//              ceiling on the time to wait, in seconds.
-// BACKOFF_TIME: length of the interval of time, in seconds, during which errors
-//               are taken into account.
+//              ceiling on the time to wait.
 
 const BACKOFF_ERRORS = 2;
-const BACKOFF_INTERVAL = 30 * 60;
-const BACKOFF_MAX = 8 * 60 * 60;
-const BACKOFF_TIME = 5 * 60;
+const BACKOFF_INTERVAL = 30 * 60 * 1000;
+const BACKOFF_MAX = 8 * 60 * 60 * 1000;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 function HashCompleter() {
-  // This is a HashCompleterRequest and is used by multiple calls to |complete|
-  // in succession to avoid unnecessarily creating requests. Once it has been
-  // started, this is set to null again.
+  // The current HashCompleterRequest in flight. Once it is started, it is set
+  // to null. It may be used by multiple calls to |complete| in succession to
+  // avoid creating multiple requests to the same gethash URL.
   this._currentRequest = null;
+  // A map of gethashUrls to HashCompleterRequests that haven't yet begun.
+  this._pendingRequests = {};
+
+  // A map of gethash URLs to RequestBackoff objects.
+  this._backoffs = {};
 
   // Whether we have been informed of a shutdown by the xpcom-shutdown event.
   this._shuttingDown = false;
 
-  // All of these backoff properties are different per completer as the DB
-  // service keeps one completer per table.
-  //
-  // _backoff tells us whether we are "backing off" from making requests.
-  // It is set in |noteServerResponse| and set after a number of failures.
-  this._backoff = false;
-  // _backoffTime tells us how long we should wait (in seconds) before making
-  // another request.
-  this._backoffTime = 0;
-  // _nextRequestTime is the earliest time at which we are allowed to make
-  // another request by the backoff policy. It is measured in milliseconds.
-  this._nextRequestTime = 0;
-  // A list of the times at which a failed request was made, recorded in
-  // |noteServerResponse|. Sorted by oldest to newest and its length is clamped
-  // by BACKOFF_ERRORS.
-  this._errorTimes = [];
-
   Services.obs.addObserver(this, "xpcom-shutdown", true);
 }
+
 HashCompleter.prototype = {
   classID: Components.ID("{9111de73-9322-4bfc-8b65-2b727f3e6ec8}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIUrlClassifierHashCompleter,
                                          Ci.nsIRunnable,
                                          Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference,
                                          Ci.nsISupports]),
 
   // This is mainly how the HashCompleter interacts with other components.
   // Even though it only takes one partial hash and callback, subsequent
   // calls are made into the same HTTP request by using a thread dispatch.
-  complete: function HC_complete(aPartialHash, aCallback) {
-    if (!this._currentRequest) {
-      this._currentRequest = new HashCompleterRequest(this);
-
-      // It's possible for getHashUrl to not be set, usually at start-up.
-      if (this._getHashUrl) {
-        Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
-      }
-    }
-
-    this._currentRequest.add(aPartialHash, aCallback);
-  },
-
-  // This is called when either the getHashUrl has been set or after a few calls
-  // to |complete|. It starts off the HTTP request by making a |begin| call
-  // to the HashCompleterRequest.
-  run: function HC_run() {
-    if (this._shuttingDown) {
-      this._currentRequest = null;
+  complete: function HC_complete(aPartialHash, aGethashUrl, aCallback) {
+    if (!aGethashUrl) {
       throw Cr.NS_ERROR_NOT_INITIALIZED;
     }
 
     if (!this._currentRequest) {
-      return;
+      this._currentRequest = new HashCompleterRequest(this, aGethashUrl);
+    }
+    if (this._currentRequest.gethashUrl == aGethashUrl) {
+      this._currentRequest.add(aPartialHash, aCallback);
+    } else {
+      if (!this._pendingRequests[aGethashUrl]) {
+        this._pendingRequests[aGethashUrl] =
+          new HashCompleterRequest(this, aGethashUrl);
+      }
+      this._pendingRequests[aGethashUrl].add(aPartialHash, aCallback);
     }
 
-    if (!this._getHashUrl) {
+    if (!this._backoffs[aGethashUrl]) {
+      // Initialize request backoffs separately, since requests are deleted
+      // after they are dispatched.
+      var jslib = Cc["@mozilla.org/url-classifier/jslib;1"]
+                  .getService().wrappedJSObject;
+      this._backoffs[aGethashUrl] = new jslib.RequestBackoff(
+        BACKOFF_ERRORS /* max errors */,
+        60*1000 /* retry interval, 1 min */,
+        10 /* keep track of max requests */,
+        0 /* don't throttle on successful requests per time period */,
+        BACKOFF_INTERVAL /* backoff interval, 60 min */,
+        BACKOFF_MAX /* max backoff, 8hr */);
+    }
+    // Start off this request. Without dispatching to a thread, every call to
+    // complete makes an individual HTTP request.
+    Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
+  },
+
+  // This is called after several calls to |complete|, or after the
+  // currentRequest has finished.  It starts off the HTTP request by making a
+  // |begin| call to the HashCompleterRequest.
+  run: function() {
+    // Clear everything on shutdown
+    if (this._shuttingDown) {
+      this._currentRequest = null;
+      this._pendingRequests = null;
+      for (var url in this._backoffs) {
+        this._backoffs[url] = null;
+      }
       throw Cr.NS_ERROR_NOT_INITIALIZED;
     }
 
-    let url = this._getHashUrl;
-
-    let uri = Services.io.newURI(url, null, null);
-    this._currentRequest.setURI(uri);
-
-    // If |begin| fails, we should get rid of our request.
-    try {
-      this._currentRequest.begin();
+    // If we don't have an in-flight request, make one
+    let pendingUrls = Object.keys(this._pendingRequests);
+    if (!this._currentRequest && (pendingUrls.length > 0)) {
+      let nextUrl = pendingUrls[0];
+      this._currentRequest = this._pendingRequests[nextUrl];
+      delete this._pendingRequests[nextUrl];
     }
-    finally {
-      this._currentRequest = null;
-    }
-  },
-
-  get gethashUrl() {
-    return this._getHashUrl;
-  },
-  // Because we hold off on making a request until we have a valid getHashUrl,
-  // we kick off the process here.
-  set gethashUrl(aNewUrl) {
-    this._getHashUrl = aNewUrl;
 
     if (this._currentRequest) {
-      Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
+      try {
+        this._currentRequest.begin();
+      } finally {
+        // If |begin| fails, we should get rid of our request.
+        this._currentRequest = null;
+      }
     }
   },
 
-  // This handles all the logic about setting a back off time based on
-  // server responses. It should only be called once in the life time of a
-  // request.
-  // The logic behind backoffs is documented in the Google Safe Browsing API,
-  // the general idea is that a completer should go into backoff mode after
-  // BACKOFF_ERRORS errors in the last BACKOFF_TIME seconds. From there,
-  // we do not make a request for BACKOFF_INTERVAL seconds and for every failed
-  // request after that we double how long to wait, to a maximum of BACKOFF_MAX.
-  // Note that even in the case of a successful response we still keep a history
-  // of past errors.
-  noteServerResponse: function HC_noteServerResponse(aSuccess) {
-    if (aSuccess) {
-      this._backoff = false;
-      this._nextRequestTime = 0;
-      this._backoffTime = 0;
-      return;
-    }
-
-    let now = Date.now();
-
-    // We only alter the size of |_errorTimes| here, so we can guarantee that
-    // its length is at most BACKOFF_ERRORS.
-    this._errorTimes.push(now);
-    if (this._errorTimes.length > BACKOFF_ERRORS) {
-      this._errorTimes.shift();
-    }
-
-    if (this._backoff) {
-      this._backoffTime *= 2;
-    } else if (this._errorTimes.length == BACKOFF_ERRORS &&
-               ((now - this._errorTimes[0]) / 1000) <= BACKOFF_TIME) {
-      this._backoff = true;
-      this._backoffTime = BACKOFF_INTERVAL;
-    }
-
-    if (this._backoff) {
-      this._backoffTime = Math.min(this._backoffTime, BACKOFF_MAX);
-      this._nextRequestTime = now + (this._backoffTime * 1000);
-    }
+  // Pass the server response status to the RequestBackoff for the given
+  // gethashUrl and fetch the next pending request, if there is one.
+  finishRequest: function(url, aStatus) {
+    this._backoffs[url].noteServerResponse(aStatus);
+    Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
   },
 
-  // This is not included on the interface but is used to communicate to the
-  // HashCompleterRequest. It returns a time in milliseconds.
-  get nextRequestTime() {
-    return this._nextRequestTime;
+  // Returns true if we can make a request from the given url, false otherwise.
+  canMakeRequest: function(aGethashUrl) {
+    return this._backoffs[aGethashUrl].canMakeRequest();
+  },
+
+  // Notifies the RequestBackoff of a new request so we can throttle based on
+  // max requests/time period. This must be called before a channel is opened,
+  // and finishRequest must be called once the response is received.
+  noteRequest: function(aGethashUrl) {
+    return this._backoffs[aGethashUrl].noteRequest();
   },
 
   observe: function HC_observe(aSubject, aTopic, aData) {
     if (aTopic == "xpcom-shutdown") {
       this._shuttingDown = true;
     }
   },
 };
 
-function HashCompleterRequest(aCompleter) {
+function HashCompleterRequest(aCompleter, aGethashUrl) {
   // HashCompleter object that created this HashCompleterRequest.
   this._completer = aCompleter;
   // The internal set of hashes and callbacks that this request corresponds to.
   this._requests = [];
-  // URI to query for hash completions. Largely comes from the
-  // browser.safebrowsing.gethashURL pref.
-  this._uri = null;
   // nsIChannel that the hash completion query is transmitted over.
   this._channel = null;
   // Response body of hash completion. Created in onDataAvailable.
   this._response = "";
   // Whether we have been informed of a shutdown by the xpcom-shutdown event.
   this._shuttingDown = false;
+  this.gethashUrl = aGethashUrl;
 }
 HashCompleterRequest.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
                                          Ci.nsIStreamListener,
                                          Ci.nsIObserver,
                                          Ci.nsISupports]),
 
   // This is called by the HashCompleter to add a hash and callback to the
@@ -208,44 +175,46 @@ HashCompleterRequest.prototype = {
     this._requests.push({
       partialHash: aPartialHash,
       callback: aCallback,
       responses: [],
     });
   },
 
   // This initiates the HTTP request. It can fail due to backoff timings and
-  // will notify all callbacks as necessary.
+  // will notify all callbacks as necessary. We notify the backoff object on
+  // begin.
   begin: function HCR_begin() {
-    if (Date.now() < this._completer.nextRequestTime) {
+    if (!this._completer.canMakeRequest(this.gethashUrl)) {
+      dump("hashcompleter: Can't make request to " + this.gethashUrl + "\n");
       this.notifyFailure(Cr.NS_ERROR_ABORT);
       return;
     }
 
     Services.obs.addObserver(this, "xpcom-shutdown", false);
 
     try {
       this.openChannel();
+      // Notify the RequestBackoff if opening the channel succeeded. At this
+      // point, finishRequest must be called.
+      this._completer.noteRequest(this.gethashUrl);
     }
     catch (err) {
       this.notifyFailure(err);
       throw err;
     }
   },
 
-  setURI: function HCR_setURI(aURI) {
-    this._uri = aURI;
-  },
-
   // Creates an nsIChannel for the request and fills the body.
   openChannel: function HCR_openChannel() {
     let loadFlags = Ci.nsIChannel.INHIBIT_CACHING |
                     Ci.nsIChannel.LOAD_BYPASS_CACHE;
 
-    let channel = Services.io.newChannelFromURI(this._uri);
+    let uri = Services.io.newURI(this.gethashUrl, null, null);
+    let channel = Services.io.newChannelFromURI(uri);
     channel.loadFlags = loadFlags;
 
     this._channel = channel;
 
     let body = this.buildRequest();
     this.addRequestBody(body);
 
     channel.asyncOpen(this, null);
@@ -301,22 +270,23 @@ HashCompleterRequest.prototype = {
   handleResponse: function HCR_handleResponse() {
     if (this._response == "") {
       return;
     }
 
     let start = 0;
 
     let length = this._response.length;
-    while (start != length)
+    while (start != length) {
       start = this.handleTable(start);
+    }
   },
 
   // This parses a table entry in the response body and calls |handleItem|
-  // for complete hash in the table entry. 
+  // for complete hash in the table entry.
   handleTable: function HCR_handleTable(aStart) {
     let body = this._response.substring(aStart);
 
     // deal with new line indexes as there could be
     // new line characters in the data parts.
     let newlineIndex = body.indexOf("\n");
     if (newlineIndex == -1) {
       throw errorWithStack();
@@ -399,26 +369,31 @@ HashCompleterRequest.prototype = {
 
   onStopRequest: function HCR_onStopRequest(aRequest, aContext, aStatusCode) {
     Services.obs.removeObserver(this, "xpcom-shutdown");
 
     if (this._shuttingDown) {
       throw Cr.NS_ERROR_ABORT;
     }
 
+    // Default HTTP status to service unavailable, in case we can't retrieve
+    // the true status from the channel.
+    let httpStatus = 503;
     if (Components.isSuccessCode(aStatusCode)) {
       let channel = aRequest.QueryInterface(Ci.nsIHttpChannel);
       let success = channel.requestSucceeded;
+      httpStatus = channel.responseStatus;
       if (!success) {
         aStatusCode = Cr.NS_ERROR_ABORT;
       }
     }
 
     let success = Components.isSuccessCode(aStatusCode);
-    this._completer.noteServerResponse(success);
+    // Notify the RequestBackoff once a response is received.
+    this._completer.finishRequest(this.gethashUrl, httpStatus);
 
     if (success) {
       try {
         this.handleResponse();
       }
       catch (err) {
         dump(err.stack);
         aStatusCode = err.value;
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -34,23 +34,23 @@ static const PRLogModuleInfo *gUrlClassi
 // This class does absolutely nothing, except pass requests onto the DBService.
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIUrlClassiferStreamUpdater implementation
 // Handles creating/running the stream listener
 
 nsUrlClassifierStreamUpdater::nsUrlClassifierStreamUpdater()
   : mIsUpdating(false), mInitialized(false), mDownloadError(false),
-    mBeganStream(false), mUpdateUrl(nullptr), mChannel(nullptr)
+    mBeganStream(false), mChannel(nullptr)
 {
 #if defined(PR_LOGGING)
   if (!gUrlClassifierStreamUpdaterLog)
     gUrlClassifierStreamUpdaterLog = PR_NewLogModule("UrlClassifierStreamUpdater");
 #endif
-
+  LOG(("nsUrlClassifierStreamUpdater init [this=%p]", this));
 }
 
 NS_IMPL_ISUPPORTS(nsUrlClassifierStreamUpdater,
                   nsIUrlClassifierStreamUpdater,
                   nsIUrlClassifierUpdateObserver,
                   nsIRequestObserver,
                   nsIStreamListener,
                   nsIObserver,
@@ -71,43 +71,30 @@ nsUrlClassifierStreamUpdater::DownloadDo
   mSuccessCallback = nullptr;
   mUpdateErrorCallback = nullptr;
   mDownloadErrorCallback = nullptr;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIUrlClassifierStreamUpdater implementation
 
-NS_IMETHODIMP
-nsUrlClassifierStreamUpdater::GetUpdateUrl(nsACString & aUpdateUrl)
-{
-  if (mUpdateUrl) {
-    mUpdateUrl->GetSpec(aUpdateUrl);
-  } else {
-    aUpdateUrl.Truncate();
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsUrlClassifierStreamUpdater::SetUpdateUrl(const nsACString & aUpdateUrl)
-{
-  LOG(("Update URL is %s\n", PromiseFlatCString(aUpdateUrl).get()));
-
-  nsresult rv = NS_NewURI(getter_AddRefs(mUpdateUrl), aUpdateUrl);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
 nsresult
 nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
                                           const nsACString & aRequestBody,
                                           const nsACString & aStreamTable)
 {
+
+#ifdef DEBUG
+  {
+    nsCString spec;
+    aUpdateUrl->GetSpec(spec);
+    LOG(("Fetching update %s from %s", aRequestBody.Data(), spec.get()));
+  }
+#endif
+
   nsresult rv;
   uint32_t loadFlags = nsIChannel::INHIBIT_CACHING |
                        nsIChannel::LOAD_BYPASS_CACHE;
   rv = NS_NewChannel(getter_AddRefs(mChannel), aUpdateUrl, nullptr, nullptr, this,
                      loadFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mBeganStream = false;
@@ -160,34 +147,43 @@ nsUrlClassifierStreamUpdater::FetchUpdat
 
   LOG(("(post) Fetching update from %s\n", urlSpec.get()));
 
   return FetchUpdate(uri, aRequestBody, aStreamTable);
 }
 
 NS_IMETHODIMP
 nsUrlClassifierStreamUpdater::DownloadUpdates(
-                                const nsACString &aRequestTables,
-                                const nsACString &aRequestBody,
-                                nsIUrlClassifierCallback *aSuccessCallback,
-                                nsIUrlClassifierCallback *aUpdateErrorCallback,
-                                nsIUrlClassifierCallback *aDownloadErrorCallback,
-                                bool *_retval)
+  const nsACString &aRequestTables,
+  const nsACString &aRequestBody,
+  const nsACString &aUpdateUrl,
+  nsIUrlClassifierCallback *aSuccessCallback,
+  nsIUrlClassifierCallback *aUpdateErrorCallback,
+  nsIUrlClassifierCallback *aDownloadErrorCallback,
+  bool *_retval)
 {
   NS_ENSURE_ARG(aSuccessCallback);
   NS_ENSURE_ARG(aUpdateErrorCallback);
   NS_ENSURE_ARG(aDownloadErrorCallback);
 
   if (mIsUpdating) {
-    LOG(("already updating, skipping update"));
+    LOG(("Already updating, queueing update %s from %s", aRequestBody.Data(),
+         aUpdateUrl.Data()));
     *_retval = false;
+    PendingRequest *request = mPendingRequests.AppendElement();
+    request->mTables = aRequestTables;
+    request->mRequest = aRequestBody;
+    request->mUrl = aUpdateUrl;
+    request->mSuccessCallback = aSuccessCallback;
+    request->mUpdateErrorCallback = aUpdateErrorCallback;
+    request->mDownloadErrorCallback = aDownloadErrorCallback;
     return NS_OK;
   }
 
-  if (!mUpdateUrl) {
+  if (aUpdateUrl.IsEmpty()) {
     NS_ERROR("updateUrl not set");
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   nsresult rv;
 
   if (!mInitialized) {
     // Add an observer for shutdown so we can cancel any pending list
@@ -203,38 +199,44 @@ nsUrlClassifierStreamUpdater::DownloadUp
     mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mInitialized = true;
   }
 
   rv = mDBService->BeginUpdate(this, aRequestTables);
   if (rv == NS_ERROR_NOT_AVAILABLE) {
-    LOG(("already updating, skipping update"));
+    LOG(("Service busy, already updating, queuing update %s from %s",
+         aRequestBody.Data(), aUpdateUrl.Data()));
     *_retval = false;
+    PendingRequest *request = mPendingRequests.AppendElement();
+    request->mTables = aRequestTables;
+    request->mRequest = aRequestBody;
+    request->mUrl = aUpdateUrl;
+    request->mSuccessCallback = aSuccessCallback;
+    request->mUpdateErrorCallback = aUpdateErrorCallback;
+    request->mDownloadErrorCallback = aDownloadErrorCallback;
     return NS_OK;
-  } else if (NS_FAILED(rv)) {
+  }
+
+  if (NS_FAILED(rv)) {
     return rv;
   }
 
   mSuccessCallback = aSuccessCallback;
   mUpdateErrorCallback = aUpdateErrorCallback;
   mDownloadErrorCallback = aDownloadErrorCallback;
 
   mIsUpdating = true;
   *_retval = true;
 
-  nsAutoCString urlSpec;
-  mUpdateUrl->GetAsciiSpec(urlSpec);
-
-  LOG(("FetchUpdate: %s", urlSpec.get()));
+  LOG(("FetchUpdate: %s", aUpdateUrl.Data()));
   //LOG(("requestBody: %s", aRequestBody.Data()));
 
-  LOG(("Calling into FetchUpdate"));
-  return FetchUpdate(mUpdateUrl, aRequestBody, EmptyCString());
+  return FetchUpdate(aUpdateUrl, aRequestBody, EmptyCString());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIUrlClassifierUpdateObserver implementation
 
 NS_IMETHODIMP
 nsUrlClassifierStreamUpdater::UpdateUrlRequested(const nsACString &aUrl,
                                                  const nsACString &aTable)
@@ -285,16 +287,44 @@ nsUrlClassifierStreamUpdater::FetchNext(
     return rv;
   }
 
   mPendingUpdates.RemoveElementAt(0);
 
   return NS_OK;
 }
 
+nsresult
+nsUrlClassifierStreamUpdater::FetchNextRequest()
+{
+  if (mPendingRequests.Length() == 0) {
+    LOG(("No more requests, returning"));
+    return NS_OK;
+  }
+
+  PendingRequest &request = mPendingRequests[0];
+  LOG(("Stream updater: fetching next request: %s, %s",
+       request.mTables.get(), request.mUrl.get()));
+  bool dummy;
+  DownloadUpdates(
+    request.mTables,
+    request.mRequest,
+    request.mUrl,
+    request.mSuccessCallback,
+    request.mUpdateErrorCallback,
+    request.mDownloadErrorCallback,
+    &dummy);
+  request.mSuccessCallback = nullptr;
+  request.mUpdateErrorCallback = nullptr;
+  request.mDownloadErrorCallback = nullptr;
+  mPendingRequests.RemoveElementAt(0);
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsUrlClassifierStreamUpdater::StreamFinished(nsresult status,
                                              uint32_t requestedDelay)
 {
   LOG(("nsUrlClassifierStreamUpdater::StreamFinished [%x, %d]", status, requestedDelay));
   if (NS_FAILED(status) || mPendingUpdates.Length() == 0) {
     // We're done.
     mDBService->FinishUpdate();
@@ -329,16 +359,19 @@ nsUrlClassifierStreamUpdater::UpdateSucc
   nsCOMPtr<nsIUrlClassifierCallback> successCallback = mDownloadError ? nullptr : mSuccessCallback.get();
   DownloadDone();
 
   nsAutoCString strTimeout;
   strTimeout.AppendInt(requestedTimeout);
   if (successCallback) {
     successCallback->HandleEvent(strTimeout);
   }
+  // Now fetch the next request
+  LOG(("stream updater: calling into fetch next request"));
+  FetchNextRequest();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsUrlClassifierStreamUpdater::UpdateError(nsresult result)
 {
   LOG(("nsUrlClassifierStreamUpdater::UpdateError [this=%p]", this));
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.h
@@ -58,27 +58,39 @@ private:
                        const nsACString &aTable);
   // Dumb wrapper so we don't have to create URIs.
   nsresult FetchUpdate(const nsACString &aURI,
                        const nsACString &aRequestBody,
                        const nsACString &aTable);
 
   // Fetches the next table, from mPendingUpdates.
   nsresult FetchNext();
+  // Fetches the next request, from mPendingRequests
+  nsresult FetchNextRequest();
+
 
   bool mIsUpdating;
   bool mInitialized;
   bool mDownloadError;
   bool mBeganStream;
-  nsCOMPtr<nsIURI> mUpdateUrl;
   nsCString mStreamTable;
   nsCOMPtr<nsIChannel> mChannel;
   nsCOMPtr<nsIUrlClassifierDBService> mDBService;
   nsCOMPtr<nsITimer> mTimer;
 
+  struct PendingRequest {
+    nsCString mTables;
+    nsCString mRequest;
+    nsCString mUrl;
+    nsCOMPtr<nsIUrlClassifierCallback> mSuccessCallback;
+    nsCOMPtr<nsIUrlClassifierCallback> mUpdateErrorCallback;
+    nsCOMPtr<nsIUrlClassifierCallback> mDownloadErrorCallback;
+  };
+  nsTArray<PendingRequest> mPendingRequests;
+
   struct PendingUpdate {
     nsCString mUrl;
     nsCString mTable;
   };
   nsTArray<PendingUpdate> mPendingUpdates;
 
   nsCOMPtr<nsIUrlClassifierCallback> mSuccessCallback;
   nsCOMPtr<nsIUrlClassifierCallback> mUpdateErrorCallback;
--- a/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
+++ b/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
@@ -169,19 +169,18 @@ function doErrorUpdate(tables, success, 
  * data: uri
  */
 function doStreamUpdate(updateText, success, failure, downloadFailure) {
   var dataUpdate = "data:," + encodeURIComponent(updateText);
 
   if (!downloadFailure)
     downloadFailure = failure;
 
-  streamUpdater.updateUrl = dataUpdate;
   streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "",
-                                success, failure, downloadFailure);
+                                dataUpdate, success, failure, downloadFailure);
 }
 
 var gAssertions = {
 
 tableData : function(expectedTables, cb)
 {
   dbservice.getTables(function(tables) {
       // rebuild the tables in a predictable order.
--- a/toolkit/components/url-classifier/tests/unit/test_digest256.js
+++ b/toolkit/components/url-classifier/tests/unit/test_digest256.js
@@ -97,33 +97,33 @@ function createURI(s) {
 // Just throw if we ever get an update or download error.
 function handleError(aEvent) {
   do_throw("We didn't download or update correctly: " + aEvent);
 }
 
 add_test(function test_update() {
   let streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"]
     .getService(Ci.nsIUrlClassifierStreamUpdater);
-  streamUpdater.updateUrl = "http://localhost:4444/downloads";
 
   // Load up some update chunks for the safebrowsing server to serve.
   registerTableUpdate("goog-downloadwhite-digest256", "data/digest1.chunk");
   registerTableUpdate("goog-downloadwhite-digest256", "data/digest2.chunk");
 
   // Download some updates, and don't continue until the downloads are done.
   function updateSuccess(aEvent) {
     // Timeout of n:1000 is constructed in processUpdateRequest above and
     // passed back in the callback in nsIUrlClassifierStreamUpdater on success.
     do_check_eq("1000", aEvent);
     do_print("All data processed");
     run_next_test();
   }
   streamUpdater.downloadUpdates(
     "goog-downloadwhite-digest256",
     "goog-downloadwhite-digest256;\n",
+    "http://localhost:4444/downloads",
     updateSuccess, handleError, handleError);
 });
 
 add_test(function test_url_not_whitelisted() {
   let uri = createURI("http://example.com");
   let principal = gSecMan.getNoAppCodebasePrincipal(uri);
   gDbService.lookup(principal, "goog-downloadwhite-digest256",
     function handleEvent(aEvent) {
--- a/toolkit/components/url-classifier/tests/unit/test_hashcompleter.js
+++ b/toolkit/components/url-classifier/tests/unit/test_hashcompleter.js
@@ -10,16 +10,18 @@
 // This tests makes a request for each element of |completionSets|, waits for
 // a response and then moves to the next element.
 // Each element of |completionSets| is an array of completions, and each
 // completion is an object with the properties:
 //   hash: complete hash for the completion. Automatically right-padded
 //         to be COMPLETE_LENGTH.
 //   expectCompletion: boolean indicating whether the server should respond
 //                     with a full hash.
+//   forceServerError: boolean indicating whether the server should respond
+//                     with a 503.
 //   table: name of the table that the hash corresponds to. Only needs to be set
 //          if a completion is expected.
 //   chunkId: positive integer corresponding to the chunk that the hash belongs
 //            to. Only needs to be set if a completion is expected.
 //   multipleCompletions: boolean indicating whether the server should respond
 //                        with more than one full hash. If this is set to true
 //                        then |expectCompletion| must also be set to true and
 //                        |hash| must have the same prefix as all |completions|.
@@ -109,60 +111,63 @@ let multipleResponsesCompletionSet = [
         hash: "123478",
         table: "test2",
         chunkId: 4,
       }
     ],
   }
 ];
 
-// The fifth completion set is added at runtime by addRandomCompletionSet.
+// The fifth completion set is added at runtime by getRandomCompletionSet.
 // Each completion in the set only has one response and its purpose is to
 // provide an easy way to test the HashCompleter handling an arbitrarily large
 // completion set (determined by SIZE_OF_RANDOM_SET).
 const SIZE_OF_RANDOM_SET = 16;
-function addRandomCompletionSet() {
+function getRandomCompletionSet(forceServerError) {
   let completionSet = [];
   let hashPrefixes = [];
 
   let seed = Math.floor(Math.random() * Math.pow(2, 32));
   dump("Using seed of " + seed + " for random completion set.\n");
   let rand = new LFSRgenerator(seed);
 
   for (let i = 0; i < SIZE_OF_RANDOM_SET; i++) {
-    let completion = {};
+    let completion = { expectCompletion: false, forceServerError: false, _finished: false };
 
     // Generate a random 256 bit hash. First we get a random number and then
     // convert it to a string.
     let hash;
     let prefix;
     do {
       hash = "";
       let length = 1 + rand.nextNum(5);
       for (let i = 0; i < length; i++)
         hash += String.fromCharCode(rand.nextNum(8));
       prefix = hash.substring(0,4);
     } while (hashPrefixes.indexOf(prefix) != -1);
 
     hashPrefixes.push(prefix);
     completion.hash = hash;
 
-    completion.expectCompletion = rand.nextNum(1) == 1;
+    if (!forceServerError) {
+      completion.expectCompletion = rand.nextNum(1) == 1;
+    } else {
+      completion.forceServerError = true;
+    }
     if (completion.expectCompletion) {
       // Generate a random alpha-numeric string of length at most 6 for the
       // table name.
       completion.table = (rand.nextNum(31)).toString(36);
 
       completion.chunkId = rand.nextNum(16);
     }
-
     completionSet.push(completion);
   }
 
-  completionSets.push(completionSet);
+  return completionSet;
 }
 
 let completionSets = [basicCompletionSet, falseCompletionSet,
                       dupedCompletionSet, multipleResponsesCompletionSet];
 let currentCompletionSet = -1;
 let finishedCompletions = 0;
 
 const SERVER_PORT = 8080;
@@ -172,18 +177,32 @@ let server;
 // Completion hashes are automatically right-padded with null chars to have a
 // length of COMPLETE_LENGTH.
 // Taken from nsUrlClassifierDBService.h
 const COMPLETE_LENGTH = 32;
 
 let completer = Cc["@mozilla.org/url-classifier/hashcompleter;1"].
                   getService(Ci.nsIUrlClassifierHashCompleter);
 
+let gethashUrl;
+
+// Expected highest completion set for which the server sends a response.
+let expectedMaxServerCompletionSet = 0;
+let maxServerCompletionSet = 0;
+
 function run_test() {
-  addRandomCompletionSet();
+  // Generate a random completion set that return successful responses.
+  completionSets.push(getRandomCompletionSet(false));
+  // We backoff after receiving an error, so requests shouldn't reach the
+  // server after that.
+  expectedMaxServerCompletionSet = completionSets.length;
+  // Generate some completion sets that return 503s.
+  for (let j = 0; j < 10; ++j) {
+    completionSets.push(getRandomCompletionSet(true));
+  }
 
   // Fix up the completions before running the test.
   for each (let completionSet in completionSets) {
     for each (let completion in completionSet) {
       // Pad the right of each |hash| so that the length is COMPLETE_LENGTH.
       if (completion.multipleCompletions) {
         for each (let responseCompletion in completion.completions) {
           let numChars = COMPLETE_LENGTH - responseCompletion.hash.length;
@@ -199,42 +218,36 @@ function run_test() {
   do_test_pending();
 
   server = new HttpServer();
   server.registerPathHandler(SERVER_PATH, hashCompleterServer);
 
   const SERVER_PORT = 8080;
   server.start(SERVER_PORT);
 
-  completer.gethashUrl = "http://localhost:" + SERVER_PORT + SERVER_PATH;
-
-  runNextCompletion();
-}
-
-function doneCompletionSet() {
-  do_check_eq(finishedCompletions, completionSets[currentCompletionSet].length);
-
-  for each (let completion in completionSets[currentCompletionSet])
-    do_check_true(completion._finished);
+  gethashUrl = "http://localhost:" + SERVER_PORT + SERVER_PATH;
 
   runNextCompletion();
 }
 
 function runNextCompletion() {
+  // The server relies on currentCompletionSet to send the correct response, so
+  // don't increment it until we start the new set of callbacks.
   currentCompletionSet++;
-  finishedCompletions = 0;
-
   if (currentCompletionSet >= completionSets.length) {
     finish();
     return;
   }
 
-  dump("Now on completion set index " + currentCompletionSet + "\n");
+  dump("Now on completion set index " + currentCompletionSet + ", length " +
+       completionSets[currentCompletionSet].length + "\n");
+  // Number of finished completions for this set.
+  finishedCompletions = 0;
   for each (let completion in completionSets[currentCompletionSet]) {
-    completer.complete(completion.hash.substring(0,4),
+    completer.complete(completion.hash.substring(0,4), gethashUrl,
                        (new callback(completion)));
   }
 }
 
 function hashCompleterServer(aRequest, aResponse) {
   let stream = aRequest.bodyInputStream;
   let wrapperStream = Cc["@mozilla.org/binaryinputstream;1"].
                         createInstance(Ci.nsIBinaryInputStream);
@@ -246,44 +259,51 @@ function hashCompleterServer(aRequest, a
   // To avoid a response with duplicate hash completions, we keep track of all
   // completed hash prefixes so far.
   let completedHashes = [];
   let responseText = "";
 
   function responseForCompletion(x) {
     return x.table + ":" + x.chunkId + ":" + x.hash.length + "\n" + x.hash;
   }
+  // As per the spec, a server should response with a 204 if there are no
+  // full-length hashes that match the prefixes.
+  let httpStatus = 204;
   for each (let completion in completionSets[currentCompletionSet]) {
     if (completion.expectCompletion &&
         (completedHashes.indexOf(completion.hash) == -1)) {
       completedHashes.push(completion.hash);
 
       if (completion.multipleCompletions)
         responseText += completion.completions.map(responseForCompletion).join("");
       else
         responseText += responseForCompletion(completion);
     }
+    if (completion.forceServerError) {
+      httpStatus = 503;
+    }
   }
 
-  // As per the spec, a server should response with a 204 if there are no
-  // full-length hashes that match the prefixes.
-  if (responseText)
+  dump("Server sending response for " + currentCompletionSet + "\n");
+  maxServerCompletionSet = currentCompletionSet;
+  if (responseText && httpStatus != 503) {
     aResponse.write(responseText);
-  else
-    aResponse.setStatusLine(null, 204, null);
+  } else {
+    aResponse.setStatusLine(null, httpStatus, null);
+  }
 }
 
 
 function callback(completion) {
   this._completion = completion;
 }
+
 callback.prototype = {
   completion: function completion(hash, table, chunkId, trusted) {
     do_check_true(this._completion.expectCompletion);
-
     if (this._completion.multipleCompletions) {
       for each (let completion in this._completion.completions) {
         if (completion.hash == hash) {
           do_check_eq(JSON.stringify(hash), JSON.stringify(completion.hash));
           do_check_eq(table, completion.table);
           do_check_eq(chunkId, completion.chunkId);
 
           completion._completed = true;
@@ -301,22 +321,26 @@ callback.prototype = {
       do_check_eq(table, this._completion.table);
       do_check_eq(chunkId, this._completion.chunkId);
 
       this._completed = true;
     }
   },
 
   completionFinished: function completionFinished(status) {
+    finishedCompletions++;
     do_check_eq(!!this._completion.expectCompletion, !!this._completed);
     this._completion._finished = true;
 
-    finishedCompletions++;
-    if (finishedCompletions == completionSets[currentCompletionSet].length)
-      doneCompletionSet();
+    // currentCompletionSet can mutate before all of the callbacks are complete.
+    if (currentCompletionSet < completionSets.length &&
+        finishedCompletions == completionSets[currentCompletionSet].length) {
+      runNextCompletion();
+    }
   },
 };
 
 function finish() {
+  do_check_eq(expectedMaxServerCompletionSet, maxServerCompletionSet);
   server.stop(function() {
     do_test_finished();
   });
 }
--- a/toolkit/components/url-classifier/tests/unit/test_partial.js
+++ b/toolkit/components/url-classifier/tests/unit/test_partial.js
@@ -15,17 +15,17 @@ QueryInterface: function(iid)
 {
   if (!iid.equals(Ci.nsISupports) &&
       !iid.equals(Ci.nsIUrlClassifierHashCompleter)) {
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
   return this;
 },
 
-complete: function(partialHash, cb)
+complete: function(partialHash, gethashUrl, cb)
 {
   this.queries.push(partialHash);
   var fragments = this.fragments;
   var self = this;
   var doCallback = function() {
       if (self.alwaysFail) {
         cb.completionFinished(1);
         return;
--- a/toolkit/components/url-classifier/tests/unit/xpcshell.ini
+++ b/toolkit/components/url-classifier/tests/unit/xpcshell.ini
@@ -5,13 +5,13 @@ support-files =
   data/digest1.chunk
   data/digest2.chunk
 
 [test_addsub.js]
 [test_backoff.js]
 [test_dbservice.js]
 [test_hashcompleter.js]
 # Bug 752243: Profile cleanup frequently fails
-skip-if = os == "mac" || os == "linux"
+#skip-if = os == "mac" || os == "linux"
 [test_partial.js]
 [test_prefixset.js]
 [test_streamupdater.js]
 [test_digest256.js]
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -566,19 +566,20 @@ nsAppShell::ProcessNextNativeEvent(bool 
       // window server.
       EventRef currentEvent = AcquireFirstMatchingEventInQueue(currentEventQueue, 0, NULL,
                                                                kEventQueueOptionsNone);
       if (!currentEvent) {
         continue;
       }
       EventAttributes attrs = GetEventAttributes(currentEvent);
       UInt32 eventKind = GetEventKind(currentEvent);
+      UInt32 eventClass = GetEventClass(currentEvent);
       bool osCocoaEvent =
-        ((GetEventClass(currentEvent) == 'cgs ') &&
-         ((eventKind == NSAppKitDefined) || (eventKind == NSSystemDefined)));
+        ((eventClass == 'appl') ||
+         ((eventClass == 'cgs ') && (eventKind != NSApplicationDefined)));
       // If attrs is kEventAttributeUserEvent or kEventAttributeMonitored
       // (i.e. a user input event), we shouldn't process it here while
       // aMayWait is false.  Likewise if currentEvent will eventually be
       // turned into an OS-defined Cocoa event.  Doing otherwise risks
       // doing too much work here, and preventing the event from being
       // properly processed as a Cocoa event.
       if ((attrs != kEventAttributeNone) || osCocoaEvent) {
         // Since we can't process the next event here (while aMayWait is false),
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -64,33 +64,34 @@ using namespace mozilla::layers;
 
 namespace mozilla {
 
 static StaticRefPtr<HwcComposer2D> sInstance;
 
 HwcComposer2D::HwcComposer2D()
     : mHwc(nullptr)
     , mList(nullptr)
+    , mGLContext(nullptr)
     , mMaxLayerCount(0)
     , mColorFill(false)
     , mRBSwapSupport(false)
 #if ANDROID_VERSION >= 17
     , mPrevRetireFence(Fence::NO_FENCE)
     , mPrevDisplayFence(Fence::NO_FENCE)
 #endif
     , mPrepared(false)
 {
 }
 
 HwcComposer2D::~HwcComposer2D() {
     free(mList);
 }
 
 int
-HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur)
+HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur, gl::GLContext* aGLContext)
 {
     MOZ_ASSERT(!Initialized());
 
     mHwc = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
     if (!mHwc) {
         LOGE("Failed to initialize hwc");
         return -1;
     }
@@ -118,16 +119,17 @@ HwcComposer2D::Init(hwc_display_t dpy, h
     char propValue[PROPERTY_VALUE_MAX];
     property_get("ro.display.colorfill", propValue, "0");
     mColorFill = (atoi(propValue) == 1) ? true : false;
     mRBSwapSupport = true;
 #endif
 
     mDpy = dpy;
     mSur = sur;
+    mGLContext = aGLContext;
 
     return 0;
 }
 
 HwcComposer2D*
 HwcComposer2D::GetInstance()
 {
     if (!sInstance) {
@@ -578,16 +580,23 @@ HwcComposer2D::TryHwComposition()
                     break;
             }
         }
 
         if (gpuComposite) {
             // GPU or partial OVERLAY Composition
             return false;
         } else if (blitComposite) {
+            // Some EGLSurface implementations require glClear() on blit composition.
+            // See bug 1029856.
+            if (mGLContext) {
+                mGLContext->MakeCurrent();
+                mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
+                mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
+            }
             // BLIT Composition, flip FB target
             GetGonkDisplay()->UpdateFBSurface(mDpy, mSur);
             FramebufferSurface* fbsurface = (FramebufferSurface*)(GetGonkDisplay()->GetFBSurface());
             if (!fbsurface) {
                 LOGE("H/W Composition failed. NULL FBSurface.");
                 return false;
             }
             mList->hwLayers[idx].handle = fbsurface->lastHandle;
--- a/widget/gonk/HwcComposer2D.h
+++ b/widget/gonk/HwcComposer2D.h
@@ -24,16 +24,20 @@
 
 #include <hardware/hwcomposer.h>
 #if ANDROID_VERSION >= 17
 #include <ui/Fence.h>
 #endif
 
 namespace mozilla {
 
+namespace gl {
+    class GLContext;
+}
+
 namespace layers {
 class ContainerLayer;
 class Layer;
 }
 
 //Holds a dynamically allocated vector of rectangles
 //used to decribe the complex visible region of a layer
 typedef std::vector<hwc_rect_t> RectVector;
@@ -64,17 +68,17 @@ typedef hwc_layer_t HwcLayer;
  * using the GPU with OpenGL.
  *
  */
 class HwcComposer2D : public mozilla::layers::Composer2D {
 public:
     HwcComposer2D();
     virtual ~HwcComposer2D();
 
-    int Init(hwc_display_t aDisplay, hwc_surface_t aSurface);
+    int Init(hwc_display_t aDisplay, hwc_surface_t aSurface, gl::GLContext* aGLContext);
 
     bool Initialized() const { return mHwc; }
 
     static HwcComposer2D* GetInstance();
 
     // Returns TRUE if the container has been succesfully rendered
     // Returns FALSE if the container cannot be fully rendered
     // by this composer so nothing was rendered at all
@@ -93,16 +97,17 @@ private:
           const gfxMatrix& aParentTransform, const gfxMatrix& aGLWorldTransform);
     void setCrop(HwcLayer* layer, hwc_rect_t srcCrop);
     void setHwcGeometry(bool aGeometryChanged);
 
     HwcDevice*              mHwc;
     HwcList*                mList;
     hwc_display_t           mDpy;
     hwc_surface_t           mSur;
+    gl::GLContext*          mGLContext;
     nsIntRect               mScreenRect;
     int                     mMaxLayerCount;
     bool                    mColorFill;
     bool                    mRBSwapSupport;
     //Holds all the dynamically allocated RectVectors needed
     //to render the current frame
     std::list<RectVector>   mVisibleRegions;
 #if ANDROID_VERSION >= 17
--- a/xpcom/base/AvailableMemoryTracker.h
+++ b/xpcom/base/AvailableMemoryTracker.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 ci et: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AvailableMemoryTracker_h
 #define mozilla_AvailableMemoryTracker_h
 
 namespace mozilla {
--- a/xpcom/base/ClearOnShutdown.cpp
+++ b/xpcom/base/ClearOnShutdown.cpp
@@ -1,14 +1,13 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et ft=cpp : */
-
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
+ * 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/ClearOnShutdown.h"
 
 namespace mozilla {
 namespace ClearOnShutdown_Internal {
 
 bool sHasShutDown = false;
 StaticAutoPtr<LinkedList<ShutdownObserver>> sShutdownObservers;
--- a/xpcom/base/ClearOnShutdown.h
+++ b/xpcom/base/ClearOnShutdown.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et ft=cpp : */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ClearOnShutdown_h
 #define mozilla_ClearOnShutdown_h
 
 #include "mozilla/LinkedList.h"
--- a/xpcom/base/Debug.cpp
+++ b/xpcom/base/Debug.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Debug.h"
 
 #ifdef XP_WIN
 #include <windows.h>
--- a/xpcom/base/Debug.h
+++ b/xpcom/base/Debug.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Debug_h__
 #define mozilla_Debug_h__
 
 namespace mozilla {
--- a/xpcom/base/StackWalk.h
+++ b/xpcom/base/StackWalk.h
@@ -1,9 +1,10 @@
-/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* API for getting a stack trace of the C/C++ */
 
 #ifndef StackWalk_h_
 #define StackWalk_h_
--- a/xpcom/base/VisualEventTracer.cpp
+++ b/xpcom/base/VisualEventTracer.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/VisualEventTracer.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/TimeStamp.h"
 #include "nscore.h"
--- a/xpcom/base/VisualEventTracer.h
+++ b/xpcom/base/VisualEventTracer.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Visual event tracer, creates a log of events on each thread for visualization */
 
 /**
  * The event tracer code is by default disabled in both build and run time.
--- a/xpcom/base/nsAllocator.h
+++ b/xpcom/base/nsAllocator.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 ////////////////////////////////////////////////////////////////////////////////
 // obsolete
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/xpcom/base/nsCom.h
+++ b/xpcom/base/nsCom.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCom_h__
 #define nsCom_h__
 #include "nscore.h"
 #endif
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCycleCollector_h__
 #define nsCycleCollector_h__
 
 class nsICycleCollectorListener;
--- a/xpcom/base/nsIID.h
+++ b/xpcom/base/nsIID.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsIID_h
 #define __nsIID_h
 #include "nsID.h"
 #endif /* __nsIID_h */
--- a/xpcom/base/nsISupportsBase.h
+++ b/xpcom/base/nsISupportsBase.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsISupports.h"
 
 #ifndef nsISupportsBase_h__
 #define nsISupportsBase_h__
 
--- a/xpcom/base/nsInterfaceRequestorAgg.cpp
+++ b/xpcom/base/nsInterfaceRequestorAgg.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsInterfaceRequestorAgg.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
--- a/xpcom/base/nsInterfaceRequestorAgg.h
+++ b/xpcom/base/nsInterfaceRequestorAgg.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsInterfaceRequestorAgg_h__
 #define nsInterfaceRequestorAgg_h__
 
 #include "nsError.h"
--- a/xpcom/base/nsMacUtilsImpl.h
+++ b/xpcom/base/nsMacUtilsImpl.h
@@ -1,9 +1,10 @@
-  /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsMacUtilsImpl_h___
 #define nsMacUtilsImpl_h___
 
 #include "nsIMacUtils.h"
--- a/xpcom/base/nsMessageLoop.cpp
+++ b/xpcom/base/nsMessageLoop.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMessageLoop.h"
 #include "mozilla/WeakPtr.h"
 #include "base/message_loop.h"
 #include "base/task.h"
--- a/xpcom/base/nsMessageLoop.h
+++ b/xpcom/base/nsMessageLoop.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIMessageLoop.h"
 
 /*
  * nsMessageLoop implements nsIMessageLoop, which wraps Chromium's MessageLoop
--- a/xpcom/base/nsSecurityConsoleMessage.cpp
+++ b/xpcom/base/nsSecurityConsoleMessage.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSecurityConsoleMessage.h"
 
 NS_IMPL_ISUPPORTS(nsSecurityConsoleMessage, nsISecurityConsoleMessage)
 
--- a/xpcom/base/nsSetDllDirectory.h
+++ b/xpcom/base/nsSetDllDirectory.h
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsSetDllDirectory_h
 #define nsSetDllDirectory_h
 
 #ifndef XP_WIN
--- a/xpcom/base/nsStackWalkPrivate.h
+++ b/xpcom/base/nsStackWalkPrivate.h
@@ -1,9 +1,10 @@
-/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Initialize the critical sections for this platform so that we can
  * abort stack walks when needed.
  */
--- a/xpcom/base/nsVersionComparatorImpl.h
+++ b/xpcom/base/nsVersionComparatorImpl.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Attributes.h"
 
 #include "nsIVersionComparator.h"
 
--- a/xpcom/base/nsWeakPtr.h
+++ b/xpcom/base/nsWeakPtr.h
@@ -1,11 +1,11 @@
-/* -*- 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWeakPtr_h__
 #define nsWeakPtr_h__
 
 #include "nsIWeakReference.h"
 #include "nsCOMPtr.h"
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -84,17 +84,17 @@ if CONFIG['MOZ_OPTIMIZE']:
 
 GENERATED_INCLUDES += ['..']
 LOCAL_INCLUDES += [
     '../base',
     '../components',
     '../ds',
     '../glue',
     '../io',
-    '../reflect/xptinfo/src',
+    '../reflect/xptinfo',
     '../threads',
     '/chrome/src',
     '/docshell/base',
 ]
 
 if CONFIG['MOZ_VPX']:
     LOCAL_INCLUDES += [
         '/media/libvpx',
--- a/xpcom/components/moz.build
+++ b/xpcom/components/moz.build
@@ -44,12 +44,12 @@ MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'xpcom_core'
 
 GENERATED_INCLUDES += ['..']
 LOCAL_INCLUDES += [
     '../base',
     '../build',
     '../ds',
-    '../reflect/xptinfo/src',
+    '../reflect/xptinfo',
     '/chrome/src',
     '/modules/libjar',
 ]
--- a/xpcom/glue/AppData.cpp
+++ b/xpcom/glue/AppData.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/AppData.h"
 #include "nsXULAppAPI.h"
 #include "nsINIParser.h"
 #include "nsIFile.h"
--- a/xpcom/glue/AppData.h
+++ b/xpcom/glue/AppData.h
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AppData_h
 #define mozilla_AppData_h
 
 #include "nsXREAppData.h"
--- a/xpcom/glue/AutoRestore.h
+++ b/xpcom/glue/AutoRestore.h
@@ -1,9 +1,10 @@
-/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* functions for restoring saved values at the end of a C++ scope */
 
 #ifndef mozilla_AutoRestore_h_
 #define mozilla_AutoRestore_h_
--- a/xpcom/glue/BlockingResourceBase.cpp
+++ b/xpcom/glue/BlockingResourceBase.cpp
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/BlockingResourceBase.h"
 
 #ifdef DEBUG
 #include "nsAutoPtr.h"
 
--- a/xpcom/glue/BlockingResourceBase.h
+++ b/xpcom/glue/BlockingResourceBase.h
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef mozilla_BlockingResourceBase_h
 #define mozilla_BlockingResourceBase_h
 
 #include "prlog.h"
--- a/xpcom/glue/CondVar.h
+++ b/xpcom/glue/CondVar.h
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_CondVar_h
 #define mozilla_CondVar_h
 
 #include "prcvar.h"
 
--- a/xpcom/glue/DeadlockDetector.cpp
+++ b/xpcom/glue/DeadlockDetector.cpp
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DeadlockDetector.h"
 
 namespace mozilla {
 const CallStack CallStack::kNone((CallStack::callstack_id)-1);
 }
--- a/xpcom/glue/DeadlockDetector.h
+++ b/xpcom/glue/DeadlockDetector.h
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef mozilla_DeadlockDetector_h
 #define mozilla_DeadlockDetector_h
 
 #include "mozilla/Attributes.h"
 
 #include <stdlib.h>
--- a/xpcom/glue/EnumeratedArrayCycleCollection.h
+++ b/xpcom/glue/EnumeratedArrayCycleCollection.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef EnumeratedArrayCycleCollection_h_
 #define EnumeratedArrayCycleCollection_h_
 
 #include "mozilla/EnumeratedArray.h"
--- a/xpcom/glue/FileUtils.cpp
+++ b/xpcom/glue/FileUtils.cpp
@@ -1,10 +1,11 @@
-/* -*- 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <errno.h>
 #include <stdio.h>
 
 #include "nscore.h"
 #include "nsStringGlue.h"
--- a/xpcom/glue/FileUtils.h
+++ b/xpcom/glue/FileUtils.h
@@ -1,10 +1,11 @@
-/* -*- 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_FileUtils_h
 #define mozilla_FileUtils_h
 
 #include "nscore.h" // nullptr
 
--- a/xpcom/glue/GenericFactory.cpp
+++ b/xpcom/glue/GenericFactory.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/GenericFactory.h"
 
 namespace mozilla {
 
--- a/xpcom/glue/GenericFactory.h
+++ b/xpcom/glue/GenericFactory.h
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_GenericFactory_h
 #define mozilla_GenericFactory_h
 
 #include "mozilla/Attributes.h"
--- a/xpcom/glue/GenericModule.cpp
+++ b/xpcom/glue/GenericModule.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/GenericFactory.h"
 
 #include "nsICategoryManager.h"
--- a/xpcom/glue/IntentionalCrash.h
+++ b/xpcom/glue/IntentionalCrash.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <string>
 #include <sstream>
 #include <stdlib.h>
 #include <stdio.h>
--- a/xpcom/glue/MainThreadUtils.h
+++ b/xpcom/glue/MainThreadUtils.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MainThreadUtils_h_
 #define MainThreadUtils_h_
 
 #include "nscore.h"
--- a/xpcom/glue/Monitor.h
+++ b/xpcom/glue/Monitor.h
@@ -1,11 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Monitor_h
 #define mozilla_Monitor_h
 
 #include "mozilla/CondVar.h"
--- a/xpcom/glue/Mutex.h
+++ b/xpcom/glue/Mutex.h
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Mutex_h
 #define mozilla_Mutex_h
 
 #include "prlock.h"
 
--- a/xpcom/glue/Observer.h
+++ b/xpcom/glue/Observer.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Observer_h
 #define mozilla_Observer_h
 
 #include "nsTArray.h"
--- a/xpcom/glue/ReentrantMonitor.h
+++ b/xpcom/glue/ReentrantMonitor.h
@@ -1,11 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ReentrantMonitor_h
 #define mozilla_ReentrantMonitor_h
 
 #include "prmon.h"
 
--- a/xpcom/glue/nsArrayEnumerator.cpp
+++ b/xpcom/glue/nsArrayEnumerator.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Attributes.h"
 
 #include "nsArrayEnumerator.h"
 
--- a/xpcom/glue/nsArrayEnumerator.h
+++ b/xpcom/glue/nsArrayEnumerator.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsArrayEnumerator_h__
 #define nsArrayEnumerator_h__
 
 // enumerator implementation for nsIArray
--- a/xpcom/glue/nsArrayUtils.cpp
+++ b/xpcom/glue/nsArrayUtils.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsArrayUtils.h"
 
 //
 // do_QueryElementAt helper stuff
--- a/xpcom/glue/nsArrayUtils.h
+++ b/xpcom/glue/nsArrayUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsArrayUtils_h__
 #define nsArrayUtils_h__
 
 #include "nsCOMPtr.h"
--- a/xpcom/glue/nsBaseHashtable.h
+++ b/xpcom/glue/nsBaseHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsBaseHashtable_h__
 #define nsBaseHashtable_h__
 
 #include "mozilla/MemoryReporting.h"
--- a/xpcom/glue/nsCOMArray.cpp
+++ b/xpcom/glue/nsCOMArray.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMArray.h"
 
 #include "mozilla/MemoryReporting.h"
 
--- a/xpcom/glue/nsCOMArray.h
+++ b/xpcom/glue/nsCOMArray.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCOMArray_h__
 #define nsCOMArray_h__
 
 #include "mozilla/Attributes.h"
--- a/xpcom/glue/nsCOMPtr.cpp
+++ b/xpcom/glue/nsCOMPtr.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 
 nsresult
 nsQueryInterface::operator()(const nsIID& aIID, void** aAnswer) const
--- a/xpcom/glue/nsCOMPtr.h
+++ b/xpcom/glue/nsCOMPtr.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCOMPtr_h___
 #define nsCOMPtr_h___
 
 /*
--- a/xpcom/glue/nsCRTGlue.cpp
+++ b/xpcom/glue/nsCRTGlue.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCRTGlue.h"
 #include "nsXPCOM.h"
 #include "nsDebug.h"
 #include "prtime.h"
--- a/xpcom/glue/nsCRTGlue.h
+++ b/xpcom/glue/nsCRTGlue.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCRTGlue_h__
 #define nsCRTGlue_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsCategoryCache.cpp
+++ b/xpcom/glue/nsCategoryCache.cpp
@@ -1,9 +1,10 @@
-/* vim:set st=2 sts=2 ts=2 et cin: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIStringEnumerator.h"
--- a/xpcom/glue/nsCategoryCache.h
+++ b/xpcom/glue/nsCategoryCache.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCategoryCache_h_
 #define nsCategoryCache_h_
 
 #include "mozilla/Attributes.h"
--- a/xpcom/glue/nsClassHashtable.h
+++ b/xpcom/glue/nsClassHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsClassHashtable_h__
 #define nsClassHashtable_h__
 
 #include "mozilla/Move.h"
--- a/xpcom/glue/nsClassInfoImpl.cpp
+++ b/xpcom/glue/nsClassInfoImpl.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIClassInfoImpl.h"
 #include "nsIProgrammingLanguage.h"
 
 NS_IMETHODIMP_(MozExternalRefCountType)
--- a/xpcom/glue/nsComponentManagerUtils.cpp
+++ b/xpcom/glue/nsComponentManagerUtils.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXPCOM_h__
 #include "nsXPCOM.h"
 #endif
 
--- a/xpcom/glue/nsComponentManagerUtils.h
+++ b/xpcom/glue/nsComponentManagerUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsComponentManagerUtils_h__
 #define nsComponentManagerUtils_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsCycleCollectionNoteChild.h
+++ b/xpcom/glue/nsCycleCollectionNoteChild.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This header will be included by headers that define refpointer and array classes
 // in order to specialize CC helpers such as ImplCycleCollectionTraverse for them.
 
 #ifndef nsCycleCollectionNoteChild_h__
--- a/xpcom/glue/nsCycleCollectionParticipant.cpp
+++ b/xpcom/glue/nsCycleCollectionParticipant.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
 #include "jsapi.h"
 
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCycleCollectionParticipant_h__
 #define nsCycleCollectionParticipant_h__
 
 #include "mozilla/MacroArgs.h"
--- a/xpcom/glue/nsCycleCollectionTraversalCallback.h
+++ b/xpcom/glue/nsCycleCollectionTraversalCallback.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCycleCollectionTraversalCallback_h__
 #define nsCycleCollectionTraversalCallback_h__
 
 #include "nsISupports.h"
--- a/xpcom/glue/nsDataHashtable.h
+++ b/xpcom/glue/nsDataHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDataHashtable_h__
 #define nsDataHashtable_h__
 
 #include "nsHashKeys.h"
--- a/xpcom/glue/nsDebug.h
+++ b/xpcom/glue/nsDebug.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDebug_h___
 #define nsDebug_h___
 
 #include "nscore.h"
--- a/xpcom/glue/nsDeque.cpp
+++ b/xpcom/glue/nsDeque.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDeque.h"
 #include "nsISupportsImpl.h"
 #include <string.h>
 #ifdef DEBUG_rickg
--- a/xpcom/glue/nsDeque.h
+++ b/xpcom/glue/nsDeque.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * MODULE NOTES:
  *
  * The Deque is a very small, very efficient container object
--- a/xpcom/glue/nsEnumeratorUtils.cpp
+++ b/xpcom/glue/nsEnumeratorUtils.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Attributes.h"
 
 #include "nsEnumeratorUtils.h"
 
--- a/xpcom/glue/nsEnumeratorUtils.h
+++ b/xpcom/glue/nsEnumeratorUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsEnumeratorUtils_h__
 #define nsEnumeratorUtils_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsHashKeys.h
+++ b/xpcom/glue/nsHashKeys.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTHashKeys_h__
 #define nsTHashKeys_h__
 
 #include "nsID.h"
--- a/xpcom/glue/nsIClassInfoImpl.h
+++ b/xpcom/glue/nsIClassInfoImpl.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIClassInfoImpl_h__
 #define nsIClassInfoImpl_h__
 
 #include "mozilla/Alignment.h"
--- a/xpcom/glue/nsID.cpp
+++ b/xpcom/glue/nsID.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsID.h"
 #include "prprf.h"
 #include "nsMemory.h"
 
--- a/xpcom/glue/nsID.h
+++ b/xpcom/glue/nsID.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsID_h__
 #define nsID_h__
 
 #include <string.h>
--- a/xpcom/glue/nsIInterfaceRequestorUtils.cpp
+++ b/xpcom/glue/nsIInterfaceRequestorUtils.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 nsresult
--- a/xpcom/glue/nsIInterfaceRequestorUtils.h
+++ b/xpcom/glue/nsIInterfaceRequestorUtils.h
@@ -1,11 +1,11 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsInterfaceRequestorUtils_h
 #define __nsInterfaceRequestorUtils_h
 
 #include "nsCOMPtr.h"
 
--- a/xpcom/glue/nsINIParser.cpp
+++ b/xpcom/glue/nsINIParser.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Moz headers (alphabetical)
 #include "nsCRTGlue.h"
 #include "nsError.h"
 #include "nsIFile.h"
--- a/xpcom/glue/nsINIParser.h
+++ b/xpcom/glue/nsINIParser.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This file was shamelessly copied from mozilla/xpinstall/wizard/unix/src2
 
 #ifndef nsINIParser_h__
 #define nsINIParser_h__
--- a/xpcom/glue/nsISupportsImpl.cpp
+++ b/xpcom/glue/nsISupportsImpl.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupportsImpl.h"
 
 nsresult NS_FASTCALL
 NS_TableDrivenQI(void* aThis, REFNSIID aIID, void** aInstancePtr,
--- a/xpcom/glue/nsISupportsImpl.h
+++ b/xpcom/glue/nsISupportsImpl.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsISupports.h"
 
 
 #ifndef nsISupportsImpl_h__
 #define nsISupportsImpl_h__
--- a/xpcom/glue/nsISupportsUtils.h
+++ b/xpcom/glue/nsISupportsUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsISupportsUtils_h__
 #define nsISupportsUtils_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsIWeakReferenceUtils.h
+++ b/xpcom/glue/nsIWeakReferenceUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIWeakReferenceUtils_h__
 #define nsIWeakReferenceUtils_h__
 
 #include "nsCOMPtr.h"
--- a/xpcom/glue/nsInterfaceHashtable.h
+++ b/xpcom/glue/nsInterfaceHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsInterfaceHashtable_h__
 #define nsInterfaceHashtable_h__
 
 #include "nsBaseHashtable.h"
--- a/xpcom/glue/nsJSThingHashtable.h
+++ b/xpcom/glue/nsJSThingHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsJSThingHashtable_h__
 #define nsJSThingHashtable_h__
 
 #include "nsHashKeys.h"
--- a/xpcom/glue/nsMemory.cpp
+++ b/xpcom/glue/nsMemory.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsXPCOM.h"
 #include "nsMemory.h"
 #include "nsIMemory.h"
 #include "nsXPCOMPrivate.h"
--- a/xpcom/glue/nsMemory.h
+++ b/xpcom/glue/nsMemory.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsMemory_h__
 #define nsMemory_h__
 
 #include "nsXPCOM.h"
--- a/xpcom/glue/nsProxyRelease.cpp
+++ b/xpcom/glue/nsProxyRelease.cpp
@@ -1,9 +1,10 @@
-/* vim:set ts=4 sw=4 sts=4 et cin: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 #include "nsAutoPtr.h"
 
--- a/xpcom/glue/nsProxyRelease.h
+++ b/xpcom/glue/nsProxyRelease.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsProxyRelease_h__
 #define nsProxyRelease_h__
 
 #include "nsIEventTarget.h"
--- a/xpcom/glue/nsQuickSort.h
+++ b/xpcom/glue/nsQuickSort.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 /* We need this because Solaris' version of qsort is broken and
  * causes array bounds reads.
  */
--- a/xpcom/glue/nsRefPtrHashtable.h
+++ b/xpcom/glue/nsRefPtrHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsRefPtrHashtable_h__
 #define nsRefPtrHashtable_h__
 
 #include "nsBaseHashtable.h"
--- a/xpcom/glue/nsServiceManagerUtils.h
+++ b/xpcom/glue/nsServiceManagerUtils.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsServiceManagerUtils_h__
 #define nsServiceManagerUtils_h__
 
 #include "nsIServiceManager.h"
--- a/xpcom/glue/nsStringAPI.cpp
+++ b/xpcom/glue/nsStringAPI.cpp
@@ -1,9 +1,10 @@
-/* vim:set ts=2 sw=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nscore.h"
 #include "nsCRTGlue.h"
 #include "prprf.h"
 #include "nsStringAPI.h"
--- a/xpcom/glue/nsStringAPI.h
+++ b/xpcom/glue/nsStringAPI.h
@@ -1,9 +1,10 @@
-/* vim:set ts=2 sw=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * This header provides wrapper classes around the frozen string API
  * which are roughly equivalent to the internal string classes.
  */
--- a/xpcom/glue/nsStringGlue.h
+++ b/xpcom/glue/nsStringGlue.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsString.h"
 
 /**
  * @file nsStringGlue.h
  * This header exists solely to #include the proper internal/frozen string
--- a/xpcom/glue/nsTArray-inl.h
+++ b/xpcom/glue/nsTArray-inl.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTArray_h__
 #  error "Don't include this file directly"
 #endif
 
--- a/xpcom/glue/nsTArray.cpp
+++ b/xpcom/glue/nsTArray.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <string.h>
 #include "nsTArray.h"
 #include "nsXPCOM.h"
 #include "nsDebug.h"
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTArray_h__
 #define nsTArray_h__
 
 #include "nsTArrayForwardDeclare.h"
--- a/xpcom/glue/nsTArrayForwardDeclare.h
+++ b/xpcom/glue/nsTArrayForwardDeclare.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTArrayForwardDeclare_h__
 #define nsTArrayForwardDeclare_h__
 
 //
--- a/xpcom/glue/nsTHashtable.cpp
+++ b/xpcom/glue/nsTHashtable.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsTHashtable.h"
 
 PLDHashOperator
 PL_DHashStubEnumRemove(PLDHashTable*    aTable,
--- a/xpcom/glue/nsTHashtable.h
+++ b/xpcom/glue/nsTHashtable.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTHashtable_h__
 #define nsTHashtable_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsTObserverArray.cpp
+++ b/xpcom/glue/nsTObserverArray.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsTObserverArray.h"
 
 void
 nsTObserverArray_base::AdjustIterators(index_type aModPos,
--- a/xpcom/glue/nsTObserverArray.h
+++ b/xpcom/glue/nsTObserverArray.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTObserverArray_h___
 #define nsTObserverArray_h___
 
 #include "mozilla/MemoryReporting.h"
--- a/xpcom/glue/nsTPriorityQueue.h
+++ b/xpcom/glue/nsTPriorityQueue.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NS_TPRIORITY_QUEUE_H_
 #define NS_TPRIORITY_QUEUE_H_
 
 #include "nsTArray.h"
--- a/xpcom/glue/nsTWeakRef.h
+++ b/xpcom/glue/nsTWeakRef.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTWeakRef_h__
 #define nsTWeakRef_h__
 
 #ifndef nsDebug_h___
--- a/xpcom/glue/nsTextFormatter.cpp
+++ b/xpcom/glue/nsTextFormatter.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Portable safe sprintf code.
  *
  * Code based on mozilla/nsprpub/src/io/prprf.c rev 3.7
--- a/xpcom/glue/nsTextFormatter.h
+++ b/xpcom/glue/nsTextFormatter.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * This code was copied from xpcom/ds/nsTextFormatter r1.3
  *           Memory model and Frozen linkage changes only.
  *                           -- Prasad <prasad@medhas.org>
--- a/xpcom/glue/nsThreadIDs.h
+++ b/xpcom/glue/nsThreadIDs.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _mozilla_threads_nsThreadIDs_h_
 #define _mozilla_threads_nsThreadIDs_h_
 
 namespace mozilla {
--- a/xpcom/glue/nsThreadUtils.cpp
+++ b/xpcom/glue/nsThreadUtils.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsThreadUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
 
--- a/xpcom/glue/nsThreadUtils.h
+++ b/xpcom/glue/nsThreadUtils.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsThreadUtils_h__
 #define nsThreadUtils_h__
 
 #include "prthread.h"
--- a/xpcom/glue/nsVersionComparator.cpp
+++ b/xpcom/glue/nsVersionComparator.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsVersionComparator.h"
 
 #include <stdlib.h>
 #include <string.h>
--- a/xpcom/glue/nsVersionComparator.h
+++ b/xpcom/glue/nsVersionComparator.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsVersionComparator_h__
 #define nsVersionComparator_h__
 
 #include "nscore.h"
--- a/xpcom/glue/nsVoidArray.cpp
+++ b/xpcom/glue/nsVoidArray.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; c-file-offsets: ((substatement-open . 0)) -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/MemoryReporting.h"
 #include <stdlib.h>
 
--- a/xpcom/glue/nsVoidArray.h
+++ b/xpcom/glue/nsVoidArray.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; c-file-offsets: ((substatement-open . 0))  -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsVoidArray_h___
 #define nsVoidArray_h___
 
 //#define DEBUG_VOIDARRAY 1
 
--- a/xpcom/glue/nsWeakReference.cpp
+++ b/xpcom/glue/nsWeakReference.cpp
@@ -1,11 +1,11 @@
-/* -*- 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // nsWeakReference.cpp
 
 #include "mozilla/Attributes.h"
 
 #include "nsWeakReference.h"
--- a/xpcom/glue/nsWeakReference.h
+++ b/xpcom/glue/nsWeakReference.h
@@ -1,11 +1,11 @@
-/* -*- 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWeakReference_h__
 #define nsWeakReference_h__
 
 // nsWeakReference.h
 
--- a/xpcom/glue/nsXPTCUtils.h
+++ b/xpcom/glue/nsXPTCUtils.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXPTCUtils_h__
 #define nsXPTCUtils_h__
 
 #include "xptcall.h"
--- a/xpcom/glue/pldhash.cpp
+++ b/xpcom/glue/pldhash.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Double hashing implementation.
  */
 #include <stdio.h>
--- a/xpcom/glue/pldhash.h
+++ b/xpcom/glue/pldhash.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef pldhash_h___
 #define pldhash_h___
 /*
  * Double hashing, a la Knuth 6.
--- a/xpcom/glue/standalone/nsXPCOMGlue.cpp
+++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:set ts=4 sw=4 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsXPCOMGlue.h"
 
 #include "nspr.h"
 #include "nsDebug.h"
--- a/xpcom/glue/standalone/nsXPCOMGlue.h
+++ b/xpcom/glue/standalone/nsXPCOMGlue.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXPCOMGlue_h__
 #define nsXPCOMGlue_h__
 
 #include "nscore.h"
--- a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp
+++ b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp
@@ -1,11 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Tests that generational garbage collection post-barriers are correctly
  * implemented for nsTArrays that contain JavaScript Values.
  */
--- a/xpcom/glue/unused.cpp
+++ b/xpcom/glue/unused.cpp
@@ -1,11 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/unused.h"
 
 namespace mozilla {
 
--- a/xpcom/glue/unused.h
+++ b/xpcom/glue/unused.h
@@ -1,11 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_unused_h
 #define mozilla_unused_h
 
 #include "nscore.h"
--- a/xpcom/idl-parser/xpidl.py
+++ b/xpcom/idl-parser/xpidl.py
@@ -511,17 +511,17 @@ class Interface(object):
 
             if self.attributes.scriptable and realbase.attributes.builtinclass and not self.attributes.builtinclass:
                 raise IDLError("interface '%s' is not builtinclass but derives from builtinclass '%s'" % (self.name, self.base), self.location)
 
         for member in self.members:
             member.resolve(self)
 
         # The number 250 is NOT arbitrary; this number is the maximum number of
-        # stub entries defined in xpcom/reflect/xptcall/public/genstubs.pl
+        # stub entries defined in xpcom/reflect/xptcall/genstubs.pl
         # Do not increase this value without increasing the number in that
         # location, or you WILL cause otherwise unknown problems!
         if self.countEntries() > 250 and not self.attributes.builtinclass:
             raise IDLError("interface '%s' has too many entries" % self.name,
                 self.location)
 
     def isScriptable(self):
         # NOTE: this is not whether *this* interface is scriptable... it's
--- a/xpcom/io/Base64.h
+++ b/xpcom/io/Base64.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Base64_h__
 #define mozilla_Base64_h__
 
 #include "nsString.h"
--- a/xpcom/io/CocoaFileUtils.h
+++ b/xpcom/io/CocoaFileUtils.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-// vim:set ts=2 sts=2 sw=2 et cin:
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This namespace contains methods with Obj-C/Cocoa implementations. The header
 // is C/C++ for inclusion in C/C++-only files.
 
 #ifndef CocoaFileUtils_h_
--- a/xpcom/io/nsAnonymousTemporaryFile.cpp
+++ b/xpcom/io/nsAnonymousTemporaryFile.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "mozilla/dom/ContentChild.h"
 #include "nsAnonymousTemporaryFile.h"
 #include "nsDirectoryServiceUtils.h"
--- a/xpcom/io/nsAnonymousTemporaryFile.h
+++ b/xpcom/io/nsAnonymousTemporaryFile.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #pragma once
 
 #include "prio.h"
 #include "nscore.h"
--- a/xpcom/io/nsAppDirectoryServiceDefs.h
+++ b/xpcom/io/nsAppDirectoryServiceDefs.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAppDirectoryServiceDefs_h___
 #define nsAppDirectoryServiceDefs_h___
 
 //========================================================================================
--- a/xpcom/io/nsDirectoryServiceAtomList.h
+++ b/xpcom/io/nsDirectoryServiceAtomList.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 DIR_ATOM(sCurrentProcess, NS_XPCOM_CURRENT_PROCESS_DIR)
 DIR_ATOM(sGRE_Directory, NS_GRE_DIR)
 DIR_ATOM(sOS_DriveDirectory, NS_OS_DRIVE_DIR)
 DIR_ATOM(sOS_TemporaryDirectory, NS_OS_TEMP_DIR)
--- a/xpcom/io/nsIOUtil.cpp
+++ b/xpcom/io/nsIOUtil.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIOUtil.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsStreamUtils.h"
--- a/xpcom/io/nsIOUtil.h
+++ b/xpcom/io/nsIOUtil.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIOUtil_h__
 #define nsIOUtil_h__
 
 #define NS_IOUTIL_CID                                                \
--- a/xpcom/io/nsLinebreakConverter.cpp
+++ b/xpcom/io/nsLinebreakConverter.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsLinebreakConverter.h"
 
 #include "nsMemory.h"
 #include "nsCRT.h"
--- a/xpcom/io/nsLinebreakConverter.h
+++ b/xpcom/io/nsLinebreakConverter.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsLinebreakConverter_h_
 #define nsLinebreakConverter_h_
 
 #include "nscore.h"
--- a/xpcom/io/nsPipe.h
+++ b/xpcom/io/nsPipe.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPipe_h__
 #define nsPipe_h__
 
 #define NS_PIPE_CONTRACTID \
--- a/xpcom/io/nsScriptableBase64Encoder.cpp
+++ b/xpcom/io/nsScriptableBase64Encoder.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsScriptableBase64Encoder.h"
 #include "mozilla/Base64.h"
 
 using namespace mozilla;
--- a/xpcom/io/nsScriptableBase64Encoder.h
+++ b/xpcom/io/nsScriptableBase64Encoder.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsScriptableBase64Encoder_h__
 #define nsScriptableBase64Encoder_h__
 
 #include "nsIScriptableBase64Encoder.h"
--- a/xpcom/io/nsScriptableInputStream.cpp
+++ b/xpcom/io/nsScriptableInputStream.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsScriptableInputStream.h"
 #include "nsMemory.h"
 #include "nsString.h"
 
--- a/xpcom/io/nsStringStream.h
+++ b/xpcom/io/nsStringStream.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsStringStream_h__
 #define nsStringStream_h__
 
 #include "nsIStringStream.h"
--- a/xpcom/io/nsUnicharInputStream.cpp
+++ b/xpcom/io/nsUnicharInputStream.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsUnicharInputStream.h"
 #include "nsIInputStream.h"
 #include "nsIServiceManager.h"
 #include "nsString.h"
--- a/xpcom/io/nsUnicharInputStream.h
+++ b/xpcom/io/nsUnicharInputStream.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsUnicharInputStream_h__
 #define nsUnicharInputStream_h__
 
 #include "nsISimpleUnicharStreamFactory.h"
--- a/xpcom/io/nsWildCard.h
+++ b/xpcom/io/nsWildCard.h
@@ -1,9 +1,10 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * nsWildCard.h: Defines and prototypes for shell exp. match routines
  *
  * See nsIZipReader.findEntries docs in nsIZipReader.idl for a description of
rename from xpcom/reflect/xptcall/public/genstubs.pl
rename to xpcom/reflect/xptcall/genstubs.pl
--- a/xpcom/reflect/xptcall/public/genstubs.pl
+++ b/xpcom/reflect/xptcall/genstubs.pl
@@ -11,17 +11,17 @@
 #
 # if "$entry_count" is ever changed and the .inc files regenerated then
 # the following issues need to be addressed:
 #
 # 1) The current Linux ARM code has a limitation of only having 256-3 stubs,
 #    as a result of the limitations of immediate values in ARM assembly.
 #
 # This number is verified by the IDL parser in xpcom/idl-parser/xpidl.py, as
-# well as in xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp, to
+# well as in xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp, to
 # prevent generating interfaces or loading xpt files that would cause the
 # stubs to run off the entries.
 # If you change this number, please update that location.
 
 # 3 entries are already 'used' by the 3 methods of nsISupports.
 # 3+247+5=255 This should get us in under the Linux ARM limitation
 $entry_count    = 247;
 $sentinel_count = 5;
rename from xpcom/reflect/xptcall/src/md/moz.build
rename to xpcom/reflect/xptcall/md/moz.build
rename from xpcom/reflect/xptcall/src/md/test/README
rename to xpcom/reflect/xptcall/md/test/README
rename from xpcom/reflect/xptcall/src/md/test/clean.bat
rename to xpcom/reflect/xptcall/md/test/clean.bat
rename from xpcom/reflect/xptcall/src/md/test/invoke_test.cpp
rename to xpcom/reflect/xptcall/md/test/invoke_test.cpp
rename from xpcom/reflect/xptcall/src/md/test/mk_invoke.bat
rename to xpcom/reflect/xptcall/md/test/mk_invoke.bat
rename from xpcom/reflect/xptcall/src/md/test/mk_stub.bat
rename to xpcom/reflect/xptcall/md/test/mk_stub.bat
rename from xpcom/reflect/xptcall/src/md/test/moz.build
rename to xpcom/reflect/xptcall/md/test/moz.build
rename from xpcom/reflect/xptcall/src/md/test/stub_test.cpp
rename to xpcom/reflect/xptcall/md/test/stub_test.cpp
rename from xpcom/reflect/xptcall/src/md/unix/Makefile.in
rename to xpcom/reflect/xptcall/md/unix/Makefile.in
rename from xpcom/reflect/xptcall/src/md/unix/moz.build
rename to xpcom/reflect/xptcall/md/unix/moz.build
--- a/xpcom/reflect/xptcall/src/md/unix/moz.build
+++ b/xpcom/reflect/xptcall/md/unix/moz.build
@@ -326,12 +326,12 @@ if CONFIG['OS_ARCH'] == 'Linux':
             '-fomit-frame-pointer',
             '-mbackchain',
         ]
 
 FINAL_LIBRARY = 'xpcom_core'
 
 LOCAL_INCLUDES += [
     '../..',
-    '../../../../xptinfo/src',
+    '/xpcom/reflect/xptinfo',
 ]
 
 NO_PGO = True
rename from xpcom/reflect/xptcall/src/md/unix/vtable_layout_x86.cpp
rename to xpcom/reflect/xptcall/md/unix/vtable_layout_x86.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h
rename to xpcom/reflect/xptcall/md/unix/xptc_gcc_x86_unix.h
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_aarch64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_alpha_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_alpha_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_amd64_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_amd64_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_arm.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_arm_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_arm_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_aarch64.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_aarch64.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf32.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ipf32.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ipf64.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips64.S
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_mips64.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_pa32.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_pa32.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_parisc_linux.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_parisc_linux.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.S
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc64_linux.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_aix.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_aix64.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_aix64.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_ibmobj_aix.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_linux.S
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_linux.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_netbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_netbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_openbsd.S
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_openbsd.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc_rhapsody.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_ppc_rhapsody.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_openbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc64_openbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_linux_GCC3.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_netbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_netbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_openbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_openbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_SUNW.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparcv9_solaris_SUNW.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_x86_solaris_SUNW.s
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_solaris_SUNW.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_darwin.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_darwin.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf32.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ipf32.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ipf64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ipf64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_alpha.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_linux_alpha.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_m68k.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_linux_m68k.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_linux_s390.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390x.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_linux_s390x.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_mips.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_mips64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_mips64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_netbsd_m68k.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_netbsd_m68k.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_pa32.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_pa32.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc64_linux.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_aix.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_aix64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_aix64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_linux.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_linux.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc_rhapsody.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc_rhapsody.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparcv9_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_sparcv9_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_unix.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_aarch64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_aarch64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_alpha_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_alpha_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_amd64_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_amd64_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_arm.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_arm_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_arm_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_aarch64.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_aarch64.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf32.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ipf32.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ipf64.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ipf64.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_mips.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.m4
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_mips.s.m4
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips64.S
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_mips64.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_pa32.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_pa32.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_parisc_linux.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_parisc_linux.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.S
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc64_linux.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix.s.m4
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_aix.s.m4
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_aix64.s.m4
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_aix64.s.m4
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_darwin.s.m4
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_darwin.s.m4
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_linux.S
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_linux.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_netbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_netbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc_openbsd.S
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_ppc_openbsd.S
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc64_openbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc64_openbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_netbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_netbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_openbsd.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_openbsd.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc_solaris.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparcv9_solaris.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparcv9_solaris.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_x86_64_solaris_SUNW.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_x86_64_solaris_SUNW.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_x86_solaris_SUNW.s
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_asm_x86_solaris_SUNW.s
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_darwin.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_darwin.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_gcc_x86_unix.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_gcc_x86_unix.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf32.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ipf32.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ipf64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ipf64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_alpha.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_linux_alpha.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_m68k.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_linux_m68k.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_linux_s390.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_s390x.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_linux_s390x.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_mips.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_mips64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_mips64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_netbsd_m68k.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_netbsd_m68k.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_pa32.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_pa32.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_aix.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_aix64.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_aix64.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_linux.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_linux.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_rhapsody.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_netbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_netbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_openbsd.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_openbsd.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparcv9_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_sparcv9_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_darwin.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_x86_64_darwin.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_x86_64_linux.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_x86_64_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_solaris.cpp
rename to xpcom/reflect/xptcall/md/unix/xptcstubs_x86_solaris.cpp
rename from xpcom/reflect/xptcall/src/md/win32/moz.build
rename to xpcom/reflect/xptcall/md/win32/moz.build
--- a/xpcom/reflect/xptcall/src/md/win32/moz.build
+++ b/xpcom/reflect/xptcall/md/win32/moz.build
@@ -33,15 +33,15 @@ else:
             'xptcinvoke.cpp',
             'xptcstubs.cpp',
         ]
 
 FINAL_LIBRARY = 'xpcom_core'
 
 LOCAL_INCLUDES += [
     '../..',
-    '../../../../xptinfo/src',
+    '/xpcom/reflect/xptinfo',
 ]
 
 if CONFIG['TARGET_CPU'] != 'x86_64':
     if not CONFIG['GNU_CXX']:
         # FIXME: bug 413019
         NO_PGO = True
rename from xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp
rename from xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_x86_64.asm
rename to xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64.asm
rename from xpcom/reflect/xptcall/src/md/win32/xptcinvoke_asm_x86_64_gnu.s
rename to xpcom/reflect/xptcall/md/win32/xptcinvoke_asm_x86_64_gnu.s
rename from xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_64.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_64.cpp
rename from xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_gnu.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcinvoke_x86_gnu.cpp
rename from xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcstubs.cpp
rename from xpcom/reflect/xptcall/src/md/win32/xptcstubs_asm_x86_64.asm
rename to xpcom/reflect/xptcall/md/win32/xptcstubs_asm_x86_64.asm
rename from xpcom/reflect/xptcall/src/md/win32/xptcstubs_x86_64.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64.cpp
rename from xpcom/reflect/xptcall/src/md/win32/xptcstubs_x86_64_gnu.cpp
rename to xpcom/reflect/xptcall/md/win32/xptcstubs_x86_64_gnu.cpp
--- a/xpcom/reflect/xptcall/moz.build
+++ b/xpcom/reflect/xptcall/moz.build
@@ -1,8 +1,25 @@
 # -*- 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/.
 
-DIRS += ['public', 'src']
+DIRS += ['md']
+
+SOURCES += [
+    'xptcall.cpp',
+]
 
+EXPORTS += [
+    'xptcall.h',
+    'xptcstubsdecl.inc',
+    'xptcstubsdef.inc',
+]
+
+MSVC_ENABLE_PGO = True
+
+LOCAL_INCLUDES += [
+    '/xpcom/reflect/xptinfo',
+]
+
+FINAL_LIBRARY = 'xpcom_core'
--- a/xpcom/reflect/xptcall/porting.html
+++ b/xpcom/reflect/xptcall/porting.html
@@ -23,21 +23,21 @@ ported to all platforms that want to sup
 
 <h3>The tree</h3>
 
 <blockquote>
 <pre>
 <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall">mozilla/xpcom/reflect/xptcall</a>
   +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public">public</a>  // exported headers
   +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src">src</a>  // core source
-  |  \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md">md</a>  // platform specific parts
-  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a>  // mac ppc
-  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a>  // all unix
-  |     \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a>  // win32
-  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">test</a>  // simple tests to get started
+  |  \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md">md</a>  // platform specific parts
+  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/mac">mac</a>  // mac ppc
+  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a>  // all unix
+  |     \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/win32">win32</a>  // win32
+  |     +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/test">test</a>  // simple tests to get started
   \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">tests</a>  // full tests via api
 </pre>
 
 Porters are free to create subdirectories under the base <code>md</code>
 directory for their given platforms and to integrate into the build system as
 appropriate for their platform.
 
 </blockquote>
@@ -46,50 +46,50 @@ appropriate for their platform.
 
 <blockquote>
 
 There are really two pieces of functionality: <i>invoke</i> and <i>stubs</i>...
 
 <p>
 
 The <b><i>invoke</i></b> functionality requires the implementation of the
-following on each platform (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>):
+following on each platform (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/xptcall.h">xptcall/xptcall.h</a>):
 
 <pre>
 XPTC_PUBLIC_API(nsresult)
 NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
                    uint32_t paramCount, nsXPTCVariant* params);
 </pre>
 
 Calling code is expected to supply an array of <code>nsXPTCVariant</code>
 structs. These are discriminated unions describing the type and value of each
 parameter of the target function. The platform specific code then builds a call
 frame and invokes the method indicated by the index <code>methodIndex</code> on
 the xpcom interface <code>that</code>.
 
 <p>
 
 Here are examples of this implementation for 
-<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp">Win32</a>
+<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/win32/xptcinvoke.cpp">Win32</a>
 and 
-<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>.
+<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix/xptcinvoke_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>.
 
 Both of these implementations use the basic strategy of: figure out how much
 stack space is needed for the params, make the space in a new frame, copy the
 params to that space, invoke the method, cleanup and return. C++ is used where
 appropriate, Assembly language is used where necessary. Inline assembly language is used here,
 but it is equally valid to use separate assembly language source files. Porters
 can decide how best to do this for their platforms.
 
 <p>
 
 The <b><i>stubs</i></b> functionality is more complex. The goal here is a class
 whose vtbl can look like the vtbl of any arbitrary xpcom interface. Objects of
 this class can then be built to impersonate any xpcom object. The base interface
-for this is (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>):
+for this is (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/xptcall.h">xptcall/xptcall.h</a>):
 
 <pre>
 class nsXPTCStubBase : public nsISupports
 {
 public:
     // Include generated vtbl stub declarations.
     // These are virtual and *also* implemented by this class..
 #include "xptcstubsdecl.inc"
@@ -125,32 +125,32 @@ specific method that uses the interface 
 the overridden <code>GetInterfaceInfo</code> to extract the parameters and build
 an array of platform independent <code>nsXPTCMiniVariant</code> structs which
 are in turn passed on to the overridden <code>CallMethod</code>. The
 platform dependent code is responsible for doing any cleanup and returning.
 
 <p>
 
 The stub methods are declared in <a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdecl.inc">xptcall/public/xptcstubsdecl.inc</a>.
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/xptcstubsdecl.inc">xptcall/xptcstubsdecl.inc</a>.
 These are '#included' into the declaration of <code>nsXPTCStubBase</code>. A
 similar include file (<a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdef.inc">xptcall/public/xptcstubsdef.inc</a>)
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/xptcstubsdef.inc">xptcall/xptcstubsdef.inc</a>)
 is expanded using platform specific macros to define the stub functions. These
 '.inc' files are checked into cvs. However, they can be regenerated as necessary
 (i.e. to change the number of stubs or to change their specific declaration)
 using the Perl script  <a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/genstubs.pl">xptcall/public/genstubs.pl</a>.
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/genstubs.pl">xptcall/genstubs.pl</a>.
 
 <p>
 
 Here are examples of this implementation for  <a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp">Win32</a>
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/win32/xptcstubs.cpp">Win32</a>
 and  <a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>.
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix/xptcstubs_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>.
 Both of these examples use inline assembly language. That is just how I
 decided to do it. You can do it as you choose.
 
 <p>
 
 The Win32 version is somewhat tighter because the __declspec(naked) feature
 allows for very small stubs. However, the __stdcall requires the callee to clean
 up the stack, so it is imperative that the interface information scheme allow
@@ -171,17 +171,17 @@ paste as necessary. Please remember that
 important than speed optimizations. This code is primarily used to connect XPCOM
 components with JavaScript; function call overhead is a <b>tiny</b> part of the
 time involved.
 
 <p>
 
 I put together 
 <a
-href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">xptcall/src/md/test
+href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/test">xptcall/md/test
 </a> as a place to evolve the basic functionality as a port is coming together.
 Not all of the functionality is exercised, but it is a place to get started. 
 <a
 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">xptcall/tests
 </a> has an api level test for <code>NS_InvokeByIndex</code>, but no tests for
 the <i>stubs</i> functionality. Such a test ought to be written, but this has not
 yet been done.
 
deleted file mode 100644
--- a/xpcom/reflect/xptcall/public/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
-    'xptcall.h',
-    'xptcstubsdecl.inc',
-    'xptcstubsdef.inc',
-]
-
deleted file mode 100644
--- a/xpcom/reflect/xptcall/src/moz.build
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['md']
-
-SOURCES += [
-    'xptcall.cpp',
-]
-
-MSVC_ENABLE_PGO = True
-
-LOCAL_INCLUDES += [
-    '/xpcom/reflect/xptinfo/src',
-]
-
-FINAL_LIBRARY = 'xpcom_core'
--- a/xpcom/reflect/xptcall/status.html
+++ b/xpcom/reflect/xptcall/status.html
@@ -39,86 +39,86 @@ is the best contact regarding 'nix (Unix
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Win32 x86</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:jband@netscape.com">John Bandhauer &lt;jband@netscape.com&gt;</a>
 </TD>
 <TD>
-<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a></TD>
+<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/win32">win32</a></TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Linux x86</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:jband@netscape.com">John Bandhauer &lt;jband@netscape.com&gt;</a><br>
 <img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:drepper@cygnus.com">Ulrich Drepper &lt;drepper@cygnus.com&gt;</a>
 </TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a>
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a>
 </TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>FreeBSD and NetBSD x86</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:toshok@hungry.com">Christoph Toshok &lt;toshok@hungry.com&gt;</a>,<BR>
 <img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:jband@netscape.com">John Bandhauer &lt;jband@netscape.com&gt;</a></TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (same as Linux 86 code)</TD>
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a> (same as Linux 86 code)</TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>BSD/OS x86</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:bert_driehuis@nl.compuware.com">Bert Driehuis &lt;bert_driehuis@nl.compuware.com&gt;</a></TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (same as Linux 86 code)
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a> (same as Linux 86 code)
 Bert contributed patches that *should* do the right thing for all the unixish-x86
 versions of this code for GCC 2.7 or 2.8 vs. EGCS 1.1. He notes that the vtbl 
 scheme is different. He is hoping that others will help test the changes using 
 these two compilers on the various platforms where this same code is used. 
 <a href="news://news.mozilla.org/372DD257.4248C821%40nl.compuware.com">Bert's details</a>
 </TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Mac PPC</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
  <a href="mailto:rogerl@netscape.com">Roger Lawrence &lt;rogerl@netscape.com&gt;</a>,<BR>
 <img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:beard@netscape.com">Patrick Beard &lt;beard@netscape.com&gt;</a>
 </TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a> (passing tests and checked in)</TD>
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/mac">mac</a> (passing tests and checked in)</TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Solaris Sparc</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:rogerl@netscape.com">Roger Lawrence &lt;rogerl@netscape.com&gt;</a>,<BR>
 <img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:mcafee@netscape.com">Chris McAfee &lt;mcafee@netscape.com&gt;</a>
 </TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> This is checked in and working.</TD>
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a> This is checked in and working.</TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Solaris Sparc v9 (64bit)</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:pavlov@netscape.com">Stuart Parmenter &lt;pavlov@netscape.com&gt;</a>,<BR>
 <img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:cls@seawood.org">Chris Seawood &lt;cls@seawood.org&gt;</a>
 </TD>
-<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> This is checked in and (pavlov claims!) working.</TD>
+<TD><a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a> This is checked in and (pavlov claims!) working.</TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>OS/2</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:mjf35@cam.ac.uk">John Fairhurst &lt;mjf35@cam.ac.uk&gt;</a></TD>
 <TD>I never heard exactly who did what. But mozilla has been working on OS/2 
@@ -150,17 +150,17 @@ It is a variation of the IRIS port (only
 Notice the last 2 files (the change to mozilla\xpcom\build\makefile.win and
 mozilla\xpcom\build) are needed because I was unable to figure how to do a
 "declspecexport" from the assembler ASAXP ... if some knows how to do that then
 those last 2 files won't be needed.
 <p>
 I have had someone look over this code at bridge.com (the entry point to
 compaq/gem compiler team) and this code was given the OK. I consider it "done".
 <p>
-This code lives in the files where the name includes 'alpha' in the <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a> directory.<BR>
+This code lives in the files where the name includes 'alpha' in the <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/win32">win32</a> directory.<BR>
 </TD>
 </TR>
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>Linux ARM</TD>
 <TD><img alt="Started" title="Started" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:sh990154@mail.uni-greifswald.de">Stefan Hanske&lt;sh990154@mail.uni-greifswald.de&gt;</a><BR>
@@ -296,17 +296,17 @@ is the interim maintainer until someone 
 
 <TR>
 <TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
 <TD>BeOS x86</TD>
 <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
 <a href="mailto:duncan@be.com">Duncan Wilcox &lt;duncan@be.com&gt;</a><BR>
 </TD>
 <TD>
-<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> (yet another reuse of the Linux 86 code!)<BR>
+<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/md/unix">unix</a> (yet another reuse of the Linux 86 code!)<BR>
 Duncan says this is all working. He did the code for old cfront style 'this' adjustment for others to use too!
 </TD>
 </TR>
 
 <TR>
 <TD bgcolor="red"><font color="white"><b>HELP!</b></font></TD>
 <TD>BeOS PPC</TD>
 <TD align="center">-</TD>
rename from xpcom/reflect/xptcall/src/xptcall.cpp
rename to xpcom/reflect/xptcall/xptcall.cpp
rename from xpcom/reflect/xptcall/public/xptcall.h
rename to xpcom/reflect/xptcall/xptcall.h
rename from xpcom/reflect/xptcall/src/xptcprivate.h
rename to xpcom/reflect/xptcall/xptcprivate.h
rename from xpcom/reflect/xptcall/public/xptcstubsdecl.inc
rename to xpcom/reflect/xptcall/xptcstubsdecl.inc
rename from xpcom/reflect/xptcall/public/xptcstubsdef.inc
rename to xpcom/reflect/xptcall/xptcstubsdef.inc
rename from xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
rename to xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
rename from xpcom/reflect/xptinfo/src/ShimInterfaceInfo.h
rename to xpcom/reflect/xptinfo/ShimInterfaceInfo.h
rename from xpcom/reflect/xptinfo/src/TODO
rename to xpcom/reflect/xptinfo/TODO
rename from xpcom/reflect/xptinfo/public/XPTInterfaceInfoManager.h
rename to xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h
--- a/xpcom/reflect/xptinfo/moz.build
+++ b/xpcom/reflect/xptinfo/moz.build
@@ -1,8 +1,36 @@
 # -*- 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/.
 
-DIRS += ['public', 'src']
+UNIFIED_SOURCES += [
+    'ShimInterfaceInfo.cpp',
+    'xptiInterfaceInfo.cpp',
+    'xptiInterfaceInfoManager.cpp',
+    'xptiTypelibGuts.cpp',
+    'xptiWorkingSet.cpp',
+]
+
+XPIDL_SOURCES += [
+    'nsIInterfaceInfo.idl',
+    'nsIInterfaceInfoManager.idl',
+]
+
+XPIDL_MODULE = 'xpcom_xpti'
 
+EXPORTS += [
+    'xptinfo.h',
+]
+
+EXPORTS.mozilla += [
+    'XPTInterfaceInfoManager.h',
+]
+
+LOCAL_INCLUDES += [
+    '/dom/base',
+]
+
+MSVC_ENABLE_PGO = True
+
+FINAL_LIBRARY = 'xpcom_core'
rename from xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl
rename to xpcom/reflect/xptinfo/nsIInterfaceInfo.idl
rename from xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl
rename to xpcom/reflect/xptinfo/nsIInterfaceInfoManager.idl
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/public/moz.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'nsIInterfaceInfo.idl',
-    'nsIInterfaceInfoManager.idl',
-]
-
-XPIDL_MODULE = 'xpcom_xpti'
-
-EXPORTS += [
-    'xptinfo.h',
-]
-
-EXPORTS.mozilla += [
-    'XPTInterfaceInfoManager.h',
-]
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/src/moz.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-UNIFIED_SOURCES += [
-    'ShimInterfaceInfo.cpp',
-    'xptiInterfaceInfo.cpp',
-    'xptiInterfaceInfoManager.cpp',
-    'xptiTypelibGuts.cpp',
-    'xptiWorkingSet.cpp',
-]
-
-LOCAL_INCLUDES += [
-    '/dom/base',
-]
-
-MSVC_ENABLE_PGO = True
-
-FINAL_LIBRARY = 'xpcom_core'
rename from xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
rename to xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
rename from xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
rename to xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
@@ -136,17 +136,17 @@ void
 XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                                 uint16_t idx,
                                                 xptiTypelibGuts* typelib)
 {
     if (!iface->interface_descriptor)
         return;