Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 22 Aug 2013 20:48:10 -0400
changeset 144038 fb2318875cd48d38d9be87c04e21c6fccea9fa9b
parent 144037 9b78d0aa824991f7de37775ab998c0b31e1d61b1 (current diff)
parent 143964 581251a392cd043b126fb5afed9482a309aba296 (diff)
child 144039 487f1cb462cdbc8e11ba36e72d9a481e9390eaed
child 144138 073fbcfa3e1f0d7860780c35717b30041a7d29b3
child 155736 f840508bc61433a47020173890dffac6fbd41f14
push id32853
push userryanvm@gmail.com
push dateFri, 23 Aug 2013 14:56:08 +0000
treeherdermozilla-inbound@fa56d4c9e630 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
fb2318875cd4 / 26.0a1 / 20130823030204 / files
nightly linux64
fb2318875cd4 / 26.0a1 / 20130823030204 / files
nightly mac
fb2318875cd4 / 26.0a1 / 20130823030204 / files
nightly win32
fb2318875cd4 / 26.0a1 / 20130823030204 / files
nightly win64
fb2318875cd4 / 26.0a1 / 20130823030204 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team.
gfx/gl/GLContextExtensionGroupQueries.cpp
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1762,26 +1762,30 @@ ContentPermissionPrompt.prototype = {
   _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aActions,
                                        aNotificationId, aAnchorId, aOptions) {
     function onFullScreen() {
       popup.remove();
     }
 
     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 
-    var requestingWindow = aRequest.window.top;
-    var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
-    var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
+    var browser;
+    try {
+      // "element" is only defined in e10s mode, otherwise it throws.
+      browser = aRequest.element;
+    } catch (e) {}
     if (!browser) {
+      var requestingWindow = aRequest.window.top;
       // find the requesting browser or iframe
       browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIWebNavigation)
                                   .QueryInterface(Ci.nsIDocShell)
                                   .chromeEventHandler;
     }
+    var chromeWin = browser.ownerDocument.defaultView;
     var requestPrincipal = aRequest.principal;
 
     // Transform the prompt actions into PopupNotification actions.
     var popupNotificationActions = [];
     for (var i = 0; i < aActions.length; i++) {
       let promptAction = aActions[i];
 
       // Don't offer action in PB mode if the action remembers permission for more than a session.
--- a/browser/devtools/debugger/test/browser_dbg_listtabs-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_listtabs-02.js
@@ -17,134 +17,146 @@ let onListChangedCount = 0;
 function onListChangedHandler() {
   onListChangedCount++;
 }
 
 function test() {
   tabList = new DebuggerServer.BrowserTabList("fake DebuggerServerConnection");
   tabList._testing = true;
   tabList.onListChanged = onListChangedHandler;
-
-  checkSingleTab();
-  // Open a new tab. We should be notified.
-  is(onListChangedCount, 0, "onListChanged handler call count");
-  tabA = addTab(testPage, onTabA);
+  checkSingleTab(function () {
+    is(onListChangedCount, 0, "onListChanged handler call count");
+    tabA = addTab(testPage, onTabA);
+  });
 }
 
-function checkSingleTab() {
-  var tabActors = [t for (t of tabList)];
-  is(tabActors.length, 1, "initial tab list: contains initial tab");
-  firstActor = tabActors[0];
-  is(firstActor.url, "about:blank", "initial tab list: initial tab URL is 'about:blank'");
-  is(firstActor.title, "New Tab", "initial tab list: initial tab title is 'New Tab'");
+function checkSingleTab(callback) {
+  tabList.getList().then(function (tabActors) {
+    is(tabActors.length, 1, "initial tab list: contains initial tab");
+    firstActor = tabActors[0];
+    is(firstActor.url, "about:blank", "initial tab list: initial tab URL is 'about:blank'");
+    is(firstActor.title, "New Tab", "initial tab list: initial tab title is 'New Tab'");
+    callback();
+  });
 }
 
 function onTabA() {
   is(onListChangedCount, 1, "onListChanged handler call count");
 
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 2, "tabA opened: two tabs in list");
-  ok(tabActors.has(firstActor), "tabA opened: initial tab present");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 2, "tabA opened: two tabs in list");
+    ok(tabActors.has(firstActor), "tabA opened: initial tab present");
 
-  info("actors: " + [a.url for (a of tabActors)]);
-  actorA = [a for (a of tabActors) if (a !== firstActor)][0];
-  ok(actorA.url.match(/^data:text\/html;/), "tabA opened: new tab URL");
-  is(actorA.title, "JS Debugger BrowserTabList test page", "tabA opened: new tab title");
+    info("actors: " + [a.url for (a of tabActors)]);
+    actorA = [a for (a of tabActors) if (a !== firstActor)][0];
+    ok(actorA.url.match(/^data:text\/html;/), "tabA opened: new tab URL");
+    is(actorA.title, "JS Debugger BrowserTabList test page", "tabA opened: new tab title");
 
-  tabB = addTab(testPage, onTabB);
+    tabB = addTab(testPage, onTabB);
+  });
 }
 
 function onTabB() {
   is(onListChangedCount, 2, "onListChanged handler call count");
 
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 3, "tabB opened: three tabs in list");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 3, "tabB opened: three tabs in list");
 
-  // Test normal close.
-  gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
-    gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
-    ok(!aEvent.detail, "This was a normal tab close");
-    // Let the actor's TabClose handler finish first.
-    executeSoon(testTabClose);
-  }, false);
-  gBrowser.removeTab(tabA);
+    // Test normal close.
+    gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
+      gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
+      ok(!aEvent.detail, "This was a normal tab close");
+      // Let the actor's TabClose handler finish first.
+      executeSoon(testTabClose);
+    }, false);
+    gBrowser.removeTab(tabA);
+  });
 }
 
 function testTabClose() {
   is(onListChangedCount, 3, "onListChanged handler call count");
 
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 2, "tabA closed: two tabs in list");
-  ok(tabActors.has(firstActor), "tabA closed: initial tab present");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 2, "tabA closed: two tabs in list");
+    ok(tabActors.has(firstActor), "tabA closed: initial tab present");
 
-  info("actors: " + [a.url for (a of tabActors)]);
-  actorA = [a for (a of tabActors) if (a !== firstActor)][0];
-  ok(actorA.url.match(/^data:text\/html;/), "tabA closed: new tab URL");
-  is(actorA.title, "JS Debugger BrowserTabList test page", "tabA closed: new tab title");
+    info("actors: " + [a.url for (a of tabActors)]);
+    actorA = [a for (a of tabActors) if (a !== firstActor)][0];
+    ok(actorA.url.match(/^data:text\/html;/), "tabA closed: new tab URL");
+    is(actorA.title, "JS Debugger BrowserTabList test page", "tabA closed: new tab title");
 
-  // Test tab close by moving tab to a window.
-  tabC = addTab(testPage, onTabC);
+    // Test tab close by moving tab to a window.
+    tabC = addTab(testPage, onTabC);
+  });
 }
 
 function onTabC() {
   is(onListChangedCount, 4, "onListChanged handler call count");
 
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 3, "tabC opened: three tabs in list");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 3, "tabC opened: three tabs in list");
 
-  gBrowser.tabContainer.addEventListener("TabClose", function onClose2(aEvent) {
-    gBrowser.tabContainer.removeEventListener("TabClose", onClose2, false);
-    ok(aEvent.detail, "This was a tab closed by moving");
-    // Let the actor's TabClose handler finish first.
-    executeSoon(testWindowClose);
-  }, false);
-  newWin = gBrowser.replaceTabWithWindow(tabC);
+    gBrowser.tabContainer.addEventListener("TabClose", function onClose2(aEvent) {
+      gBrowser.tabContainer.removeEventListener("TabClose", onClose2, false);
+      ok(aEvent.detail, "This was a tab closed by moving");
+      // Let the actor's TabClose handler finish first.
+      executeSoon(testWindowClose);
+    }, false);
+    newWin = gBrowser.replaceTabWithWindow(tabC);
+  });
 }
 
 function testWindowClose() {
   is(onListChangedCount, 5, "onListChanged handler call count");
 
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 3, "tabC closed: three tabs in list");
-  ok(tabActors.has(firstActor), "tabC closed: initial tab present");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 3, "tabC closed: three tabs in list");
+    ok(tabActors.has(firstActor), "tabC closed: initial tab present");
 
-  info("actors: " + [a.url for (a of tabActors)]);
-  actorA = [a for (a of tabActors) if (a !== firstActor)][0];
-  ok(actorA.url.match(/^data:text\/html;/), "tabC closed: new tab URL");
-  is(actorA.title, "JS Debugger BrowserTabList test page", "tabC closed: new tab title");
+    info("actors: " + [a.url for (a of tabActors)]);
+    actorA = [a for (a of tabActors) if (a !== firstActor)][0];
+    ok(actorA.url.match(/^data:text\/html;/), "tabC closed: new tab URL");
+    is(actorA.title, "JS Debugger BrowserTabList test page", "tabC closed: new tab title");
 
-  // Cleanup.
-  newWin.addEventListener("unload", function onUnload(aEvent) {
-    newWin.removeEventListener("unload", onUnload, false);
-    ok(!aEvent.detail, "This was a normal window close");
-    // Let the actor's TabClose handler finish first.
-    executeSoon(checkWindowClose);
-  }, false);
-  newWin.close();
+    // Cleanup.
+    newWin.addEventListener("unload", function onUnload(aEvent) {
+      newWin.removeEventListener("unload", onUnload, false);
+      ok(!aEvent.detail, "This was a normal window close");
+      // Let the actor's TabClose handler finish first.
+      executeSoon(checkWindowClose);
+    }, false);
+    newWin.close();
+  });
 }
 
 function checkWindowClose() {
   is(onListChangedCount, 6, "onListChanged handler call count");
 
   // Check that closing a XUL window leaves the other actors intact.
-  var tabActors = new Set([t for (t of tabList)]);
-  is(tabActors.size, 2, "newWin closed: two tabs in list");
-  ok(tabActors.has(firstActor), "newWin closed: initial tab present");
+  tabList.getList().then(function (tabActors) {
+    tabActors = new Set(tabActors);
+    is(tabActors.size, 2, "newWin closed: two tabs in list");
+    ok(tabActors.has(firstActor), "newWin closed: initial tab present");
 
-  info("actors: " + [a.url for (a of tabActors)]);
-  actorA = [a for (a of tabActors) if (a !== firstActor)][0];
-  ok(actorA.url.match(/^data:text\/html;/), "newWin closed: new tab URL");
-  is(actorA.title, "JS Debugger BrowserTabList test page", "newWin closed: new tab title");
+    info("actors: " + [a.url for (a of tabActors)]);
+    actorA = [a for (a of tabActors) if (a !== firstActor)][0];
+    ok(actorA.url.match(/^data:text\/html;/), "newWin closed: new tab URL");
+    is(actorA.title, "JS Debugger BrowserTabList test page", "newWin closed: new tab title");
 
-  // Test normal close.
-  gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
-    gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
-    ok(!aEvent.detail, "This was a normal tab close");
-    // Let the actor's TabClose handler finish first.
-    executeSoon(finishTest);
-  }, false);
-  gBrowser.removeTab(tabB);
+    // Test normal close.
+    gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
+      gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
+      ok(!aEvent.detail, "This was a normal tab close");
+      // Let the actor's TabClose handler finish first.
+      executeSoon(finishTest);
+    }, false);
+    gBrowser.removeTab(tabB);
+  });
 }
 
 function finishTest() {
-  checkSingleTab();
-  finish();
+  checkSingleTab(finish);
 }
--- a/configure.in
+++ b/configure.in
@@ -5802,16 +5802,28 @@ dnl Permissions System
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(permissions,
 [  --disable-permissions   Disable permissions (popup and cookie blocking)],
     MOZ_PERMISSIONS=,
     MOZ_PERMISSIONS=1
 )
 
 dnl ========================================================
+dnl Child permissions, currently only used for b2g
+dnl ========================================================
+if test -n "$MOZ_B2G"; then
+    if test -n "$MOZ_PERMISSIONS"; then
+        MOZ_CHILD_PERMISSIONS=1
+    else
+        AC_MSG_ERROR([You need to enable MOZ_PERMISSIONS for MOZ_CHILD_PERMISSIONS])
+    fi
+fi
+AC_SUBST(MOZ_CHILD_PERMISSIONS)
+
+dnl ========================================================
 dnl NegotiateAuth
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(negotiateauth,
 [  --disable-negotiateauth Disable GSS-API negotiation ],
     MOZ_AUTH_EXTENSION=,
     MOZ_AUTH_EXTENSION=1 )
 
 dnl ========================================================
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -77,16 +77,23 @@
 #include "nsWrapperCacheInlines.h"
 #include "nsDOMJSUtils.h"
 
 #include "nsWidgetsCID.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Telemetry.h"
 
+#ifdef XP_WIN
+// Thanks so much, Microsoft! :(
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
+#endif // XP_WIN
+
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo*
 GetObjectLog()
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -664,25 +664,24 @@ MOCHITEST_FILES_C= \
 		file_CSP_bug802872.html^headers^ \
 		file_CSP_bug802872.js \
 		file_CSP_bug802872.sjs \
 		test_bug907892.html \
 		file_bug907892.html \
 		$(NULL)
 
 # OOP tests don't work on Windows (bug 763081) or native-fennec
-# (see Bug 774939)
-ifneq ($(OS_ARCH),WINNT)
-ifndef MOZ_ANDROID_OMTC
+# (see Bug 774939). App permission checks are also disabled on
+# anything but B2G (Bug 900707).
+ifdef MOZ_CHILD_PERMISSIONS
 MOCHITEST_FILES_B += \
 		test_messagemanager_assertpermission.html \
 		test_child_process_shutdown_message.html \
 		$(NULL)
 endif
-endif
 
 MOCHITEST_CHROME_FILES =	\
 		test_bug357450.js \
 		test_copypaste.xul \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 gtk3 windows,$(MOZ_WIDGET_TOOLKIT)))
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -966,26 +966,26 @@ bool WebGLContext::IsExtensionSupported(
 bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
 {
     if (mDisableExtensions) {
         return false;
     }
 
     switch (ext) {
         case OES_element_index_uint:
-            return gl->IsExtensionSupported(GLContext::XXX_element_index_uint);
+            return gl->IsSupported(GLFeature::element_index_uint);
         case OES_standard_derivatives:
-            return gl->IsExtensionSupported(GLContext::XXX_standard_derivatives);
+            return gl->IsSupported(GLFeature::standard_derivatives);
         case WEBGL_lose_context:
             // We always support this extension.
             return true;
         case OES_texture_float:
-            return gl->IsExtensionSupported(GLContext::XXX_texture_float);
+            return gl->IsSupported(GLFeature::texture_float);
         case OES_texture_float_linear:
-            return gl->IsExtensionSupported(GLContext::XXX_texture_float_linear);
+            return gl->IsSupported(GLFeature::texture_float_linear);
         case OES_vertex_array_object:
             return WebGLExtensionVertexArray::IsSupported(this);
         case EXT_texture_filter_anisotropic:
             return gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
         case WEBGL_compressed_texture_s3tc:
             if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
                 return true;
             }
@@ -996,18 +996,18 @@ bool WebGLContext::IsExtensionSupported(
                 return true;
             }
             return false;
         case WEBGL_compressed_texture_atc:
             return gl->IsExtensionSupported(GLContext::AMD_compressed_ATC_texture);
         case WEBGL_compressed_texture_pvrtc:
             return gl->IsExtensionSupported(GLContext::IMG_texture_compression_pvrtc);
         case WEBGL_depth_texture:
-            return gl->IsExtensionSupported(GLContext::XXX_packed_depth_stencil) &&
-                   gl->IsExtensionSupported(GLContext::XXX_depth_texture);
+            return gl->IsSupported(GLFeature::packed_depth_stencil) &&
+                   gl->IsSupported(GLFeature::depth_texture);
         case ANGLE_instanced_arrays:
             return WebGLExtensionInstancedArrays::IsSupported(this);
         default:
             // For warnings-as-errors.
             break;
     }
 
     if (Preferences::GetBool("webgl.enable-draft-extensions", false) || IsWebGL2()) {
--- a/content/canvas/src/WebGLContextAsyncQueries.cpp
+++ b/content/canvas/src/WebGLContextAsyncQueries.cpp
@@ -39,19 +39,19 @@ GetQueryTargetEnumString(WebGLenum targe
 
 static inline GLenum
 SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target)
 {
     MOZ_ASSERT(target == LOCAL_GL_ANY_SAMPLES_PASSED ||
                target == LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
                "unknown occlusion query target");
 
-    if (gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query_boolean)) {
+    if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean)) {
         return target;
-    } else if (gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query2)) {
+    } else if (gl->IsSupported(gl::GLFeature::occlusion_query2)) {
         return LOCAL_GL_ANY_SAMPLES_PASSED;
     }
 
     return LOCAL_GL_SAMPLES_PASSED;
 }
 
 already_AddRefed<WebGLQuery>
 WebGLContext::CreateQuery()
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -863,17 +863,17 @@ WebGLContext::InitAndValidateGL()
     mGLMaxTextureSize = floorPOT(mGLMaxTextureSize);
     mGLMaxRenderbufferSize = floorPOT(mGLMaxRenderbufferSize);
 
     if (MinCapabilityMode()) {
         mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
         mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
         mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
     } else {
-        if (gl->IsExtensionSupported(gl::GLContext::XXX_ES2_compatibility)) {
+        if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) {
             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
             gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
         } else {
             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
             mGLMaxFragmentUniformVectors /= 4;
             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
             mGLMaxVertexUniformVectors /= 4;
@@ -966,18 +966,18 @@ WebGLContext::InitAndValidateGL()
     }
 
     if (IsWebGL2() &&
         (!IsExtensionSupported(OES_vertex_array_object) ||
          !IsExtensionSupported(WEBGL_draw_buffers) ||
          !IsExtensionSupported(ANGLE_instanced_arrays) ||
          !gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4) ||
          !gl->IsExtensionSupported(gl::GLContext::EXT_blend_minmax) ||
-         (!gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query) &&
-          !gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query_boolean))
+         (!gl->IsSupported(gl::GLFeature::occlusion_query) &&
+          !gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
         ))
     {
         // Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
         return false;
     }
 
     mMemoryPressureObserver
         = new WebGLMemoryPressureObserver(this);
--- a/content/canvas/src/WebGLExtensionDrawBuffers.cpp
+++ b/content/canvas/src/WebGLExtensionDrawBuffers.cpp
@@ -50,17 +50,17 @@ void WebGLExtensionDrawBuffers::DrawBuff
 {
     mContext->DrawBuffers(buffers);
 }
 
 bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* context)
 {
     gl::GLContext * gl = context->GL();
 
-    if (!gl->IsExtensionSupported(GLContext::XXX_draw_buffers)) {
+    if (!gl->IsSupported(GLFeature::draw_buffers)) {
         return false;
     }
 
     GLint supportedColorAttachments = 0;
     GLint supportedDrawBuffers = 0;
 
     context->MakeContextCurrent();
 
--- a/content/canvas/src/WebGLExtensionInstancedArrays.cpp
+++ b/content/canvas/src/WebGLExtensionInstancedArrays.cpp
@@ -41,13 +41,13 @@ WebGLExtensionInstancedArrays::VertexAtt
     mContext->VertexAttribDivisor(index, divisor);
 }
 
 bool
 WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* context)
 {
     gl::GLContext* gl = context->GL();
 
-    return gl->IsExtensionSupported(gl::GLContext::XXX_draw_instanced) &&
-           gl->IsExtensionSupported(gl::GLContext::XXX_instanced_arrays);
+    return gl->IsSupported(gl::GLFeature::draw_instanced) &&
+           gl->IsSupported(gl::GLFeature::instanced_arrays);
 }
 
 IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionInstancedArrays)
--- a/content/canvas/src/WebGLExtensionVertexArray.cpp
+++ b/content/canvas/src/WebGLExtensionVertexArray.cpp
@@ -41,12 +41,12 @@ void WebGLExtensionVertexArray::BindVert
 {
     mContext->BindVertexArray(array);
 }
 
 bool WebGLExtensionVertexArray::IsSupported(const WebGLContext* context)
 {
     gl::GLContext* gl = context->GL();
 
-    return gl->IsExtensionSupported(gl::GLContext::XXX_vertex_array_object);
+    return gl->IsSupported(gl::GLFeature::vertex_array_object);
 }
 
 IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray)
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -71,16 +71,17 @@
 
 #include "AudioChannelService.h"
 
 #include "nsCSSParser.h"
 #include "nsIMediaList.h"
 
 #include "ImageContainer.h"
 #include "nsIPowerManagerService.h"
+#include "nsRange.h"
 #include <algorithm>
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gMediaElementLog;
 static PRLogModuleInfo* gMediaElementEventsLog;
 #define LOG(type, msg) PR_LOG(gMediaElementLog, type, msg)
 #define LOG_EVENT(type, msg) PR_LOG(gMediaElementEventsLog, type, msg)
 #else
--- a/dom/fm/DOMFMRadioParent.jsm
+++ b/dom/fm/DOMFMRadioParent.jsm
@@ -331,17 +331,17 @@ this.DOMFMRadioParent = {
       this._sendMessage("DOMFMRadio:enable:Return", false, null, msg);
       return;
     }
 
     this._enabling = true;
     let self = this;
 
     FMRadio.addEventListener("enabled", function on_enabled() {
-      debug("FM Radio is enabled!");
+      dump("Perf:FMRadio:Enable " + (Date.now()- timeStart) + " ms.\n");
       self._enabling = false;
 
       FMRadio.removeEventListener("enabled", on_enabled);
 
       // To make sure the FM app will get right frequency after the FM
       // radio is enabled, we have to set the frequency first.
       FMRadio.setFrequency(frequencyInKHz);
 
@@ -353,16 +353,18 @@ this.DOMFMRadioParent = {
       self._updatePowerState();
       self._sendMessage("DOMFMRadio:enable:Return", true, null, msg);
 
       // The frequency is changed from 'null' to some number, so we should
       // send the 'frequencyChange' message manually.
       ppmm.broadcastAsyncMessage("DOMFMRadio:frequencyChange", { });
     });
 
+    let timeStart = Date.now();
+
     FMRadio.enable({
       lowerLimit: FM_BANDS[self._currentBand].lower,
       upperLimit: FM_BANDS[self._currentBand].upper,
       channelWidth:  self._currentWidth   // 100KHz by default
     });
   },
 
   _disableFMRadio: function(msg) {
--- a/dom/ipc/AppProcessChecker.cpp
+++ b/dom/ipc/AppProcessChecker.cpp
@@ -13,16 +13,18 @@
 #include "TabParent.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::services;
 
 namespace mozilla {
 
+#ifdef MOZ_CHILD_PERMISSIONS
+
 bool
 AssertAppProcess(PBrowserParent* aActor,
                  AssertAppProcessType aType,
                  const char* aCapability)
 {
   if (!aActor) {
     NS_WARNING("Testing process capability for null actor");
     return false;
@@ -118,9 +120,52 @@ AssertAppStatus(PContentParent* aActor,
 bool
 AssertAppProcess(PHalParent* aActor,
                  AssertAppProcessType aType,
                  const char* aCapability)
 {
   return AssertAppProcess(aActor->Manager(), aType, aCapability);
 }
 
+#else
+
+bool
+AssertAppProcess(mozilla::dom::PBrowserParent* aActor,
+                 AssertAppProcessType aType,
+                 const char* aCapability)
+{
+  return true;
+}
+
+bool
+AssertAppStatus(mozilla::dom::PBrowserParent* aActor,
+                unsigned short aStatus)
+{
+  return true;
+}
+
+
+bool
+AssertAppProcess(mozilla::dom::PContentParent* aActor,
+                 AssertAppProcessType aType,
+                 const char* aCapability)
+{
+  return true;
+}
+
+bool
+AssertAppStatus(mozilla::dom::PContentParent* aActor,
+                unsigned short aStatus)
+{
+  return true;
+}
+
+bool
+AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
+                 AssertAppProcessType aType,
+                 const char* aCapability)
+{
+  return true;
+}
+
+#endif
+
 } // namespace mozilla
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -9,67 +9,161 @@
 
 #include "base/basictypes.h"
 
 #include "Blob.h"
 
 #include "nsIDOMFile.h"
 #include "nsIInputStream.h"
 #include "nsIIPCSerializableInputStream.h"
+#include "nsIMultiplexInputStream.h"
 #include "nsIRemoteBlob.h"
 #include "nsISeekableStream.h"
 
 #include "mozilla/Monitor.h"
 #include "mozilla/unused.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "nsDOMFile.h"
+#include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 
 #include "ContentChild.h"
 #include "ContentParent.h"
 
 #define PRIVATE_REMOTE_INPUT_STREAM_IID \
   {0x30c7699f, 0x51d2, 0x48c8, {0xad, 0x56, 0xc0, 0x16, 0xd7, 0x6f, 0x71, 0x27}}
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::ipc;
 
 namespace {
 
+/**
+ * Ensure that a nsCOMPtr/nsRefPtr is released on the main thread.
+ */
+template <template <class> class SmartPtr, class T>
+void
+ProxyReleaseToMainThread(SmartPtr<T>& aDoomed)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+  NS_ENSURE_TRUE_VOID(mainThread);
+
+  if (NS_FAILED(NS_ProxyRelease(mainThread, aDoomed, true))) {
+    NS_WARNING("Failed to proxy release to main thread!");
+  }
+}
+
+
 class NS_NO_VTABLE IPrivateRemoteInputStream : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(PRIVATE_REMOTE_INPUT_STREAM_IID)
 
   // This will return the underlying stream.
   virtual nsIInputStream*
   BlockAndGetInternalStream() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IPrivateRemoteInputStream,
                               PRIVATE_REMOTE_INPUT_STREAM_IID)
 
+// This class exists to keep a blob alive at least as long as its internal
+// stream.
+class BlobInputStreamTether : public nsIMultiplexInputStream,
+                              public nsISeekableStream,
+                              public nsIIPCSerializableInputStream
+{
+  nsCOMPtr<nsIInputStream> mStream;
+  nsCOMPtr<nsIDOMBlob> mSourceBlob;
+
+  nsIMultiplexInputStream* mWeakMultiplexStream;
+  nsISeekableStream* mWeakSeekableStream;
+  nsIIPCSerializableInputStream* mWeakSerializableStream;
+
+public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_FORWARD_NSIINPUTSTREAM(mStream->)
+  NS_FORWARD_SAFE_NSIMULTIPLEXINPUTSTREAM(mWeakMultiplexStream)
+  NS_FORWARD_SAFE_NSISEEKABLESTREAM(mWeakSeekableStream)
+  NS_FORWARD_SAFE_NSIIPCSERIALIZABLEINPUTSTREAM(mWeakSerializableStream)
+
+  BlobInputStreamTether(nsIInputStream* aStream, nsIDOMBlob* aSourceBlob)
+  : mStream(aStream), mSourceBlob(aSourceBlob), mWeakMultiplexStream(nullptr),
+    mWeakSeekableStream(nullptr), mWeakSerializableStream(nullptr)
+  {
+    MOZ_ASSERT(aStream);
+    MOZ_ASSERT(aSourceBlob);
+
+    nsCOMPtr<nsIMultiplexInputStream> multiplexStream =
+      do_QueryInterface(aStream);
+    if (multiplexStream) {
+      MOZ_ASSERT(SameCOMIdentity(aStream, multiplexStream));
+      mWeakMultiplexStream = multiplexStream;
+    }
+
+    nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(aStream);
+    if (seekableStream) {
+      MOZ_ASSERT(SameCOMIdentity(aStream, seekableStream));
+      mWeakSeekableStream = seekableStream;
+    }
+
+    nsCOMPtr<nsIIPCSerializableInputStream> serializableStream =
+      do_QueryInterface(aStream);
+    if (serializableStream) {
+      MOZ_ASSERT(SameCOMIdentity(aStream, serializableStream));
+      mWeakSerializableStream = serializableStream;
+    }
+  }
+
+protected:
+  virtual ~BlobInputStreamTether()
+  {
+    MOZ_ASSERT(mStream);
+    MOZ_ASSERT(mSourceBlob);
+
+    if (!NS_IsMainThread()) {
+      mStream = nullptr;
+      ProxyReleaseToMainThread(mSourceBlob);
+    }
+  }
+};
+
+NS_IMPL_ADDREF(BlobInputStreamTether)
+NS_IMPL_RELEASE(BlobInputStreamTether)
+
+NS_INTERFACE_MAP_BEGIN(BlobInputStreamTether)
+  NS_INTERFACE_MAP_ENTRY(nsIInputStream)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMultiplexInputStream,
+                                     mWeakMultiplexStream)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, mWeakSeekableStream)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
+                                     mWeakSerializableStream)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
+NS_INTERFACE_MAP_END
+
 class RemoteInputStream : public nsIInputStream,
                           public nsISeekableStream,
                           public nsIIPCSerializableInputStream,
                           public IPrivateRemoteInputStream
 {
   mozilla::Monitor mMonitor;
+  nsCOMPtr<nsIInputStream> mStream;
   nsCOMPtr<nsIDOMBlob> mSourceBlob;
-  nsCOMPtr<nsIInputStream> mStream;
-  nsCOMPtr<nsISeekableStream> mSeekableStream;
+  nsISeekableStream* mWeakSeekableStream;
   ActorFlavorEnum mOrigin;
 
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   RemoteInputStream(nsIDOMBlob* aSourceBlob, ActorFlavorEnum aOrigin)
   : mMonitor("RemoteInputStream.mMonitor"), mSourceBlob(aSourceBlob),
-    mOrigin(aOrigin)
+    mWeakSeekableStream(nullptr), mOrigin(aOrigin)
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aSourceBlob);
   }
 
   void
   Serialize(InputStreamParams& aParams)
   {
@@ -97,24 +191,26 @@ public:
   SetStream(nsIInputStream* aStream)
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aStream);
 
     nsCOMPtr<nsIInputStream> stream = aStream;
     nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(aStream);
 
+    MOZ_ASSERT_IF(seekableStream, SameCOMIdentity(aStream, seekableStream));
+
     {
       mozilla::MonitorAutoLock lock(mMonitor);
 
       MOZ_ASSERT(!mStream);
-      MOZ_ASSERT(!mSeekableStream);
+      MOZ_ASSERT(!mWeakSeekableStream);
 
       mStream.swap(stream);
-      mSeekableStream.swap(seekableStream);
+      mWeakSeekableStream = seekableStream;
 
       mMonitor.Notify();
     }
   }
 
   NS_IMETHOD
   Close() MOZ_OVERRIDE
   {
@@ -182,22 +278,22 @@ public:
   }
 
   NS_IMETHOD
   Seek(int32_t aWhence, int64_t aOffset) MOZ_OVERRIDE
   {
     nsresult rv = BlockAndWaitForStream();
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!mSeekableStream) {
+    if (!mWeakSeekableStream) {
       NS_WARNING("Underlying blob stream is not seekable!");
       return NS_ERROR_NO_INTERFACE;
     }
 
-    rv = mSeekableStream->Seek(aWhence, aOffset);
+    rv = mWeakSeekableStream->Seek(aWhence, aOffset);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   NS_IMETHOD
   Tell(int64_t* aResult)
   {
@@ -207,39 +303,39 @@ public:
     if (NS_IsMainThread() && !mStream) {
       *aResult = 0;
       return NS_OK;
     }
 
     nsresult rv = BlockAndWaitForStream();
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!mSeekableStream) {
+    if (!mWeakSeekableStream) {
       NS_WARNING("Underlying blob stream is not seekable!");
       return NS_ERROR_NO_INTERFACE;
     }
 
-    rv = mSeekableStream->Tell(aResult);
+    rv = mWeakSeekableStream->Tell(aResult);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   NS_IMETHOD
   SetEOF()
   {
     nsresult rv = BlockAndWaitForStream();
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!mSeekableStream) {
+    if (!mWeakSeekableStream) {
       NS_WARNING("Underlying blob stream is not seekable!");
       return NS_ERROR_NO_INTERFACE;
     }
 
-    rv = mSeekableStream->SetEOF();
+    rv = mWeakSeekableStream->SetEOF();
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   virtual nsIInputStream*
   BlockAndGetInternalStream()
   {
@@ -248,17 +344,23 @@ public:
     nsresult rv = BlockAndWaitForStream();
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     return mStream;
   }
 
 private:
   virtual ~RemoteInputStream()
-  { }
+  {
+    if (!NS_IsMainThread()) {
+      mStream = nullptr;
+      mWeakSeekableStream = nullptr;
+      ProxyReleaseToMainThread(mSourceBlob);
+    }
+  }
 
   void
   ReallyBlockAndWaitForStream()
   {
     mozilla::DebugOnly<bool> waited;
 
     {
       mozilla::MonitorAutoLock lock(mMonitor);
@@ -268,19 +370,19 @@ private:
       while (!mStream) {
         mMonitor.Wait();
       }
     }
 
     MOZ_ASSERT(mStream);
 
 #ifdef DEBUG
-    if (waited && mSeekableStream) {
+    if (waited && mWeakSeekableStream) {
       int64_t position;
-      MOZ_ASSERT(NS_SUCCEEDED(mSeekableStream->Tell(&position)),
+      MOZ_ASSERT(NS_SUCCEEDED(mWeakSeekableStream->Tell(&position)),
                  "Failed to determine initial stream position!");
       MOZ_ASSERT(!position, "Stream not starting at 0!");
     }
 #endif
   }
 
   nsresult
   BlockAndWaitForStream()
@@ -303,17 +405,17 @@ private:
         NS_WARNING("Don't know if this stream is seekable yet!");
         return true;
       }
     }
     else {
       ReallyBlockAndWaitForStream();
     }
 
-    return !!mSeekableStream;
+    return !!mWeakSeekableStream;
   }
 };
 
 NS_IMPL_ADDREF(RemoteInputStream)
 NS_IMPL_RELEASE(RemoteInputStream)
 
 NS_INTERFACE_MAP_BEGIN(RemoteInputStream)
   NS_INTERFACE_MAP_ENTRY(nsIInputStream)
@@ -650,16 +752,34 @@ public:
   typedef RemoteBlob<ActorFlavor> SelfType;
   typedef Blob<ActorFlavor> ActorType;
   typedef InputStreamActor<ActorFlavor> StreamActorType;
   typedef typename ActorType::ConstructorParamsType ConstructorParamsType;
 
 private:
   ActorType* mActor;
 
+  virtual ~RemoteBlob()
+  {
+    if (mActor) {
+      mActor->NoteDyingRemoteBlob();
+    }
+  }
+
+  nsresult
+  GetInternalStreamViaHelper(nsIInputStream** aStream)
+  {
+    if (!mActor) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
+    return helper->GetStream(aStream);
+  }
+
   class StreamHelper : public nsRunnable
   {
     typedef Blob<ActorFlavor> ActorType;
     typedef InputStreamActor<ActorFlavor> StreamActorType;
 
     mozilla::Monitor mMonitor;
     ActorType* mActor;
     nsCOMPtr<nsIDOMBlob> mSourceBlob;
@@ -888,23 +1008,16 @@ public:
 
   RemoteBlob()
   : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
   , mActor(nullptr)
   {
     mImmutable = true;
   }
 
-  virtual ~RemoteBlob()
-  {
-    if (mActor) {
-      mActor->NoteDyingRemoteBlob();
-    }
-  }
-
   void
   SetActor(ActorType* aActor)
   {
     MOZ_ASSERT(!aActor || !mActor);
     mActor = aActor;
   }
 
   void
@@ -933,17 +1046,17 @@ public:
 
   virtual void*
   GetPBlob() MOZ_OVERRIDE
   {
     return static_cast<typename ActorType::ProtocolType*>(mActor);
   }
 
   NS_IMETHOD
-  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
+  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) MOZ_OVERRIDE
   {
     if (IsDateUnknown()) {
       aLastModifiedDate->setNull();
     } else {
       JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
       if (!date) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
@@ -975,44 +1088,37 @@ RemoteBlob<Child>::MaybeSetInputStream(c
   // Nothing needed on the child side!
 }
 
 template <>
 NS_IMETHODIMP
 RemoteBlob<Parent>::GetInternalStream(nsIInputStream** aStream)
 {
   if (mInputStreamParams.type() != InputStreamParams::T__None) {
-    nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(mInputStreamParams);
-    if (!stream) {
+    nsCOMPtr<nsIInputStream> realStream =
+      DeserializeInputStream(mInputStreamParams);
+    if (!realStream) {
       NS_WARNING("Failed to deserialize stream!");
       return NS_ERROR_UNEXPECTED;
     }
 
+    nsCOMPtr<nsIInputStream> stream =
+      new BlobInputStreamTether(realStream, this);
     stream.forget(aStream);
     return NS_OK;
   }
 
-  if (!mActor) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
-  return helper->GetStream(aStream);
+  return GetInternalStreamViaHelper(aStream);
 }
 
 template <>
 NS_IMETHODIMP
 RemoteBlob<Child>::GetInternalStream(nsIInputStream** aStream)
 {
-  if (!mActor) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
-  return helper->GetStream(aStream);
+  return GetInternalStreamViaHelper(aStream);
 }
 
 template <ActorFlavorEnum ActorFlavor>
 Blob<ActorFlavor>::Blob(ContentManager* aManager, nsIDOMBlob* aBlob)
 : mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true)
 , mBlobIsFile(false), mManager(aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -1221,33 +1327,33 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
       MOZ_ASSERT(false, "Should never fail!");
     }
 
     return;
   }
 
   // Must do this before calling Send__delete__ or we'll crash there trying to
   // access a dangling pointer.
+  mBlob = nullptr;
   mRemoteBlob = nullptr;
 
   mozilla::unused << ProtocolType::Send__delete__(this);
 }
 
 template <ActorFlavorEnum ActorFlavor>
 void
 Blob<ActorFlavor>::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mBlob);
 
   if (mRemoteBlob) {
     mRemoteBlob->SetActor(nullptr);
   }
 
-  if (mOwnsBlob) {
+  if (mBlob && mOwnsBlob) {
     mBlob->Release();
   }
 }
 
 template <ActorFlavorEnum ActorFlavor>
 bool
 Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
 {
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2526,17 +2526,17 @@ AddGeolocationListener(nsIDOMGeoPosition
   geo->WatchPosition(watcher, nullptr, options, &retval);
   return retval;
 }
 
 bool
 ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
                                           const bool& aHighAccuracy)
 {
-#ifdef MOZ_PERMISSIONS
+#ifdef MOZ_CHILD_PERMISSIONS
   if (Preferences::GetBool("geo.testing.ignore_ipc_principal", false) == false) {
     nsIPrincipal* principal = aPrincipal;
     if (principal == nullptr) {
       KillHard();
       return true;
     }
 
     uint32_t principalAppId;
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -45,9 +45,13 @@ DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"
 ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
 DEFINES += -DMOZ_ENABLE_FREETYPE
 endif
 
 ifdef MOZ_PERMISSIONS
 DEFINES += -DMOZ_PERMISSIONS
 endif
 
+ifdef MOZ_CHILD_PERMISSIONS
+DEFINES += -DMOZ_CHILD_PERMISSIONS
+endif
+
 CXXFLAGS += $(TK_CFLAGS)
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -294,17 +294,16 @@ TabChild::TabChild(ContentChild* aManage
   , mLastBackgroundColor(NS_RGB(255, 255, 255))
   , mDidFakeShow(false)
   , mNotified(false)
   , mContentDocumentIsDisplayed(false)
   , mTriedBrowserInit(false)
   , mOrientation(eScreenOrientation_PortraitPrimary)
   , mUpdateHitRegion(false)
 {
-    printf("creating %d!\n", NS_IsMainThread());
 }
 
 // Get the DOMWindowUtils for the window corresponding to the given document.
 static already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils(nsIDocument* doc)
 {
   nsCOMPtr<nsIDOMWindowUtils> utils;
   nsCOMPtr<nsIDOMWindow> window = doc->GetDefaultView();
   if (window) {
@@ -1278,17 +1277,16 @@ TabChild::IsRootContentDocument()
     // breaks our remote reftests.
 
     return !HasAppOwnerApp();
 }
 
 bool
 TabChild::RecvLoadURL(const nsCString& uri)
 {
-    printf("loading %s, %d\n", uri.get(), NS_IsMainThread());
     SetProcessNameToAppName();
 
     nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(),
                                    nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
                                    nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER,
                                    NULL, NULL, NULL);
     if (NS_FAILED(rv)) {
         NS_WARNING("mWebNav->LoadURI failed. Eating exception, what else can I do?");
@@ -1455,18 +1453,16 @@ TabChild::DoFakeShow()
 bool
 TabChild::RecvShow(const nsIntSize& size)
 {
 
     if (mDidFakeShow) {
         return true;
     }
 
-    printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
-
     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
     if (!baseWindow) {
         NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
         return false;
     }
 
     if (!InitRenderingState()) {
         // We can fail to initialize our widget if the <browser
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -1341,16 +1341,27 @@ Geolocation::ClearWatch(int32_t aWatchId
   for (uint32_t i = 0, length = mWatchingCallbacks.Length(); i < length; ++i) {
     if (mWatchingCallbacks[i]->WatchId() == aWatchId) {
       mWatchingCallbacks[i]->Shutdown();
       RemoveRequest(mWatchingCallbacks[i]);
       break;
     }
   }
 
+  // make sure we also search through the pending requests lists for
+  // watches to clear...
+  for (uint32_t i = 0, length = mPendingRequests.Length(); i < length; ++i) {
+    if ((mPendingRequests[i].type == PendingRequest::WatchPosition) &&
+        (mPendingRequests[i].request->WatchId() == aWatchId)) {
+      mPendingRequests[i].request->Shutdown();
+      mPendingRequests.RemoveElementAt(i);
+      break;
+    }
+  }
+
   return NS_OK;
 }
 
 void
 Geolocation::ServiceReady()
 {
   for (uint32_t length = mPendingRequests.Length(); length > 0; --length) {
     switch (mPendingRequests[0].type) {
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -60,16 +60,17 @@
 #include "nsIContent.h"
 #include "nsEventListenerManager.h"
 #include "nsGUIEvent.h"
 #include "nsRange.h"
 #include "nsContentUtils.h"
 #include "nsEditor.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
+#include "nsITextControlElement.h"
 
 using namespace mozilla::dom;
 
 // Set to spew messages to the console about what is happening.
 //#define DEBUG_INLINESPELL
 
 // the number of milliseconds that we will take at once to do spellchecking
 #define INLINESPELL_CHECK_TIMEOUT 50
@@ -1263,16 +1264,31 @@ mozInlineSpellChecker::SkipSpellCheckFor
     // Check spelling only if the node is editable, and GetSpellcheck() is true
     // on the nearest HTMLElement ancestor.
     nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
     if (!content->IsEditable()) {
       *checkSpelling = false;
       return NS_OK;
     }
 
+    // Make sure that we can always turn on spell checking for inputs/textareas.
+    // Note that because of the previous check, at this point we know that the
+    // node is editable.
+    if (content->IsInAnonymousSubtree()) {
+      nsCOMPtr<nsIContent> node = content->GetParent();
+      while (node && node->IsInNativeAnonymousSubtree()) {
+        node = node->GetParent();
+      }
+      nsCOMPtr<nsITextControlElement> textControl = do_QueryInterface(node);
+      if (textControl) {
+        *checkSpelling = true;
+        return NS_OK;
+      }
+    }
+
     // Get HTML element ancestor (might be aNode itself, although probably that
     // has to be a text node in real life here)
     nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(content);
     while (content && !htmlElement) {
       content = content->GetParent();
       htmlElement = do_QueryInterface(content);
     }
     NS_ASSERTION(htmlElement, "Why do we have no htmlElement?");
--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -31,17 +31,17 @@ namespace gfx {
  * To ensure that these interpretations are explicitly disambiguated, we
  * deny access to the == and != operators and require use of IsEqualEdges and
  * IsEqualInterior instead. Similarly we provide separate Union and UnionEdges
  * methods.
  *
  * Do not use this class directly. Subclass it, pass that subclass as the
  * Sub parameter, and only use that subclass.
  */
-template <class T, class Sub, class Point, class SizeT, class Margin>
+template <class T, class Sub, class Point, class SizeT, class MarginT>
 struct BaseRect {
   T x, y, width, height;
 
   // Constructors
   BaseRect() : x(0), y(0), width(0), height(0) {}
   BaseRect(const Point& aOrigin, const SizeT &aSize) :
       x(aOrigin.x), y(aOrigin.y), width(aSize.width), height(aSize.height)
   {
@@ -184,34 +184,34 @@ struct BaseRect {
   void Inflate(T aD) { Inflate(aD, aD); }
   void Inflate(T aDx, T aDy)
   {
     x -= aDx;
     y -= aDy;
     width += 2 * aDx;
     height += 2 * aDy;
   }
-  void Inflate(const Margin& aMargin)
+  void Inflate(const MarginT& aMargin)
   {
     x -= aMargin.left;
     y -= aMargin.top;
     width += aMargin.LeftRight();
     height += aMargin.TopBottom();
   }
   void Inflate(const SizeT& aSize) { Inflate(aSize.width, aSize.height); }
 
   void Deflate(T aD) { Deflate(aD, aD); }
   void Deflate(T aDx, T aDy)
   {
     x += aDx;
     y += aDy;
     width = std::max(T(0), width - 2 * aDx);
     height = std::max(T(0), height - 2 * aDy);
   }
-  void Deflate(const Margin& aMargin)
+  void Deflate(const MarginT& aMargin)
   {
     x += aMargin.left;
     y += aMargin.top;
     width = std::max(T(0), width - aMargin.LeftRight());
     height = std::max(T(0), height - aMargin.TopBottom());
   }
   void Deflate(const SizeT& aSize) { Deflate(aSize.width, aSize.height); }
 
@@ -246,22 +246,22 @@ struct BaseRect {
   }
   Sub& operator-=(const Point& aPoint)
   {
     MoveBy(-aPoint);
     return *static_cast<Sub*>(this);
   }
 
   // Find difference as a Margin
-  Margin operator-(const Sub& aRect) const
+  MarginT operator-(const Sub& aRect) const
   {
-    return Margin(aRect.y - y,
-                  XMost() - aRect.XMost(),
-                  YMost() - aRect.YMost(),
-                  aRect.x - x);
+    return MarginT(aRect.y - y,
+                   XMost() - aRect.XMost(),
+                   YMost() - aRect.YMost(),
+                   aRect.x - x);
   }
 
   // Helpers for accessing the vertices
   Point TopLeft() const { return Point(x, y); }
   Point TopRight() const { return Point(XMost(), y); }
   Point BottomLeft() const { return Point(x, YMost()); }
   Point BottomRight() const { return Point(XMost(), YMost()); }
   Point Center() const { return Point(x, y) + Point(width, height)/2; }
--- a/gfx/2d/Rect.h
+++ b/gfx/2d/Rect.h
@@ -12,35 +12,47 @@
 #include "Tools.h"
 
 #include <cmath>
 
 namespace mozilla {
 namespace gfx {
 
 template<class units>
+struct IntMarginTyped:
+    public BaseMargin<int32_t, IntMarginTyped<units> >,
+    public units {
+    typedef BaseMargin<int32_t, IntMarginTyped<units> > Super;
+
+    IntMarginTyped() : Super() {}
+    IntMarginTyped(int32_t aTop, int32_t aRight, int32_t aBottom, int32_t aLeft) :
+        Super(aTop, aRight, aBottom, aLeft) {}
+};
+typedef IntMarginTyped<UnknownUnits> IntMargin;
+
+template<class units>
 struct MarginTyped:
     public BaseMargin<Float, MarginTyped<units> >,
     public units {
     typedef BaseMargin<Float, MarginTyped<units> > Super;
 
-    MarginTyped() : Super(0, 0, 0, 0) {}
-    MarginTyped(const MarginTyped<units>& aMargin) :
+    MarginTyped() : Super() {}
+    MarginTyped(Float aTop, Float aRight, Float aBottom, Float aLeft) :
+        Super(aTop, aRight, aBottom, aLeft) {}
+    explicit MarginTyped(const IntMarginTyped<units>& aMargin) :
         Super(float(aMargin.top), float(aMargin.right),
               float(aMargin.bottom), float(aMargin.left)) {}
-    MarginTyped(Float aTop, Float aRight, Float aBottom, Float aLeft) :
-        Super(aTop, aRight, aBottom, aLeft) {}
 };
 typedef MarginTyped<UnknownUnits> Margin;
 
 template<class units>
 struct IntRectTyped :
-    public BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, Margin>,
+    public BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, IntMarginTyped<units> >,
     public units {
-    typedef BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, Margin> Super;
+    typedef BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, IntMarginTyped<units> > Super;
 
     IntRectTyped() : Super() {}
     IntRectTyped(IntPointTyped<units> aPos, IntSizeTyped<units> aSize) :
         Super(aPos, aSize) {}
     IntRectTyped(int32_t _x, int32_t _y, int32_t _width, int32_t _height) :
         Super(_x, _y, _width, _height) {}
 
     // Rounding isn't meaningful on an integer rectangle.
@@ -58,19 +70,19 @@ struct IntRectTyped :
     IntRectTyped<UnknownUnits> ToUnknownRect() const {
         return IntRectTyped<UnknownUnits>(this->x, this->y, this->width, this->height);
     }
 };
 typedef IntRectTyped<UnknownUnits> IntRect;
 
 template<class units>
 struct RectTyped :
-    public BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, Margin>,
+    public BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> >,
     public units {
-    typedef BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, Margin> Super;
+    typedef BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> > Super;
 
     RectTyped() : Super() {}
     RectTyped(PointTyped<units> aPos, SizeTyped<units> aSize) :
         Super(aPos, aSize) {}
     RectTyped(Float _x, Float _y, Float _width, Float _height) :
         Super(_x, _y, _width, _height) {}
     explicit RectTyped(const IntRectTyped<units>& rect) :
         Super(float(rect.x), float(rect.y),
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -466,56 +466,56 @@ GLContext::InitWithPrefix(const char *pr
                     mSymbols.fGetGraphicsResetStatus = nullptr;
                 } else {
                     mHasRobustness = true;
                 }
             }
         }
 
         // Check for aux symbols based on extensions
-        if (IsExtensionSupported(XXX_framebuffer_blit))
+        if (IsSupported(GLFeature::framebuffer_blit))
         {
             SymLoadStruct auxSymbols[] = {
                 {
                     (PRFuncPtr*) &mSymbols.fBlitFramebuffer,
                     {
                         "BlitFramebuffer",
                         "BlitFramebufferEXT",
                         "BlitFramebufferANGLE",
                         nullptr
                     }
                 },
                 { nullptr, { nullptr } },
             };
             if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports framebuffer_blit without supplying glBlitFramebuffer");
 
-                MarkExtensionGroupUnsupported(XXX_framebuffer_blit);
+                MarkUnsupported(GLFeature::framebuffer_blit);
                 mSymbols.fBlitFramebuffer = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_framebuffer_multisample))
+        if (IsSupported(GLFeature::framebuffer_multisample))
         {
             SymLoadStruct auxSymbols[] = {
                 {
                     (PRFuncPtr*) &mSymbols.fRenderbufferStorageMultisample,
                     {
                         "RenderbufferStorageMultisample",
                         "RenderbufferStorageMultisampleEXT",
                         "RenderbufferStorageMultisampleANGLE",
                         nullptr
                     }
                 },
                 { nullptr, { nullptr } },
             };
             if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports framebuffer_multisample without supplying glRenderbufferStorageMultisample");
 
-                MarkExtensionGroupUnsupported(XXX_framebuffer_multisample);
+                MarkUnsupported(GLFeature::framebuffer_multisample);
                 mSymbols.fRenderbufferStorageMultisample = nullptr;
             }
         }
 
         if (IsExtensionSupported(ARB_sync)) {
             SymLoadStruct syncSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fFenceSync,      { "FenceSync",      nullptr } },
                 { (PRFuncPtr*) &mSymbols.fIsSync,         { "IsSync",         nullptr } },
@@ -565,17 +565,17 @@ GLContext::InitWithPrefix(const char *pr
                 { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArray", "BindVertexArrayOES", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArrays", "DeleteVertexArraysOES", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
 
-                MarkExtensionGroupUnsupported(XXX_vertex_array_object);
+                MarkUnsupported(GLFeature::vertex_array_object);
                 mSymbols.fIsVertexArray = nullptr;
                 mSymbols.fGenVertexArrays = nullptr;
                 mSymbols.fBindVertexArray = nullptr;
                 mSymbols.fDeleteVertexArrays = nullptr;
             }
         }
         else if (IsExtensionSupported(APPLE_vertex_array_object)) {
             /*
@@ -588,25 +588,25 @@ GLContext::InitWithPrefix(const char *pr
                 { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArrayAPPLE", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArraysAPPLE", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
 
-                MarkExtensionGroupUnsupported(XXX_vertex_array_object);
+                MarkUnsupported(GLFeature::vertex_array_object);
                 mSymbols.fIsVertexArray = nullptr;
                 mSymbols.fGenVertexArrays = nullptr;
                 mSymbols.fBindVertexArray = nullptr;
                 mSymbols.fDeleteVertexArrays = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_draw_instanced)) {
+        if (IsSupported(GLFeature::draw_instanced)) {
             SymLoadStruct drawInstancedSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced,
                   { "DrawArraysInstanced",
                     "DrawArraysInstancedARB",
                     "DrawArraysInstancedEXT",
                     "DrawArraysInstancedNV",
                     "DrawArraysInstancedANGLE",
                     nullptr
@@ -622,44 +622,44 @@ GLContext::InitWithPrefix(const char *pr
                   }
                 },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(drawInstancedSymbols, trygl, prefix)) {
                 NS_ERROR("GL supports instanced draws without supplying its functions.");
 
-                MarkExtensionGroupUnsupported(XXX_draw_instanced);
+                MarkUnsupported(GLFeature::draw_instanced);
                 mSymbols.fDrawArraysInstanced = nullptr;
                 mSymbols.fDrawElementsInstanced = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_instanced_arrays)) {
+        if (IsSupported(GLFeature::instanced_arrays)) {
             SymLoadStruct instancedArraySymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor,
                   { "VertexAttribDivisor",
                     "VertexAttribDivisorARB",
                     "VertexAttribDivisorNV",
                     "VertexAttribDivisorANGLE",
                     nullptr
                   }
                 },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(instancedArraySymbols, trygl, prefix)) {
                 NS_ERROR("GL supports array instanced without supplying it function.");
 
-                mInitialized &= MarkExtensionGroupUnsupported(XXX_instanced_arrays);
+                mInitialized &= MarkUnsupported(GLFeature::instanced_arrays);
                 mSymbols.fVertexAttribDivisor = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_transform_feedback)) {
+        if (IsSupported(GLFeature::transform_feedback)) {
             SymLoadStruct transformFeedbackSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fBindBufferBase,
                   { "BindBufferBase",
                     "BindBufferBaseEXT",
                     "BindBufferBaseNV",
                     nullptr
                   }
                 },
@@ -706,88 +706,88 @@ GLContext::InitWithPrefix(const char *pr
                   }
                 },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(transformFeedbackSymbols, trygl, prefix)) {
                 NS_ERROR("GL supports transform feedback without supplying its functions.");
 
-                MarkExtensionGroupUnsupported(XXX_transform_feedback);
-                MarkExtensionGroupUnsupported(XXX_bind_buffer_offset);
+                MarkUnsupported(GLFeature::transform_feedback);
+                MarkUnsupported(GLFeature::bind_buffer_offset);
                 mSymbols.fBindBufferBase = nullptr;
                 mSymbols.fBindBufferRange = nullptr;
                 mSymbols.fBeginTransformFeedback = nullptr;
                 mSymbols.fEndTransformFeedback = nullptr;
                 mSymbols.fTransformFeedbackVaryings = nullptr;
                 mSymbols.fGetTransformFeedbackVarying = nullptr;
                 mSymbols.fGetIntegeri_v = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_bind_buffer_offset)) {
+        if (IsSupported(GLFeature::bind_buffer_offset)) {
             SymLoadStruct bindBufferOffsetSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fBindBufferOffset,
                   { "BindBufferOffset",
                     "BindBufferOffsetEXT",
                     "BindBufferOffsetNV",
                     nullptr
                   }
                 },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(bindBufferOffsetSymbols, trygl, prefix)) {
                 NS_ERROR("GL supports BindBufferOffset without supplying its function.");
 
-                MarkExtensionGroupUnsupported(XXX_bind_buffer_offset);
+                MarkUnsupported(GLFeature::bind_buffer_offset);
                 mSymbols.fBindBufferOffset = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_query_objects)) {
+        if (IsSupported(GLFeature::query_objects)) {
             SymLoadStruct queryObjectsSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", "BeginQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", "GenQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", "DeleteQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", "EndQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", "GetQueryivEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", "GetQueryObjectuivEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", "IsQueryEXT", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(queryObjectsSymbols, trygl, prefix)) {
                 NS_ERROR("GL supports query objects without supplying its functions.");
 
-                mInitialized &= MarkExtensionGroupUnsupported(XXX_query_objects);
-                mInitialized &= MarkExtensionGroupUnsupported(XXX_get_query_object_iv);
-                mInitialized &= MarkExtensionGroupUnsupported(XXX_occlusion_query);
-                MarkExtensionGroupUnsupported(XXX_occlusion_query_boolean);
-                MarkExtensionGroupUnsupported(XXX_occlusion_query2);
+                mInitialized &= MarkUnsupported(GLFeature::query_objects);
+                mInitialized &= MarkUnsupported(GLFeature::get_query_object_iv);
+                mInitialized &= MarkUnsupported(GLFeature::occlusion_query);
+                MarkUnsupported(GLFeature::occlusion_query_boolean);
+                MarkUnsupported(GLFeature::occlusion_query2);
                 mSymbols.fBeginQuery = nullptr;
                 mSymbols.fGenQueries = nullptr;
                 mSymbols.fDeleteQueries = nullptr;
                 mSymbols.fEndQuery = nullptr;
                 mSymbols.fGetQueryiv = nullptr;
                 mSymbols.fGetQueryObjectuiv = nullptr;
                 mSymbols.fIsQuery = nullptr;
             }
         }
 
-        if (IsExtensionSupported(XXX_get_query_object_iv)) {
+        if (IsSupported(GLFeature::get_query_object_iv)) {
             SymLoadStruct queryObjectsSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", "GetQueryObjectivEXT", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(queryObjectsSymbols, trygl, prefix)) {
                 NS_ERROR("GL supports query objects iv getter without supplying its function.");
 
-                mInitialized &= MarkExtensionGroupUnsupported(XXX_get_query_object_iv);
+                mInitialized &= MarkUnsupported(GLFeature::get_query_object_iv);
                 mSymbols.fGetQueryObjectiv = nullptr;
             }
         }
 
 
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
@@ -848,17 +848,17 @@ GLContext::InitWithPrefix(const char *pr
             mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 2048);
             mNeedsTextureSizeChecks = true;
         }
 #endif
 
         mMaxTextureImageSize = mMaxTextureSize;
 
         mMaxSamples = 0;
-        if (IsExtensionSupported(XXX_framebuffer_multisample)) {
+        if (IsSupported(GLFeature::framebuffer_multisample)) {
             fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
         }
 
         // We're ready for final setup.
         fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
         if (mCaps.any)
             DetermineCaps();
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -77,16 +77,51 @@ namespace mozilla {
     namespace layers {
         class ColorTextureLayerProgram;
         class LayerManagerOGL;
     }
 }
 
 namespace mozilla {
 namespace gl {
+
+/** GLFeature::Enum
+ * We don't use typed enum to keep the implicit integer conversion.
+ * This enum should be sorted by name.
+ */
+namespace GLFeature {
+    enum Enum {
+        bind_buffer_offset,
+        depth_texture,
+        draw_buffers,
+        draw_instanced,
+        element_index_uint,
+        ES2_compatibility,
+        ES3_compatibility,
+        framebuffer_blit,
+        framebuffer_multisample,
+        framebuffer_object,
+        get_query_object_iv,
+        instanced_arrays,
+        occlusion_query,
+        occlusion_query_boolean,
+        occlusion_query2,
+        packed_depth_stencil,
+        query_objects,
+        robustness,
+        standard_derivatives,
+        texture_float,
+        texture_float_linear,
+        texture_non_power_of_two,
+        transform_feedback,
+        vertex_array_object,
+        EnumMax
+    };
+}
+
 typedef uintptr_t SharedTextureHandle;
 
 MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
     Unknown = 0,
     OpenGL, // only for IsAtLeast's <profile> parameter
     OpenGLCore,
     OpenGLCompatibility,
     OpenGLES
@@ -458,69 +493,37 @@ public:
     };
 
 
 protected:
     ExtensionBitset<Extensions_Max> mAvailableExtensions;
 
 
 // -----------------------------------------------------------------------------
-// XXX_* Extension group queries
+// Feature queries
 /*
- * This mecahnism introduces a new way to check if an extension is supported,
- * regardless if it is an ARB, EXT, OES, etc.
+ * This mecahnism introduces a new way to check if a OpenGL feature is
+ * supported, regardless of whether it is supported by an extension or natively
+ * by the context version/profile
  */
 public:
-
-    /**
-     * This enum should be sorted by name.
-     */
-    enum GLExtensionGroup {
-        XXX_bind_buffer_offset,
-        XXX_depth_texture,
-        XXX_draw_buffers,
-        XXX_draw_instanced,
-        XXX_element_index_uint,
-        XXX_ES2_compatibility,
-        XXX_ES3_compatibility,
-        XXX_framebuffer_blit,
-        XXX_framebuffer_multisample,
-        XXX_framebuffer_object,
-        XXX_get_query_object_iv,
-        XXX_instanced_arrays,
-        XXX_occlusion_query,
-        XXX_occlusion_query_boolean,
-        XXX_occlusion_query2,
-        XXX_packed_depth_stencil,
-        XXX_query_objects,
-        XXX_robustness,
-        XXX_standard_derivatives,
-        XXX_texture_float,
-        XXX_texture_float_linear,
-        XXX_texture_non_power_of_two,
-        XXX_transform_feedback,
-        XXX_vertex_array_object,
-        ExtensionGroup_Max
-    };
-
-    bool IsExtensionSupported(GLExtensionGroup extensionGroup) const;
-
-    static const char* GetExtensionGroupName(GLExtensionGroup extensionGroup);
+    bool IsSupported(GLFeature::Enum feature) const;
+
+    static const char* GetFeatureName(GLFeature::Enum feature);
 
 
 private:
 
     /**
-     * Mark all extensions of this group as unsupported.
+     * Mark all extensions of this feature as unsupported.
      *
      * Returns false if marking this extension group as unsupported contradicts
      * the OpenGL version and profile. Returns true otherwise.
      */
-    bool MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup);
-
+    bool MarkUnsupported(GLFeature::Enum feature);
 
 // -----------------------------------------------------------------------------
 // Robustness handling
 public:
 
     bool HasRobustness() {
         return mHasRobustness;
     }
@@ -2682,17 +2685,17 @@ public:
         GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
         return ret;
     }
 
     GLuint GetReadFB() {
         if (mScreen)
             return mScreen->GetReadFB();
 
-        GLenum bindEnum = IsExtensionSupported(XXX_framebuffer_blit)
+        GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit)
                             ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
                             : LOCAL_GL_FRAMEBUFFER_BINDING;
 
         GLuint ret = 0;
         GetUIntegerv(bindEnum, &ret);
         return ret;
     }
 
rename from gfx/gl/GLContextExtensionGroupQueries.cpp
rename to gfx/gl/GLContextFeatures.cpp
--- a/gfx/gl/GLContextExtensionGroupQueries.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -13,378 +13,382 @@ namespace gl {
 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
 
 // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
 static const unsigned int kGLCoreVersionForES2Compat = 410;
 
 // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
 static const unsigned int kGLCoreVersionForES3Compat = 430;
 
-struct ExtensionGroupInfo
+struct FeatureInfo
 {
     const char* mName;
     unsigned int mOpenGLVersion;
     unsigned int mOpenGLESVersion;
     GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
 };
 
-static const ExtensionGroupInfo sExtensionGroupInfoArr[] = {
+static const FeatureInfo sFeatureInfoArr[] = {
     {
-        "XXX_bind_buffer_offset",
+        "bind_buffer_offset",
         0,   // OpenGL version
         0,   // OpenGL ES version
         {
             GLContext::EXT_transform_feedback,
             GLContext::NV_transform_feedback,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_depth_texture",
+        "depth_texture",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_depth_texture,
             GLContext::OES_depth_texture,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_draw_buffers",
+        "draw_buffers",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_draw_buffers,
             GLContext::EXT_draw_buffers,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_draw_instanced",
+        "draw_instanced",
         310, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_draw_instanced,
             GLContext::EXT_draw_instanced,
             GLContext::NV_draw_instanced,
             GLContext::ANGLE_instanced_arrays,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_element_index_uint",
+        "element_index_uint",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::OES_element_index_uint,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_ES2_compatibility",
+        "ES2_compatibility",
         kGLCoreVersionForES2Compat,
         200, // OpenGL ES version
         {
             GLContext::ARB_ES2_compatibility,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_ES3_compatibility",
+        "ES3_compatibility",
         kGLCoreVersionForES3Compat,
         300, // OpenGL ES version
         {
             GLContext::ARB_ES3_compatibility,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_framebuffer_blit",
+        "framebuffer_blit",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_framebuffer_blit,
             GLContext::ANGLE_framebuffer_blit,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_framebuffer_multisample",
+        "framebuffer_multisample",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_framebuffer_multisample,
             GLContext::ANGLE_framebuffer_multisample,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_framebuffer_object",
+        "framebuffer_object",
         300, // OpenGL version
         200, // OpenGL ES version
         {
             GLContext::ARB_framebuffer_object,
             GLContext::EXT_framebuffer_object,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_get_query_object_iv",
+        "get_query_object_iv",
         200, // OpenGL version
         0,   // OpenGL ES version
         {
             GLContext::Extensions_End
         }
         /*
          * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
          * ARB_occlusion_query (added by OpenGL 2.0).
          */
     },
     {
-        "XXX_instanced_arrays",
+        "instanced_arrays",
         330, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_instanced_arrays,
             GLContext::NV_instanced_arrays,
             GLContext::ANGLE_instanced_arrays,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_occlusion_query",
+        "occlusion_query",
         200, // OpenGL version
         0,   // OpenGL ES version
         {
             GLContext::Extensions_End
         }
         // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
     },
     {
-        "XXX_occlusion_query_boolean",
+        "occlusion_query_boolean",
         kGLCoreVersionForES3Compat,
         300, // OpenGL ES version
         {
             GLContext::ARB_ES3_compatibility,
             GLContext::EXT_occlusion_query_boolean,
             GLContext::Extensions_End
         }
         /*
          * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
          * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
          * it is supported on desktop if ARB_ES3_compatibility because 
          * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
          */
     },
     {
-        "XXX_occlusion_query2",
+        "occlusion_query2",
         330, // = min(330, kGLCoreVersionForES3Compat),
         300, // OpenGL ES version
         {
             GLContext::ARB_occlusion_query2,
             GLContext::ARB_ES3_compatibility,
             GLContext::EXT_occlusion_query_boolean,
             GLContext::Extensions_End
         }
         /*
          * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
          * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
          * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
          */
     },
     {
-        "XXX_packed_depth_stencil",
+        "packed_depth_stencil",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_packed_depth_stencil,
             GLContext::OES_packed_depth_stencil,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_query_objects",
+        "query_objects",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_occlusion_query_boolean,
             GLContext::Extensions_End
         }
         /*
          * XXX_query_objects only provide entry points commonly supported by
          * ARB_occlusion_query (added in OpenGL 2.0) and EXT_occlusion_query_boolean
          * (added in OpenGL ES 3.0)
          */
     },
     {
-        "XXX_robustness",
+        "robustness",
         0,   // OpenGL version
         0,   // OpenGL ES version
         {
             GLContext::ARB_robustness,
             GLContext::EXT_robustness,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_standard_derivatives",
+        "standard_derivatives",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::OES_standard_derivatives,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_texture_float",
+        "texture_float",
         310, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_texture_float,
             GLContext::OES_texture_float,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_texture_float_linear",
+        "texture_float_linear",
         310, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_texture_float,
             GLContext::OES_texture_float_linear,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_texture_non_power_of_two",
+        "texture_non_power_of_two",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_texture_non_power_of_two,
             GLContext::OES_texture_npot,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_transform_feedback",
+        "transform_feedback",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_transform_feedback,
             GLContext::NV_transform_feedback,
             GLContext::Extensions_End
         }
     },
     {
-        "XXX_vertex_array_object",
+        "vertex_array_object",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_vertex_array_object,
             GLContext::OES_vertex_array_object,
             GLContext::APPLE_vertex_array_object,
             GLContext::Extensions_End
         }
     }
 };
 
-static inline const ExtensionGroupInfo&
-GetExtensionGroupInfo(GLContext::GLExtensionGroup extensionGroup)
+static inline const FeatureInfo&
+GetFeatureInfo(GLFeature::Enum feature)
 {
-    static_assert(MOZ_ARRAY_LENGTH(sExtensionGroupInfoArr) == size_t(GLContext::ExtensionGroup_Max),
-                  "Mismatched lengths for sExtensionGroupInfos and ExtensionGroup enums");
+    static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
+                  "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
 
-    MOZ_ASSERT(extensionGroup < GLContext::ExtensionGroup_Max,
-               "GLContext::GetExtensionGroupInfo : unknown <extensionGroup>");
+    MOZ_ASSERT(feature < GLFeature::EnumMax,
+               "GLContext::GetFeatureInfoInfo : unknown <feature>");
 
-    return sExtensionGroupInfoArr[extensionGroup];
+    return sFeatureInfoArr[feature];
 }
 
 static inline uint32_t
-ProfileVersionForExtensionGroup(GLContext::GLExtensionGroup extensionGroup, ContextProfile profile)
+ProfileVersionForFeature(GLFeature::Enum feature, ContextProfile profile)
 {
     MOZ_ASSERT(profile != ContextProfile::Unknown,
-               "GLContext::ProfileVersionForExtensionGroup : unknown <profile>");
+               "GLContext::ProfileVersionForFeature : unknown <profile>");
 
-    const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
+    const FeatureInfo& featureInfo = GetFeatureInfo(feature);
 
     if (profile == ContextProfile::OpenGLES) {
-        return groupInfo.mOpenGLESVersion;
+        return featureInfo.mOpenGLESVersion;
     }
 
-    return groupInfo.mOpenGLVersion;
+    return featureInfo.mOpenGLVersion;
 }
 
 static inline bool
-IsExtensionGroupIsPartOfProfileVersion(GLContext::GLExtensionGroup extensionGroup,
-                                       ContextProfile profile, unsigned int version)
+IsFeatureIsPartOfProfileVersion(GLFeature::Enum feature,
+                                ContextProfile profile, unsigned int version)
 {
-    unsigned int profileVersion = ProfileVersionForExtensionGroup(extensionGroup, profile);
+    unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
 
+    /**
+     * if `profileVersion` is zero, it means that no version of the profile
+     * added support for the feature.
+     */
     return profileVersion && version >= profileVersion;
 }
 
 const char*
-GLContext::GetExtensionGroupName(GLExtensionGroup extensionGroup)
+GLContext::GetFeatureName(GLFeature::Enum feature)
 {
-    return GetExtensionGroupInfo(extensionGroup).mName;
+    return GetFeatureInfo(feature).mName;
 }
 
 bool
-GLContext::IsExtensionSupported(GLExtensionGroup extensionGroup) const
+GLContext::IsSupported(GLFeature::Enum feature) const
 {
-    if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
+    if (IsFeatureIsPartOfProfileVersion(feature, mProfile, mVersion)) {
         return true;
     }
 
-    const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
+    const FeatureInfo& featureInfo = GetFeatureInfo(feature);
 
     for (size_t i = 0; true; i++)
     {
         MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
 
-        if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
+        if (featureInfo.mExtensions[i] == GLContext::Extensions_End) {
             break;
         }
 
-        if (IsExtensionSupported(groupInfo.mExtensions[i])) {
+        if (IsExtensionSupported(featureInfo.mExtensions[i])) {
             return true;
         }
     }
 
     return false;
 }
 
 bool
-GLContext::MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup)
+GLContext::MarkUnsupported(GLFeature::Enum feature)
 {
-    MOZ_ASSERT(IsExtensionSupported(extensionGroup), "extension group is already unsupported!");
+    MOZ_ASSERT(IsSupported(feature), "extension group is already unsupported!");
 
-    if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
+    if (IsFeatureIsPartOfProfileVersion(feature, mProfile, mVersion)) {
         NS_WARNING(nsPrintfCString("%s marked as unsupported, but it's supposed to be supported by %s %s",
-                                   GetExtensionGroupName(extensionGroup),
+                                   GetFeatureName(feature),
                                    ProfileString(),
                                    VersionString()).get());
         return false;
     }
 
-    const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
+    const FeatureInfo& featureInfo = GetFeatureInfo(feature);
 
     for (size_t i = 0; true; i++)
     {
         MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
 
-        if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
+        if (featureInfo.mExtensions[i] == GLContext::Extensions_End) {
             break;
         }
 
-        MarkExtensionUnsupported(groupInfo.mExtensions[i]);
+        MarkExtensionUnsupported(featureInfo.mExtensions[i]);
     }
 
-    MOZ_ASSERT(!IsExtensionSupported(extensionGroup), "GLContext::MarkExtensionGroupUnsupported has failed!");
+    MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkExtensionGroupUnsupported has failed!");
 
-    NS_WARNING(nsPrintfCString("%s marked as unsupported", GetExtensionGroupName(extensionGroup)).get());
+    NS_WARNING(nsPrintfCString("%s marked as unsupported", GetFeatureName(feature)).get());
 
     return true;
 }
 
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -24,17 +24,17 @@ namespace mozilla {
 namespace gl {
 
 GLScreenBuffer*
 GLScreenBuffer::Create(GLContext* gl,
                      const gfxIntSize& size,
                      const SurfaceCaps& caps)
 {
     if (caps.antialias &&
-        !gl->IsExtensionSupported(GLContext::XXX_framebuffer_multisample))
+        !gl->IsSupported(GLFeature::framebuffer_multisample))
     {
         return nullptr;
     }
 
     SurfaceFactory_GL* factory = nullptr;
 
 #ifdef MOZ_WIDGET_GONK
     /* On B2G, we want a Gralloc factory, and we want one right at the start */
@@ -74,37 +74,37 @@ GLScreenBuffer::~GLScreenBuffer()
 
 
 void
 GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
 {
     GLuint drawFB = DrawFB();
     GLuint readFB = ReadFB();
 
-    if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
+    if (!gl->IsSupported(GLFeature::framebuffer_blit)) {
         MOZ_ASSERT(drawFB == readFB);
         gl->raw_fBindFramebuffer(target, readFB);
         return;
     }
 
     switch (target) {
     case LOCAL_GL_FRAMEBUFFER:
         gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
         gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
         break;
 
     case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
-        if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
+        if (!gl->IsSupported(GLFeature::framebuffer_blit))
             NS_WARNING("DRAW_FRAMEBUFFER requested but unavailable.");
 
         gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
         break;
 
     case LOCAL_GL_READ_FRAMEBUFFER_EXT:
-        if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
+        if (!gl->IsSupported(GLFeature::framebuffer_blit))
             NS_WARNING("READ_FRAMEBUFFER requested but unavailable.");
 
         gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
         break;
 
     default:
         MOZ_CRASH("Bad `target` for BindFramebuffer.");
     }
@@ -119,31 +119,31 @@ GLScreenBuffer::BindFB(GLuint fb)
     mUserDrawFB = fb;
     mUserReadFB = fb;
     mInternalDrawFB = (fb == 0) ? drawFB : fb;
     mInternalReadFB = (fb == 0) ? readFB : fb;
 
     if (mInternalDrawFB == mInternalReadFB) {
         mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
     } else {
-        MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit));
+        MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
         mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
         mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
     }
 
 #ifdef DEBUG
     mInInternalMode_DrawFB = false;
     mInInternalMode_ReadFB = false;
 #endif
 }
 
 void
 GLScreenBuffer::BindDrawFB(GLuint fb)
 {
-    if (!mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
+    if (!mGL->IsSupported(GLFeature::framebuffer_blit)) {
         NS_WARNING("DRAW_FRAMEBUFFER requested, but unsupported.");
 
         mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
     } else {
         GLuint drawFB = DrawFB();
         mUserDrawFB = fb;
         mInternalDrawFB = (fb == 0) ? drawFB : fb;
 
@@ -153,17 +153,17 @@ GLScreenBuffer::BindDrawFB(GLuint fb)
 #ifdef DEBUG
     mInInternalMode_DrawFB = false;
 #endif
 }
 
 void
 GLScreenBuffer::BindReadFB(GLuint fb)
 {
-    if (!mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
+    if (!mGL->IsSupported(GLFeature::framebuffer_blit)) {
         NS_WARNING("READ_FRAMEBUFFER requested, but unsupported.");
 
         mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
     } else {
         GLuint readFB = ReadFB();
         mUserReadFB = fb;
         mInternalReadFB = (fb == 0) ? readFB : fb;
 
@@ -228,17 +228,17 @@ GLScreenBuffer::GetReadFB() const
 {
 #ifdef DEBUG
     MOZ_ASSERT(mGL->IsCurrent());
     MOZ_ASSERT(!mInInternalMode_ReadFB);
 
     // We use raw_ here because this is debug code and we need to see what
     // the driver thinks.
     GLuint actual = 0;
-    if (mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
+    if (mGL->IsSupported(GLFeature::framebuffer_blit))
         mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
     else
         mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
 
     GLuint predicted = mInternalReadFB;
     if (predicted != actual) {
         printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
                       predicted, actual);
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -96,17 +96,17 @@ else:
 
 if gl_provider == 'EGL':
     CPP_SOURCES += [
         'GLLibraryEGL.cpp',
     ]
 
 CPP_SOURCES += [
     'GLContext.cpp',
-    'GLContextExtensionGroupQueries.cpp',
+    'GLContextFeatures.cpp',
     'GLContextTypes.cpp',
     'GLContextUtils.cpp',
     'GLLibraryLoader.cpp',
     'GLScreenBuffer.cpp',
     'GLTextureImage.cpp',
     'SharedSurface.cpp',
     'SharedSurfaceEGL.cpp',
     'SharedSurfaceGL.cpp',
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5662,17 +5662,18 @@ frontend::EmitTree(ExclusiveContext *cx,
             // mode for scripts does not allow separate emitter passes.
             for (ParseNode *pn2 = pnchild; pn2; pn2 = pn2->pn_next) {
                 if (pn2->isKind(PNK_FUNCTION) && pn2->functionIsHoisted()) {
                     if (!EmitTree(cx, bce, pn2))
                         return false;
                 }
             }
         }
-        if (fun->hasDefaults()) {
+        bool hasDefaults = bce->sc->asFunctionBox()->hasDefaults();
+        if (hasDefaults) {
             ParseNode *rest = NULL;
             bool restIsDefn = false;
             if (fun->hasRest()) {
                 JS_ASSERT(!bce->sc->asFunctionBox()->argumentsHasLocalBinding());
 
                 // Defaults with a rest parameter need special handling. The
                 // rest parameter needs to be undefined while defaults are being
                 // processed. To do this, we create the rest argument and let it
@@ -5711,17 +5712,17 @@ frontend::EmitTree(ExclusiveContext *cx,
         }
         for (ParseNode *pn2 = pn->pn_head; pn2 != pnlast; pn2 = pn2->pn_next) {
             // Only bind the parameter if it's not aliased by a nested function
             // in the body.
             if (!pn2->isDefn())
                 continue;
             if (!BindNameToSlot(cx, bce, pn2))
                 return false;
-            if (pn2->pn_next == pnlast && fun->hasRest() && !fun->hasDefaults()) {
+            if (pn2->pn_next == pnlast && fun->hasRest() && !hasDefaults) {
                 // Fill rest parameter. We handled the case with defaults above.
                 JS_ASSERT(!bce->sc->asFunctionBox()->argumentsHasLocalBinding());
                 bce->switchToProlog();
                 if (Emit1(cx, bce, JSOP_REST) < 0)
                     return false;
                 CheckTypeSet(cx, bce, JSOP_REST);
                 if (!EmitVarOp(cx, pn2, JSOP_SETARG, bce))
                     return false;
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -466,17 +466,17 @@ template <typename ParseHandler>
 FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
                          ParseContext<ParseHandler> *outerpc, Directives directives,
                          bool extraWarnings, GeneratorKind generatorKind)
   : ObjectBox(fun, traceListHead),
     SharedContext(cx, directives, extraWarnings),
     bindings(),
     bufStart(0),
     bufEnd(0),
-    ndefaults(0),
+    length(0),
     generatorKindBits_(GeneratorKindAsBits(generatorKind)),
     inWith(false),                  // initialized below
     inGenexpLambda(false),
     hasDestructuringArgs(false),
     useAsm(directives.asmJS()),
     insideUseAsm(outerpc && outerpc->useAsmOrInsideUseAsm()),
     usesArguments(false),
     usesApply(false),
@@ -878,16 +878,17 @@ Parser<FullParseHandler>::standaloneFunc
     argsbody->setOp(JSOP_NOP);
     argsbody->makeEmpty();
     fn->pn_body = argsbody;
 
     FunctionBox *funbox = newFunctionBox(fn, fun, /* outerpc = */ NULL, inheritedDirectives,
                                          generatorKind);
     if (!funbox)
         return null();
+    funbox->length = fun->nargs - fun->hasRest();
     handler.setFunctionBox(fn, funbox);
 
     ParseContext<FullParseHandler> funpc(this, pc, fn, funbox, newDirectives,
                                          /* staticLevel = */ 0, /* bodyid = */ 0);
     if (!funpc.init())
         return null();
 
     for (unsigned i = 0; i < formals.length(); i++) {
@@ -1535,51 +1536,51 @@ Parser<ParseHandler>::bindDestructuringA
 
     return pc->define(parser->tokenStream, name, data->pn, Definition::VAR);
 }
 #endif /* JS_HAS_DESTRUCTURING */
 
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, Node funcpn,
-                                        bool &hasRest)
+                                        bool *hasRest)
 {
     FunctionBox *funbox = pc->sc->asFunctionBox();
 
+    *hasRest = false;
+
     bool parenFreeArrow = false;
     if (kind == Arrow && tokenStream.peekToken() == TOK_NAME) {
         parenFreeArrow = true;
     } else {
         if (tokenStream.getToken() != TOK_LP) {
             report(ParseError, false, null(),
                    kind == Arrow ? JSMSG_BAD_ARROW_ARGS : JSMSG_PAREN_BEFORE_FORMAL);
             return false;
         }
 
         // Record the start of function source (for FunctionToString). If we
         // are parenFreeArrow, we will set this below, after consuming the NAME.
         funbox->setStart(tokenStream);
     }
 
-    hasRest = false;
-
     Node argsbody = handler.newList(PNK_ARGSBODY);
     if (!argsbody)
         return false;
     handler.setFunctionBody(funcpn, argsbody);
 
     if (parenFreeArrow || !tokenStream.matchToken(TOK_RP)) {
         bool hasDefaults = false;
         Node duplicatedArg = null();
 #if JS_HAS_DESTRUCTURING
         Node list = null();
 #endif
 
         do {
-            if (hasRest) {
+            if (*hasRest) {
                 report(ParseError, false, null(), JSMSG_PARAMETER_AFTER_REST);
                 return false;
             }
 
             TokenKind tt = tokenStream.getToken();
             JS_ASSERT_IF(parenFreeArrow, tt == TOK_NAME);
             switch (tt) {
 #if JS_HAS_DESTRUCTURING
@@ -1643,17 +1644,17 @@ Parser<ParseHandler>::functionArguments(
 
               case TOK_YIELD:
                 if (!checkYieldNameValidity(JSMSG_MISSING_FORMAL))
                     return false;
                 goto TOK_NAME;
 
               case TOK_TRIPLEDOT:
               {
-                hasRest = true;
+                *hasRest = true;
                 tt = tokenStream.getToken();
                 if (tt != TOK_NAME) {
                     if (tt != TOK_ERROR)
                         report(ParseError, false, null(), JSMSG_NO_REST_NAME);
                     return false;
                 }
                 goto TOK_NAME;
               }
@@ -1671,33 +1672,35 @@ Parser<ParseHandler>::functionArguments(
 
                 if (tokenStream.matchToken(TOK_ASSIGN)) {
                     // A default argument without parentheses would look like:
                     // a = expr => body, but both operators are right-associative, so
                     // that would have been parsed as a = (expr => body) instead.
                     // Therefore it's impossible to get here with parenFreeArrow.
                     JS_ASSERT(!parenFreeArrow);
 
-                    if (hasRest) {
+                    if (*hasRest) {
                         report(ParseError, false, null(), JSMSG_REST_WITH_DEFAULT);
                         return false;
                     }
                     if (duplicatedArg) {
                         report(ParseError, false, duplicatedArg, JSMSG_BAD_DUP_ARGS);
                         return false;
                     }
-                    hasDefaults = true;
+                    if (!hasDefaults) {
+                        hasDefaults = true;
+
+                        // The Function.length property is the number of formals
+                        // before the first default argument.
+                        funbox->length = pc->numArgs() - 1;
+                    }
                     Node def_expr = assignExprWithoutYield(JSMSG_YIELD_IN_DEFAULT);
                     if (!def_expr)
                         return false;
                     handler.setLastFunctionArgumentDefault(funcpn, def_expr);
-                    funbox->ndefaults++;
-                } else if (!hasRest && hasDefaults) {
-                    report(ParseError, false, null(), JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT);
-                    return false;
                 }
 
                 break;
               }
 
               default:
                 report(ParseError, false, null(), JSMSG_MISSING_FORMAL);
                 /* FALL THROUGH */
@@ -1705,16 +1708,19 @@ Parser<ParseHandler>::functionArguments(
                 return false;
             }
         } while (!parenFreeArrow && tokenStream.matchToken(TOK_COMMA));
 
         if (!parenFreeArrow && tokenStream.getToken() != TOK_RP) {
             report(ParseError, false, null(), JSMSG_PAREN_AFTER_FORMAL);
             return false;
         }
+
+        if (!hasDefaults)
+            funbox->length = pc->numArgs() - *hasRest;
     }
 
     return true;
 }
 
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::checkFunctionName(HandlePropertyName funName)
@@ -2244,16 +2250,17 @@ Parser<FullParseHandler>::standaloneLazy
     if (!pn)
         return null();
 
     Directives directives(/* strict = */ strict);
     FunctionBox *funbox = newFunctionBox(pn, fun, /* outerpc = */ NULL, directives,
                                          generatorKind);
     if (!funbox)
         return null();
+    funbox->length = fun->nargs - fun->hasRest();
 
     Directives newDirectives = directives;
     ParseContext<FullParseHandler> funpc(this, /* parent = */ NULL, pn, funbox,
                                          &newDirectives, staticLevel, /* bodyid = */ 0);
     if (!funpc.init())
         return null();
 
     if (!functionArgsAndBodyGeneric(pn, fun, Normal, Statement, &newDirectives)) {
@@ -2287,24 +2294,22 @@ Parser<ParseHandler>::functionArgsAndBod
     // Given a properly initialized parse context, try to parse an actual
     // function without concern for conversion to strict mode, use of lazy
     // parsing and such.
 
     context->maybePause();
 
     Node prelude = null();
     bool hasRest;
-    if (!functionArguments(kind, &prelude, pn, hasRest))
+    if (!functionArguments(kind, &prelude, pn, &hasRest))
         return false;
 
     FunctionBox *funbox = pc->sc->asFunctionBox();
 
     fun->setArgCount(pc->numArgs());
-    if (funbox->ndefaults)
-        fun->setHasDefaults();
     if (hasRest)
         fun->setHasRest();
 
     if (type == Getter && fun->nargs > 0) {
         report(ParseError, false, null(), JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
         return false;
     }
     if (type == Setter && fun->nargs != 1) {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -514,17 +514,17 @@ class Parser : private AutoGCRooter, pub
     Node unaryExpr();
     Node memberExpr(TokenKind tt, bool allowCallSyntax);
     Node primaryExpr(TokenKind tt);
     Node parenExpr(bool *genexp = NULL);
 
     /*
      * Additional JS parsers.
      */
-    bool functionArguments(FunctionSyntaxKind kind, Node *list, Node funcpn, bool &hasRest);
+    bool functionArguments(FunctionSyntaxKind kind, Node *list, Node funcpn, bool *hasRest);
 
     Node functionDef(HandlePropertyName name, const TokenStream::Position &start,
                      FunctionType type, FunctionSyntaxKind kind, GeneratorKind generatorKind);
     bool functionArgsAndBody(Node pn, HandleFunction fun,
                              FunctionType type, FunctionSyntaxKind kind,
                              GeneratorKind generatorKind,
                              Directives inheritedDirectives, Directives *newDirectives);
 
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -253,17 +253,17 @@ SharedContext::asModuleBox()
 class FunctionBox : public ObjectBox, public SharedContext
 {
   public:
     Bindings        bindings;               /* bindings for this function */
     uint32_t        bufStart;
     uint32_t        bufEnd;
     uint32_t        startLine;
     uint32_t        startColumn;
-    uint16_t        ndefaults;
+    uint16_t        length;
 
     uint8_t         generatorKindBits_;     /* The GeneratorKind of this function. */
     bool            inWith:1;               /* some enclosing scope is a with-statement */
     bool            inGenexpLambda:1;       /* lambda from generator expression */
     bool            hasDestructuringArgs:1; /* arguments list contains destructuring expression */
     bool            useAsm:1;               /* function contains "use asm" directive */
     bool            insideUseAsm:1;         /* nested function of function of "use asm" directive */
 
@@ -302,16 +302,20 @@ class FunctionBox : public ObjectBox, pu
 
     void setMightAliasLocals()             { funCxFlags.mightAliasLocals         = true; }
     void setHasExtensibleScope()           { funCxFlags.hasExtensibleScope       = true; }
     void setNeedsDeclEnvObject()           { funCxFlags.needsDeclEnvObject       = true; }
     void setArgumentsHasLocalBinding()     { funCxFlags.argumentsHasLocalBinding = true; }
     void setDefinitelyNeedsArgsObj()       { JS_ASSERT(funCxFlags.argumentsHasLocalBinding);
                                              funCxFlags.definitelyNeedsArgsObj   = true; }
 
+    bool hasDefaults() const {
+        return length != function()->nargs - function()->hasRest();
+    }
+
     // Return whether this function has either specified "use asm" or is
     // (transitively) nested inside a function that has.
     bool useAsmOrInsideUseAsm() const {
         return useAsm || insideUseAsm;
     }
 
     void setStart(const TokenStream &tokenStream) {
         bufStart = tokenStream.currentToken().pos.begin;
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -196,17 +196,17 @@ def main(argv):
     if options.debug:
         if len(job_list) > 1:
             print 'Multiple tests match command line arguments, debugger can only run one'
             for tc in job_list:
                 print '    %s' % tc.path
             sys.exit(1)
 
         tc = job_list[0]
-        cmd = ['gdb', '--args'] + tc.command(prefix)
+        cmd = ['gdb', '--args'] + tc.command(prefix, jittests.LIB_DIR)
         subprocess.call(cmd)
         sys.exit()
 
     try:
         ok = None
         if options.remote:
             ok = jittests.run_tests_remote(job_list, prefix, options)
         elif options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
--- a/js/src/jit-test/tests/arguments/defaults-basic.js
+++ b/js/src/jit-test/tests/arguments/defaults-basic.js
@@ -19,8 +19,17 @@ f2(1, 3, 4, undefined);
 f2(1, 42, 4, 42, undefined);
 f2(1, 3, 42, undefined, 42);
 function f3(a, b, c=4) {
     assertEq(a, 1);
     assertEq(b, undefined);
     assertEq(c, 4);
 }
 f3(1);
+function f4(a, bIs, cIs, b=3, c) {
+    assertEq(a, 1);
+    assertEq(b, bIs);
+    assertEq(c, cIs);
+}
+assertEq(f4.length, 3);
+f4(1, 3, undefined);
+f4(1, 4, undefined, 4);
+f4(1, 4, 5, 4, 5);
--- a/js/src/jit-test/tests/arguments/defaults-invalid-syntax.js
+++ b/js/src/jit-test/tests/arguments/defaults-invalid-syntax.js
@@ -1,17 +1,14 @@
 load(libdir + "asserts.js");
 
 assertThrowsInstanceOf(function () {
     eval("function f(...rest=23) {}");
 }, SyntaxError);
 assertThrowsInstanceOf(function () {
-    eval("function f(a=16, b) {}");
-}, SyntaxError);
-assertThrowsInstanceOf(function () {
     eval("function f([a]=4) {}");
 }, SyntaxError);
 assertThrowsInstanceOf(function () {
     eval("function f(a=4, [b]) {}");
 }, SyntaxError);
 assertThrowsInstanceOf(function () {
     eval("function f(a=yield 24) {}");
 }, SyntaxError);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-906241.js
@@ -0,0 +1,9 @@
+// |jit-test| error: InternalError: too much recursion
+for (let y in []);
+(function f(x) {
+    Float64Array(ArrayBuffer());
+    {
+        f(x)
+        function t() {}
+    }
+})();
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -2570,32 +2570,30 @@ CheckModuleLevelName(ModuleCompiler &m, 
 }
 
 static bool
 CheckFunctionHead(ModuleCompiler &m, ParseNode *fn)
 {
     JSFunction *fun = FunctionObject(fn);
     if (fun->hasRest())
         return m.fail(fn, "rest args not allowed");
-    if (fun->hasDefaults())
-        return m.fail(fn, "default args not allowed");
     if (fun->isExprClosure())
         return m.fail(fn, "expression closures not allowed");
     if (fn->pn_funbox->hasDestructuringArgs)
         return m.fail(fn, "destructuring args not allowed");
     return true;
 }
 
 static bool
 CheckArgument(ModuleCompiler &m, ParseNode *arg, PropertyName **name)
 {
     if (!IsDefinition(arg))
         return m.fail(arg, "duplicate argument name not allowed");
 
-    if (MaybeDefinitionInitializer(arg))
+    if (arg->pn_dflags & PND_DEFAULT)
         return m.fail(arg, "default arguments not allowed");
 
     if (!CheckIdentifier(m, arg, arg->name()))
         return false;
 
     *name = arg->name();
     return true;
 }
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -453,17 +453,27 @@ NewSlots(JSRuntime *rt, unsigned nslots)
 
     return reinterpret_cast<HeapSlot *>(slots);
 }
 
 JSObject *
 NewCallObject(JSContext *cx, HandleScript script,
               HandleShape shape, HandleTypeObject type, HeapSlot *slots)
 {
-    return CallObject::create(cx, script, shape, type, slots);
+    JSObject *obj = CallObject::create(cx, script, shape, type, slots);
+
+#ifdef JSGC_GENERATIONAL
+    // The JIT creates call objects in the nursery, so elides barriers for
+    // the initializing writes. The interpreter, however, may have allocated
+    // the call object tenured, so barrier as needed before re-entering.
+    if (!IsInsideNursery(cx->runtime(), obj))
+        cx->runtime()->gcStoreBuffer.putWholeCell(obj);
+#endif
+
+    return obj;
 }
 
 JSObject *
 NewStringObject(JSContext *cx, HandleString str)
 {
     return StringObject::create(cx, str);
 }
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1101,19 +1101,23 @@ JS_GetCompartmentPrivate(JSCompartment *
     return compartment->data;
 }
 
 JS_PUBLIC_API(bool)
 JS_WrapObject(JSContext *cx, JSObject **objp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    if (*objp)
-        JS::ExposeGCThingToActiveJS(*objp, JSTRACE_OBJECT);
-    return cx->compartment()->wrap(cx, objp);
+    RootedObject obj(cx, *objp);
+    if (obj)
+        JS::ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT);
+    if (!cx->compartment()->wrap(cx, &obj))
+        return false;
+    *objp = obj;
+    return true;
 }
 
 JS_PUBLIC_API(bool)
 JS_WrapValue(JSContext *cx, jsval *vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (vp)
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -927,38 +927,38 @@ array_join_sub(JSContext *cx, CallArgs &
     }
 
     // Step 6 is implicit in the loops below
 
     StringBuffer sb(cx);
 
     // Various optimized versions of steps 7-10
     if (!locale && !seplen && obj->is<ArrayObject>() && !ObjectMayHaveExtraIndexedProperties(obj)) {
-        const Value *start = obj->getDenseElements();
-        const Value *end = start + obj->getDenseInitializedLength();
-        const Value *elem;
-        for (elem = start; elem < end; elem++) {
+        uint32_t i;
+        for (i = 0; i < obj->getDenseInitializedLength(); ++i) {
             if (!JS_CHECK_OPERATION_LIMIT(cx))
                 return false;
 
+            const Value *elem = &obj->getDenseElement(i);
+
             /*
              * Object stringifying is slow; delegate it to a separate loop to
              * keep this one tight.
              */
             if (elem->isObject())
                 break;
 
             if (!elem->isMagic(JS_ELEMENTS_HOLE) && !elem->isNullOrUndefined()) {
                 if (!ValueToStringBuffer(cx, *elem, sb))
                     return false;
             }
         }
 
         RootedValue v(cx);
-        for (uint32_t i = uint32_t(PointerRangeSize(start, elem)); i < length; i++) {
+        for (; i < length; ++i) {
             if (!JS_CHECK_OPERATION_LIMIT(cx))
                 return false;
 
             bool hole;
             if (!GetElement(cx, obj, i, &hole, &v))
                 return false;
             if (!hole && !v.isNullOrUndefined()) {
                 if (!ValueToStringBuffer(cx, v, sb))
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -170,166 +170,173 @@ JSCompartment::ensureIonCompartmentExist
         return false;
     }
 
     return true;
 }
 #endif
 
 static bool
-WrapForSameCompartment(JSContext *cx, HandleObject obj, MutableHandleValue vp)
+WrapForSameCompartment(JSContext *cx, MutableHandleObject obj)
 {
     JS_ASSERT(cx->compartment() == obj->compartment());
-    if (!cx->runtime()->sameCompartmentWrapObjectCallback) {
-        vp.setObject(*obj);
+    if (!cx->runtime()->sameCompartmentWrapObjectCallback)
         return true;
-    }
 
-    JSObject *wrapped = cx->runtime()->sameCompartmentWrapObjectCallback(cx, obj);
+    RootedObject wrapped(cx);
+    wrapped = cx->runtime()->sameCompartmentWrapObjectCallback(cx, obj);
     if (!wrapped)
         return false;
-    vp.setObject(*wrapped);
+    obj.set(wrapped);
     return true;
 }
 
 bool
 JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper)
 {
     JS_ASSERT(wrapped.wrapped);
     JS_ASSERT(!IsPoisonedPtr(wrapped.wrapped));
     JS_ASSERT(!IsPoisonedPtr(wrapped.debugger));
     JS_ASSERT(!IsPoisonedPtr(wrapper.toGCThing()));
     JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString());
     JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject());
     return crossCompartmentWrappers.put(wrapped, wrapper);
 }
 
 bool
-JSCompartment::wrap(JSContext *cx, MutableHandleValue vp, HandleObject existingArg)
+JSCompartment::wrap(JSContext *cx, JSString **strp)
 {
-    JSRuntime *rt = runtimeFromMainThread();
+    JS_ASSERT(!cx->runtime()->isAtomsCompartment(this));
+    JS_ASSERT(cx->compartment() == this);
+
+    /* If the string is already in this compartment, we are done. */
+    JSString *str = *strp;
+    if (str->zone() == zone())
+        return true;
+
+    /* If the string is an atom, we don't have to copy. */
+    if (str->isAtom()) {
+        JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
+        return true;
+    }
+
+    /* Check the cache. */
+    RootedValue key(cx, StringValue(str));
+    if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
+        *strp = p->value.get().toString();
+        return true;
+    }
 
+    /* No dice. Make a copy, and cache it. */
+    Rooted<JSLinearString *> linear(cx, str->ensureLinear(cx));
+    if (!linear)
+        return false;
+    JSString *copy = js_NewStringCopyN<CanGC>(cx, linear->chars(),
+                                              linear->length());
+    if (!copy)
+        return false;
+    if (!putWrapper(key, StringValue(copy)))
+        return false;
+
+    if (linear->zone()->isGCMarking()) {
+        /*
+         * All string wrappers are dropped when collection starts, but we
+         * just created a new one.  Mark the wrapped string to stop it being
+         * finalized, because if it was then the pointer in this
+         * compartment's wrapper map would be left dangling.
+         */
+        JSString *tmp = linear;
+        MarkStringUnbarriered(&cx->runtime()->gcMarker, &tmp, "wrapped string");
+        JS_ASSERT(tmp == linear);
+    }
+
+    *strp = copy;
+    return true;
+}
+
+bool
+JSCompartment::wrap(JSContext *cx, HeapPtrString *strp)
+{
+    RootedString str(cx, *strp);
+    if (!wrap(cx, str.address()))
+        return false;
+    *strp = str;
+    return true;
+}
+
+bool
+JSCompartment::wrap(JSContext *cx, MutableHandleObject obj, HandleObject existingArg)
+{
+    JS_ASSERT(!cx->runtime()->isAtomsCompartment(this));
     JS_ASSERT(cx->compartment() == this);
-    JS_ASSERT(!rt->isAtomsCompartment(this));
     JS_ASSERT_IF(existingArg, existingArg->compartment() == cx->compartment());
-    JS_ASSERT_IF(existingArg, vp.isObject());
     JS_ASSERT_IF(existingArg, IsDeadProxyObject(existingArg));
 
-    unsigned flags = 0;
-
-    JS_CHECK_CHROME_RECURSION(cx, return false);
-
-    AutoDisableProxyCheck adpc(rt);
-
-    /* Only GC things have to be wrapped or copied. */
-    if (!vp.isMarkable())
+    if (!obj)
         return true;
-
-    if (vp.isString()) {
-        JSString *str = vp.toString();
-
-        /* If the string is already in this compartment, we are done. */
-        if (str->zone() == zone())
-            return true;
-
-        /* If the string is an atom, we don't have to copy. */
-        if (str->isAtom()) {
-            JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
-            return true;
-        }
-    }
+    AutoDisableProxyCheck adpc(cx->runtime());
 
     /*
      * Wrappers should really be parented to the wrapped parent of the wrapped
      * object, but in that case a wrapped global object would have a NULL
      * parent without being a proper global object (JSCLASS_IS_GLOBAL). Instead,
      * we parent all wrappers to the global object in their home compartment.
      * This loses us some transparency, and is generally very cheesy.
      */
     HandleObject global = cx->global();
     JS_ASSERT(global);
 
-    /* Unwrap incoming objects. */
-    if (vp.isObject()) {
-        RootedObject obj(cx, &vp.toObject());
-
-        if (obj->compartment() == this)
-            return WrapForSameCompartment(cx, obj, vp);
-
-        /* Translate StopIteration singleton. */
-        if (obj->is<StopIterationObject>())
-            return js_FindClassObject(cx, JSProto_StopIteration, vp);
-
-        /* Unwrap the object, but don't unwrap outer windows. */
-        obj = UncheckedUnwrap(obj, /* stopAtOuter = */ true, &flags);
-
-        if (obj->compartment() == this)
-            return WrapForSameCompartment(cx, obj, vp);
-
-        if (cx->runtime()->preWrapObjectCallback) {
-            obj = cx->runtime()->preWrapObjectCallback(cx, global, obj, flags);
-            if (!obj)
-                return false;
-        }
+    if (obj->compartment() == this)
+        return WrapForSameCompartment(cx, obj);
 
-        if (obj->compartment() == this)
-            return WrapForSameCompartment(cx, obj, vp);
-        vp.setObject(*obj);
-
-#ifdef DEBUG
-        {
-            JSObject *outer = GetOuterObject(cx, obj);
-            JS_ASSERT(outer && outer == obj);
-        }
-#endif
-    }
-
-    RootedValue key(cx, vp);
-
-    /* If we already have a wrapper for this value, use it. */
-    if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
-        vp.set(p->value);
-        if (vp.isObject()) {
-            DebugOnly<JSObject *> obj = &vp.toObject();
-            JS_ASSERT(obj->is<CrossCompartmentWrapperObject>());
-            JS_ASSERT(obj->getParent() == global);
-        }
+    /* Translate StopIteration singleton. */
+    if (obj->is<StopIterationObject>()) {
+        RootedValue v(cx);
+        if (!js_FindClassObject(cx, JSProto_StopIteration, &v))
+            return false;
+        obj.set(&v.toObject());
         return true;
     }
 
-    if (vp.isString()) {
-        Rooted<JSLinearString *> str(cx, vp.toString()->ensureLinear(cx));
-        if (!str)
-            return false;
+    /* Unwrap the object, but don't unwrap outer windows. */
+    unsigned flags = 0;
+    obj.set(UncheckedUnwrap(obj, /* stopAtOuter = */ true, &flags));
+
+    if (obj->compartment() == this)
+        return WrapForSameCompartment(cx, obj);
 
-        JSString *wrapped = js_NewStringCopyN<CanGC>(cx, str->chars(), str->length());
-        if (!wrapped)
+    /* Invoke the prewrap callback. We're a bit worried about infinite
+     * recursion here, so we do a check - see bug 809295. */
+    JS_CHECK_CHROME_RECURSION(cx, return false);
+    if (cx->runtime()->preWrapObjectCallback) {
+        obj.set(cx->runtime()->preWrapObjectCallback(cx, global, obj, flags));
+        if (!obj)
             return false;
-
-        vp.setString(wrapped);
-        if (!putWrapper(key, vp))
-            return false;
+    }
 
-        if (str->zone()->isGCMarking()) {
-            /*
-             * All string wrappers are dropped when collection starts, but we
-             * just created a new one.  Mark the wrapped string to stop it being
-             * finalized, because if it was then the pointer in this
-             * compartment's wrapper map would be left dangling.
-             */
-            JSString *tmp = str;
-            MarkStringUnbarriered(&rt->gcMarker, &tmp, "wrapped string");
-            JS_ASSERT(tmp == str);
-        }
+    if (obj->compartment() == this)
+        return WrapForSameCompartment(cx, obj);
 
+#ifdef DEBUG
+    {
+        JSObject *outer = GetOuterObject(cx, obj);
+        JS_ASSERT(outer && outer == obj);
+    }
+#endif
+
+    /* If we already have a wrapper for this value, use it. */
+    RootedValue key(cx, ObjectValue(*obj));
+    if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
+        obj.set(&p->value.get().toObject());
+        JS_ASSERT(obj->is<CrossCompartmentWrapperObject>());
+        JS_ASSERT(obj->getParent() == global);
         return true;
     }
 
     RootedObject proto(cx, Proxy::LazyProto);
-    RootedObject obj(cx, &vp.toObject());
     RootedObject existing(cx, existingArg);
     if (existing) {
         /* Is it possible to reuse |existing|? */
         if (!existing->getTaggedProto().isLazy() ||
             // Note: don't use is<ObjectProxyObject>() here -- it also matches subclasses!
             existing->getClass() != &ObjectProxyObject::class_ ||
             existing->getParent() != global ||
             obj->isCallable())
@@ -338,60 +345,27 @@ JSCompartment::wrap(JSContext *cx, Mutab
         }
     }
 
     /*
      * We hand in the original wrapped object into the wrap hook to allow
      * the wrap hook to reason over what wrappers are currently applied
      * to the object.
      */
-    RootedObject wrapper(cx);
-    wrapper = cx->runtime()->wrapObjectCallback(cx, existing, obj, proto, global, flags);
-    if (!wrapper)
+    obj.set(cx->runtime()->wrapObjectCallback(cx, existing, obj, proto, global, flags));
+    if (!obj)
         return false;
 
-    // We maintain the invariant that the key in the cross-compartment wrapper
-    // map is always directly wrapped by the value.
-    JS_ASSERT(Wrapper::wrappedObject(wrapper) == &key.get().toObject());
-
-    vp.setObject(*wrapper);
-    return putWrapper(key, vp);
-}
-
-bool
-JSCompartment::wrap(JSContext *cx, JSString **strp)
-{
-    RootedValue value(cx, StringValue(*strp));
-    if (!wrap(cx, &value))
-        return false;
-    *strp = value.get().toString();
-    return true;
-}
+    /*
+     * We maintain the invariant that the key in the cross-compartment wrapper
+     * map is always directly wrapped by the value.
+     */
+    JS_ASSERT(Wrapper::wrappedObject(obj) == &key.get().toObject());
 
-bool
-JSCompartment::wrap(JSContext *cx, HeapPtrString *strp)
-{
-    RootedValue value(cx, StringValue(*strp));
-    if (!wrap(cx, &value))
-        return false;
-    *strp = value.get().toString();
-    return true;
-}
-
-bool
-JSCompartment::wrap(JSContext *cx, JSObject **objp, JSObject *existingArg)
-{
-    if (!*objp)
-        return true;
-    RootedValue value(cx, ObjectValue(**objp));
-    RootedObject existing(cx, existingArg);
-    if (!wrap(cx, &value, existing))
-        return false;
-    *objp = &value.get().toObject();
-    return true;
+    return putWrapper(key, ObjectValue(*obj));
 }
 
 bool
 JSCompartment::wrapId(JSContext *cx, jsid *idp)
 {
     MOZ_ASSERT(*idp != JSID_VOID, "JSID_VOID is an out-of-band sentinel value");
     if (JSID_IS_INT(*idp))
         return true;
@@ -424,17 +398,17 @@ JSCompartment::wrap(JSContext *cx, Stric
         return false;
     *propp = CastAsStrictPropertyOp(value.toObjectOrNull());
     return true;
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, MutableHandle<PropertyDescriptor> desc)
 {
-    if (!wrap(cx, desc.object().address()))
+    if (!wrap(cx, desc.object()))
         return false;
 
     if (desc.hasGetterObject()) {
         if (!wrap(cx, &desc.getter()))
             return false;
     }
     if (desc.hasSetterObject()) {
         if (!wrap(cx, &desc.setter()))
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -276,20 +276,81 @@ struct JSCompartment
     ~JSCompartment();
 
     bool init(JSContext *cx);
 
     /* Mark cross-compartment wrappers. */
     void markCrossCompartmentWrappers(JSTracer *trc);
     void markAllCrossCompartmentWrappers(JSTracer *trc);
 
-    bool wrap(JSContext *cx, JS::MutableHandleValue vp, JS::HandleObject existing = js::NullPtr());
+    bool wrap(JSContext *cx, JS::MutableHandleValue vp,
+              JS::HandleObject existing = js::NullPtr())
+    {
+        JS_ASSERT_IF(existing, vp.isObject());
+
+        /* Only GC things have to be wrapped or copied. */
+        if (!vp.isMarkable())
+            return true;
+
+        /* Handle strings. */
+        if (vp.isString()) {
+            JSString *str = vp.toString();
+            if (!wrap(cx, &str))
+                return false;
+            vp.setString(str);
+            return true;
+        }
+
+        JS_ASSERT(vp.isObject());
+
+        /*
+         * All that's left are objects.
+         *
+         * Object wrapping isn't the fastest thing in the world, in part because
+         * we have to unwrap and invoke the prewrap hook to find the identity
+         * object before we even start checking the cache. Neither of these
+         * operations are needed in the common case, where we're just wrapping
+         * a plain JS object from the wrappee's side of the membrane to the
+         * wrapper's side.
+         *
+         * To optimize this, we note that the cache should only ever contain
+         * identity objects - that is to say, objects that serve as the
+         * canonical representation for a unique object identity observable by
+         * script. Unwrap and prewrap are both steps that we take to get to the
+         * identity of an incoming objects, and as such, they shuld never map
+         * one identity object to another object. This means that we can safely
+         * check the cache immediately, and only risk false negatives. Do this
+         * in opt builds, and do both in debug builds so that we can assert
+         * that we get the same answer.
+         */
+#ifdef DEBUG
+        JS::RootedObject cacheResult(cx);
+#endif
+        JS::RootedValue v(cx, vp);
+        if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(v)) {
+#ifdef DEBUG
+            cacheResult = &p->value.get().toObject();
+#else
+            vp.set(p->value);
+            return true;
+#endif
+        }
+
+        JS::RootedObject obj(cx, &vp.toObject());
+        if (!wrap(cx, &obj, existing))
+            return false;
+        vp.setObject(*obj);
+        JS_ASSERT_IF(cacheResult, obj == cacheResult);
+        return true;
+    }
+
     bool wrap(JSContext *cx, JSString **strp);
     bool wrap(JSContext *cx, js::HeapPtrString *strp);
-    bool wrap(JSContext *cx, JSObject **objp, JSObject *existing = NULL);
+    bool wrap(JSContext *cx, JS::MutableHandleObject obj,
+              JS::HandleObject existingArg = js::NullPtr());
     bool wrapId(JSContext *cx, jsid *idp);
     bool wrap(JSContext *cx, js::PropertyOp *op);
     bool wrap(JSContext *cx, js::StrictPropertyOp *op);
     bool wrap(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc);
     bool wrap(JSContext *cx, js::AutoIdVector &props);
 
     bool putWrapper(const js::CrossCompartmentKey& wrapped, const js::Value& wrapper);
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -267,18 +267,19 @@ js::fun_resolve(JSContext *cx, HandleObj
 
     if (JSID_IS_ATOM(id, cx->names().length) || JSID_IS_ATOM(id, cx->names().name)) {
         JS_ASSERT(!IsInternalFunctionObject(obj));
 
         RootedValue v(cx);
         if (JSID_IS_ATOM(id, cx->names().length)) {
             if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
                 return false;
-            uint16_t ndefaults = fun->hasScript() ? fun->nonLazyScript()->ndefaults : 0;
-            v.setInt32(fun->nargs - ndefaults - fun->hasRest());
+            uint16_t length = fun->hasScript() ? fun->nonLazyScript()->funLength :
+                fun->nargs - fun->hasRest();
+            v.setInt32(length);
         } else {
             v.setString(fun->atom() == NULL ?  cx->runtime()->emptyString : fun->atom());
         }
 
         if (!DefineNativeProperty(cx, fun, id, v, JS_PropertyStub, JS_StrictPropertyStub,
                                   JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
             return false;
         }
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -38,35 +38,35 @@ class JSFunction : public JSObject
         LAMBDA           = 0x0080,  /* function comes from a FunctionExpression, ArrowFunction, or
                                        Function() call (not a FunctionDeclaration or nonstandard
                                        function-statement) */
         SELF_HOSTED      = 0x0100,  /* function is self-hosted builtin and must not be
                                        decompilable nor constructible. */
         SELF_HOSTED_CTOR = 0x0200,  /* function is self-hosted builtin constructor and
                                        must be constructible but not decompilable. */
         HAS_REST         = 0x0400,  /* function has a rest (...) parameter */
-        HAS_DEFAULTS     = 0x0800,  /* function has at least one default parameter */
+        // 0x0800 is available
         INTERPRETED_LAZY = 0x1000,  /* function is interpreted but doesn't have a script yet */
         ARROW            = 0x2000,  /* ES6 '(args) => body' syntax */
         SH_WRAPPABLE     = 0x4000,  /* self-hosted function is wrappable, doesn't need to be cloned */
 
         /* Derived Flags values for convenience: */
         NATIVE_FUN = 0,
         INTERPRETED_LAMBDA = INTERPRETED | LAMBDA,
         INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW
     };
 
     static void staticAsserts() {
         JS_STATIC_ASSERT(INTERPRETED == JS_FUNCTION_INTERPRETED_BIT);
         static_assert(sizeof(JSFunction) == sizeof(js::shadow::Function),
                       "shadow interface must match actual interface");
     }
 
-    uint16_t        nargs;        /* maximum number of specified arguments,
-                                     reflected as f.length/f.arity */
+    uint16_t        nargs;        /* number of formal arguments
+                                     (including defaults and the rest parameter unlike f.length) */
     uint16_t        flags;        /* bitfield composed of the above Flags enum */
     union U {
         class Native {
             friend class JSFunction;
             js::Native          native;       /* native method pointer or null */
             const JSJitInfo     *jitinfo;     /* Information about this function to be
                                                  used by the JIT;
                                                  use the accessor! */
@@ -112,17 +112,16 @@ class JSFunction : public JSObject
     bool isInterpretedLazy()        const { return flags & INTERPRETED_LAZY; }
     bool hasScript()                const { return flags & INTERPRETED; }
     bool isExprClosure()            const { return flags & EXPR_CLOSURE; }
     bool hasGuessedAtom()           const { return flags & HAS_GUESSED_ATOM; }
     bool isLambda()                 const { return flags & LAMBDA; }
     bool isSelfHostedBuiltin()      const { return flags & SELF_HOSTED; }
     bool isSelfHostedConstructor()  const { return flags & SELF_HOSTED_CTOR; }
     bool hasRest()                  const { return flags & HAS_REST; }
-    bool hasDefaults()              const { return flags & HAS_DEFAULTS; }
     bool isWrappable()              const {
         JS_ASSERT_IF(flags & SH_WRAPPABLE, isSelfHostedBuiltin());
         return flags & SH_WRAPPABLE;
     }
 
     // Arrow functions are a little weird.
     //
     // Like all functions, (1) when the compiler parses an arrow function, it
@@ -165,21 +164,16 @@ class JSFunction : public JSObject
         this->nargs = nargs;
     }
 
     // Can be called multiple times by the parser.
     void setHasRest() {
         flags |= HAS_REST;
     }
 
-    // Can be called multiple times by the parser.
-    void setHasDefaults() {
-        flags |= HAS_DEFAULTS;
-    }
-
     void setIsSelfHostedBuiltin() {
         JS_ASSERT(!isSelfHostedBuiltin());
         flags |= SELF_HOSTED;
     }
 
     void setIsSelfHostedConstructor() {
         JS_ASSERT(!isSelfHostedConstructor());
         flags |= SELF_HOSTED_CTOR;
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -414,17 +414,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl
         OwnSource,
         ExplicitUseStrict,
         SelfHosted
     };
 
     uint32_t length, lineno, nslots;
     uint32_t natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, i;
     uint32_t prologLength, version;
-    uint32_t ndefaults = 0;
+    uint32_t funLength = 0;
     uint32_t nTypeSets = 0;
     uint32_t scriptBits = 0;
 
     JSContext *cx = xdr->cx();
     RootedScript script(cx);
     nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = 0;
 
     /* XDR arguments and vars. */
@@ -466,17 +466,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl
         if (script->hasObjects())
             nobjects = script->objects()->length;
         if (script->hasRegexps())
             nregexps = script->regexps()->length;
         if (script->hasTrynotes())
             ntrynotes = script->trynotes()->length;
 
         nTypeSets = script->nTypeSets;
-        ndefaults = script->ndefaults;
+        funLength = script->funLength;
 
         if (script->noScriptRval)
             scriptBits |= (1 << NoScriptRval);
         if (script->savedCallerFun)
             scriptBits |= (1 << SavedCallerFun);
         if (script->strict)
             scriptBits |= (1 << Strict);
         if (script->explicitUseStrict)
@@ -526,17 +526,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl
     if (!xdr->codeUint32(&nobjects))
         return false;
     if (!xdr->codeUint32(&nregexps))
         return false;
     if (!xdr->codeUint32(&nconsts))
         return false;
     if (!xdr->codeUint32(&nTypeSets))
         return false;
-    if (!xdr->codeUint32(&ndefaults))
+    if (!xdr->codeUint32(&funLength))
         return false;
     if (!xdr->codeUint32(&scriptBits))
         return false;
 
     if (mode == XDR_DECODE) {
         /* Note: version is packed into the 32b space with another 16b value. */
         JSVersion version_ = JSVersion(version & JS_BITMASK(16));
         JS_ASSERT((version_ & VersionFlags::MASK) == unsigned(version_));
@@ -572,17 +572,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl
     if (mode == XDR_DECODE) {
         if (!JSScript::partiallyInit(cx, script, nobjects, nregexps, ntrynotes, nconsts, nTypeSets))
             return false;
 
         JS_ASSERT(!script->mainOffset);
         script->mainOffset = prologLength;
         script->length = length;
         script->nfixed = uint16_t(version >> 16);
-        script->ndefaults = ndefaults;
+        script->funLength = funLength;
 
         scriptp.set(script);
 
         if (scriptBits & (1 << Strict))
             script->strict = true;
         if (scriptBits & (1 << ExplicitUseStrict))
             script->explicitUseStrict = true;
         if (scriptBits & (1 << ContainsDynamicNameAccess))
@@ -1973,17 +1973,17 @@ JSScript::fullyInitFromEmitter(Exclusive
             // This must precede the script->bindings.transfer() call below
             script->setArgumentsHasVarBinding();
             if (funbox->definitelyNeedsArgsObj())
                 script->setNeedsArgsObj(true);
         } else {
             JS_ASSERT(!funbox->definitelyNeedsArgsObj());
         }
 
-        script->ndefaults = funbox->ndefaults;
+        script->funLength = funbox->length;
     }
 
     RootedFunction fun(cx, NULL);
     if (funbox) {
         JS_ASSERT(!bce->script->noScriptRval);
         script->isGeneratorExp = funbox->inGenexpLambda;
         script->setGeneratorKind(funbox->generatorKind());
         script->setFunction(funbox->function());
@@ -2464,16 +2464,17 @@ js::CloneScript(JSContext *cx, HandleObj
     /* Script filenames, bytecodes and atoms are runtime-wide. */
     dst->code = src->code;
     dst->atoms = src->atoms;
 
     dst->length = src->length;
     dst->lineno = src->lineno;
     dst->mainOffset = src->mainOffset;
     dst->natoms = src->natoms;
+    dst->funLength = src->funLength;
     dst->nfixed = src->nfixed;
     dst->nTypeSets = src->nTypeSets;
     dst->nslots = src->nslots;
     if (src->argumentsHasVarBinding()) {
         dst->setArgumentsHasVarBinding();
         if (src->analyzedArgsUsage())
             dst->setNeedsArgsObj(src->needsArgsObj());
     }
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -516,17 +516,17 @@ class JSScript : public js::gc::Cell
 
     // 16-bit fields.
 
   private:
     uint16_t        PADDING16;
     uint16_t        version;    /* JS version under which script was compiled */
 
   public:
-    uint16_t        ndefaults;  /* number of defaults the function has */
+    uint16_t        funLength;  /* ES6 function length */
 
     uint16_t        nfixed;     /* number of slots besides stack operands in
                                    slot array */
 
     uint16_t        nTypeSets;  /* number of type sets used in this script for
                                    dynamic type monitoring */
 
     uint16_t        nslots;     /* vars plus maximum stack depth */
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -288,17 +288,17 @@ CrossCompartmentWrapper::hasOwn(JSContex
 bool
 CrossCompartmentWrapper::get(JSContext *cx, HandleObject wrapper, HandleObject receiver,
                              HandleId id, MutableHandleValue vp)
 {
     RootedObject receiverCopy(cx, receiver);
     RootedId idCopy(cx, id);
     {
         AutoCompartment call(cx, wrappedObject(wrapper));
-        if (!cx->compartment()->wrap(cx, receiverCopy.address()) ||
+        if (!cx->compartment()->wrap(cx, &receiverCopy) ||
             !cx->compartment()->wrapId(cx, idCopy.address()))
         {
             return false;
         }
 
         if (!Wrapper::get(cx, wrapper, receiverCopy, idCopy, vp))
             return false;
     }
@@ -307,17 +307,17 @@ CrossCompartmentWrapper::get(JSContext *
 
 bool
 CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleObject receiver,
                              HandleId id, bool strict, MutableHandleValue vp)
 {
     RootedObject receiverCopy(cx, receiver);
     RootedId idCopy(cx, id);
     PIERCE(cx, wrapper,
-           cx->compartment()->wrap(cx, receiverCopy.address()) &&
+           cx->compartment()->wrap(cx, &receiverCopy) &&
            cx->compartment()->wrapId(cx, idCopy.address()) &&
            cx->compartment()->wrap(cx, vp),
            Wrapper::set(cx, wrapper, receiverCopy, idCopy, strict, vp),
            NOTHING);
 }
 
 bool
 CrossCompartmentWrapper::keys(JSContext *cx, HandleObject wrapper, AutoIdVector &props)
@@ -359,17 +359,17 @@ Reify(JSContext *cx, JSCompartment *orig
 {
     Rooted<PropertyIteratorObject*> iterObj(cx, &vp.toObject().as<PropertyIteratorObject>());
     NativeIterator *ni = iterObj->getNativeIterator();
 
     AutoCloseIterator close(cx, iterObj);
 
     /* Wrap the iteratee. */
     RootedObject obj(cx, ni->obj);
-    if (!origin->wrap(cx, obj.address()))
+    if (!origin->wrap(cx, &obj))
         return false;
 
     /*
      * Wrap the elements in the iterator's snapshot.
      * N.B. the order of closing/creating iterators is important due to the
      * implicit cx->enumerators state.
      */
     size_t length = ni->numKeys();
@@ -570,17 +570,17 @@ CrossCompartmentWrapper::getPrototypeOf(
         RootedObject wrapped(cx, wrappedObject(wrapper));
         AutoCompartment call(cx, wrapped);
         if (!JSObject::getProto(cx, wrapped, protop))
             return false;
         if (protop)
             protop->setDelegate(cx);
     }
 
-    return cx->compartment()->wrap(cx, protop.address());
+    return cx->compartment()->wrap(cx, protop);
 }
 
 CrossCompartmentWrapper CrossCompartmentWrapper::singleton(0u);
 
 /* Security wrappers. */
 
 template <class Base>
 SecurityWrapper<Base>::SecurityWrapper(unsigned flags)
@@ -928,17 +928,17 @@ js::RemapWrapper(JSContext *cx, JSObject
     // immediately cease to be a cross-compartment wrapper. Neuter it.
     NukeCrossCompartmentWrapper(cx, wobj);
 
     // First, we wrap it in the new compartment. We try to use the existing
     // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
     // the choice to reuse |wobj| or not.
     RootedObject tobj(cx, newTarget);
     AutoCompartment ac(cx, wobj);
-    if (!wcompartment->wrap(cx, tobj.address(), wobj))
+    if (!wcompartment->wrap(cx, &tobj, wobj))
         MOZ_CRASH();
 
     // If wrap() reused |wobj|, it will have overwritten it and returned with
     // |tobj == wobj|. Otherwise, |tobj| will point to a new wrapper and |wobj|
     // will still be nuked. In the latter case, we replace |wobj| with the
     // contents of the new wrapper in |tobj|.
     if (tobj != wobj) {
         // Now, because we need to maintain object identity, we do a brain
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2514,17 +2514,17 @@ NewSandbox(JSContext *cx, bool lazy)
 
         RootedValue value(cx, BooleanValue(lazy));
         if (!JS_SetProperty(cx, obj, "lazy", value))
             return NULL;
     }
 
     JS_FireOnNewGlobalObject(cx, obj);
 
-    if (!cx->compartment()->wrap(cx, obj.address()))
+    if (!cx->compartment()->wrap(cx, &obj))
         return NULL;
     return obj;
 }
 
 static bool
 EvalInContext(JSContext *cx, unsigned argc, jsval *vp)
 {
     RootedString str(cx);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -854,17 +854,17 @@ CloneObject(JSContext *cx, HandleObject 
 {
     CloneMemory::AddPtr p = clonedObjects.lookupForAdd(srcObj.get());
     if (p)
         return p->value;
     RootedObject clone(cx);
     if (srcObj->is<JSFunction>()) {
         if (srcObj->as<JSFunction>().isWrappable()) {
             clone = srcObj;
-            if (!cx->compartment()->wrap(cx, clone.address()))
+            if (!cx->compartment()->wrap(cx, &clone))
                 return NULL;
         } else {
             RootedFunction fun(cx, &srcObj->as<JSFunction>());
             clone = CloneFunctionObject(cx, fun, cx->global(), fun->getAllocKind(), TenuredObject);
         }
     } else if (srcObj->is<RegExpObject>()) {
         RegExpObject &reobj = srcObj->as<RegExpObject>();
         RootedAtom source(cx, reobj.getSource());
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -18,17 +18,17 @@ namespace js {
  * Bytecode version number. Increment the subtrahend whenever JS bytecode
  * changes incompatibly.
  *
  * This version number is XDR'd near the front of xdr bytecode and
  * aborts deserialization if there is a mismatch between the current
  * and saved versions. If deserialization fails, the data should be
  * invalidated if possible.
  */
-static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 150);
+static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 151);
 
 class XDRBuffer {
   public:
     XDRBuffer(JSContext *cx)
       : context(cx), base(NULL), cursor(NULL), limit(NULL) { }
 
     JSContext *cx() const {
         return context;
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -568,16 +568,32 @@ SameOriginCheckedComponent::CanSetProper
     return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
                                              REFNSIID aIID,
                                              void** aInstancePtr)
 {
+    if (MOZ_UNLIKELY(!NS_IsMainThread())) {
+        printf("Uh oh! DelegatedQueryInterface called off-main-thread!\n");
+        printf("Name: %s\n", GetInterfaceName());
+        JSCompartment *c = js::GetObjectCompartment(self->GetJSObjectPreserveColor());
+        char *origin = nullptr;
+        nsresult rv = xpc::GetCompartmentPrincipal(c)->GetOrigin(&origin);
+        if (NS_SUCCEEDED(rv)) {
+            printf("Principal origin: %s\n", origin);
+            NS_Free(origin);
+        } else {
+            printf("Unable to get origin from principal :-(\n");
+        }
+        nsAutoCString loc(EnsureCompartmentPrivate(c)->GetLocation());
+        printf("Global's Location: %s\n", loc.get());
+        MOZ_CRASH();
+    }
     if (aIID.Equals(NS_GET_IID(nsIXPConnectJSObjectHolder))) {
         NS_ADDREF(self);
         *aInstancePtr = (void*) static_cast<nsIXPConnectJSObjectHolder*>(self);
         return NS_OK;
     }
 
     // Objects internal to xpconnect are the only objects that even know *how*
     // to ask for this iid. And none of them bother refcounting the thing.
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -22,40 +22,44 @@ struct ScreenPixel;
 
 typedef gfx::PointTyped<CSSPixel> CSSPoint;
 typedef gfx::IntPointTyped<CSSPixel> CSSIntPoint;
 typedef gfx::SizeTyped<CSSPixel> CSSSize;
 typedef gfx::IntSizeTyped<CSSPixel> CSSIntSize;
 typedef gfx::RectTyped<CSSPixel> CSSRect;
 typedef gfx::IntRectTyped<CSSPixel> CSSIntRect;
 typedef gfx::MarginTyped<CSSPixel> CSSMargin;
+typedef gfx::IntMarginTyped<CSSPixel> CSSIntMargin;
 
 typedef gfx::PointTyped<LayoutDevicePixel> LayoutDevicePoint;
 typedef gfx::IntPointTyped<LayoutDevicePixel> LayoutDeviceIntPoint;
 typedef gfx::SizeTyped<LayoutDevicePixel> LayoutDeviceSize;
 typedef gfx::IntSizeTyped<LayoutDevicePixel> LayoutDeviceIntSize;
 typedef gfx::RectTyped<LayoutDevicePixel> LayoutDeviceRect;
 typedef gfx::IntRectTyped<LayoutDevicePixel> LayoutDeviceIntRect;
 typedef gfx::MarginTyped<LayoutDevicePixel> LayoutDeviceMargin;
+typedef gfx::IntMarginTyped<LayoutDevicePixel> LayoutDeviceIntMargin;
 
 typedef gfx::PointTyped<LayerPixel> LayerPoint;
 typedef gfx::IntPointTyped<LayerPixel> LayerIntPoint;
 typedef gfx::SizeTyped<LayerPixel> LayerSize;
 typedef gfx::IntSizeTyped<LayerPixel> LayerIntSize;
 typedef gfx::RectTyped<LayerPixel> LayerRect;
 typedef gfx::IntRectTyped<LayerPixel> LayerIntRect;
 typedef gfx::MarginTyped<LayerPixel> LayerMargin;
+typedef gfx::IntMarginTyped<LayerPixel> LayerIntMargin;
 
 typedef gfx::PointTyped<ScreenPixel> ScreenPoint;
 typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint;
 typedef gfx::SizeTyped<ScreenPixel> ScreenSize;
 typedef gfx::IntSizeTyped<ScreenPixel> ScreenIntSize;
 typedef gfx::RectTyped<ScreenPixel> ScreenRect;
 typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect;
 typedef gfx::MarginTyped<ScreenPixel> ScreenMargin;
+typedef gfx::IntMarginTyped<ScreenPixel> ScreenIntMargin;
 
 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
 typedef gfx::ScaleFactor<LayerPixel, CSSPixel> LayerToCSSScale;
 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
 typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -673,16 +673,26 @@ static void RecordFrameMetrics(nsIFrame*
 
   if (nsIWidget* widget = aForFrame->GetNearestWidget()) {
     nsIntRect bounds;
     widget->GetBounds(bounds);
     metrics.mCompositionBounds = ScreenIntRect::FromUnknownRect(
       mozilla::gfx::IntRect(bounds.x, bounds.y, bounds.width, bounds.height));
   }
 
+  // Adjust for the size of scroll bars.
+  if (scrollableFrame) {
+    nsMargin sizes = scrollableFrame->GetActualScrollbarSizes();
+    ScreenIntMargin boundMargins(nsPresContext::AppUnitsToIntCSSPixels(sizes.top),
+                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.right),
+                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.bottom),
+                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.left));
+    metrics.mCompositionBounds.Deflate(boundMargins);
+  }
+
   metrics.mPresShellId = presShell->GetPresShellId();
 
   aRoot->SetFrameMetrics(metrics);
 }
 
 nsDisplayListBuilder::~nsDisplayListBuilder() {
   NS_ASSERTION(mFramesMarkedForDisplay.Length() == 0,
                "All frames should have been unmarked");
--- a/layout/generic/ScrollbarActivity.cpp
+++ b/layout/generic/ScrollbarActivity.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ScrollbarActivity.h"
 #include "nsIScrollbarOwner.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMNSEvent.h"
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIFrame.h"
 #include "nsContentUtils.h"
 #include "nsAString.h"
 #include "nsQueryFrame.h"
 #include "nsComponentManagerUtils.h"
 #include "mozilla/LookAndFeel.h"
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -14,17 +14,16 @@
 #include "nsCSSAnonBoxes.h"
 #include "nsGfxScrollFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsRect.h"
 #include "nsRenderingContext.h"
 #include "nsTextFrame.h"
-#include "nsStyleStructInlines.h"
 #include "mozilla/Util.h"
 #include "mozilla/Likely.h"
 
 namespace mozilla {
 namespace css {
 
 class LazyReferenceRenderingContextGetterFromFrame MOZ_FINAL :
     public gfxFontGroup::LazyReferenceContextGetter {
--- a/layout/generic/TextOverflow.h
+++ b/layout/generic/TextOverflow.h
@@ -3,24 +3,23 @@
 /* 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 TextOverflow_h_
 #define TextOverflow_h_
 
 #include "nsDisplayList.h"
-#include "nsLineBox.h"
-#include "nsStyleStruct.h"
 #include "nsTHashtable.h"
 #include "mozilla/Likely.h"
 #include <algorithm>
 
 class nsIScrollableFrame;
 class gfxTextRun;
+class nsLineBox;
 
 namespace mozilla {
 namespace css {
 
 /**
  * A class for rendering CSS3 text-overflow.
  * Usage:
  *  1. allocate an object using WillProcessLines
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -8,22 +8,19 @@
  * object that is a containing block for them
  */
 
 #include "nsAbsoluteContainingBlock.h"
 
 #include "nsContainerFrame.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
-#include "nsHTMLParts.h"
 #include "nsHTMLReflowState.h"
 #include "nsPresContext.h"
-#include "nsFrameManager.h"
 #include "nsCSSFrameConstructor.h"
-#include "nsIDocumentInlines.h"
 
 #ifdef DEBUG
 #include "nsBlockFrame.h"
 
 static void PrettyUC(nscoord aSize, char* aBuf)
 {
   if (NS_UNCONSTRAINEDSIZE == aSize) {
     strcpy(aBuf, "UC");
--- a/layout/generic/nsBRFrame.cpp
+++ b/layout/generic/nsBRFrame.cpp
@@ -2,27 +2,25 @@
 /* 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/. */
 
 /* rendering object for HTML <br> elements */
 
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
-#include "nsHTMLParts.h"
 #include "nsPresContext.h"
 #include "nsLineLayout.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "nsRenderingContext.h"
 #include "nsLayoutUtils.h"
 
 //FOR SELECTION
 #include "nsIContent.h"
-#include "nsFrameSelection.h"
 //END INCLUDES FOR SELECTION
 
 using namespace mozilla;
 
 class BRFrame : public nsFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -5,72 +5,58 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * rendering object for CSS display:block, inline-block, and list-item
  * boxes, also used for various anonymous boxes
  */
 
 #include "mozilla/DebugOnly.h"
-#include "mozilla/Likely.h"
 #include "mozilla/Util.h"
 
 #include "nsCOMPtr.h"
 #include "nsBlockFrame.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "nsBlockReflowContext.h"
 #include "nsBlockReflowState.h"
 #include "nsBulletFrame.h"
 #include "nsLineBox.h"
-#include "nsInlineFrame.h"
 #include "nsLineLayout.h"
 #include "nsPlaceholderFrame.h"
 #include "nsStyleConsts.h"
 #include "nsFrameManager.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsStyleContext.h"
-#include "nsView.h"
 #include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
-#include "nsIDOMEvent.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "prprf.h"
-#include "nsStyleChangeList.h"
-#include "nsFrameSelection.h"
 #include "nsFloatManager.h"
-#include "nsIntervalSet.h"
 #include "prenv.h"
 #include "plstr.h"
-#include "nsGUIEvent.h"
 #include "nsError.h"
 #include "nsAutoPtr.h"
-#include "nsIServiceManager.h"
 #include "nsIScrollableFrame.h"
 #include <algorithm>
 #ifdef ACCESSIBILITY
 #include "nsIDOMHTMLDocument.h"
 #endif
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSFrameConstructor.h"
-#include "nsCSSRendering.h"
-#include "FrameLayerBuilder.h"
 #include "nsRenderingContext.h"
 #include "TextOverflow.h"
-#include "nsStyleStructInlines.h"
 
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
 
-#include "nsIDOMHTMLHtmlElement.h"
-
 static const int MIN_LINES_NEEDING_CURSOR = 20;
 
 static const PRUnichar kDiscCharacter = 0x2022;
 static const PRUnichar kCircleCharacter = 0x25e6;
 static const PRUnichar kSquareCharacter = 0x25aa;
 
 #define DISABLE_FLOAT_BREAKING_IN_COLUMNS
 
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -39,19 +39,17 @@ enum LineReflowStatus {
   // The line did not fit in the available vertical space. Try pushing it to
   // the next page or column if it's not the first line on the current page/column.
   LINE_REFLOW_TRUNCATED
 };
 
 class nsBlockReflowState;
 class nsBlockInFlowLineIterator;
 class nsBulletFrame;
-class nsLineBox;
 class nsFirstLineFrame;
-class nsIntervalSet;
 
 /**
  * Some invariants:
  * -- The overflow out-of-flows list contains the out-of-
  * flow frames whose placeholders are in the overflow list.
  * -- A given piece of content has at most one placeholder
  * frame in a block's normal child list.
  * -- While a block is being reflowed, and from then until
--- a/layout/generic/nsBlockReflowContext.cpp
+++ b/layout/generic/nsBlockReflowContext.cpp
@@ -2,27 +2,21 @@
 // vim:cindent:ts=2:et:sw=2:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* class that a parent frame uses to reflow a block frame */
 
 #include "nsBlockReflowContext.h"
-#include "nsLineLayout.h"
+#include "nsBlockReflowState.h"
 #include "nsFloatManager.h"
-#include "nsPresContext.h"
-#include "nsFrameManager.h"
-#include "nsIContent.h"
-#include "nsStyleContext.h"
 #include "nsContainerFrame.h"
 #include "nsBlockFrame.h"
 #include "nsLineBox.h"
-#include "nsGkAtoms.h"
-#include "nsCOMPtr.h"
 #include "nsLayoutUtils.h"
 
 #ifdef DEBUG
 #undef  NOISY_MAX_ELEMENT_SIZE
 #undef   REALLY_NOISY_MAX_ELEMENT_SIZE
 #undef  NOISY_VERTICAL_MARGINS
 #else
 #undef  NOISY_MAX_ELEMENT_SIZE
--- a/layout/generic/nsBlockReflowContext.h
+++ b/layout/generic/nsBlockReflowContext.h
@@ -11,20 +11,18 @@
 
 #include "nsIFrame.h"
 #include "nsHTMLReflowMetrics.h"
 
 class nsBlockFrame;
 class nsBlockReflowState;
 struct nsHTMLReflowState;
 class nsLineBox;
-class nsIFrame;
 class nsPresContext;
 class nsLineLayout;
-struct nsStylePosition;
 struct nsBlockHorizontalAlign;
 
 /**
  * An encapsulation of the state and algorithm for reflowing block frames.
  */
 class nsBlockReflowContext {
 public:
   nsBlockReflowContext(nsPresContext* aPresContext,
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -1,31 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:cindent:ts=2:et:sw=2:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* state used in reflow of block frames */
 
-#include "nsBlockReflowState.h"
-
 #include "mozilla/DebugOnly.h"
 
-#include "nsBlockReflowContext.h"
 #include "nsBlockFrame.h"
 #include "nsLineLayout.h"
 #include "nsPresContext.h"
-#include "nsGkAtoms.h"
 #include "nsIFrame.h"
-#include "nsFrameManager.h"
 #include "mozilla/AutoRestore.h"
-#include "FrameLayerBuilder.h"
-
-#include "nsINameSpaceManager.h"
 #include <algorithm>
 
 #ifdef DEBUG
 #include "nsBlockDebugFlags.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::layout;
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -5,20 +5,20 @@
 
 /* state used in reflow of block frames */
 
 #ifndef nsBlockReflowState_h__
 #define nsBlockReflowState_h__
 
 #include "nsFloatManager.h"
 #include "nsLineBox.h"
-#include "nsFrameList.h"
 #include "nsHTMLReflowState.h"
 
 class nsBlockFrame;
+class nsFrameList;
 class nsOverflowContinuationTracker;
 
   // block reflow state flags
 #define BRS_UNCONSTRAINEDHEIGHT   0x00000001
 #define BRS_ISTOPMARGINROOT       0x00000002  // Is this frame a root for top/bottom margin collapsing?
 #define BRS_ISBOTTOMMARGINROOT    0x00000004
 #define BRS_APPLYTOPMARGIN        0x00000008  // See ShouldApplyTopMargin
 #define BRS_ISFIRSTINFLOW         0x00000010
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -3,37 +3,29 @@
  * 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/. */
 
 /* rendering object for list-item bullets */
 
 #include "nsCOMPtr.h"
 #include "nsBulletFrame.h"
 #include "nsGkAtoms.h"
-#include "nsHTMLParts.h"
-#include "nsContainerFrame.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsRenderingContext.h"
-#include "nsILoadGroup.h"
-#include "nsIURL.h"
-#include "nsNetUtil.h"
 #include "prprf.h"
 #include "nsDisplayList.h"
 #include "nsCounterManager.h"
 
-#include "imgILoader.h"
 #include "imgIContainer.h"
 #include "imgRequestProxy.h"
 
-#include "nsIServiceManager.h"
-#include "nsIComponentManager.h"
 #include <algorithm>
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -5,19 +5,17 @@
 
 /* rendering object for list-item bullets */
 
 #ifndef nsBulletFrame_h___
 #define nsBulletFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsFrame.h"
-#include "nsStyleContext.h"
 
-#include "imgIRequest.h"
 #include "imgINotificationObserver.h"
 
 class imgIContainer;
 class imgRequestProxy;
 
 #define BULLET_FRAME_IMAGE_LOADING NS_FRAME_STATE_BIT(63)
 #define BULLET_FRAME_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(62)
 
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -1,36 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object that goes directly inside the document's scrollbars */
 
 #include "nsCanvasFrame.h"
-#include "nsIServiceManager.h"
-#include "nsHTMLParts.h"
 #include "nsContainerFrame.h"
 #include "nsCSSRendering.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsRenderingContext.h"
-#include "nsGUIEvent.h"
-#include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
-#include "nsEventStateManager.h"
 #include "nsIPresShell.h"
-#include "nsIScrollPositionListener.h"
 #include "nsDisplayList.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsFrameManager.h"
 
 // for focus
 #include "nsIScrollableFrame.h"
+#ifdef DEBUG_CANVAS_FOCUS
 #include "nsIDocShell.h"
+#endif
 
 //#define DEBUG_CANVAS_FOCUS
 
 using namespace mozilla::layout;
 
 nsIFrame*
 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -7,17 +7,16 @@
 
 #ifndef nsCanvasFrame_h___
 #define nsCanvasFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIScrollPositionListener.h"
 #include "nsDisplayList.h"
-#include "nsGkAtoms.h"
 
 class nsPresContext;
 class nsRenderingContext;
 class nsEvent;
 
 /**
  * Root frame class.
  *
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for css3 multi-column layout */
 
 #include "nsColumnSetFrame.h"
+#include "nsCSSRendering.h"
+#include "nsDisplayList.h"
 
 using namespace mozilla;
 using namespace mozilla::layout;
 
 /**
  * Tracking issues:
  *
  * XXX cursor movement around the top and bottom of colums seems to make the editor
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -2,29 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for css3 multi-column layout */
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
-#include "nsIContent.h"
-#include "nsIFrame.h"
-#include "nsISupports.h"
-#include "nsIAtom.h"
-#include "nsPresContext.h"
-#include "nsHTMLParts.h"
-#include "nsGkAtoms.h"
-#include "nsStyleConsts.h"
-#include "nsCOMPtr.h"
-#include "nsLayoutUtils.h"
-#include "nsDisplayList.h"
-#include "nsCSSRendering.h"
-#include <algorithm>
 
 class nsColumnSetFrame : public nsContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsColumnSetFrame(nsStyleContext* aContext);
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -3,47 +3,36 @@
  * 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/. */
 
 /* base class #1 for rendering objects that have child lists */
 
 #include "nsContainerFrame.h"
 
 #include "nsAbsoluteContainingBlock.h"
-#include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsRect.h"
 #include "nsPoint.h"
-#include "nsGUIEvent.h"
 #include "nsStyleConsts.h"
 #include "nsView.h"
-#include "nsFrameManager.h"
 #include "nsIPresShell.h"
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
-#include "nsCSSAnonBoxes.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
-#include "nsGfxCIID.h"
-#include "nsIServiceManager.h"
 #include "nsCSSRendering.h"
-#include "nsTransform2D.h"
-#include "nsRegion.h"
 #include "nsError.h"
 #include "nsDisplayList.h"
-#include "nsListControlFrame.h"
 #include "nsIBaseWindow.h"
-#include "nsThemeConstants.h"
 #include "nsBoxLayoutState.h"
-#include "nsRenderingContext.h"
 #include "nsCSSFrameConstructor.h"
+#include "nsBlockFrame.h"
 #include "mozilla/AutoRestore.h"
-#include "mozilla/dom/Element.h"
 #include <algorithm>
 
 #ifdef DEBUG
 #undef NOISY
 #else
 #undef NOISY
 #endif
 
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS :first-letter pseudo-element */
 
-#include "nsCOMPtr.h"
 #include "nsFirstLetterFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsIContent.h"
 #include "nsLineLayout.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyleSet.h"
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -988,17 +988,16 @@ private:
   nscoord  mPackingSpaceRemaining;
   uint32_t mNumAutoMarginsInMainAxis;
   uint32_t mNumPackingSpacesRemaining;
   uint8_t  mJustifyContent;
 };
 
 // Utility class for managing our position along the cross axis along
 // the whole flex container (at a higher level than a single line)
-class SingleLineCrossAxisPositionTracker;
 class MOZ_STACK_CLASS CrossAxisPositionTracker : public PositionTracker {
 public:
   CrossAxisPositionTracker(nsFlexContainerFrame* aFlexContainerFrame,
                            const FlexboxAxisTracker& aAxisTracker,
                            const nsHTMLReflowState& aReflowState);
 
   // XXXdholbert This probably needs a ResolveStretchedLines() method,
   // (which takes an array of SingleLineCrossAxisPositionTracker objects
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -6,28 +6,27 @@
  * http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS "display: flex" */
 
 #ifndef nsFlexContainerFrame_h___
 #define nsFlexContainerFrame_h___
 
 #include "nsContainerFrame.h"
-#include "nsTArray.h"
-#include "mozilla/Types.h"
 
 nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
                                    nsStyleContext* aContext);
 
 typedef nsContainerFrame nsFlexContainerFrameSuper;
 
 class FlexItem;
 class FlexboxAxisTracker;
 class MainAxisPositionTracker;
 class SingleLineCrossAxisPositionTracker;
+template <class T> class nsTArray;
 
 class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
   NS_DECL_FRAMEARENA_HELPERS
   NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
   NS_DECL_QUERYFRAME
 
   // Factory method:
   friend nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -2,18 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
 
 #include "nsFontInflationData.h"
 #include "FramePropertyTable.h"
-#include "nsTextFragment.h"
-#include "nsIFormControlFrame.h"
 #include "nsTextControlFrame.h"
 #include "nsListControlFrame.h"
 #include "nsComboboxControlFrame.h"
 #include "nsHTMLReflowState.h"
 #include "nsTextFrameUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::layout;
--- a/layout/generic/nsFontInflationData.h
+++ b/layout/generic/nsFontInflationData.h
@@ -4,18 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
 
 #ifndef nsFontInflationData_h_
 #define nsFontInflationData_h_
 
 #include "nsIFrame.h"
-#include "nsLayoutUtils.h"
-#include "nsBlockFrame.h"
 
 struct nsHTMLReflowState;
 
 class nsFontInflationData
 {
 public:
 
   static nsFontInflationData* FindFontInflationDataFor(const nsIFrame *aFrame);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -8,95 +8,77 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsFrameList.h"
 #include "nsPlaceholderFrame.h"
-#include "nsLineLayout.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsStyleContext.h"
 #include "nsTableOuterFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsPresContext.h"
-#include "nsCRT.h"
 #include "nsGUIEvent.h"
-#include "nsIDOMEvent.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsStyleConsts.h"
 #include "nsIPresShell.h"
 #include "prlog.h"
 #include "prprf.h"
 #include <stdarg.h>
 #include "nsFrameManager.h"
-#include "nsCSSRendering.h"
 #include "nsLayoutUtils.h"
 
 #include "nsIDOMNode.h"
 #include "nsEventStateManager.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsFrameSelection.h"
-#include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
 #include "nsCSSAnonBoxes.h"
-#include "nsCSSPseudoElements.h"
-#include "nsCSSFrameConstructor.h"
 
 #include "nsFrameTraversal.h"
-#include "nsStyleChangeList.h"
-#include "nsIDOMRange.h"
 #include "nsRange.h"
-#include "nsITableCellLayout.h"//  "
 #include "nsITextControlFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPercentHeightObserver.h"
 #include "nsStyleStructInlines.h"
 #include <algorithm>
 
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif
 
 // For triple-click pref
-#include "nsIServiceManager.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
-#include "nsLayoutCID.h"
-#include "nsUnicharUtils.h"
 #include "nsError.h"
 #include "nsContainerFrame.h"
 #include "nsBoxLayoutState.h"
 #include "nsBlockFrame.h"
 #include "nsDisplayList.h"
-#include "nsIObjectLoadingContent.h"
 #include "nsExpirationTracker.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGEffects.h"
 #include "nsChangeHint.h"
 #include "nsDeckFrame.h"
-#include "nsTableFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGTextFrame2.h"
 
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
-#include "CSSCalc.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "nsFontInflationData.h"
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/css/ImageLoader.h"
 #include "mozilla/gfx/Tools.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -7,24 +7,22 @@
 
 #ifndef nsFrame_h___
 #define nsFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
 #include "nsBox.h"
 #include "nsRect.h"
-#include "nsString.h"
 #include "prlog.h"
 
 #include "nsIPresShell.h"
-#include "nsFrameSelection.h"
 #include "nsHTMLReflowState.h"
-#include "nsHTMLReflowMetrics.h"
 #include "nsHTMLParts.h"
+#include "nsISelectionDisplay.h"
 
 /**
  * nsFrame logging constants. We redefine the nspr
  * PRLogModuleInfo.level field to be a bitfield.  Each bit controls a
  * specific type of logging. Each logging operation has associated
  * inline methods defined below.
  */
 #define NS_FRAME_TRACE_CALLS        0x1
--- a/layout/generic/nsFrameList.cpp
+++ b/layout/generic/nsFrameList.cpp
@@ -5,17 +5,16 @@
 
 #include "nsFrameList.h"
 #include "nsIFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 
 #ifdef IBMBIDI
-#include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 #include "nsILineIterator.h"
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
 
 namespace mozilla {
 namespace layout {
 namespace detail {
--- a/layout/generic/nsFrameList.h
+++ b/layout/generic/nsFrameList.h
@@ -1,25 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsFrameList_h___
 #define nsFrameList_h___
 
-#include "nscore.h"
-#include "nsTraceRefcnt.h"
 #include <stdio.h> /* for FILE* */
 #include "nsDebug.h"
-#include "nsTArray.h"
 
 class nsIFrame;
 class nsIPresShell;
 class nsPresContext;
+template <class T> class nsTArray;
 
 namespace mozilla {
 namespace layout {
   class FrameChildList;
   enum FrameChildListID {
       // The individual concrete child lists.
       kPrincipalList                = 0x1,
       kPopupList                    = 0x2,
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -3,40 +3,29 @@
  * 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/. */
 
 /* rendering object for HTML <frameset> elements */
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Likely.h"
 
-#include "nsCOMPtr.h"
 #include "nsFrameSetFrame.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsLeafFrame.h"
 #include "nsContainerFrame.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsIComponentManager.h"
-#include "nsIStreamListener.h"
-#include "nsIURL.h"
-#include "nsIDocument.h"
-#include "nsINodeInfo.h"
-#include "nsView.h"
-#include "nsViewManager.h"
-#include "nsWidgetsCID.h"
 #include "nsGkAtoms.h"
-#include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
 #include "nsStyleContext.h"
 #include "nsHTMLParts.h"
 #include "nsGUIEvent.h"
 #include "nsRenderingContext.h"
-#include "nsIServiceManager.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsINameSpaceManager.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsAutoPtr.h"
 #include "nsStyleSet.h"
 #include "mozilla/dom/Element.h"
 #include "nsDisplayList.h"
 #include "nsNodeUtils.h"
--- a/layout/generic/nsFrameSetFrame.h
+++ b/layout/generic/nsFrameSetFrame.h
@@ -4,26 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for HTML <frameset> elements */
 
 #ifndef nsHTMLFrameset_h___
 #define nsHTMLFrameset_h___
 
 #include "mozilla/Attributes.h"
-#include "nsGkAtoms.h"
 #include "nsContainerFrame.h"
 #include "nsColor.h"
-#include "nsIObserver.h"
-#include "nsWeakPtr.h"
 
 class  nsIContent;
-class  nsIFrame;
 class  nsPresContext;
-class  nsRenderingContext;
 struct nsRect;
 struct nsHTMLReflowState;
 struct nsSize;
 class  nsIAtom;
 class  nsHTMLFramesetBorderFrame;
 class  nsGUIEvent;
 class  nsHTMLFramesetFrame;
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2,65 +2,57 @@
 /* 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/. */
 
 /* rendering object to wrap rendering objects that should be scrollable */
 
 #include "base/compiler_specific.h"
 #include "nsCOMPtr.h"
-#include "nsHTMLParts.h"
 #include "nsPresContext.h"
-#include "nsIServiceManager.h"
 #include "nsView.h"
 #include "nsIScrollable.h"
-#include "nsViewManager.h"
 #include "nsContainerFrame.h"
 #include "nsGfxScrollFrame.h"
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 #include "nsContentList.h"
 #include "nsIDocumentInlines.h"
 #include "nsFontMetrics.h"
-#include "nsIDocumentObserver.h"
 #include "nsBoxLayoutState.h"
 #include "nsINodeInfo.h"
 #include "nsScrollbarFrame.h"
 #include "nsIScrollbarMediator.h"
 #include "nsITextControlFrame.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsNodeInfoManager.h"
-#include "nsIURI.h"
 #include "nsGUIEvent.h"
 #include "nsContentCreatorFunctions.h"
-#include "nsISupportsPrimitives.h"
 #include "nsAutoPtr.h"
 #include "nsPresState.h"
-#include "nsDocShellCID.h"
 #include "nsIHTMLDocument.h"
 #include "nsEventDispatcher.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsBidiUtils.h"
-#include "nsFrameManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/dom/Element.h"
 #include <stdint.h>
-#include "mozilla/Util.h"
 #include "mozilla/MathAlgorithms.h"
 #include "FrameLayerBuilder.h"
 #include "nsSMILKeySpline.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "mozilla/Attributes.h"
 #include "ScrollbarActivity.h"
 #include "nsRefreshDriver.h"
-#include "nsContentList.h"
 #include "nsThemeConstants.h"
+#include "nsSVGIntegrationUtils.h"
+#include "nsIScrollPositionListener.h"
 #include <algorithm>
 #include <cstdlib> // for std::abs(int/long)
 #include <cmath> // for std::abs(float/double)
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -7,35 +7,31 @@
 
 #ifndef nsGfxScrollFrame_h___
 #define nsGfxScrollFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsBoxFrame.h"
-#include "nsDisplayList.h"
 #include "nsIScrollableFrame.h"
-#include "nsIScrollPositionListener.h"
 #include "nsIStatefulFrame.h"
 #include "nsThreadUtils.h"
 #include "nsIReflowCallback.h"
 #include "nsBoxLayoutState.h"
 #include "nsQueryFrame.h"
-#include "nsCOMArray.h"
-#include "nsSVGIntegrationUtils.h"
 #include "nsExpirationTracker.h"
 
 class nsPresContext;
 class nsIPresShell;
 class nsIContent;
 class nsIAtom;
-class nsIDocument;
 class nsIScrollFrameInternal;
 class nsPresState;
+class nsIScrollPositionListener;
 struct ScrollReflowState;
 
 namespace mozilla {
 namespace layout {
 class ScrollbarActivity;
 }
 }
 
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -1,29 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for the HTML <canvas> element */
 
-#include "nsHTMLParts.h"
-#include "nsCOMPtr.h"
-#include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
-
 #include "nsHTMLCanvasFrame.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsDisplayList.h"
 #include "nsLayoutUtils.h"
 #include "Layers.h"
 
-#include "nsTransform2D.h"
-
-#include "gfxContext.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 class nsDisplayCanvas : public nsDisplayItem {
 public:
--- a/layout/generic/nsHTMLCanvasFrame.h
+++ b/layout/generic/nsHTMLCanvasFrame.h
@@ -5,30 +5,28 @@
 
 /* rendering object for the HTML <canvas> element */
 
 #ifndef nsHTMLCanvasFrame_h___
 #define nsHTMLCanvasFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
-#include "nsString.h"
-#include "nsAString.h"
-#include "nsIIOService.h"
 #include "FrameLayerBuilder.h"
 
 namespace mozilla {
 namespace layers {
 class Layer;
 class LayerManager;
 }
 }
 
 class nsPresContext;
 class nsDisplayItem;
+class nsAString;
 
 nsIFrame* NS_NewHTMLCanvasFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 class nsHTMLCanvasFrame : public nsContainerFrame
 {
 public:
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
--- a/layout/generic/nsHTMLReflowMetrics.h
+++ b/layout/generic/nsHTMLReflowMetrics.h
@@ -3,19 +3,16 @@
  * 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/. */
 
 /* struct containing the output from nsIFrame::Reflow */
 
 #ifndef nsHTMLReflowMetrics_h___
 #define nsHTMLReflowMetrics_h___
 
-#include <stdio.h>
-#include "nsISupports.h"
-#include "nsMargin.h"
 #include "nsRect.h"
 #include "nsBoundingMetrics.h"
 
 //----------------------------------------------------------------------
 
 // Option flags
 #define NS_REFLOW_CALC_BOUNDING_METRICS  0x0001
 
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1,35 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* struct containing the input to nsIFrame::Reflow */
 
-#include "nsCOMPtr.h"
 #include "nsStyleConsts.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsFrame.h"
 #include "nsIContent.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsFontMetrics.h"
 #include "nsBlockFrame.h"
 #include "nsLineBox.h"
 #include "nsFlexContainerFrame.h"
 #include "nsImageFrame.h"
 #include "nsTableFrame.h"
 #include "nsTableCellFrame.h"
-#include "nsIServiceManager.h"
 #include "nsIPercentHeightObserver.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/Preferences.h"
-#include "nsBidiUtils.h"
 #include "nsFontInflationData.h"
 #include <algorithm>
 
 #ifdef DEBUG
 #undef NOISY_VERTICAL_ALIGN
 #else
 #undef NOISY_VERTICAL_ALIGN
 #endif
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -15,24 +15,16 @@
 #include "mozilla/Assertions.h"
 #include <algorithm>
 
 class nsPresContext;
 class nsRenderingContext;
 class nsFloatManager;
 class nsLineLayout;
 class nsIPercentHeightObserver;
-
-struct nsStyleDisplay;
-struct nsStyleVisibility;
-struct nsStylePosition;
-struct nsStyleBorder;
-struct nsStyleMargin;
-struct nsStylePadding;
-struct nsStyleText;
 struct nsHypotheticalBox;
 
 
 /**
  * @return aValue clamped to [aMinValue, aMaxValue].
  *
  * @note This function needs to handle aMinValue > aMaxValue. In that case,
  *       aMinValue is returned.
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2,69 +2,56 @@
 /* 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/. */
 
 /* rendering object for replaced elements with bitmap image data */
 
 #include "mozilla/DebugOnly.h"
 
-#include "nsHTMLParts.h"
 #include "nsCOMPtr.h"
 #include "nsImageFrame.h"
 #include "nsIImageLoadingContent.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
-#include "nsINodeInfo.h"
 #include "nsContentUtils.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsStyleCoord.h"
 #include "nsTransform2D.h"
 #include "nsImageMap.h"
-#include "nsILinkHandler.h"
-#include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsILoadGroup.h"
 #include "nsISupportsPriority.h"
-#include "nsIServiceManager.h"
 #include "nsNetUtil.h"
-#include "nsContainerFrame.h"
-#include "prprf.h"
 #include "nsCSSRendering.h"
 #include "nsIDOMHTMLAnchorElement.h"
-#include "nsIDOMHTMLImageElement.h"
 #include "nsINameSpaceManager.h"
-#include "nsTextFragment.h"
-#include "nsIDOMHTMLMapElement.h"
-#include "nsIScriptSecurityManager.h"
 #include <algorithm>
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsIDOMNode.h"
 #include "nsGUIEvent.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 
 #include "imgIContainer.h"
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
 
 #include "nsCSSFrameConstructor.h"
 #include "nsIDOMRange.h"
 
-#include "nsIContentPolicy.h"
-#include "nsContentPolicyUtils.h"
 #include "nsEventStates.h"
 #include "nsError.h"
 #include "nsBidiUtils.h"
 #include "nsBidiPresUtils.h"
 
 #include "gfxRect.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -13,29 +13,26 @@
 #include "nsIObserver.h"
 
 #include "imgINotificationObserver.h"
 
 #include "nsDisplayList.h"
 #include "imgIContainer.h"
 #include "mozilla/Attributes.h"
 
-class nsIFrame;
 class nsImageMap;
 class nsIURI;
 class nsILoadGroup;
 struct nsHTMLReflowState;
 struct nsHTMLReflowMetrics;
-struct nsSize;
 class nsDisplayImage;
 class nsPresContext;
 class nsImageFrame;
 class nsTransform2D;
 class nsImageLoadingContent;
-class imgRequestProxy;
 
 namespace mozilla {
 namespace layers {
   class ImageContainer;
   class ImageLayer;
   class LayerManager;
 }
 }
--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -7,28 +7,21 @@
 
 #include "nsImageMap.h"
 
 #include "nsString.h"
 #include "nsDOMEvent.h"
 #include "nsReadableUtils.h"
 #include "nsRenderingContext.h"
 #include "nsPresContext.h"
-#include "nsIURL.h"
-#include "nsIServiceManager.h"
-#include "nsNetUtil.h"
-#include "nsTextFragment.h"
 #include "mozilla/dom/Element.h"
-#include "nsIDocument.h"
 #include "nsINameSpaceManager.h"
 #include "nsGkAtoms.h"
-#include "nsIPresShell.h"
 #include "nsImageFrame.h"
 #include "nsCoord.h"
-#include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 #include "nsIStringBundle.h"
 #include "nsContentUtils.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
--- a/layout/generic/nsImageMap.h
+++ b/layout/generic/nsImageMap.h
@@ -3,27 +3,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/. */
 
 /* code for HTML client-side image maps */
 
 #ifndef nsImageMap_h
 #define nsImageMap_h
 
-#include "nsISupports.h"
+#include "nsCOMPtr.h"
 #include "nsCoord.h"
 #include "nsTArray.h"
 #include "nsStubMutationObserver.h"
 #include "nsIDOMEventListener.h"
-#include "nsIFrame.h"
+#include "nsRect.h"
 
 class Area;
-class nsIDOMEvent;
 class nsRenderingContext;
 class nsImageFrame;
+class nsIFrame;
+class nsIContent;
 
 class nsImageMap : public nsStubMutationObserver,
                    public nsIDOMEventListener
 {
 public:
   nsImageMap();
 
   nsresult Init(nsImageFrame* aImageFrame, nsIContent* aMap);
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1,24 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS display:inline objects */
 
 #include "nsInlineFrame.h"
-#include "nsCOMPtr.h"
 #include "nsLineLayout.h"
 #include "nsBlockFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsGkAtoms.h"
-#include "nsHTMLParts.h"
 #include "nsStyleContext.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsAutoPtr.h"
 #include "RestyleManager.h"
 #include "nsDisplayList.h"
 #include "mozilla/Likely.h"
 
--- a/layout/generic/nsIntervalSet.cpp
+++ b/layout/generic/nsIntervalSet.cpp
@@ -2,17 +2,16 @@
 // vim:cindent:ts=8:et:sw=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/. */
 
 /* a set of ranges on a number-line */
 
 #include "nsIntervalSet.h"
-#include "nsAlgorithm.h"
 #include <new>
 #include <algorithm>
 
 nsIntervalSet::nsIntervalSet(IntervalSetAlloc aAlloc, IntervalSetFree aFree,
                              void* aAllocatorClosure)
     : mList(nullptr),
       mAlloc(aAlloc),
       mFree(aFree),
--- a/layout/generic/nsIntervalSet.h
+++ b/layout/generic/nsIntervalSet.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* a set of ranges on a number-line */
 
 #ifndef nsIntervalSet_h___
 #define nsIntervalSet_h___
 
 #include "nsCoord.h"
-#include "nsDebug.h"
 
 typedef void *
 (* IntervalSetAlloc)(size_t aBytes, void *aClosure);
 
 typedef void
 (* IntervalSetFree) (size_t aBytes, void *aPtr, void *aClosure);
 
 /*
--- a/layout/generic/nsLeafFrame.cpp
+++ b/layout/generic/nsLeafFrame.cpp
@@ -1,19 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* base class for rendering objects that do not have child lists */
 
-#include "nsCOMPtr.h"
 #include "nsLeafFrame.h"
-#include "nsContainerFrame.h"
-#include "nsHTMLParts.h"
 #include "nsPresContext.h"
 
 nsLeafFrame::~nsLeafFrame()
 {
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsLeafFrame)
 
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -2,25 +2,22 @@
 // vim:cindent:ts=2:et:sw=2:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* representation of one line within a block frame, a CSS line box */
 
 #include "nsLineBox.h"
-#include "nsLineLayout.h"
 #include "prprf.h"
-#include "nsBlockFrame.h"
-#include "nsIFrame.h"
+#include "nsFrame.h"
 #include "nsPresArena.h"
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif
-#include "nsStyleStructInlines.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Likely.h"
 
 #ifdef DEBUG
 static int32_t ctorCount;
 int32_t nsLineBox::GetCtorCount() { return ctorCount; }
 #endif
 
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -4,34 +4,28 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* state and methods used while laying out a single line of a block frame */
 
 #define PL_ARENA_CONST_ALIGN_MASK (sizeof(void*)-1)
 #include "plarena.h"
 
 #include "mozilla/Util.h"
-#include "nsCOMPtr.h"
 #include "nsLineLayout.h"
 #include "nsBlockFrame.h"
-#include "nsInlineFrame.h"
 #include "nsStyleConsts.h"
 #include "nsContainerFrame.h"
 #include "nsFloatManager.h"
 #include "nsStyleContext.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
-#include "nsPlaceholderFrame.h"
 #include "nsIContent.h"
-#include "nsTextFragment.h"
-#include "nsBidiUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsTextFrame.h"
-#include "nsCSSRendering.h"
 #include <algorithm>
 
 #ifdef DEBUG
 #undef  NOISY_HORIZONTAL_ALIGN
 #undef  NOISY_VERTICAL_ALIGN
 #undef  REALLY_NOISY_VERTICAL_ALIGN
 #undef  NOISY_REFLOW
 #undef  REALLY_NOISY_REFLOW
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -12,27 +12,22 @@
  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
  */
 
 /* state and methods used while laying out a single line of a block frame */
 
 #ifndef nsLineLayout_h___
 #define nsLineLayout_h___
 
-#include "nsFrame.h"
-#include "nsDeque.h"
 #include "nsLineBox.h"
 #include "nsBlockReflowState.h"
 #include "plarena.h"
 #include "gfxTypes.h"
 
-class nsBlockFrame;
-
 class nsFloatManager;
-class nsPlaceholderFrame;
 struct nsStyleText;
 
 class nsLineLayout {
 public:
   nsLineLayout(nsPresContext* aPresContext,
                nsFloatManager* aFloatManager,
                const nsHTMLReflowState* aOuterReflowState,
                const nsLineList::iterator* aLine);
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1,137 +1,81 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set ts=2 sts=2 sw=2 et cin:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering objects for replaced elements implemented by a plugin */
 
+#ifdef XP_WIN
+// This is needed for DoublePassRenderingEvent.
 #include "mozilla/plugins/PluginMessageUtils.h"
+#endif
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsWidgetsCID.h"
 #include "nsView.h"
 #include "nsViewManager.h"
-#include "nsIDOMEventListener.h"
-#include "nsIDOMDragEvent.h"
-#include "nsPluginHost.h"
 #include "nsString.h"
-#include "nsReadableUtils.h"
 #include "nsGkAtoms.h"
-#include "nsIAppShell.h"
-#include "nsIDocument.h"
-#include "nsINodeInfo.h"
-#include "nsIURL.h"
-#include "nsNetUtil.h"
 #include "nsIPluginInstanceOwner.h"
 #include "nsNPAPIPluginInstance.h"
-#include "nsIPluginTagInfo.h"
-#include "plstr.h"
-#include "nsILinkHandler.h"
-#include "nsIScrollPositionListener.h"
-#include "nsITimer.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsDocShellCID.h"
-#include "nsIWebBrowserChrome.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMNodeList.h"
-#include "nsIDOMHTMLObjectElement.h"
-#include "nsIDOMHTMLEmbedElement.h"
-#include "nsIDOMHTMLAppletElement.h"
-#include "nsIDOMWindow.h"
-#include "nsIDocumentEncoder.h"
-#include "nsXPIDLString.h"
-#include "nsIDOMRange.h"
-#include "nsIPluginWidget.h"
 #include "nsGUIEvent.h"
 #include "nsRenderingContext.h"
 #include "npapi.h"
-#include "nsTransform2D.h"
-#include "nsIImageLoadingContent.h"
 #include "nsIObjectLoadingContent.h"
-#include "nsPIDOMWindow.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
-#include "nsAttrName.h"
-#include "nsDataHashtable.h"
-#include "nsDOMClassInfo.h"
 #include "nsFocusManager.h"
 #include "nsLayoutUtils.h"
 #include "nsFrameManager.h"
-#include "nsComponentManagerUtils.h"
 #include "nsIObserverService.h"
-#include "nsIScrollableFrame.h"
-#include "mozilla/Preferences.h"
 #include "GeckoProfiler.h"
 #include <algorithm>
 
-// headers for plugin scriptability
-#include "nsIScriptGlobalObject.h"
-#include "nsIScriptContext.h"
-#include "nsIXPConnect.h"
-#include "nsIXPCScriptable.h"
-#include "nsIClassInfo.h"
-#include "nsIDOMClientRect.h"
-
 #include "nsObjectFrame.h"
 #include "nsIObjectFrame.h"
 #include "nsPluginNativeWindow.h"
-#include "nsIPluginDocument.h"
 #include "FrameLayerBuilder.h"
 
-#include "nsThreadUtils.h"
-
-#include "gfxContext.h"
-#include "gfxPlatform.h"
 #include "ImageLayers.h"
+#include "nsPluginInstanceOwner.h"
 
 #ifdef XP_WIN
 #include "gfxWindowsNativeDrawing.h"
 #include "gfxWindowsSurface.h"
 #endif
 
-#include "gfxImageSurface.h"
-#include "gfxUtils.h"
 #include "Layers.h"
 #include "ReadbackLayer.h"
+#include "ImageContainer.h"
 
 // accessibility support
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG 1 /* Allow logging in the release build */
 #endif /* MOZ_LOGGING */
 #include "prlog.h"
 
-#include <errno.h>
-
-#include "nsContentCID.h"
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef XP_MACOSX
 #include "gfxQuartzNativeDrawing.h"
 #include "nsPluginUtilsOSX.h"
 #include "mozilla/gfx/QuartzSupport.h"
 #endif
 
-#if defined(MOZ_WIDGET_GTK)
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-#include "gfxXlibNativeRenderer.h"
-#endif
-
 #ifdef MOZ_X11
 #include "mozilla/X11Util.h"
 using mozilla::DefaultXDisplay;
 #endif
 
 #ifdef XP_WIN
 #include <wtypes.h>
 #include <winuser.h>
--- a/layout/generic/nsObjectFrame.h
+++ b/layout/generic/nsObjectFrame.h
@@ -4,29 +4,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering objects for replaced elements implemented by a plugin */
 
 #ifndef nsObjectFrame_h___
 #define nsObjectFrame_h___
 
 #include "mozilla/Attributes.h"
-#include "nsPluginInstanceOwner.h"
 #include "nsIObjectFrame.h"
 #include "nsFrame.h"
 #include "nsRegion.h"
 #include "nsDisplayList.h"
 #include "nsIReflowCallback.h"
 
-class nsPluginHost;
+#ifdef XP_WIN
+#include <windows.h> // For HWND :(
+#endif
+
 class nsPresContext;
 class nsRootPresContext;
 class nsDisplayPlugin;
 class nsIOSurface;
 class PluginBackgroundSink;
+class nsPluginInstanceOwner;
 
 namespace mozilla {
 namespace layers {
 class ImageContainer;
 class Layer;
 class LayerManager;
 }
 }
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -1,25 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsPageContentFrame.h"
-#include "nsPageFrame.h"
-#include "nsPlaceholderFrame.h"
 #include "nsCSSFrameConstructor.h"
-#include "nsContainerFrame.h"
-#include "nsHTMLParts.h"
-#include "nsIContent.h"
 #include "nsPresContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
-#include "nsReadableUtils.h"
 #include "nsSimplePageSequence.h"
-#include "nsDisplayList.h"
 
 nsIFrame*
 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsPageContentFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageContentFrame)
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -1,32 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsPageFrame.h"
 #include "nsPresContext.h"
-#include "nsStyleContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
-#include "nsCSSFrameConstructor.h"
-#include "nsReadableUtils.h"
 #include "nsPageContentFrame.h"
 #include "nsDisplayList.h"
 #include "nsLayoutUtils.h" // for function BinarySearchForPosition
-#include "nsCSSRendering.h"
 #include "nsSimplePageSequence.h" // for nsSharedPageData
 #include "nsTextFormatter.h" // for page number localization formatting
 #ifdef IBMBIDI
 #include "nsBidiUtils.h"
 #endif
 #include "nsIPrintSettings.h"
-#include "nsRegion.h"
 
 #include "prlog.h"
 #ifdef PR_LOGGING 
 extern PRLogModuleInfo *GetLayoutPrintingLog();
 #define PR_PL(_p1)  PR_LOG(GetLayoutPrintingLog(), PR_LOG_DEBUG, _p1)
 #else
 #define PR_PL(_p1)
 #endif
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -8,46 +8,38 @@
  * Implementation of selection: nsISelection,nsISelectionPrivate and nsFrameSelection
  */
 
 #include "mozilla/Selection.h"
 
 #include "mozilla/Attributes.h"
 
 #include "nsCOMPtr.h"
-#include "nsWeakReference.h"
-#include "nsIFactory.h"
 #include "nsString.h"
-#include "nsReadableUtils.h"
 #include "nsFrameSelection.h"
 #include "nsISelectionListener.h"
-#include "nsIComponentManager.h"
 #include "nsContentCID.h"
 #include "nsIContent.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsRange.h"
 #include "nsCOMArray.h"
 #include "nsGUIEvent.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsITableCellLayout.h"
-#include "nsIDOMNodeList.h"
 #include "nsTArray.h"
 #include "nsTableOuterFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentIterator.h"
 #include "nsIDocumentEncoder.h"
 #include "nsTextFragment.h"
 #include <algorithm>
 
 // for IBMBIDI
-#include "nsFrameTraversal.h"
-#include "nsILineIterator.h"
 #include "nsGkAtoms.h"
 #include "nsIFrameTraversal.h"
 #include "nsLayoutUtils.h"
 #include "nsLayoutCID.h"
 #include "nsBidiPresUtils.h"
 static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
 #include "nsTextFrame.h"
 
@@ -60,17 +52,16 @@ static NS_DEFINE_CID(kFrameTraversalCID,
 
 //included for desired x position;
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsCaret.h"
 
 
 #include "nsITimer.h"
-#include "nsIServiceManager.h"
 #include "nsFrameManager.h"
 // notifications
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 
 #include "nsISelectionController.h"//for the enums
 #include "nsAutoCopyListener.h"
 #include "nsCopySupport.h"
@@ -84,20 +75,16 @@ static NS_DEFINE_CID(kFrameTraversalCID,
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 
 //#define DEBUG_TABLE 1
 
 static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
 
-//PROTOTYPES
-class nsFrameSelection;
-class nsAutoScrollTimer;
-
 static bool IsValidSelectionPoint(nsFrameSelection *aFrameSel, nsINode *aNode);
 
 static nsIAtom *GetTag(nsINode *aNode);
 // returns the parent
 static nsINode* ParentOffset(nsINode *aNode, int32_t *aChildOffset);
 static nsINode* GetCellParent(nsINode *aDomNode);
 
 #ifdef PRINT_RANGE
--- a/layout/generic/nsSimplePageSequence.cpp
+++ b/layout/generic/nsSimplePageSequence.cpp
@@ -1,43 +1,40 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "nsCOMPtr.h" 
-#include "nsReadableUtils.h"
+#include "nsCOMPtr.h"
 #include "nsSimplePageSequence.h"
 #include "nsPresContext.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsIPrintSettings.h"
 #include "nsPageFrame.h"
 #include "nsSubDocumentFrame.h"
-#include "nsStyleConsts.h"
 #include "nsRegion.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
-#include "mozilla/Preferences.h"
 #include "nsHTMLCanvasFrame.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsICanvasRenderingContextInternal.h"
+#include "nsIDateTimeFormat.h"
+#include "nsServiceManagerUtils.h"
 #include <algorithm>
 
 // DateTime Includes
 #include "nsDateTimeFormatCID.h"
 
 #define OFFSET_NOT_SET -1
 
 // Print Options
 #include "nsIPrintOptions.h"
-#include "nsGfxCIID.h"
-#include "nsIServiceManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1";
 
 //
 
--- a/layout/generic/nsSimplePageSequence.h
+++ b/layout/generic/nsSimplePageSequence.h
@@ -5,18 +5,26 @@
 #ifndef nsSimplePageSequence_h___
 #define nsSimplePageSequence_h___
 
 #include "mozilla/Attributes.h"
 #include "nsIPageSequenceFrame.h"
 #include "nsContainerFrame.h"
 #include "nsIPrintSettings.h"
 #include "nsIPrintOptions.h"
-#include "nsIDateTimeFormat.h"
-#include "mozilla/dom/HTMLCanvasElement.h"
+
+class nsIDateTimeFormat;
+
+namespace mozilla {
+namespace dom {
+
+class HTMLCanvasElement;
+
+}
+}
 
 //-----------------------------------------------
 // This class maintains all the data that 
 // is used by all the page frame
 // It lives while the nsSimplePageSequenceFrame lives
 class nsSharedPageData {
 public:
   // This object a shared by all the nsPageFrames
--- a/layout/generic/nsSplittableFrame.cpp
+++ b/layout/generic/nsSplittableFrame.cpp
@@ -4,19 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * base class for rendering objects that can be split across lines,
  * columns, or pages
  */
 
 #include "nsSplittableFrame.h"
-#include "nsIContent.h"
-#include "nsPresContext.h"
-#include "nsStyleContext.h"
 #include "nsContainerFrame.h"
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSplittableFrame)
 
 void
 nsSplittableFrame::Init(nsIContent*      aContent,
                         nsIFrame*        aParent,
                         nsIFrame*        aPrevInFlow)
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -10,73 +10,50 @@
 
 #include "mozilla/layout/RenderFrameParent.h"
 
 #include "nsSubDocumentFrame.h"
 #include "nsCOMPtr.h"
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsIDocShell.h"
-#include "nsIDocShellLoadInfo.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIDocShellTreeNode.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsIBaseWindow.h"
 #include "nsIContentViewer.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsIComponentManager.h"
-#include "nsFrameManager.h"
-#include "nsIStreamListener.h"
-#include "nsIURL.h"
-#include "nsNetUtil.h"
 #include "nsIDocument.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsGkAtoms.h"
-#include "nsStyleCoord.h"
-#include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsFrameSetFrame.h"
 #include "nsIDOMHTMLFrameElement.h"
-#include "nsIDOMHTMLIFrameElement.h"
-#include "nsIDOMXULElement.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsXPIDLString.h"
 #include "nsIScrollable.h"
 #include "nsINameSpaceManager.h"
-#include "nsWeakReference.h"
-#include "nsIDOMWindow.h"
 #include "nsDisplayList.h"
-#include "nsUnicharUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "FrameLayerBuilder.h"
 #include "nsObjectFrame.h"
-#include "nsIServiceManager.h"
 #include "nsContentUtils.h"
-#include "LayerTreeInvalidation.h"
 #include "nsIPermissionManager.h"
 
 using namespace mozilla;
 using mozilla::layout::RenderFrameParent;
 
 static nsIDocument*
 GetDocumentFromView(nsView* aView)
 {
   NS_PRECONDITION(aView, "");
 
   nsIFrame* f = aView->GetFrame();
   nsIPresShell* ps =  f ? f->PresContext()->PresShell() : nullptr;
   return ps ? ps->GetDocument() : nullptr;
 }
 
-class AsyncFrameInit;
-
 nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
   : nsLeafFrame(aContext)
   , mIsInline(false)
   , mPostedReflowCallback(false)
   , mDidCreateDoc(false)
   , mCallingShow(false)
 {
 }
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -9,78 +9,66 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "nsCOMPtr.h"
 #include "nsBlockFrame.h"
-#include "nsHTMLParts.h"
 #include "nsCRT.h"
 #include "nsSplittableFrame.h"
 #include "nsLineLayout.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsStyleConsts.h"
 #include "nsStyleContext.h"
 #include "nsStyleStruct.h"
 #include "nsStyleStructInlines.h"
 #include "nsSVGTextFrame2.h"
 #include "nsCoord.h"
 #include "nsRenderingContext.h"
 #include "nsIPresShell.h"
-#include "nsITimer.h"
 #include "nsTArray.h"
-#include "nsIDocument.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsCompatibility.h"
 #include "nsCSSColorUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTextFrameUtils.h"
 #include "nsTextRunTransformations.h"
-#include "nsFrameManager.h"
 #include "nsTextFrameTextRunCache.h"
 #include "nsExpirationTracker.h"
 #include "nsUnicodeProperties.h"
-#include "nsUnicharUtilCIID.h"
 
 #include "nsTextFragment.h"
 #include "nsGkAtoms.h"
 #include "nsFrameSelection.h"
-#include "nsISelection.h"
-#include "nsIDOMRange.h"
 #include "nsRange.h"
 #include "nsCSSRendering.h"
 #include "nsContentUtils.h"
 #include "nsLineBreaker.h"
 #include "nsIWordBreaker.h"
 #include "nsGenericDOMDataNode.h"
 
-#include "nsILineIterator.h"
-
-#include "nsIServiceManager.h"
 #include <algorithm>
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsAutoPtr.h"
 
-#include "nsBidiUtils.h"
 #include "nsPrintfCString.h"
 
 #include "gfxFont.h"
 #include "gfxContext.h"
-#include "gfxImageSurface.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 
 #include "GeckoProfiler.h"
 
 #ifdef DEBUG
 #undef NOISY_REFLOW
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -7,17 +7,16 @@
 #define nsTextFrame_h__
 
 #include "mozilla/Attributes.h"
 #include "nsFrame.h"
 #include "nsSplittableFrame.h"
 #include "nsLineBox.h"
 #include "gfxFont.h"
 #include "gfxSkipChars.h"
-#include "gfxContext.h"
 #include "nsDisplayList.h"
 
 class nsTextPaintStyle;
 class PropertyProvider;
 
 // This state bit is set on frames that have some non-collapsed characters after
 // reflow
 #define TEXT_HAS_NONCOLLAPSED_CHARACTERS NS_FRAME_STATE_BIT(31)
--- a/layout/generic/nsTextFrameUtils.cpp
+++ b/layout/generic/nsTextFrameUtils.cpp
@@ -1,21 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsTextFrameUtils.h"
 
-#include "nsIWordBreaker.h"
-#include "gfxFont.h"
 #include "nsUnicharUtils.h"
 #include "nsBidiUtils.h"
 #include "nsIContent.h"
 #include "nsStyleStruct.h"
+#include "nsTextFragment.h"
 #include <algorithm>
 
 // XXX TODO implement transform of backslash to yen that nsTextTransform does
 // when requested by PresContext->LanguageSpecificTransformType(). Do it with
 // a new factory type that just munges the input stream. But first, check
 // that we really still need this, it's only enabled via a hidden pref
 // which defaults false...
 
--- a/layout/generic/nsTextFrameUtils.h
+++ b/layout/generic/nsTextFrameUtils.h
@@ -1,19 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NSTEXTFRAMEUTILS_H_
 #define NSTEXTFRAMEUTILS_H_
 
-#include "gfxFont.h"
 #include "gfxSkipChars.h"
-#include "nsTextFragment.h"
 
 class nsIContent;
 struct nsStyleText;
 
 #define BIG_TEXT_NODE_SIZE 4096
 
 #define CH_NBSP   160
 #define CH_SHY    173
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -2,23 +2,19 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsTextRunTransformations.h"
 
 #include "mozilla/MemoryReporting.h"
 
-#include "nsTextFrameUtils.h"
-#include "gfxSkipChars.h"
 #include "nsGkAtoms.h"
-
 #include "nsStyleConsts.h"
 #include "nsStyleContext.h"
-#include "gfxContext.h"
 #include "nsUnicodeProperties.h"
 #include "nsSpecialCasingData.h"
 
 // Unicode characters needing special casing treatment in tr/az languages
 #define LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE  0x0130
 #define LATIN_SMALL_LETTER_DOTLESS_I           0x0131
 
 // Greek sigma needs custom handling for the lowercase transform; for details
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -1,41 +1,33 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 /* rendering object for the HTML <video> element */
 
-#include "nsHTMLParts.h"
 #include "nsCOMPtr.h"
-#include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 
 #include "nsVideoFrame.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "nsIDOMHTMLVideoElement.h"
 #include "nsIDOMHTMLImageElement.h"
-#include "nsIDOMHTMLElement.h"
 #include "nsDisplayList.h"
 #include "nsGenericHTMLElement.h"
-#include "gfxContext.h"
-#include "gfxImageSurface.h"
 #include "nsPresContext.h"
-#include "nsTransform2D.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsBoxLayoutState.h"
 #include "nsBoxFrame.h"
 #include "nsImageFrame.h"
 #include "nsIImageLoadingContent.h"
-#include "nsCSSRendering.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
-#include "mozilla/layers/ShadowLayers.h"
 #include "ImageContainer.h"
 #include "ImageLayers.h"
 #include "nsContentList.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -6,33 +6,30 @@
 
 /* rendering object for the HTML <video> element */
 
 #ifndef nsVideoFrame_h___
 #define nsVideoFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
-#include "nsString.h"
-#include "nsAString.h"
-#include "nsIIOService.h"
-#include "nsITimer.h"
-#include "nsTArray.h"
 #include "nsIAnonymousContentCreator.h"
 #include "FrameLayerBuilder.h"
 
 namespace mozilla {
 namespace layers {
 class Layer;
 class LayerManager;
 }
 }
 
+class nsAString;
 class nsPresContext;
 class nsDisplayItem;
+template <class T> class nsTArray;
 
 nsIFrame* NS_NewVideoFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 class nsVideoFrame : public nsContainerFrame, public nsIAnonymousContentCreator
 {
 public:
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -3,23 +3,19 @@
  * 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/. */
 
 /*
  * rendering object that is the root of the frame tree, which contains
  * the document's scrollbars and contains fixed-positioned elements
  */
 
-#include "nsCOMPtr.h"
 #include "nsViewportFrame.h"
-#include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
 #include "nsIScrollableFrame.h"
-#include "nsDisplayList.h"
-#include "FrameLayerBuilder.h"
 #include "nsSubDocumentFrame.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "GeckoProfiler.h"
 
 using namespace mozilla;
 
 nsIFrame*
 NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -8,17 +8,16 @@
  * the document's scrollbars and contains fixed-positioned elements
  */
 
 #ifndef nsViewportFrame_h___
 #define nsViewportFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
-#include "nsGkAtoms.h"
 
 class nsPresContext;
 
 /**
   * ViewportFrame is the parent of a single child - the doc root frame or a scroll frame 
   * containing the doc root frame. ViewportFrame stores this child in its primary child 
   * list.
   */
--- a/layout/mathml/nsMathMLmoFrame.cpp
+++ b/layout/mathml/nsMathMLmoFrame.cpp
@@ -5,16 +5,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsRenderingContext.h"
 #include "nsContentUtils.h"
+#include "nsFrameSelection.h"
 
 #include "nsMathMLmoFrame.h"
 #include <algorithm>
 
 //
 // <mo> -- operator, fence, or separator - implementation
 //
 
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -143,18 +143,18 @@ class LinkedListElement
       return prev->asT();
     }
 
     /*
      * Insert elem after this element in the list.  |this| must be part of a
      * linked list when you call setNext(); otherwise, this method will assert.
      */
     void setNext(T* elem) {
-        MOZ_ASSERT(isInList());
-        setNextUnsafe(elem);
+      MOZ_ASSERT(isInList());
+      setNextUnsafe(elem);
     }
 
     /*
      * Insert elem before this element in the list.  |this| must be part of a
      * linked list when you call setPrevious(); otherwise, this method will
      * assert.
      */
     void setPrevious(T* elem) {
--- a/netwerk/test/mochitests/Makefile.in
+++ b/netwerk/test/mochitests/Makefile.in
@@ -9,11 +9,13 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= @relativesrcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES = \
   partial_content.sjs \
   test_partially_cached_content.html \
+  user_agent.sjs \
+  test_user_agent_overrides.html \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/netwerk/test/mochitests/test_user_agent_overrides.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=782453
+-->
+<head>
+  <title>Test for User Agent Overrides</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=782453">Mozilla Bug 782453</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+const PREF_OVERRIDES_ENABLED = "general.useragent.site_specific_overrides";
+const PREF_OVERRIDES_BRANCH = "general.useragent.override.";
+
+const DEFAULT_UA = navigator.userAgent;
+
+const UA_WHOLE_OVERRIDE = "DummyUserAgent";
+const UA_WHOLE_EXPECTED = UA_WHOLE_OVERRIDE;
+
+const UA_PARTIAL_FROM = "\\wozilla"; // /\wozilla
+const UA_PARTIAL_SEP = "#";
+const UA_PARTIAL_TO = UA_WHOLE_OVERRIDE;
+const UA_PARTIAL_OVERRIDE = UA_PARTIAL_FROM + UA_PARTIAL_SEP + UA_PARTIAL_TO;
+const UA_PARTIAL_EXPECTED = DEFAULT_UA.replace(new RegExp(UA_PARTIAL_FROM, 'g'), UA_PARTIAL_TO);
+
+function getUA(host) {
+  var url = location.pathname;
+  url = host + url.slice(0, url.lastIndexOf('/')) + '/user_agent.sjs';
+
+  var xhr = new XMLHttpRequest();
+  xhr.open('GET', url, false); // sync request
+  xhr.send();
+  is(xhr.status, 200, 'request failed');
+  is(typeof xhr.response, 'string', 'invalid response');
+  return xhr.response;
+}
+
+function testUA(options, callback) {
+
+  var [domain, override, test_hosts, skip, expected] =
+    [options.domain, options.override, options.test_hosts, options.skip, options.expected];
+
+  info('Overriding ' + domain + ' with ' + override);
+
+  if (skip) {
+    todo(false, 'Skipping');
+    callback();
+    return;
+  }
+
+  function is_subdomain(host) {
+    var [test_domain] = host.slice(host.lastIndexOf('/') + 1).split(':', 1);
+    return test_domain === domain || test_domain.endsWith('.' + domain);
+  }
+
+  var localhost = location.origin;
+  var overrideNavigator = is_subdomain(localhost);
+  var navigator_ua, test_ua = [];
+
+  // store UA before pref change, to be compared later
+  if (overrideNavigator) {
+    navigator_ua = navigator.userAgent;
+  }
+  test_hosts.forEach(function (test_host) {
+    test_ua.push(getUA(test_host));
+  });
+  // set the override pref to override the UA
+  SpecialPowers.pushPrefEnv({
+    set: [[PREF_OVERRIDES_BRANCH + domain, override]],
+  }, function () {
+    // check that the UA has changed after pref change
+    if (overrideNavigator) {
+      is(navigator.userAgent, expected,
+        'Navigator UA not overridden at step ' + (++step));
+    } else {
+      is(navigator.userAgent, DEFAULT_UA,
+        'Navigator UA should not be overridden at step ' + (++step));
+    }
+    test_hosts.forEach(function (test_host) {
+      is(getUA(test_host), expected,
+        'Header UA not overridden at step ' + (++step));
+    });
+    // clear the override pref to undo overriding the UA
+    SpecialPowers.pushPrefEnv({
+      clear: [[PREF_OVERRIDES_BRANCH + domain]],
+    }, function () {
+      // check that the UA has changed back
+      if (overrideNavigator) {
+        is(navigator.userAgent, navigator_ua,
+          'Navigator UA not restored at step ' + (++step));
+      }
+      test_hosts.forEach(function (test_host, i) {
+        is(getUA(test_host), test_ua[i],
+          'Header UA not restored at step ' + (++step));
+      });
+      callback();
+    });
+  });
+}
+
+// mochitests on Android appear to have trouble with https
+// but when it eventually works, we should re-enable the test
+var skipHttps = /android/i.test(DEFAULT_UA);
+if (skipHttps) {
+  SimpleTest.doesThrow(function () getUA('https://example.com'), 'Re-enable https test');
+}
+
+var step = 0; // for logging
+var tests = [
+  // should override both header and navigator.userAgent
+  {
+    domain: location.hostname,
+    override: UA_WHOLE_OVERRIDE,
+    test_hosts: [location.origin],
+    expected: UA_WHOLE_EXPECTED
+  },
+
+  // should support partial overrides
+  {
+    domain: location.hostname,
+    override: UA_PARTIAL_OVERRIDE,
+    test_hosts: [location.origin],
+    expected: UA_PARTIAL_EXPECTED
+  },
+
+  // should match domain and subdomains
+  {
+    domain: 'example.org',
+    override: UA_WHOLE_OVERRIDE,
+    test_hosts: ['http://example.org',
+                 'http://test1.example.org',
+                 'http://sub1.test1.example.org'],
+    expected: UA_WHOLE_EXPECTED
+  },
+
+  // should not match superdomains
+  {
+    domain: 'sub1.test1.example.org',
+    override: UA_WHOLE_OVERRIDE,
+    test_hosts: ['http://example.org',
+                 'http://test1.example.org'],
+    expected: DEFAULT_UA
+  },
+
+  // should work with https
+  {
+    skip: skipHttps,
+    domain: 'example.com',
+    override: UA_WHOLE_OVERRIDE,
+    test_hosts: ['https://example.com',
+                 'https://test1.example.com',
+                 'https://sub1.test1.example.com'],
+    expected: UA_WHOLE_EXPECTED
+  },
+];
+
+// test that UA is not overridden when the 'site_specific_overrides' pref is off
+function testInactive(callback) {
+  SpecialPowers.pushPrefEnv({
+    set: [
+      [PREF_OVERRIDES_ENABLED, false],
+      [PREF_OVERRIDES_BRANCH + location.hostname, UA_WHOLE_OVERRIDE]
+    ]
+  }, function () {
+    isnot(navigator.userAgent, UA_WHOLE_OVERRIDE,
+      'Failed to disable navigator UA override');
+    isnot(getUA(location.origin), UA_WHOLE_OVERRIDE,
+      'Failed to disable header UA override');
+    SpecialPowers.pushPrefEnv({
+      clear: [
+        [PREF_OVERRIDES_ENABLED],
+        [PREF_OVERRIDES_BRANCH + location.hostname]
+      ]
+    }, callback);
+  });
+}
+
+function testOverrides(callback) {
+  SpecialPowers.pushPrefEnv({
+    set: [[PREF_OVERRIDES_ENABLED, true]]
+  }, function nextTest() {
+    testUA(tests.shift(), function () tests.length ? nextTest() : callback());
+  });
+}
+
+SpecialPowers.Cu.import('resource://gre/modules/UserAgentOverrides.jsm', window);
+SpecialPowers.wrap(UserAgentOverrides).init();
+
+SimpleTest.waitForExplicitFinish();
+
+testOverrides(function ()
+  testInactive(SimpleTest.finish)
+);
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/netwerk/test/mochitests/user_agent.sjs
@@ -0,0 +1,12 @@
+
+function handleRequest(request, response)
+{
+    // avoid confusing cache behaviors
+    response.setHeader("Cache-Control", "no-cache", false);
+    response.setHeader("Content-Type", "text/plain", false);
+    response.setHeader("Access-Control-Allow-Origin", "*", false);
+
+    // used by test_user_agent tests
+    response.write(request.getHeader('User-Agent'));
+}
+
--- a/python/mozboot/mozboot/osx.py
+++ b/python/mozboot/mozboot/osx.py
@@ -196,16 +196,17 @@ class OSXBootstrapper(BaseBootstrapper):
             # We need to install Python because Mercurial requires the Python
             # development headers which are missing from OS X (at least on
             # 10.8).
             ('python', 'python'),
             ('mercurial', 'mercurial'),
             ('git', 'git'),
             ('yasm', 'yasm'),
             ('autoconf213', HOMEBREW_AUTOCONF213),
+            ('terminal-notifier', 'terminal-notifier'),
         ]
 
         printed = False
 
         for name, package in packages:
             if name in installed:
                 continue
 
--- a/python/mozbuild/mozbuild/base.py
+++ b/python/mozbuild/mozbuild/base.py
@@ -82,17 +82,17 @@ class MozbuildObject(ProcessExecutionMix
 
         self._make = None
         self._topobjdir = topobjdir
         self._mozconfig = None
         self._config_guess_output = None
         self._config_environment = None
 
     @classmethod
-    def from_environment(cls):
+    def from_environment(cls, cwd=None):
         """Create a MozbuildObject by detecting the proper one from the env.
 
         This examines environment state like the current working directory and
         creates a MozbuildObject from the found source directory, mozconfig, etc.
 
         The role of this function is to identify a topsrcdir, topobjdir, and
         mozconfig file.
 
@@ -106,28 +106,29 @@ class MozbuildObject(ProcessExecutionMix
         looks inside environment variables.
 
         If the current Python interpreter is running from a virtualenv inside
         an objdir, we use that as our objdir.
 
         If we're not inside a srcdir or objdir, an exception is raised.
         """
 
+        cwd = cwd or os.getcwd()
         topsrcdir = None
         topobjdir = None
         mozconfig = None
 
         def load_mozinfo(path):
             info = json.load(open(path, 'rt'))
             topsrcdir = info.get('topsrcdir')
             topobjdir = os.path.dirname(path)
             mozconfig = info.get('mozconfig')
             return topsrcdir, topobjdir, mozconfig
 
-        for dir_path in ancestors(os.getcwd()):
+        for dir_path in ancestors(cwd):
             # If we find a mozinfo.json, we are in the objdir.
             mozinfo_path = os.path.join(dir_path, 'mozinfo.json')
             if os.path.isfile(mozinfo_path):
                 topsrcdir, topobjdir, mozconfig = load_mozinfo(mozinfo_path)
                 break
 
             # We choose an arbitrary file as an indicator that this is a
             # srcdir. We go with ourself because why not!
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -284,16 +284,17 @@ class Build(MachCommandBase):
         help='Number of concurrent jobs to run. Default is the number of CPUs.')
     @CommandArgument('what', default=None, nargs='*', help=BUILD_WHAT_HELP)
     @CommandArgument('-X', '--disable-extra-make-dependencies',
                      default=False, action='store_true',
                      help='Do not add extra make dependencies.')
     @CommandArgument('-v', '--verbose', action='store_true',
         help='Verbose output for what commands the build is running.')
     def build(self, what=None, disable_extra_make_dependencies=None, jobs=0, verbose=False):
+        import which
         from mozbuild.controller.building import BuildMonitor
         from mozbuild.util import resolve_target_to_make
 
         self.log_manager.register_structured_logger(logging.getLogger('mozbuild'))
 
         warnings_path = self._get_state_filename('warnings.json')
         monitor = self._spawn(BuildMonitor)
         monitor.init(warnings_path)
@@ -368,21 +369,38 @@ class Build(MachCommandBase):
                     '{count} compiler warnings present.')
 
             monitor.finish(record_usage=status==0)
 
         high_finder, finder_percent = monitor.have_high_finder_usage()
         if high_finder:
             print(FINDER_SLOW_MESSAGE % finder_percent)
 
-        long_build = monitor.elapsed > 600
+        if monitor.elapsed > 300:
+            # Display a notification when the build completes.
+            # This could probably be uplifted into the mach core or at least
+            # into a helper API. It is here as an experimentation to see how it
+            # is received.
+            try:
+                if sys.platform.startswith('darwin'):
+                    notifier = which.which('terminal-notifier')
+                    self.run_process([notifier, '-title',
+                        'Mozilla Build System', '-group', 'mozbuild',
+                        '-message', 'Build complete'], ensure_exit_code=False)
+            except which.WhichError:
+                pass
+            except Exception as e:
+                self.log(logging.WARNING, 'notifier-failed', {'error':
+                    e.message}, 'Notification center failed: {error}')
 
         if status:
             return status
 
+        long_build = monitor.elapsed > 600
+
         if long_build:
             print('We know it took a while, but your build finally finished successfully!')
         else:
             print('Your build was successful!')
 
         if monitor.have_resource_usage:
             print('To view resource usage of the build, run |mach '
                 'resource-usage|.')
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -7,24 +7,24 @@ import os
 import sys
 import tempfile
 
 from automation import Automation
 from automationutils import addCommonOptions, isURL
 from mozprofile import DEFAULT_PORTS
 import moznetwork
 
+here = os.path.abspath(os.path.dirname(sys.argv[0]))
+
 try:
     from mozbuild.base import MozbuildObject
-    build_obj = MozbuildObject.from_environment()
+    build_obj = MozbuildObject.from_environment(cwd=here)
 except ImportError:
     build_obj = None
 
-here = os.path.abspath(os.path.dirname(sys.argv[0]))
-
 __all__ = ["MochitestOptions", "B2GOptions"]
 
 VMWARE_RECORDING_HELPER_BASENAME = "vmwarerecordinghelper"
 
 class MochitestOptions(optparse.OptionParser):
     """Usage instructions for runtests.py.
     All arguments are optional.
     If --chrome is specified, chrome tests will be run instead of web content tests.
--- a/testing/mozbase/Makefile.in
+++ b/testing/mozbase/Makefile.in
@@ -25,16 +25,17 @@ MOZBASE_PACKAGES = \
   mozinstall \
   mozlog \
   mozprocess \
   mozprofile \
   mozrunner \
   mozdevice \
   moznetwork \
   mozsystemmonitor \
+  moztest \
   $(NULL)
 
 MOZBASE_EXTRAS = \
   setup_development.py \
   $(NULL)
 
 _DEST_DIR = $(DEPTH)/_tests/mozbase
 libs:: $(MOZBASE_PACKAGES)
--- a/toolkit/devtools/server/actors/root.js
+++ b/toolkit/devtools/server/actors/root.js
@@ -113,19 +113,17 @@ function CommonAppendExtraActors(aObject
  *      is "browser".
  *
  * Live lists:
  *
  * A "live list", as used for the |tabList|, is an object that presents a
  * list of actors, and also notifies its clients of changes to the list. A
  * live list's interface is two properties:
  *
- * - iterator: a method that returns an iterator. A for-of loop will call
- *             this method to obtain an iterator for the loop, so if LL is
- *             a live list, one can simply write 'for (i of LL) ...'.
+ * - getList: a method that returns a promise to the contents of the list.
  *
  * - onListChanged: a handler called, with no arguments, when the set of
  *             values the iterator would produce has changed since the last
  *             time 'iterator' was called. This may only be set to null or a
  *             callable value (one for which the typeof operator returns
  *             'function'). (Note that the live list will not call the
  *             onListChanged handler until the list has been iterated over
  *             once; if nobody's seen the list in the first place, nobody
@@ -216,55 +214,57 @@ RootActor.prototype = {
      * reply, and moving all the actors to a new ActorPool. We'll
      * replace the old tab actor pool with the one we build here, thus
      * retiring any actors that didn't get listed again, and preparing any
      * new actors to receive packets.
      */
     let newActorPool = new ActorPool(this.conn);
     let tabActorList = [];
     let selected;
-    for (let tabActor of tabList) {
-      if (tabActor.selected) {
-        selected = tabActorList.length;
+    return tabList.getList().then((tabActors) => {
+      for (let tabActor of tabActors) {
+        if (tabActor.selected) {
+          selected = tabActorList.length;
+        }
+        tabActor.parentID = this.actorID;
+        newActorPool.addActor(tabActor);
+        tabActorList.push(tabActor);
       }
-      tabActor.parentID = this.actorID;
-      newActorPool.addActor(tabActor);
-      tabActorList.push(tabActor);
-    }
 
-    /* DebuggerServer.addGlobalActor support: create actors. */
-    this._createExtraActors(this._parameters.globalActorFactories, newActorPool);
+      /* DebuggerServer.addGlobalActor support: create actors. */
+      this._createExtraActors(this._parameters.globalActorFactories, newActorPool);
 
-    /*
-     * Drop the old actorID -> actor map. Actors that still mattered were
-     * added to the new map; others will go away.
-     */
-    if (this._tabActorPool) {
-      this.conn.removeActorPool(this._tabActorPool);
-    }
-    this._tabActorPool = newActorPool;
-    this.conn.addActorPool(this._tabActorPool);
+      /*
+       * Drop the old actorID -> actor map. Actors that still mattered were
+       * added to the new map; others will go away.
+       */
+      if (this._tabActorPool) {
+        this.conn.removeActorPool(this._tabActorPool);
+      }
+      this._tabActorPool = newActorPool;
+      this.conn.addActorPool(this._tabActorPool);
 
-    let reply = {
-      "from": this.actorID,
-      "selected": selected || 0,
-      "tabs": [actor.grip() for (actor of tabActorList)],
-    };
+      let reply = {
+        "from": this.actorID,
+        "selected": selected || 0,
+        "tabs": [actor.grip() for (actor of tabActorList)],
+      };
 
-    /* DebuggerServer.addGlobalActor support: name actors in 'listTabs' reply. */
-    this._appendExtraActors(reply);
+      /* DebuggerServer.addGlobalActor support: name actors in 'listTabs' reply. */
+      this._appendExtraActors(reply);
 
-    /*
-     * Now that we're actually going to report the contents of tabList to
-     * the client, we're responsible for letting the client know if it
-     * changes.
-     */
-    tabList.onListChanged = this._onTabListChanged;
+      /*
+       * Now that we're actually going to report the contents of tabList to
+       * the client, we're responsible for letting the client know if it
+       * changes.
+       */
+      tabList.onListChanged = this._onTabListChanged;
 
-    return reply;
+      return reply;
+    });
   },
 
   onTabListChanged: function () {
     this.conn.send({ from: this.actorID, type:"tabListChanged" });
     /* It's a one-shot notification; no need to watch any more. */
     this._parameters.tabList.onListChanged = null;
   },
 
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -1,15 +1,18 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
+
+let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}).Promise;
+
 /**
  * Browser-specific actors.
  */
 
 /**
  * Yield all windows of type |aWindowType|, from the oldest window to the
  * youngest, using nsIWindowMediator::getEnumerator. We're usually
  * interested in "navigator:browser" windows.
@@ -177,17 +180,17 @@ function BrowserTabList(aConnection)
   this._mustNotify = false;
 
   /* True if we're testing, and should throw if consistency checks fail. */
   this._testing = false;
 }
 
 BrowserTabList.prototype.constructor = BrowserTabList;
 
-BrowserTabList.prototype.iterator = function() {
+BrowserTabList.prototype.getList = function() {
   let topXULWindow = windowMediator.getMostRecentWindow("navigator:browser");
 
   // As a sanity check, make sure all the actors presently in our map get
   // picked up when we iterate over all windows' tabs.
   let initialMapSize = this._actorByBrowser.size;
   let foundCount = 0;
 
   // To avoid mysterious behavior if tabs are closed or opened mid-iteration,
@@ -219,20 +222,17 @@ BrowserTabList.prototype.iterator = func
   }
 
   if (this._testing && initialMapSize !== foundCount)
     throw Error("_actorByBrowser map contained actors for dead tabs");
 
   this._mustNotify = true;
   this._checkListening();
 
-  /* Yield the values. */
-  for (let [browser, actor] of this._actorByBrowser) {
-    yield actor;
-  }
+  return promise.resolve([actor for ([_, actor] of this._actorByBrowser)]);
 };
 
 Object.defineProperty(BrowserTabList.prototype, 'onListChanged', {
   enumerable: true, configurable:true,
   get: function() { return this._onListChanged; },
   set: function(v) {
     if (v !== null && typeof v !== 'function') {
       throw Error("onListChanged property may only be set to 'null' or a function");
--- a/toolkit/devtools/server/tests/unit/testactors.js
+++ b/toolkit/devtools/server/tests/unit/testactors.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}).Promise;
+
 var gTestGlobals = [];
 DebuggerServer.addTestGlobal = function(aGlobal) {
   gTestGlobals.push(aGlobal);
 };
 
 // A mock tab list, for use by tests. This simply presents each global in
 // gTestGlobals as a tab, and the list is fixed: it never calls its
 // onListChanged handler.
@@ -33,20 +35,18 @@ function TestTabList(aConnection) {
     this._tabActors[0].selected = true;
   }
 
   aConnection.addActorPool(this._tabActorPool);
 }
 
 TestTabList.prototype = {
   constructor: TestTabList,
-  iterator: function() {
-    for (let actor of this._tabActors) {
-      yield actor;
-    }
+  getList: function () {
+    return promise.resolve([tabActor for (tabActor of this._tabActors)]);
   }
 };
 
 function createRootActor(aConnection)
 {
   let root = new RootActor(aConnection,
                            { tabList: new TestTabList(aConnection) });
   root.applicationType = "xpcshell-tests";
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -263,32 +263,33 @@ PopupNotifications.prototype = {
 
     let existingNotification = this.getNotification(id, browser);
     if (existingNotification)
       this._remove(existingNotification);
 
     let notifications = this._getNotificationsForBrowser(browser);
     notifications.push(notification);
 
+    let isActive = this._isActiveBrowser(browser);
     let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
-    if (browser.docShell.isActive && fm.activeWindow == this.window) {
+    if (isActive && fm.activeWindow == this.window) {
       // show panel now
       this._update(notifications, notification.anchorElement, true);
     } else {
       // Otherwise, update() will display the notification the next time the
       // relevant tab/window is selected.
 
       // If the tab is selected but the window is in the background, let the OS
       // tell the user that there's a notification waiting in that window.
       // At some point we might want to do something about background tabs here
       // too. When the user switches to this window, we'll show the panel if
       // this browser is a tab (thus showing the anchor icon). For
       // non-tabbrowser browsers, we need to make the icon visible now or the
       // user will not be able to open the panel.
-      if (!notification.dismissed && browser.docShell.isActive) {
+      if (!notification.dismissed && isActive) {
         this.window.getAttention();
         if (notification.anchorElement.parentNode != this.iconBox) {
           notification.anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
         }
       }
 
       // Notify observers that we're not showing the popup (useful for testing)
       this._notify("backgroundShow");
@@ -342,17 +343,17 @@ PopupNotifications.prototype = {
       }
 
       this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
       return false;
     }, this);
 
     this._setNotificationsForBrowser(aBrowser, notifications);
 
-    if (aBrowser.docShell.isActive) {
+    if (this._isActiveBrowser(aBrowser)) {
       // get the anchor element if the browser has defined one so it will
       // _update will handle both the tabs iconBox and non-tab permission
       // anchors.
       let anchorElement = notifications.length > 0 ? notifications[0].anchorElement : null;
       if (!anchorElement)
         anchorElement = getAnchorFromBrowser(aBrowser);
       this._update(notifications, anchorElement);
     }
@@ -360,18 +361,18 @@ PopupNotifications.prototype = {
 
   /**
    * Removes a Notification.
    * @param notification
    *        The Notification object to remove.
    */
   remove: function PopupNotifications_remove(notification) {
     this._remove(notification);
-    
-    if (notification.browser.docShell.isActive) {
+
+    if (this._isActiveBrowser(notification.browser)) {
       let notifications = this._getNotificationsForBrowser(notification.browser);
       this._update(notifications, notification.anchorElement);
     }
   },
 
   handleEvent: function (aEvent) {
     switch (aEvent.type) {
       case "popuphidden":
@@ -413,17 +414,17 @@ PopupNotifications.prototype = {
     let notifications = this._getNotificationsForBrowser(notification.browser);
     if (!notifications)
       return;
 
     var index = notifications.indexOf(notification);
     if (index == -1)
       return;
 
-    if (notification.browser.docShell.isActive)
+    if (this._isActiveBrowser(notification.browser))
       notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
 
     // remove the notification
     notifications.splice(index, 1);
     this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
   },
 
   /**
@@ -699,16 +700,24 @@ PopupNotifications.prototype = {
     }
     return notifications;
   },
   _setNotificationsForBrowser: function PopupNotifications_setNotifications(browser, notifications) {
     popupNotificationsMap.set(browser, notifications);
     return notifications;
   },
 
+  _isActiveBrowser: function (browser) {
+    // Note: This helper only exists, because in e10s builds,
+    // we can't access the docShell of a browser from chrome.
+    return browser.docShell
+      ? browser.docShell.isActive
+      : (this.window.gBrowser.selectedBrowser == browser);
+  },
+
   _onIconBoxCommand: function PopupNotifications_onIconBoxCommand(event) {
     // Left click, space or enter only
     let type = event.type;
     if (type == "click" && event.button != 0)
       return;
 
     if (type == "keypress" &&
         !(event.charCode == Ci.nsIDOMKeyEvent.DOM_VK_SPACE ||
--- a/xpcom/tests/TestHarness.h
+++ b/xpcom/tests/TestHarness.h
@@ -159,18 +159,20 @@ class ScopedXPCOM : public nsIDirectoryS
     already_AddRefed<nsIFile> GetProfileDirectory()
     {
       if (mProfD) {
         nsCOMPtr<nsIFile> copy = mProfD;
         return copy.forget();
       }
 
       // Create a unique temporary folder to use for this test.
+      // Note that runcppunittests.py will run tests with a temp
+      // directory as the cwd, so just put something under that.
       nsCOMPtr<nsIFile> profD;
-      nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
+      nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR,
                                            getter_AddRefs(profD));
       NS_ENSURE_SUCCESS(rv, nullptr);
 
       rv = profD->Append(NS_LITERAL_STRING("cpp-unit-profd"));
       NS_ENSURE_SUCCESS(rv, nullptr);
 
       rv = profD->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755);
       NS_ENSURE_SUCCESS(rv, nullptr);
--- a/xpcom/threads/nsThreadPool.cpp
+++ b/xpcom/threads/nsThreadPool.cpp
@@ -32,16 +32,34 @@ GetThreadPoolLog()
 //  o  Use nsThreadPool::Run as the main routine for each thread.
 //  o  Each thread waits on the event queue's monitor, checking for
 //     pending events and rescheduling itself as an idle thread.
 
 #define DEFAULT_THREAD_LIMIT 4
 #define DEFAULT_IDLE_THREAD_LIMIT 1
 #define DEFAULT_IDLE_THREAD_TIMEOUT PR_SecondsToInterval(60)
 
+class ShutdownHelper MOZ_FINAL : public nsRunnable
+{
+public:
+  NS_DECL_NSIRUNNABLE
+
+  ShutdownHelper(nsCOMArray<nsIThread>& aThreads,
+                 already_AddRefed<nsIThreadPoolListener> aListener)
+  : mListener(aListener)
+  {
+    MOZ_ASSERT(!aThreads.IsEmpty());
+    mThreads.SwapElements(aThreads);
+  }
+
+private:
+  nsCOMArray<nsIThread> mThreads;
+  nsCOMPtr<nsIThreadPoolListener> mListener;
+};
+
 NS_IMPL_ADDREF(nsThreadPool)
 NS_IMPL_RELEASE(nsThreadPool)
 NS_IMPL_CLASSINFO(nsThreadPool, NULL, nsIClassInfo::THREADSAFE,
                   NS_THREADPOOL_CID)
 NS_IMPL_QUERY_INTERFACE3_CI(nsThreadPool, nsIThreadPool, nsIEventTarget,
                             nsIRunnable)
 NS_IMPL_CI_INTERFACE_GETTER2(nsThreadPool, nsIThreadPool, nsIEventTarget)
 
@@ -51,17 +69,38 @@ nsThreadPool::nsThreadPool()
   , mIdleThreadTimeout(DEFAULT_IDLE_THREAD_TIMEOUT)
   , mIdleCount(0)
   , mShutdown(false)
 {
 }
 
 nsThreadPool::~nsThreadPool()
 {
-  Shutdown();
+  // Calling Shutdown() directly is not safe since it will spin the event loop
+  // (perhaps during a GC). Instead we try to delay-shutdown each thread that is
+  // still alive.
+  nsCOMArray<nsIThread> threads;
+  nsCOMPtr<nsIThreadPoolListener> listener;
+  {
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
+    if (!mShutdown) {
+      NS_WARNING("nsThreadPool destroyed before Shutdown() was called!");
+
+      mThreads.SwapElements(threads);
+      mListener.swap(listener);
+    }
+  }
+
+  if (!threads.IsEmpty()) {
+    nsRefPtr<ShutdownHelper> helper =
+      new ShutdownHelper(threads, listener.forget());
+    if (NS_FAILED(NS_DispatchToMainThread(helper, NS_DISPATCH_NORMAL))) {
+      NS_WARNING("Unable to shut down threads in this thread pool!");
+    }
+  }
 }
 
 nsresult
 nsThreadPool::PutEvent(nsIRunnable *event)
 {
   // Avoid spawning a new thread while holding the event queue lock...
  
   bool spawnThread = false;
@@ -369,8 +408,22 @@ nsThreadPool::SetName(const nsACString& 
     ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
     if (mThreads.Count())
       return NS_ERROR_NOT_AVAILABLE;
   }
 
   mName = aName;
   return NS_OK;
 }
+
+NS_IMETHODIMP
+ShutdownHelper::Run()
+{
+  MOZ_ASSERT(!mThreads.IsEmpty());
+
+  for (int32_t i = 0; i < mThreads.Count(); ++i)
+    mThreads[i]->Shutdown();
+
+  mThreads.Clear();
+
+  mListener = nullptr;
+  return NS_OK;
+}