Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 30 Apr 2013 21:49:23 -0400
changeset 141345 9f86b0aa679e2acc961eede5047e9eaef3b89058
parent 141303 b01fa7ae92389276faa875542e9c533d2048fa3e (current diff)
parent 141344 89063545e4b3c30a38e37e20f7ae23347a79c3d9 (diff)
child 141357 02aa81c59df65d69dab43cb5e6981067f38c3e23
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
content/svg/content/src/nsDOMSVGZoomEvent.cpp
content/svg/content/src/nsDOMSVGZoomEvent.h
dom/interfaces/svg/nsIDOMSVGZoomEvent.idl
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -133,18 +133,18 @@ const SEARCH_ENGINES = {
 };
 
 // The process of adding a new default snippet involves:
 //   * add a new entity to aboutHome.dtd
 //   * add a <span/> for it in aboutHome.xhtml
 //   * add an entry here in the proper ordering (based on spans)
 // The <a/> part of the snippet will be linked to the corresponding url.
 const DEFAULT_SNIPPETS_URLS = [
-  "http://www.mozilla.com/firefox/features/?WT.mc_ID=default1"
-, "https://addons.mozilla.org/firefox/?src=snippet&WT.mc_ID=default2"
+  "https://www.mozilla.org/firefox/features/?utm_source=snippet&utm_medium=snippet&utm_campaign=default+feature+snippet"
+, "https://addons.mozilla.org/firefox/?utm_source=snippet&utm_medium=snippet&utm_campaign=addons"
 ];
 
 const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day.
 
 let gObserver = new MutationObserver(function (mutations) {
   for (let mutation of mutations) {
     if (mutation.attributeName == "searchEngineURL") {
       gObserver.disconnect();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_602572_log_bodies_checkbox.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_602572_log_bodies_checkbox.js
@@ -14,41 +14,39 @@ function test()
 {
   // open tab 1
   addTab("data:text/html;charset=utf-8,Web Console test for bug 602572: log bodies checkbox. tab 1");
   tabs.push(tab);
 
   browser.addEventListener("load", function onLoad1(aEvent) {
     browser.removeEventListener(aEvent.type, onLoad1, true);
 
-    openConsole(null, function(aHud) {
-      info("iframe1 root height " + aHud.ui.rootElement.clientHeight);
+    openConsole(null, (hud) => hud.iframeWindow.mozRequestAnimationFrame(() => {
+      info("iframe1 root height " + hud.ui.rootElement.clientHeight);
 
       // open tab 2
       addTab("data:text/html;charset=utf-8,Web Console test for bug 602572: log bodies checkbox. tab 2");
       tabs.push(tab);
 
       browser.addEventListener("load", function onLoad2(aEvent) {
         browser.removeEventListener(aEvent.type, onLoad2, true);
 
-        openConsole(null, function(aHud) {
-          info("iframe2 root height " + aHud.ui.rootElement.clientHeight);
-          waitForFocus(startTest, aHud.iframeWindow);
-        });
+        openConsole(null, (hud) => hud.iframeWindow.mozRequestAnimationFrame(startTest));
       }, true);
-    });
+    }));
   }, true);
 }
 
 function startTest()
 {
   // Find the relevant elements in the Web Console of tab 2.
   let win2 = tabs[runCount*2 + 1].linkedBrowser.contentWindow;
   let hudId2 = HUDService.getHudIdByWindow(win2);
   huds[1] = HUDService.hudReferences[hudId2];
+  info("startTest: iframe2 root height " + huds[1].ui.rootElement.clientHeight);
 
   if (runCount == 0) {
     menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodies");
   }
   else {
     menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodiesContextMenu");
   }
   menupopups[1] = menuitems[1].parentNode;
--- a/browser/installer/windows/nsis/stub.nsi
+++ b/browser/installer/windows/nsis/stub.nsi
@@ -50,17 +50,16 @@ Var HWndBitmapBlurb3
 Var FontNormal
 Var FontItalic
 Var FontBlurb
 
 Var WasOptionsButtonClicked
 Var CanWriteToInstallDir
 Var HasRequiredSpaceAvailable
 Var IsDownloadFinished
-Var Initialized
 Var DownloadSizeBytes
 Var HalfOfDownload
 Var DownloadReset
 Var ExistingTopDir
 Var SpaceAvailableBytes
 Var InitialInstallDir
 Var HandleDownload
 Var CanSetAsDefault
@@ -378,16 +377,17 @@ Function .onInit
     SetShellVarContext current ; Set SHCTX to HKCU
     ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
   ${EndIf}
 
   ${If} "$R9" != "false"
     StrCpy $INSTDIR "$R9"
   ${EndIf}
 
+  ; Used to determine if the default installation directory was used.
   StrCpy $InitialInstallDir "$INSTDIR"
 
   ClearErrors
   WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
                    "Write Test"
 
   ${If} ${Errors}
   ${OrIf} ${AtLeastWin8}
@@ -404,16 +404,26 @@ Function .onInit
   StrCpy $OptionsPhaseSeconds "0"
   StrCpy $EndPreInstallPhaseTickCount "0"
   StrCpy $EndInstallPhaseTickCount "0"
   StrCpy $IntroPageShownCount "0"
   StrCpy $OptionsPageShownCount "0"
   StrCpy $InitialInstallRequirementsCode ""
   StrCpy $IsDownloadFinished ""
   StrCpy $FirefoxLaunchCode "0"
+  StrCpy $CheckboxShortcutOnBar "1"
+  StrCpy $CheckboxShortcutInStartMenu "1"
+  StrCpy $CheckboxShortcutOnDesktop "1"
+  StrCpy $CheckboxSendPing "1"
+!ifdef MOZ_MAINTENANCE_SERVICE
+  StrCpy $CheckboxInstallMaintSvc "1"
+!else
+  StrCpy $CheckboxInstallMaintSvc "0"
+!endif
+  StrCpy $WasOptionsButtonClicked "0"
 
   CreateFont $FontBlurb "$(^Font)" "12" "500"
   CreateFont $FontNormal "$(^Font)" "11" "500"
   CreateFont $FontItalic "$(^Font)" "11" "500" /ITALIC
 
   InitPluginsDir
   File /oname=$PLUGINSDIR\bgintro.bmp "bgintro.bmp"
   File /oname=$PLUGINSDIR\bgplain.bmp "bgplain.bmp"
@@ -637,29 +647,16 @@ Function SendPing
     Call RelativeGotoPage
   ${EndIf}
 FunctionEnd
 
 Function createDummy
 FunctionEnd
 
 Function createIntro
-  ; If Back is clicked on the options page reset variables
-  StrCpy $INSTDIR "$InitialInstallDir"
-  StrCpy $CheckboxShortcutOnBar "1"
-  StrCpy $CheckboxShortcutInStartMenu "1"
-  StrCpy $CheckboxShortcutOnDesktop "1"
-  StrCpy $CheckboxSendPing "1"
-!ifdef MOZ_MAINTENANCE_SERVICE
-  StrCpy $CheckboxInstallMaintSvc "1"
-!else
-  StrCpy $CheckboxInstallMaintSvc "0"
-!endif
-  StrCpy $WasOptionsButtonClicked "0"
-
   nsDialogs::Create /NOUNLOAD 1018
   Pop $Dialog
 
   GetFunctionAddress $0 OnBack
   nsDialogs::OnBack /NOUNLOAD $0
 
 !ifdef ${AB_CD}_rtl
   ; For RTL align the text with the top of the F in the Firefox bitmap
@@ -668,43 +665,33 @@ Function createIntro
   ; For LTR align the text with the top of the x in the Firefox bitmap
   StrCpy $0 "${INTRO_BLURB_LTR_TOP_DU}"
 !endif
   ${NSD_CreateLabel} ${INTRO_BLURB_EDGE_DU} $0 ${INTRO_BLURB_WIDTH_DU} 76u "${INTRO_BLURB}"
   Pop $0
   SendMessage $0 ${WM_SETFONT} $FontBlurb 0
   SetCtlColors $0 ${INTRO_BLURB_TEXT_COLOR} transparent
 
-  ${If} "$Initialized" == "true"
-    ; When the user clicked back from the options page.
-    System::Call "kernel32::GetTickCount()l .s"
-    Pop $0
-    ${GetSecondsElapsed} "$StartOptionsPhaseTickCount" "$0" $1
-    ; This is added to the previous value of $OptionsPhaseSeconds because the
-    ; options page can be displayed multiple times.
-    IntOp $OptionsPhaseSeconds $OptionsPhaseSeconds + $1
+  SetCtlColors $HWNDPARENT ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR}
+  GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox
+  ; Set as default is not supported in the installer for Win8 and above so
+  ; only display it on Windows 7 and below
+  ${If} "$CanSetAsDefault" == "true"
+    ; The uxtheme must be disabled on checkboxes in order to override the
+    ; system font color.
+    System::Call 'uxtheme::SetWindowTheme(i $0 , w " ", w " ")'
+    SendMessage $0 ${WM_SETFONT} $FontNormal 0
+    SendMessage $0 ${WM_SETTEXT} 0 "STR:$(MAKE_DEFAULT)"
+    SendMessage $0 ${BM_SETCHECK} 1 0
+    SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR}
   ${Else}
-    SetCtlColors $HWNDPARENT ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR}
-    GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox
-    ; Set as default is not supported in the installer for Win8 and above so
-    ; only display it on Windows 7 and below
-    ${If} "$CanSetAsDefault" == "true"
-      ; The uxtheme must be disabled on checkboxes in order to override the
-      ; system font color.
-      System::Call 'uxtheme::SetWindowTheme(i $0 , w " ", w " ")'
-      SendMessage $0 ${WM_SETFONT} $FontNormal 0
-      SendMessage $0 ${WM_SETTEXT} 0 "STR:$(MAKE_DEFAULT)"
-      SendMessage $0 ${BM_SETCHECK} 1 0
-      SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR}
-    ${Else}
-      ShowWindow $0 ${SW_HIDE}
-    ${EndIf}
-    GetDlgItem $0 $HWNDPARENT 11
     ShowWindow $0 ${SW_HIDE}
   ${EndIf}
+  GetDlgItem $0 $HWNDPARENT 11
+  ShowWindow $0 ${SW_HIDE}
 
   ${NSD_CreateBitmap} ${APPNAME_BMP_EDGE_DU} ${APPNAME_BMP_TOP_DU} \
                       ${APPNAME_BMP_WIDTH_DU} ${APPNAME_BMP_HEIGHT_DU} ""
   Pop $2
   ${SetStretchedTransparentImage} $2 $PLUGINSDIR\appname.bmp $0
 
   ${NSD_CreateBitmap} 0 0 100% 100% ""
   Pop $2
@@ -712,31 +699,29 @@ Function createIntro
 
   GetDlgItem $0 $HWNDPARENT 1 ; Install button
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)"
   ${NSD_SetFocus} $0
 
   GetDlgItem $0 $HWNDPARENT 2 ; Cancel button
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)"
 
-  GetDlgItem $0 $HWNDPARENT 3 ; Back and Options button
+  GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(OPTIONS_BUTTON)"
 
   IntOp $IntroPageShownCount $IntroPageShownCount + 1
 
   System::Call "kernel32::GetTickCount()l .s"
   Pop $StartIntroPhaseTickCount
 
   LockWindow off
   nsDialogs::Show
 
   ${NSD_FreeImage} $0
   ${NSD_FreeImage} $1
-
-  StrCpy $Initialized "true"
 FunctionEnd
 
 Function leaveIntro
   LockWindow on
 
   System::Call "kernel32::GetTickCount()l .s"
   Pop $0
   ${GetSecondsElapsed} "$StartIntroPhaseTickCount" "$0" $1
@@ -768,18 +753,18 @@ Function leaveIntro
   ${If} ${FileExists} "$INSTDIR"
     ; Always display the long path if the path exists.
     ${GetLongPath} "$INSTDIR" $INSTDIR
   ${EndIf}
 
 FunctionEnd
 
 Function createOptions
-  ; Check whether the requirements to install are satisfied the first time the
-  ; options page is displayed for metrics.
+  ; Check whether the install requirements are satisfied using the default
+  ; values for metrics.
   ${If} "$InitialInstallRequirementsCode" == ""
     ${If} "$CanWriteToInstallDir" != "true"
     ${AndIf} "$HasRequiredSpaceAvailable" != "true"
       StrCpy $InitialInstallRequirementsCode "1"
     ${ElseIf} "$CanWriteToInstallDir" != "true"
       StrCpy $InitialInstallRequirementsCode "2"
     ${ElseIf} "$HasRequiredSpaceAvailable" != "true"
       StrCpy $InitialInstallRequirementsCode "3"
@@ -965,18 +950,19 @@ Function createOptions
 
   GetDlgItem $0 $HWNDPARENT 1 ; Install button
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)"
   ${NSD_SetFocus} $0
 
   GetDlgItem $0 $HWNDPARENT 2 ; Cancel button
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)"
 
-  GetDlgItem $0 $HWNDPARENT 3 ; Back and Options button
-  SendMessage $0 ${WM_SETTEXT} 0 "STR:$(BACK_BUTTON)"
+  GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options
+  EnableWindow $0 0
+  ShowWindow $0 ${SW_HIDE}
 
   ; If the option button was not clicked display the reason for what needs to be
   ; resolved to continue the installation.
   ${If} "$WasOptionsButtonClicked" != "1"
     ${If} "$CanWriteToInstallDir" == "false"
       MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS)"
     ${ElseIf} "$HasRequiredSpaceAvailable" == "false"
       MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE)"
@@ -1147,17 +1133,17 @@ Function createInstall
   ${NSD_CreateBitmap} 0 0 100% 100% ""
   Pop $3
   ${NSD_SetStretchedImage} $3 $PLUGINSDIR\bgplain.bmp $1
 
   GetDlgItem $0 $HWNDPARENT 1 ; Install button
   EnableWindow $0 0
   ShowWindow $0 ${SW_HIDE}
 
-  GetDlgItem $0 $HWNDPARENT 3 ; Back and Options button
+  GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options
   EnableWindow $0 0
   ShowWindow $0 ${SW_HIDE}
 
   GetDlgItem $0 $HWNDPARENT 2 ; Cancel button
   SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)"
   ; Focus the Cancel button otherwise it isn't possible to tab to it since it is
   ; the only control that can be tabbed to.
   ${NSD_SetFocus} $0
--- a/browser/locales/en-US/installer/nsisstrings.properties
+++ b/browser/locales/en-US/installer/nsisstrings.properties
@@ -30,17 +30,16 @@ WARN_WRITE_ACCESS=You don't have access 
 WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
 WARN_ROOT_INSTALL=Unable to install to the root of your disk.\n\nClick OK to select a different location.
 WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
 
 ERROR_DOWNLOAD=Your download was interrupted.\n\nPlease click the OK button to continue.
 
 INSTALL_BUTTON=&Install
 UPGRADE_BUTTON=&Upgrade
-BACK_BUTTON=&Back
 CANCEL_BUTTON=Cancel
 OPTIONS_BUTTON=&Options
 
 MAKE_DEFAULT=&Make $BrandShortName my default browser
 CREATE_SHORTCUTS=Create Shortcuts for $BrandShortName:
 ADD_SC_TASKBAR=On my &Task bar
 ADD_SC_QUICKLAUNCHBAR=On my &Quick Launch bar
 ADD_CheckboxShortcutInStartMenu=In my &Start Menu Programs Folder
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -111,17 +111,16 @@
 
 #include "mozAutoDocUpdate.h"
 
 #include "nsCSSParser.h"
 #include "prprf.h"
 #include "nsDOMMutationObserver.h"
 #include "nsSVGFeatures.h"
 #include "nsWrapperCacheInlines.h"
-#include "nsCycleCollector.h"
 #include "xpcpublic.h"
 #include "nsIScriptError.h"
 #include "nsLayoutStatics.h"
 #include "mozilla/Telemetry.h"
 
 #include "mozilla/CORSMode.h"
 
 #include "nsStyledElement.h"
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -120,17 +120,16 @@
 #include "nsDateTimeFormatCID.h"
 #include "nsIDateTimeFormat.h"
 #include "nsEventDispatcher.h"
 #include "nsMutationEvent.h"
 #include "nsDOMCID.h"
 
 #include "jsapi.h"
 #include "nsIXPConnect.h"
-#include "nsCycleCollector.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsICategoryManager.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsIDocumentLoader.h"
 #include "nsIContentViewer.h"
 #include "nsIXMLContentSink.h"
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -21,17 +21,16 @@
 #include "nsAttrValueOrString.h"
 #include "nsBindingManager.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsClientRect.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentList.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsCycleCollector.h"
 #include "nsDocument.h"
 #include "mozilla/dom/Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsDOMCID.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsError.h"
 #include "nsDOMMutationObserver.h"
 #include "nsDOMString.h"
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -3120,17 +3120,17 @@ nsObjectLoadingContent::TeardownProtoCha
 
     obj = proto;
   }
 }
 
 bool
 nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JSHandleObject aObject,
                                      JSHandleId aId, unsigned aFlags,
-                                     JSMutableHandleObject aObjp)
+                                     JS::MutableHandle<JSObject*> aObjp)
 {
   // We don't resolve anything; we just try to make sure we're instantiated
 
   nsRefPtr<nsNPAPIPluginInstance> pi;
   nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
   if (NS_FAILED(rv)) {
     return mozilla::dom::Throw<true>(aCx, rv);
   }
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -146,17 +146,17 @@ class nsObjectLoadingContent : public ns
     // Helper for WebIDL node wrapping
     void SetupProtoChain(JSContext* aCx, JSObject* aObject);
 
     // Remove plugin from protochain
     void TeardownProtoChain();
 
     // Helper for WebIDL newResolve
     bool DoNewResolve(JSContext* aCx, JSHandleObject aObject, JSHandleId aId,
-                      unsigned aFlags, JSMutableHandleObject aObjp);
+                      unsigned aFlags, JS::MutableHandle<JSObject*> aObjp);
 
     // WebIDL API
     nsIDocument* GetContentDocument();
     void GetActualType(nsAString& aType) const
     {
       CopyUTF8toUTF16(mContentType, aType);
     }
     uint32_t DisplayedType() const
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -2412,29 +2412,37 @@ struct MOZ_STACK_CLASS CanvasBidiProcess
                              mBoundingBox.width, mBoundingBox.height));
       if (mOp == CanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL) {
         AdjustedTarget(mCtx, &bounds)->
           FillGlyphs(scaledFont, buffer,
                      CanvasGeneralPattern().
                        ForStyle(mCtx, CanvasRenderingContext2D::STYLE_FILL, mCtx->mTarget),
                      DrawOptions(mState->globalAlpha, mCtx->UsedOperation()));
       } else if (mOp == CanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
-        RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
-
+        // stroke glyphs one at a time to avoid poor CoreGraphics performance
+        // when stroking a path with a very large number of points
+        buffer.mGlyphs = &glyphBuf.front();
+        buffer.mNumGlyphs = 1;
         const ContextState& state = *mState;
-        AdjustedTarget(mCtx, &bounds)->
-          Stroke(path, CanvasGeneralPattern().
-                   ForStyle(mCtx, CanvasRenderingContext2D::STYLE_STROKE, mCtx->mTarget),
-                 StrokeOptions(state.lineWidth, state.lineJoin,
-                               state.lineCap, state.miterLimit,
-                               state.dash.Length(),
-                               state.dash.Elements(),
-                               state.dashOffset),
-                 DrawOptions(state.globalAlpha, mCtx->UsedOperation()));
-
+        AdjustedTarget target(mCtx, &bounds);
+        const StrokeOptions strokeOpts(state.lineWidth, state.lineJoin,
+                                       state.lineCap, state.miterLimit,
+                                       state.dash.Length(),
+                                       state.dash.Elements(),
+                                       state.dashOffset);
+        CanvasGeneralPattern cgp;
+        const Pattern& patForStyle
+          (cgp.ForStyle(mCtx, CanvasRenderingContext2D::STYLE_STROKE, mCtx->mTarget));
+        const DrawOptions drawOpts(state.globalAlpha, mCtx->UsedOperation());
+
+        for (unsigned i = glyphBuf.size(); i > 0; --i) {
+          RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
+          target->Stroke(path, patForStyle, strokeOpts, drawOpts);
+          buffer.mGlyphs++;
+        }
       }
     }
   }
 
   // current text run
   nsAutoPtr<gfxTextRun> mTextRun;
 
   // pointer to a screen reference context used to measure text and such
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -307,16 +307,21 @@ public:
   void UpdateSampleRateIfNeeded(AudioNodeStream* aStream)
   {
     if (mPlaybackRateTimeline.HasSimpleValue()) {
       mPlaybackRate = mPlaybackRateTimeline.GetValue();
     } else {
       mPlaybackRate = mPlaybackRateTimeline.GetValueAtTime<TrackTicks>(aStream->GetCurrentPosition());
     }
 
+    // Make sure the playback rate if something our resampler can work with.
+    if (mPlaybackRate <= 0.0 || mPlaybackRate >= 1024) {
+      mPlaybackRate = 1.0;
+    }
+
     uint32_t currentOutSampleRate, currentInSampleRate;
     if (ShouldResample()) {
       SpeexResamplerState* resampler = Resampler(mChannels);
       speex_resampler_get_rate(resampler, &currentInSampleRate, &currentOutSampleRate);
       uint32_t finalSampleRate = ComputeFinalOutSampleRate();
       if (currentOutSampleRate != finalSampleRate) {
         speex_resampler_set_rate(resampler, currentInSampleRate, finalSampleRate);
       }
--- a/content/media/webaudio/test/Makefile.in
+++ b/content/media/webaudio/test/Makefile.in
@@ -14,16 +14,17 @@ MOCHITEST_FILES := \
   webaudio.js \
   test_bug808374.html \
   test_bug827541.html \
   test_bug839753.html \
   test_bug845960.html \
   test_bug856771.html \
   test_bug866570.html \
   test_bug866737.html \
+  test_bug867089.html \
   test_analyserNode.html \
   test_AudioBuffer.html \
   test_AudioContext.html \
   test_AudioListener.html \
   test_AudioParam.html \
   test_audioBufferSourceNode.html \
   test_audioBufferSourceNodeLoop.html \
   test_audioBufferSourceNodeLoopStartEnd.html \
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_bug867089.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Crashtest for bug 867089</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SpecialPowers.setBoolPref("media.webaudio.enabled", true);
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  var ctx = new AudioContext();
+
+  // Test invalid playbackRate values for AudioBufferSourceNode.
+  var source = ctx.createBufferSource();
+  var buffer = ctx.createBuffer(2, 2048, 8000);
+  source.buffer = buffer;
+  source.playbackRate.value = 0.0;
+  source.connect(ctx.destination);
+  source.start(0);
+
+  var source2 = ctx.createBufferSource();
+  source2.buffer = buffer;
+  source2.playbackRate.value = -1.0;
+  source2.connect(ctx.destination);
+  source2.start(0);
+
+  var source3 = ctx.createBufferSource();
+  source3.buffer = buffer;
+  source3.playbackRate.value = 3000000.0;
+  source3.connect(ctx.destination);
+  source3.start(0);
+  ok(true, "We did not crash.");
+  SpecialPowers.clearUserPref("media.webaudio.enabled");
+  SimpleTest.finish();
+});
+
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -22,17 +22,16 @@ CPPSRCS		= \
 		DOMSVGNumber.cpp \
 		DOMSVGNumberList.cpp \
 		DOMSVGPathSeg.cpp \
 		DOMSVGPathSegList.cpp \
 		DOMSVGPoint.cpp \
 		DOMSVGPointList.cpp \
 		DOMSVGStringList.cpp \
 		DOMSVGTransformList.cpp \
-		nsDOMSVGZoomEvent.cpp \
 		nsISVGPoint.cpp \
 		nsSVGAngle.cpp \
 		nsSVGAnimatedTransformList.cpp \
 		nsSVGBoolean.cpp \
 		nsSVGClass.cpp \
 		nsSVGDataParser.cpp \
 		nsSVGElement.cpp \
 		nsSVGEnum.cpp \
@@ -148,16 +147,17 @@ CPPSRCS		= \
 		SVGTransformableElement.cpp \
 		SVGTransformList.cpp \
 		SVGTransformListParser.cpp \
 		SVGTransformListSMILType.cpp \
 		SVGTSpanElement.cpp \
 		SVGUseElement.cpp \
 		SVGViewBoxSMILType.cpp \
 		SVGViewElement.cpp \
+		SVGZoomEvent.cpp \
 		$(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
rename from content/svg/content/src/nsDOMSVGZoomEvent.cpp
rename to content/svg/content/src/SVGZoomEvent.cpp
--- a/content/svg/content/src/nsDOMSVGZoomEvent.cpp
+++ b/content/svg/content/src/SVGZoomEvent.cpp
@@ -1,34 +1,38 @@
 /* -*- 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 "nsDOMSVGZoomEvent.h"
+#include "mozilla/dom/SVGZoomEvent.h"
 #include "DOMSVGPoint.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/Element.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
+DOMCI_DATA(SVGZoomEvent, mozilla::dom::SVGZoomEvent)
+
+namespace mozilla {
+namespace dom {
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(mozilla::dom::EventTarget* aOwner,
-                                     nsPresContext* aPresContext,
-                                     nsGUIEvent* aEvent)
+SVGZoomEvent::SVGZoomEvent(EventTarget* aOwner,
+                           nsPresContext* aPresContext,
+                           nsGUIEvent* aEvent)
   : nsDOMUIEvent(aOwner, aPresContext,
                  aEvent ? aEvent : new nsGUIEvent(false, NS_SVG_ZOOM, 0))
   , mPreviousScale(0)
   , mNewScale(0)
 {
+  SetIsDOMBinding();
+
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->eventStructType = NS_SVGZOOM_EVENT;
     mEvent->time = PR_Now();
   }
@@ -67,71 +71,25 @@ nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(moz
           mPreviousTranslate->SetReadonly(true);
         }
       }
     }
   }
 }
 
 
-//----------------------------------------------------------------------
-// nsISupports methods:
-
-NS_IMPL_ADDREF_INHERITED(nsDOMSVGZoomEvent, nsDOMUIEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMSVGZoomEvent, nsDOMUIEvent)
-
-DOMCI_DATA(SVGZoomEvent, nsDOMSVGZoomEvent)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMSVGZoomEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGZoomEvent)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGZoomEvent)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMUIEvent)
-
-
-//----------------------------------------------------------------------
-// nsIDOMSVGZoomEvent methods:
-
-/* readonly attribute float previousScale; */
-NS_IMETHODIMP
-nsDOMSVGZoomEvent::GetPreviousScale(float *aPreviousScale)
-{
-  *aPreviousScale = mPreviousScale;
-  return NS_OK;
-}
-
-/* readonly attribute SVGPoint previousTranslate; */
-NS_IMETHODIMP
-nsDOMSVGZoomEvent::GetPreviousTranslate(nsISupports **aPreviousTranslate)
-{
-  *aPreviousTranslate = mPreviousTranslate;
-  NS_IF_ADDREF(*aPreviousTranslate);
-  return NS_OK;
-}
-
-/* readonly attribute float newScale; */
-NS_IMETHODIMP nsDOMSVGZoomEvent::GetNewScale(float *aNewScale)
-{
-  *aNewScale = mNewScale;
-  return NS_OK;
-}
-
-/* readonly attribute SVGPoint newTranslate; */
-NS_IMETHODIMP
-nsDOMSVGZoomEvent::GetNewTranslate(nsISupports **aNewTranslate)
-{
-  *aNewTranslate = mNewTranslate;
-  NS_IF_ADDREF(*aNewTranslate);
-  return NS_OK;
-}
+} // namespace dom
+} // namespace mozilla
 
 
 ////////////////////////////////////////////////////////////////////////
 // Exported creation functions:
 
 nsresult
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aInstancePtrResult,
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       nsGUIEvent *aEvent)
 {
-  nsDOMSVGZoomEvent* it = new nsDOMSVGZoomEvent(aOwner, aPresContext, aEvent);
+  mozilla::dom::SVGZoomEvent* it =
+    new mozilla::dom::SVGZoomEvent(aOwner, aPresContext, aEvent);
   return CallQueryInterface(it, aInstancePtrResult);
 }
rename from content/svg/content/src/nsDOMSVGZoomEvent.h
rename to content/svg/content/src/SVGZoomEvent.h
--- a/content/svg/content/src/nsDOMSVGZoomEvent.h
+++ b/content/svg/content/src/SVGZoomEvent.h
@@ -1,45 +1,66 @@
 /* -*- 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 __NS_SVGZOOMEVENT_H__
-#define __NS_SVGZOOMEVENT_H__
+#ifndef mozilla_dom_SVGZoomEvent_h
+#define mozilla_dom_SVGZoomEvent_h
 
 #include "nsAutoPtr.h"
 #include "nsDOMUIEvent.h"
-#include "nsIDOMSVGZoomEvent.h"
+#include "DOMSVGPoint.h"
+#include "mozilla/dom/SVGZoomEventBinding.h"
 
 class nsGUIEvent;
+class nsISVGPoint;
 class nsPresContext;
 
 namespace mozilla {
-class DOMSVGPoint;
-}
+namespace dom {
 
-class nsDOMSVGZoomEvent : public nsDOMUIEvent,
-                          public nsIDOMSVGZoomEvent
+class SVGZoomEvent MOZ_FINAL : public nsDOMUIEvent
 {
 public:
-  typedef mozilla::DOMSVGPoint DOMSVGPoint;
-
-  nsDOMSVGZoomEvent(mozilla::dom::EventTarget* aOwner,
-                    nsPresContext* aPresContext, nsGUIEvent* aEvent);
-                     
-  // nsISupports interface:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMSVGZoomEvent interface:
-  NS_DECL_NSIDOMSVGZOOMEVENT
+  SVGZoomEvent(EventTarget* aOwner, nsPresContext* aPresContext,
+               nsGUIEvent* aEvent);
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMUIEVENT
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
+  {
+    return SVGZoomEventBinding::Wrap(aCx, aScope, this);
+  }
+
+  float PreviousScale() const
+  {
+    return mPreviousScale;
+  }
+
+  nsISVGPoint* GetPreviousTranslate() const
+  {
+    return mPreviousTranslate;
+  }
+
+  float NewScale() const
+  {
+    return mNewScale;
+  }
+
+  nsISVGPoint* GetNewTranslate() const
+  {
+    return mNewTranslate;
+  }
+
 private:
   float mPreviousScale;
   float mNewScale;
   nsRefPtr<DOMSVGPoint> mPreviousTranslate;
   nsRefPtr<DOMSVGPoint> mNewTranslate;
 };
 
-#endif // __NS_SVGZOOMEVENT_H__
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_SVGZoomEvent_h
--- a/content/svg/content/src/moz.build
+++ b/content/svg/content/src/moz.build
@@ -85,10 +85,11 @@ EXPORTS.mozilla.dom += [
     'SVGTextPathElement.h',
     'SVGTextPositioningElement.h',
     'SVGTitleElement.h',
     'SVGTransformableElement.h',
     'SVGTransform.h',
     'SVGTSpanElement.h',
     'SVGUseElement.h',
     'SVGViewElement.h',
+    'SVGZoomEvent.h',
 ]
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -217,17 +217,16 @@
 #include "nsIDOMSVGAnimatedInteger.h"
 #include "nsIDOMSVGAnimatedNumber.h"
 #include "nsIDOMSVGAnimatedRect.h"
 #include "nsIDOMSVGAnimatedString.h"
 #include "nsIDOMTimeEvent.h"
 #include "nsIDOMSVGLength.h"
 #include "nsIDOMSVGNumber.h"
 #include "nsIDOMSVGRect.h"
-#include "nsIDOMSVGZoomEvent.h"
 
 #include "nsIImageDocument.h"
 
 // Storage includes
 #include "DOMStorage.h"
 
 // Device Storage
 #include "nsIDOMDeviceStorage.h"
@@ -710,18 +709,16 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(SVGAnimatedString, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGLength, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGNumber, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(SVGZoomEvent, nsEventSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozCanvasPrintState, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(WindowUtils, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(XSLTProcessor, nsDOMGenericSH,
@@ -1973,21 +1970,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(SVGNumber, nsIDOMSVGNumber)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGNumber)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGRect, nsIDOMSVGRect)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGRect)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(SVGZoomEvent, nsIDOMSVGZoomEvent)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGZoomEvent)
-    DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(MozCanvasPrintState, nsIDOMMozCanvasPrintState)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCanvasPrintState)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XSLTProcessor, nsIXSLTProcessor)
     DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessor)
     DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessorPrivate)
   DOM_CLASSINFO_MAP_END
@@ -3165,17 +3157,17 @@ GetDocument(JSObject *obj)
   return static_cast<nsHTMLDocument*>(
     static_cast<nsIHTMLDocument*>(::JS_GetPrivate(obj)));
 }
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
                                           JSHandleId id, unsigned flags,
-                                          JSMutableHandleObject objp)
+                                          JS::MutableHandle<JSObject*> objp)
 {
   if (!JSID_IS_STRING(id)) {
     // Nothing to do if we're resolving a non-string property.
     return JS_TRUE;
   }
 
   // Crash reports from the wild seem to get here during shutdown when there's
   // no more XPConnect singleton.
@@ -5358,16 +5350,50 @@ nsNavigatorSH::NewResolve(nsIXPConnectWr
 
   nsDependentJSString name(id);
 
   const nsGlobalNameStruct* name_struct =
     nameSpaceManager->LookupNavigatorName(name);
   if (!name_struct) {
     return NS_OK;
   }
+
+  if (name_struct->mType == nsGlobalNameStruct::eTypeNewDOMBinding) {
+    mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty;
+    MOZ_ASSERT(construct);
+
+    if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) {
+      return NS_OK;
+    }
+
+    JS::Rooted<JSObject*> naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
+    NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR);
+
+    JS::Rooted<JSObject*> domObject(cx);
+    {
+      JSAutoCompartment ac(cx, naviObj);
+      domObject = construct(cx, naviObj);
+      if (!domObject) {
+        return NS_ERROR_FAILURE;
+      }
+    }
+
+    if (!JS_WrapObject(cx, domObject.address()) ||
+        !JS_DefinePropertyById(cx, obj, id,
+                               JS::ObjectValue(*domObject),
+                               nullptr, nullptr, JSPROP_ENUMERATE)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    *_retval = true;
+    *objp = obj;
+
+    return NS_OK;
+  }
+
   NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeNavigatorProperty,
                "unexpected type");
 
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -6384,17 +6410,17 @@ nsHTMLDocumentSH::DocumentAllGetProperty
     vp.setUndefined();
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                        unsigned flags, JSMutableHandleObject objp)
+                                        unsigned flags, JS::MutableHandle<JSObject*> objp)
 {
   JS::RootedValue v(cx);
 
   if (sItem_id == id || sNamedItem_id == id) {
     // Define the item() or namedItem() method.
 
     JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallToGetPropMapper,
                                               0, JSPROP_ENUMERATE);
@@ -6542,17 +6568,17 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
                                               JSHandleId id, unsigned flags,
-                                              JSMutableHandleObject objp)
+                                              JS::MutableHandle<JSObject*> objp)
 {
   if (nsDOMClassInfo::sAll_id == id) {
     // document.all is resolved for the first time. Define it.
     JSObject *helper;
     if (!GetDocumentAllHelper(cx, obj, &helper)) {
       return JS_FALSE;
     }
 
@@ -6568,17 +6594,17 @@ nsHTMLDocumentSH::DocumentAllHelperNewRe
 
   return JS_TRUE;
 }
 
 
 JSBool
 nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj,
                                             JSHandleId id, unsigned flags,
-                                            JSMutableHandleObject objp)
+                                            JS::MutableHandle<JSObject*> objp)
 {
   if (JSID_IS_STRING(id)) {
     nsDocument *doc = GetDocument(obj);
 
     JSObject *proto;
     if (!::JS_GetPrototype(cx, obj, &proto)) {
       return JS_FALSE;
     }
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -367,17 +367,17 @@ public:
                         JSObject **objp, bool *_retval);
   NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
                       JSObject *obj);
   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                          JSObject * obj, JSObject * *_retval);
 
   static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
                                               JSHandleId id, unsigned flags,
-                                              JSMutableHandleObject objp);
+                                              JS::MutableHandle<JSObject*> objp);
   static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj,
                                                JSHandleId id, JSMutableHandleValue vp);
   static JSBool InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
   static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj);
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsWindowSH(aData);
   }
@@ -636,27 +636,27 @@ protected:
   static JSBool GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
                                        nsDocument *doc,
                                        nsContentList **nodeList);
 
 public:
   static JSBool DocumentAllGetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                        JSMutableHandleValue vp);
   static JSBool DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                      unsigned flags, JSMutableHandleObject objp);
+                                      unsigned flags, JS::MutableHandle<JSObject*> objp);
   static void ReleaseDocument(JSFreeOp *fop, JSObject *obj);
   static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
   static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj,
                                              JSHandleId id, JSMutableHandleValue vp);
   static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
                                             JSHandleId id, unsigned flags,
-                                            JSMutableHandleObject objp);
+                                            JS::MutableHandle<JSObject*> objp);
   static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj,
                                           JSHandleId id, unsigned flags,
-                                          JSMutableHandleObject objp);
+                                          JS::MutableHandle<JSObject*> objp);
 
   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                         JSObject *obj, jsid id, uint32_t flags,
                         JSObject **objp, bool *_retval);
   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, jsval *vp, bool *_retval);
 
   static nsresult TryResolveAll(JSContext* cx, nsHTMLDocument* doc,
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -108,17 +108,16 @@ DOMCI_CLASS(TimeEvent)
 DOMCI_CLASS(SVGAnimatedEnumeration)
 DOMCI_CLASS(SVGAnimatedInteger)
 DOMCI_CLASS(SVGAnimatedNumber)
 DOMCI_CLASS(SVGAnimatedRect)
 DOMCI_CLASS(SVGAnimatedString)
 DOMCI_CLASS(SVGLength)
 DOMCI_CLASS(SVGNumber)
 DOMCI_CLASS(SVGRect)
-DOMCI_CLASS(SVGZoomEvent)
 
 // Canvas
 DOMCI_CLASS(MozCanvasPrintState)
 
 // WindowUtils
 DOMCI_CLASS(WindowUtils)
 
 // XSLTProcessor
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -59,17 +59,16 @@
 #include "nsPluginArray.h"
 #include "nsIPluginHost.h"
 #include "nsPluginHost.h"
 #include "nsIPluginInstanceOwner.h"
 #include "nsGeolocation.h"
 #include "mozilla/dom/DesktopNotification.h"
 #include "nsContentCID.h"
 #include "nsLayoutStatics.h"
-#include "nsCycleCollector.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsAutoJSValHolder.h"
 #include "nsDOMMediaQueryList.h"
 #include "mozilla/dom/workers/Workers.h"
 #include "nsJSPrincipals.h"
 #include "mozilla/Attributes.h"
 
 // Interfaces Needed
@@ -491,28 +490,41 @@ nsTimeout::~nsTimeout()
 #ifdef DEBUG_jst
   {
     extern int gTimeoutCnt;
 
     --gTimeoutCnt;
   }
 #endif
 
+  if (mTimer) {
+    mTimer->Cancel();
+    mTimer = nullptr;
+  }
+
   MOZ_COUNT_DTOR(nsTimeout);
 }
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsTimeout)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTimeout)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptHandler)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsTimeout, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsTimeout, Release)
 
+// Return true if this timeout has a refcount of 1. This is used to check
+// that dummy_timeout doesn't leak from nsGlobalWindow::RunTimeout.
+bool
+nsTimeout::HasRefCntOne()
+{
+  return mRefCnt.get() == 1;
+}
+
 nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
 : mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
   mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
   mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
   mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
   mMayHaveMouseEnterLeaveEventListener(false),
   mIsModalContentWindow(false),
   mIsActive(false), mIsBackground(false),
@@ -10298,19 +10310,18 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
   // timeouts will run when the modal dialog is dismissed.
   if (IsInModalState() || mTimeoutsSuspendDepth) {
     return;
   }
 
   NS_ASSERTION(IsInnerWindow(), "Timeout running on outer window!");
   NS_ASSERTION(!IsFrozen(), "Timeout running on a window in the bfcache!");
 
-  nsTimeout *nextTimeout, *timeout;
+  nsTimeout *nextTimeout;
   nsTimeout *last_expired_timeout, *last_insertion_point;
-  nsTimeout dummy_timeout;
   uint32_t firingDepth = mTimeoutFiringDepth + 1;
 
   // Make sure that the window and the script context don't go away as
   // a result of running timeouts
   nsCOMPtr<nsIScriptGlobalObject> windowKungFuDeathGrip(this);
 
   // A native timer has gone off. See which of our timeouts need
   // servicing
@@ -10329,17 +10340,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
     deadline = now;
   }
 
   // The timeout list is kept in deadline order. Discover the latest
   // timeout whose deadline has expired. On some platforms, native
   // timeout events fire "early", so we need to test the timer as well
   // as the deadline.
   last_expired_timeout = nullptr;
-  for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
+  for (nsTimeout *timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
     if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
         (timeout->mFiringDepth == 0)) {
       // Mark any timeouts that are on the list to be fired with the
       // firing depth so that we can reentrantly run timeouts
       timeout->mFiringDepth = firingDepth;
       last_expired_timeout = timeout;
     }
   }
@@ -10361,34 +10372,31 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
     gLastRecordedRecentTimeouts = now;
   }
 
   // Insert a dummy timeout into the list of timeouts between the
   // portion of the list that we are about to process now and those
   // timeouts that will be processed in a future call to
   // win_run_timeout(). This dummy timeout serves as the head of the
   // list for any timeouts inserted as a result of running a timeout.
-  dummy_timeout.mFiringDepth = firingDepth;
-  dummy_timeout.mWhen = now;
-  last_expired_timeout->setNext(&dummy_timeout);
-
-  // Don't let ClearWindowTimeouts throw away our stack-allocated
-  // dummy timeout.
-  dummy_timeout.AddRef();
-  dummy_timeout.AddRef();
+  nsRefPtr<nsTimeout> dummy_timeout = new nsTimeout();
+  dummy_timeout->mFiringDepth = firingDepth;
+  dummy_timeout->mWhen = now;
+  last_expired_timeout->setNext(dummy_timeout);
+  dummy_timeout->AddRef();
 
   last_insertion_point = mTimeoutInsertionPoint;
   // If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
   // the logic in ResetTimersForNonBackgroundWindow will need to change.
-  mTimeoutInsertionPoint = &dummy_timeout;
+  mTimeoutInsertionPoint = dummy_timeout;
 
   Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
 
-  for (timeout = mTimeouts.getFirst();
-       timeout != &dummy_timeout && !IsFrozen();
+  for (nsTimeout *timeout = mTimeouts.getFirst();
+       timeout != dummy_timeout && !IsFrozen();
        timeout = nextTimeout) {
     nextTimeout = timeout->getNext();
 
     if (timeout->mFiringDepth != firingDepth) {
       // We skip the timeout since it's on the list to run at another
       // depth.
 
       continue;
@@ -10432,16 +10440,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
     ++timeoutsRan;
     bool timeout_was_cleared = RunTimeoutHandler(timeout, scx);
 
     if (timeout_was_cleared) {
       // The running timeout's window was cleared, this means that
       // ClearAllTimeouts() was called from a *nested* call, possibly
       // through a timeout that fired while a modal (to this window)
       // dialog was open or through other non-obvious paths.
+      MOZ_ASSERT(dummy_timeout->HasRefCntOne(), "dummy_timeout may leak");
 
       mTimeoutInsertionPoint = last_insertion_point;
 
       return;
     }
 
     // If we have a regular interval timer, we re-schedule the
     // timeout, accounting for clock drift.
@@ -10459,46 +10468,23 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
       InsertTimeoutIntoList(timeout);
     }
 
     // Release the timeout struct since it's possibly out of the list
     timeout->Release();
   }
 
   // Take the dummy timeout off the head of the list
-  dummy_timeout.remove();
+  dummy_timeout->remove();
+  dummy_timeout->Release();
+  MOZ_ASSERT(dummy_timeout->HasRefCntOne(), "dummy_timeout may leak");
 
   mTimeoutInsertionPoint = last_insertion_point;
 }
 
-nsrefcnt
-nsTimeout::Release()
-{
-  if (--mRefCnt > 0)
-    return mRefCnt;
-
-  // language specific cleanup done as mScriptHandler destructs...
-
-  // Kill the timer if it is still alive.
-  if (mTimer) {
-    mTimer->Cancel();
-    mTimer = nullptr;
-  }
-
-  delete this;
-  return 0;
-}
-
-nsrefcnt
-nsTimeout::AddRef()
-{
-  return ++mRefCnt;
-}
-
-
 nsresult
 nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
 {
   FORWARD_TO_INNER(ClearTimeoutOrInterval, (aTimerID), NS_ERROR_NOT_INITIALIZED);
 
   uint32_t public_id = (uint32_t)aTimerID;
   nsTimeout *timeout;
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -141,27 +141,27 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow
  * timeout.  Holds a strong reference to an nsIScriptTimeoutHandler, which
  * abstracts the language specific cruft.
  */
 struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
 {
   nsTimeout();
   ~nsTimeout();
 
-  NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(nsTimeout)
-
-  nsrefcnt Release();
-  nsrefcnt AddRef();
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsTimeout)
 
   nsresult InitTimer(nsTimerCallbackFunc aFunc, uint32_t aDelay)
   {
     return mTimer->InitWithFuncCallback(aFunc, this, aDelay,
                                         nsITimer::TYPE_ONE_SHOT);
   }
 
+  bool HasRefCntOne();
+
   // Window for which this timeout fires
   nsRefPtr<nsGlobalWindow> mWindow;
 
   // The actual timer object
   nsCOMPtr<nsITimer> mTimer;
 
   // True if the timeout was cleared
   bool mCleared;
@@ -196,20 +196,16 @@ struct nsTimeout : mozilla::LinkedListEl
   uint32_t mNestingLevel;
 
   // The popup state at timeout creation time if not created from
   // another timeout
   PopupControlState mPopupState;
 
   // The language-specific information about the callback.
   nsCOMPtr<nsIScriptTimeoutHandler> mScriptHandler;
-
-private:
-  // reference count for shared usage
-  nsAutoRefCnt mRefCnt;
 };
 
 struct IdleObserverHolder
 {
   nsCOMPtr<nsIIdleObserver> mIdleObserver;
   uint32_t mTimeInS;
   bool mPrevNotificationIdle;
 
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -14,19 +14,21 @@
 #include "nsIObserver.h"
 #include "nsIXPCScriptNotify.h"
 #include "prtime.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIXPConnect.h"
 #include "nsIArray.h"
 #include "mozilla/Attributes.h"
 
+class nsICycleCollectorListener;
 class nsIXPConnectJSObjectHolder;
 class nsRootedJSValueArray;
 class nsScriptNameSpaceManager;
+
 namespace mozilla {
 template <class> class Maybe;
 }
 
 // The amount of time we wait between a request to GC (due to leaving
 // a page) and doing the actual GC.
 #define NS_GC_DELAY                 4000 // ms
 
--- a/dom/base/nsScriptNameSpaceManager.cpp
+++ b/dom/base/nsScriptNameSpaceManager.cpp
@@ -817,16 +817,32 @@ nsScriptNameSpaceManager::RegisterDefine
     if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
       s->mType = nsGlobalNameStruct::eTypeNewDOMBinding;
     }
     s->mDefineDOMInterface = aDefineDOMInterface;
     s->mPrefEnabled = aPrefEnabled;
   }
 }
 
+void
+nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
+    const nsAFlatString& aName,
+    mozilla::dom::ConstructNavigatorProperty aNavConstructor,
+    mozilla::dom::PrefEnabled aPrefEnabled)
+{
+  nsGlobalNameStruct *s = AddToHash(&mNavigatorNames, &aName);
+  if (s) {
+    if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
+      s->mType = nsGlobalNameStruct::eTypeNewDOMBinding;
+    }
+    s->mConstructNavigatorProperty = aNavConstructor;
+    s->mPrefEnabled = aPrefEnabled;
+  }
+}
+
 struct GlobalNameClosure
 {
   nsScriptNameSpaceManager::GlobalNameEnumerator enumerator;
   void* closure;
 };
 
 static PLDHashOperator
 EnumerateGlobalName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t,
--- a/dom/base/nsScriptNameSpaceManager.h
+++ b/dom/base/nsScriptNameSpaceManager.h
@@ -62,22 +62,21 @@ struct nsGlobalNameStruct
     int32_t mDOMClassInfoID; // eTypeClassConstructor
     nsIID mIID; // eTypeInterface, eTypeClassProto
     nsExternalDOMClassInfoData* mData; // eTypeExternalClassInfo
     ConstructorAlias* mAlias; // eTypeExternalConstructorAlias
     nsCID mCID; // All other types except eTypeNewDOMBinding
   };
 
   // For new style DOM bindings.
-  mozilla::dom::DefineInterface mDefineDOMInterface;
+  union {
+    mozilla::dom::DefineInterface mDefineDOMInterface; // for window
+    mozilla::dom::ConstructNavigatorProperty mConstructNavigatorProperty; // for navigator
+  };
   mozilla::dom::PrefEnabled mPrefEnabled; // May be null if not pref controlled
-
-private:
-
-  // copy constructor
 };
 
 
 class nsIScriptContext;
 class nsICategoryManager;
 class nsIMemoryReporter;
 class GlobalNameMapEntry;
 
@@ -138,16 +137,20 @@ public:
                              const nsCID *aConstructorCID);
 
   nsGlobalNameStruct* GetConstructorProto(const nsGlobalNameStruct* aStruct);
 
   void RegisterDefineDOMInterface(const nsAFlatString& aName,
     mozilla::dom::DefineInterface aDefineDOMInterface,
     mozilla::dom::PrefEnabled aPrefEnabled);
 
+  void RegisterNavigatorDOMConstructor(const nsAFlatString& aName,
+    mozilla::dom::ConstructNavigatorProperty aNavConstructor,
+    mozilla::dom::PrefEnabled aPrefEnabled);
+
   typedef PLDHashOperator
   (* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure);
 
   void EnumerateGlobalNames(GlobalNameEnumerator aEnumerator,
                             void* aClosure);
 
   size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
 
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1311,16 +1311,26 @@ DOMInterfaces = {
         'register': False
         },
 
 'TestJSImplInterface6' : {
         'headerFile': 'TestJSImplGenBinding.h',
         'register': False
         },
 
+'TestNavigator' : {
+        'headerFile': 'TestJSImplGenBinding.h',
+        'register' : False
+        },
+
+'TestNavigatorWithConstructor' : {
+        'headerFile': 'TestJSImplGenBinding.h',
+        'register' : False
+        },
+
 'TestExternalInterface' : {
         'nativeType': 'mozilla::dom::TestExternalInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestNonWrapperCacheInterface' : {
         'headerFile': 'TestBindingHeader.h',
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1078,16 +1078,65 @@ class CGClassConstructor(CGAbstractStati
   JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
 """
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
         callGenerator = CGMethodCall(nativeName, True, self.descriptor,
                                      self._ctor, isConstructor=True)
         return preamble + callGenerator.define();
 
+# Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
+class CGConstructNavigatorObjectHelper(CGAbstractStaticMethod):
+    """
+    Construct a new JS-implemented WebIDL DOM object, for use on navigator.
+    """
+    def __init__(self, descriptor):
+        name = "ConstructNavigatorObjectHelper"
+        args = [Argument('GlobalObject&', 'global'), Argument('ErrorResult&', 'aRv')]
+        rtype = 'already_AddRefed<%s>' % descriptor.name
+        CGAbstractStaticMethod.__init__(self, descriptor, name, rtype, args)
+
+    def definition_body(self):
+        return genConstructorBody(self.descriptor)
+
+class CGConstructNavigatorObject(CGAbstractMethod):
+    """
+    Wrap a JS-implemented WebIDL object into a JS value, for use on navigator.
+    """
+    def __init__(self, descriptor):
+        name = 'ConstructNavigatorObject'
+        args = [Argument('JSContext*', 'aCx'), Argument('JS::Handle<JSObject*>', 'aObj')]
+        CGAbstractMethod.__init__(self, descriptor, name, 'JSObject*', args)
+
+    def definition_body(self):
+        if not self.descriptor.interface.isJSImplemented():
+            raise TypeError("Only JS-implemented classes are currently supported "
+                            "on navigator. See bug 856820.")
+        return string.Template("""  GlobalObject global(aCx, aObj);
+  if (global.Failed()) {
+    return nullptr;
+  }
+  ErrorResult rv;
+  nsRefPtr<mozilla::dom::${descriptorName}> result = ConstructNavigatorObjectHelper(global, rv);
+  rv.WouldReportJSException();
+  if (rv.Failed()) {
+    ThrowMethodFailedWithDetails<${mainThread}>(aCx, rv, "${descriptorName}", "navigatorConstructor");
+    return nullptr;
+  }
+  JS::Rooted<JS::Value> v(aCx);
+  if (!WrapNewBindingObject(aCx, aObj, result, v.address())) {
+    MOZ_ASSERT(JS_IsExceptionPending(aCx));
+    return nullptr;
+  }
+  return &v.toObject();""").substitute(
+    {
+        'descriptorName' : self.descriptor.name,
+        'mainThread' : toStringBool(not self.descriptor.workers),
+    })
+
 class CGClassConstructHookHolder(CGGeneric):
     def __init__(self, descriptor):
         if descriptor.interface.ctor():
             constructHook = CONSTRUCT_HOOK_NAME
         else:
             constructHook = "ThrowingConstructor"
         CGGeneric.__init__(self,
                            "static const JSNativeHolder " + CONSTRUCT_HOOK_NAME + "_holder = {\n" +
@@ -4795,17 +4844,17 @@ class CGLegacyCallHook(CGAbstractBinding
 class CGNewResolveHook(CGAbstractBindingMethod):
     """
     NewResolve hook for our object
     """
     def __init__(self, descriptor):
         self._needNewResolve = descriptor.interface.getExtendedAttribute("NeedNewResolve")
         args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj_'),
                 Argument('JSHandleId', 'id'), Argument('unsigned', 'flags'),
-                Argument('JSMutableHandleObject', 'objp')]
+                Argument('JS::MutableHandle<JSObject*>', 'objp')]
         # Our "self" is actually the callee in this case, not the thisval.
         CGAbstractBindingMethod.__init__(
             self, descriptor, NEWRESOLVE_HOOK_NAME,
             args, getThisObj="obj_")
 
     def define(self):
         if not self._needNewResolve:
             return ""
@@ -7003,16 +7052,20 @@ class CGDescriptor(CGThing):
         if hasMethod: cgThings.append(CGGenericMethod(descriptor))
         if hasGetter: cgThings.append(CGGenericGetter(descriptor))
         if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
                                                              lenientThis=True))
         if hasSetter: cgThings.append(CGGenericSetter(descriptor))
         if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
                                                              lenientThis=True))
 
+        if descriptor.interface.getNavigatorProperty():
+            cgThings.append(CGConstructNavigatorObjectHelper(descriptor))
+            cgThings.append(CGConstructNavigatorObject(descriptor))
+
         if descriptor.concrete:
             if descriptor.nativeOwnership == 'owned' or descriptor.nativeOwnership == 'refcounted':
                 cgThings.append(CGDeferredFinalizePointers(descriptor))
                 cgThings.append(CGGetDeferredFinalizePointers(descriptor))
                 cgThings.append(CGDeferredFinalize(descriptor))
 
             if not descriptor.proxy:
                 if not descriptor.workers and descriptor.wrapperCache:
@@ -7470,36 +7523,43 @@ class CGRegisterProtos(CGAbstractMethod)
         self.config = config
 
     def _defineMacro(self):
        return """
 #define REGISTER_PROTO(_dom_class, _pref_check) \\
   aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check);
 #define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _pref_check) \\
   aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _pref_check);
+#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _pref_check) \\
+  aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _pref_check);
 
 """
     def _undefineMacro(self):
         return """
 #undef REGISTER_CONSTRUCTOR
-#undef REGISTER_PROTO"""
+#undef REGISTER_PROTO
+#undef REGISTER_NAVIGATOR_CONSTRUCTOR"""
     def _registerProtos(self):
         def getPrefCheck(desc):
             if (desc.interface.getExtendedAttribute("PrefControlled") is None and
                 desc.interface.getExtendedAttribute("Pref") is None):
                 return "nullptr"
             return "%sBinding::PrefEnabled" % desc.name
         lines = []
         for desc in self.config.getDescriptors(hasInterfaceObject=True,
                                                isExternal=False,
                                                workers=False,
                                                register=True):
             lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc)))
             lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getPrefCheck(desc))
                          for n in desc.interface.namedConstructors)
+        for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True):
+            propName = desc.interface.getNavigatorProperty()
+            assert propName
+            lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getPrefCheck(desc)))
         return '\n'.join(lines) + '\n'
     def definition_body(self):
         return self._defineMacro() + self._registerProtos() + self._undefineMacro()
 
 def dependencySortObjects(objects, dependencyGetter, nameGetter):
     """
     Sort IDL objects with dependencies on each other such that if A
     depends on B then B will come before A.  This is needed for
@@ -8441,17 +8501,19 @@ class CGJSImplMethod(CGNativeMember):
         return 'return mImpl->%s(%s);' % (self.name, ", ".join(callbackArgs))
 
     def getConstructorImpl(self):
         assert self.descriptor.interface.isJSImplemented()
         if self.name != 'Constructor':
             raise TypeError("Named constructors are not supported for JS implemented WebIDL. See bug 851287.")
         if len(self.signature[1]) != 0:
             raise TypeError("Constructors with arguments are unsupported. See bug 851178.")
-
+        return genConstructorBody(self.descriptor)
+
+def genConstructorBody(descriptor):
         return string.Template(
 """  // Get the window to use as a parent and for initialization.
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global.Get());
   if (!window) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
   // Get the XPCOM component containing the JS implementation.
@@ -8482,18 +8544,18 @@ class CGJSImplMethod(CGNativeMember):
   }
   JSObject* jsImplObj;
   if (NS_FAILED(implWrapped->GetJSObject(&jsImplObj))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
   // Build the C++ implementation.
   nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, window);
-  return impl.forget();""").substitute({"implClass" : self.descriptor.name,
-                 "contractId" : self.descriptor.interface.getJSImplementation()
+  return impl.forget();""").substitute({"implClass" : descriptor.name,
+                 "contractId" : descriptor.interface.getJSImplementation()
                  })
 
 # We're always fallible
 def callbackGetterName(attr):
     return "Get" + MakeNativeName(attr.identifier.name)
 
 def callbackSetterName(attr):
     return "Set" + MakeNativeName(attr.identifier.name)
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -110,16 +110,18 @@ class Configuration:
             elif key == 'hasInterfaceOrInterfacePrototypeObject':
                 getter = lambda x: x.hasInterfaceOrInterfacePrototypeObject()
             elif key == 'isCallback':
                 getter = lambda x: x.interface.isCallback()
             elif key == 'isExternal':
                 getter = lambda x: x.interface.isExternal()
             elif key == 'isJSImplemented':
                 getter = lambda x: x.interface.isJSImplemented()
+            elif key == 'isNavigatorProperty':
+                getter = lambda x: x.interface.getNavigatorProperty() != None
             else:
                 getter = lambda x: getattr(x, key)
             curr = filter(lambda x: getter(x) == val, curr)
         return curr
     def getEnums(self, webIDLFile):
         return filter(lambda e: e.filename() == webIDLFile, self.enums)
 
     @staticmethod
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -477,16 +477,19 @@ class IDLExternalInterface(IDLObjectWith
         pass
 
     def getJSImplementation(self):
         return None
 
     def isJSImplemented(self):
         return False
 
+    def getNavigatorProperty(self):
+        return None
+
     def _getDependentObjects(self):
         return set()
 
 class IDLInterface(IDLObjectWithScope):
     def __init__(self, location, parentScope, name, parent, members,
                  isPartial):
         assert isinstance(parentScope, IDLScope)
         assert isinstance(name, IDLUnresolvedIdentifier)
@@ -894,21 +897,22 @@ class IDLInterface(IDLObjectWithScope):
                         self.namedConstructors.add(method)
                     elif not newMethod in self.namedConstructors:
                         raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
                                           [method.location, newMethod.location])
             elif (identifier == "PrefControlled" or
                   identifier == "Pref" or
                   identifier == "NeedNewResolve" or
                   identifier == "JSImplementation" or
-                  identifier == "HeaderFile"):
+                  identifier == "HeaderFile" or
+                  identifier == "NavigatorProperty"):
                 # Known attributes that we don't need to do anything with here
                 pass
             else:
-                raise WebIDLError("Unknown extended attribute %s" % identifier,
+                raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
                                   [attr.location])
 
             attrlist = attr.listValue()
             self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
 
     def addImplementedInterface(self, implementedInterface):
         assert(isinstance(implementedInterface, IDLInterface))
         self.implementedInterfaces.add(implementedInterface)
@@ -986,16 +990,25 @@ class IDLInterface(IDLObjectWithScope):
             return classId
         assert isinstance(classId, list)
         assert len(classId) == 1
         return classId[0]
 
     def isJSImplemented(self):
         return bool(self.getJSImplementation())
 
+    def getNavigatorProperty(self):
+        naviProp = self.getExtendedAttribute("NavigatorProperty")
+        if not naviProp:
+            return None
+        assert len(naviProp) == 1
+        assert isinstance(naviProp, list)
+        assert len(naviProp[0]) != 0
+        return naviProp[0]
+
     def hasChildInterfaces(self):
         return self._hasChildInterfaces
 
     def _getDependentObjects(self):
         deps = set(self.members)
         deps.union(self.implementedInterfaces)
         if self.parent:
             deps.add(self.parent)
@@ -2515,17 +2528,17 @@ class IDLAttribute(IDLInterfaceMember):
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "Constant" or
               identifier == "Func" or
               identifier == "Creator"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
-            raise WebIDLError("Unknown extended attribute %s" % identifier,
+            raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def resolve(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         self.type.resolveType(parentScope)
         IDLObjectWithIdentifier.resolve(self, parentScope)
 
@@ -3059,17 +3072,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
               identifier == "Creator" or
               identifier == "ChromeOnly" or
               identifier == "Pref" or
               identifier == "Func" or
               identifier == "WebGLHandlesContextLoss"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
-            raise WebIDLError("Unknown extended attribute %s" % identifier,
+            raise WebIDLError("Unknown extended attribute %s on method" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def _getDependentObjects(self):
         deps = set()
         for overload in self._overloads:
             deps.union(overload._getDependentObjects())
         return deps
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -416,13 +416,21 @@ interface TestJSImplInterface {
   [Throws] void throwingMethod();
   [Throws] attribute boolean throwingAttr;
   [GetterThrows] attribute boolean throwingGetterAttr;
   [SetterThrows] attribute boolean throwingSetterAttr;
 
   // If you add things here, add them to TestCodeGen as well
 };
 
+[NavigatorProperty="TestNavigator", JSImplementation="@mozilla.org/test;1"]
+interface TestNavigator {
+};
+
+[Constructor, NavigatorProperty="TestNavigatorWithConstructor", JSImplementation="@mozilla.org/test;1"]
+interface TestNavigatorWithConstructor {
+};
+
 interface TestCImplementedInterface : TestJSImplInterface {
 };
 
 interface TestCImplementedInterface2 {
 };
--- a/dom/interfaces/svg/moz.build
+++ b/dom/interfaces/svg/moz.build
@@ -12,17 +12,16 @@ XPIDL_SOURCES += [
     'nsIDOMSVGAnimatedNumber.idl',
     'nsIDOMSVGAnimatedRect.idl',
     'nsIDOMSVGAnimatedString.idl',
     'nsIDOMSVGDocument.idl',
     'nsIDOMSVGElement.idl',
     'nsIDOMSVGLength.idl',
     'nsIDOMSVGNumber.idl',
     'nsIDOMSVGRect.idl',
-    'nsIDOMSVGZoomEvent.idl',
 ]
 
 XPIDL_MODULE = 'dom_svg'
 
 XPIDL_FLAGS += [
     '-I$(topsrcdir)/dom/interfaces/base',
     '-I$(topsrcdir)/dom/interfaces/core',
     '-I$(topsrcdir)/dom/interfaces/events',
deleted file mode 100644
--- a/dom/interfaces/svg/nsIDOMSVGZoomEvent.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: IDL; 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 "nsIDOMUIEvent.idl"
-
-/**
- * For more information on this interface please see
- * http://www.w3.org/TR/SVG11/script.html#InterfaceSVGZoomEvent
- */
-
-interface nsIDOMSVGRect;
-
-[scriptable, builtinclass, uuid(9cf032c6-8485-4bde-90d4-0c8bbff27a12)]
-interface nsIDOMSVGZoomEvent : nsIDOMUIEvent
-{
-  // Not implemented
-  // readonly attribute nsIDOMSVGRect  zoomRectScreen;
-  readonly attribute float          previousScale;
-  // SVGPoint
-  readonly attribute nsISupports    previousTranslate;
-  readonly attribute float          newScale;
-  // SVGPoint
-  readonly attribute nsISupports    newTranslate;
-};
--- a/dom/locales/en-US/chrome/plugins.properties
+++ b/dom/locales/en-US/chrome/plugins.properties
@@ -2,18 +2,18 @@
 # 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/.
 
 # LOCALIZATION NOTE (plugins.properties):
 #    Those strings are inserted into an HTML page, so you all HTML characters
 #    have to be escaped in a way that they show up correctly in HTML!
 
 title_label=About Plugins
-enabledplugins_label=Enabled plugins
-nopluginsareenabled_label=No enabled plugins found
+installedplugins_label=Installed plugins
+nopluginsareinstalled_label=No installed plugins found
 findpluginupdates_label=Find updates for installed plugins at
 file_label=File:
 path_label=Path:
 version_label=Version:
 state_label=State:
 mimetype_label=MIME Type
 description_label=Description
 suffixes_label=Suffixes
--- a/dom/network/src/TCPSocketChild.cpp
+++ b/dom/network/src/TCPSocketChild.cpp
@@ -13,17 +13,17 @@
 #include "jsfriendapi.h"
 #include "jswrapper.h"
 
 using mozilla::net::gNeckoChild;
 
 namespace IPC {
 
 bool
-DeserializeArrayBuffer(JSRawObject aObj,
+DeserializeArrayBuffer(JSObject* aObj,
                        const InfallibleTArray<uint8_t>& aBuffer,
                        JS::Value* aVal)
 {
   JSContext* cx = nsContentUtils::GetSafeJSContext();
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, aObj);
 
   JSObject* obj = JS_NewArrayBuffer(cx, aBuffer.Length());
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -9,17 +9,17 @@
 #include "nsIDOMTCPSocket.h"
 #include "mozilla/unused.h"
 #include "mozilla/AppProcessChecker.h"
 
 namespace IPC {
 
 //Defined in TCPSocketChild.cpp
 extern bool
-DeserializeArrayBuffer(JSRawObject aObj,
+DeserializeArrayBuffer(JSObject* aObj,
                        const InfallibleTArray<uint8_t>& aBuffer,
                        JS::Value* aVal);
 
 }
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -121,17 +121,17 @@ static JSBool
 NPObjWrapper_GetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp);
 
 static JSBool
 NPObjWrapper_newEnumerate(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
                           JS::Value *statep, jsid *idp);
 
 static JSBool
 NPObjWrapper_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                        JSMutableHandleObject objp);
+                        JS::MutableHandle<JSObject*> objp);
 
 static JSBool
 NPObjWrapper_Convert(JSContext *cx, JSHandleObject obj, JSType type, JSMutableHandleValue vp);
 
 static void
 NPObjWrapper_Finalize(JSFreeOp *fop, JSObject *obj);
 
 static JSBool
@@ -1555,17 +1555,17 @@ NPObjWrapper_newEnumerate(JSContext *cx,
     break;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
 NPObjWrapper_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                        JSMutableHandleObject objp)
+                        JS::MutableHandle<JSObject*> objp)
 {
   NPObject *npobj = GetNPObject(cx, obj);
 
   if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
       !npobj->_class->hasMethod) {
     ThrowJSException(cx, "Bad NPObject as private data!");
 
     return JS_FALSE;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGZoomEvent.webidl
@@ -0,0 +1,25 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGZoomEvent : UIEvent {
+  // Not implemented
+  // readonly attribute SVGRect zoomRectScreen;
+
+  [Constant]
+  readonly attribute float previousScale;
+  [Constant]
+  readonly attribute SVGPoint? previousTranslate;
+  [Constant]
+  readonly attribute float newScale;
+  [Constant]
+  readonly attribute SVGPoint? newTranslate;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -285,16 +285,17 @@ webidl_files = \
   SVGTransform.webidl \
   SVGTransformList.webidl \
   SVGTSpanElement.webidl \
   SVGUnitTypes.webidl \
   SVGUseElement.webidl \
   SVGURIReference.webidl \
   SVGViewElement.webidl \
   SVGZoomAndPan.webidl \
+  SVGZoomEvent.webidl \
   Text.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   TimeRanges.webidl \
   Touch.webidl \
   TouchEvent.webidl \
   TransitionEvent.webidl \
   TreeColumns.webidl \
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -566,17 +566,17 @@ public:
 
 } /* anonymous namespace */
 
 BEGIN_WORKERS_NAMESPACE
 
 // Entry point for the DOM.
 JSBool
 ResolveWorkerClasses(JSContext* aCx, JSHandleObject aObj, JSHandleId aId, unsigned aFlags,
-                     JSMutableHandleObject aObjp)
+                     JS::MutableHandle<JSObject*> aObjp)
 {
   AssertIsOnMainThread();
 
   // Make sure our strings are interned.
   if (JSID_IS_VOID(gStringIDs[0])) {
     for (uint32_t i = 0; i < ID_COUNT; i++) {
       JSString* str = JS_InternString(aCx, gStringChars[i]);
       if (!str) {
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -806,17 +806,17 @@ private:
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          Class()->name);
     return false;
   }
 
   static JSBool
   Resolve(JSContext* aCx, JSHandleObject aObj, JSHandleId aId, unsigned aFlags,
-          JSMutableHandleObject aObjp)
+          JS::MutableHandle<JSObject*> aObjp)
   {
     JSBool resolved;
     if (!JS_ResolveStandardClass(aCx, aObj, aId, &resolved)) {
       return false;
     }
 
     aObjp.set(resolved ? aObj.get() : NULL);
     return true;
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -40,17 +40,17 @@ AssertIsOnMainThread();
 inline void
 AssertIsOnMainThread()
 { }
 #endif
 
 // All of these are implemented in RuntimeService.cpp
 JSBool
 ResolveWorkerClasses(JSContext* aCx, JSHandleObject aObj, JSHandleId aId, unsigned aFlags,
-                     JSMutableHandleObject aObjp);
+                     JS::MutableHandle<JSObject*> aObjp);
 
 void
 CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
 void
 SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
 void
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -396,17 +396,17 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& a
                            float aSigma)
   : mRect(int32_t(aRect.x), int32_t(aRect.y),
           int32_t(aRect.width), int32_t(aRect.height)),
     mSpreadRadius(),
     mBlurRadius(CalculateBlurRadius(Point(aSigma, aSigma))),
     mStride(aStride),
     mSurfaceAllocationSize(-1)
 {
-  CheckedInt<int32_t> minDataSize = CheckedInt<int32_t>(aRect.width*aRect.height);
+  CheckedInt<int32_t> minDataSize = CheckedInt<int32_t>(aRect.width)*aRect.height;
   if (minDataSize.isValid()) {
     mSurfaceAllocationSize = minDataSize.value();
   }
 }
 
 
 AlphaBoxBlur::~AlphaBoxBlur()
 {
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -665,20 +665,17 @@ DrawTargetCG::Stroke(const Path *aPath, 
   SetStrokeOptions(cg, aStrokeOptions);
 
   if (isGradient(aPattern)) {
     CGContextReplacePathWithStrokedPath(cg);
     //XXX: should we use EO clip here?
     CGContextClip(cg);
     DrawGradient(cg, aPattern);
   } else {
-    CGContextBeginPath(cg);
     // XXX: we could put fill mode into the path fill rule if we wanted
-    const PathCG *cgPath = static_cast<const PathCG*>(aPath);
-    CGContextAddPath(cg, cgPath->GetPath());
 
     SetStrokeFromPattern(cg, mColorSpace, aPattern);
     CGContextStrokePath(cg);
   }
 
   fixer.Fix(mCg);
   CGContextRestoreGState(mCg);
 }
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -170,16 +170,31 @@ ImageClientSingle::UpdateImage(ImageCont
 
     AutoLockTextureClient lock(mTextureClient);
 
     SurfaceDescriptor desc = static_cast<GonkIOSurfaceImage*>(image)->GetSurfaceDescriptor();
     if (!IsSurfaceDescriptorValid(desc)) {
       return false;
     }
     mTextureClient->SetDescriptor(desc);
+  } else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) {
+    EnsureTextureClient(TEXTURE_SHARED_GL_EXTERNAL);
+
+    nsIntRect rect(0, 0,
+                   image->GetSize().width,
+                   image->GetSize().height);
+    UpdatePictureRect(rect);
+
+    AutoLockTextureClient lock(mTextureClient);
+
+    SurfaceDescriptor desc = static_cast<GrallocPlanarYCbCrImage*>(image)->GetSurfaceDescriptor();
+    if (!IsSurfaceDescriptorValid(desc)) {
+      return false;
+    }
+    mTextureClient->SetDescriptor(desc);
 #endif
   } else {
     nsRefPtr<gfxASurface> surface = image->GetAsSurface();
     MOZ_ASSERT(surface);
 
     EnsureTextureClient(TEXTURE_SHMEM);
 
     nsRefPtr<gfxPattern> pattern = new gfxPattern(surface);
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -170,28 +170,27 @@ NS_MEMORY_REPORTER_IMPLEMENT(GrallocBuff
   "Special RAM that can be shared between processes and directly "
   "accessed by both the CPU and GPU.  Gralloc memory is usually a "
   "relatively precious resource, with much less available than generic "
   "RAM.  When it's exhausted, graphics performance can suffer. "
   "This value can be incorrect because of race conditions.");
 
 GrallocBufferActor::GrallocBufferActor()
 : mAllocBytes(0)
+, mTextureHost(nullptr)
 {
   static bool registered;
   if (!registered) {
     // We want to be sure that the first call here will always run on
     // the main thread.
     NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
     NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(GrallocBufferActor));
     registered = true;
   }
-
-  mTextureHost = nullptr;
 }
 
 GrallocBufferActor::~GrallocBufferActor()
 {
   if (mAllocBytes > 0) {
     sCurrentAlloc -= mAllocBytes;
   }
 }
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -588,32 +588,64 @@ SurfaceFormatForAndroidPixelFormat(andro
   case android::PIXEL_FORMAT_RGBA_8888:
     return FORMAT_B8G8R8A8;
   case android::PIXEL_FORMAT_RGBX_8888:
     return FORMAT_B8G8R8X8;
   case android::PIXEL_FORMAT_RGB_565:
     return FORMAT_R5G6B5;
   case android::PIXEL_FORMAT_A_8:
     return FORMAT_A8;
-  case 17: // NV21 YUV format, see http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21
+  case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+  case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+  case HAL_PIXEL_FORMAT_YCbCr_422_I:
+  case HAL_PIXEL_FORMAT_YV12:
     return FORMAT_B8G8R8A8; // yup, use FORMAT_B8G8R8A8 even though it's a YUV texture. This is an external texture.
   default:
-    MOZ_NOT_REACHED("Unknown Android pixel format");
-    return FORMAT_UNKNOWN;
+    if (aFormat >= 0x100 && aFormat <= 0x1FF) {
+      // Reserved range for HAL specific formats.
+      return FORMAT_B8G8R8A8;
+    } else {
+      // This is not super-unreachable, there's a bunch of hypothetical pixel
+      // formats we don't deal with.
+      // We only want to abort in debug builds here, since if we crash here
+      // we'll take down the compositor process and thus the phone. This seems
+      // like undesirable behaviour. We'd rather have a subtle artifact.
+      MOZ_ASSERT(false, "Unknown Android pixel format.");
+      return FORMAT_UNKNOWN;
+    }
   }
 }
 
 static GLenum
 TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
 {
   switch (aFormat) {
-  case 17: // NV21 YUV format, see http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21
+  case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+  case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+  case HAL_PIXEL_FORMAT_YCbCr_422_I:
+  case HAL_PIXEL_FORMAT_YV12:
     return LOCAL_GL_TEXTURE_EXTERNAL;
+  case android::PIXEL_FORMAT_RGBA_8888:
+  case android::PIXEL_FORMAT_RGBX_8888:
+  case android::PIXEL_FORMAT_RGB_565:
+  case android::PIXEL_FORMAT_A_8:
+    return LOCAL_GL_TEXTURE_2D;
   default:
-    return LOCAL_GL_TEXTURE_2D;
+    if (aFormat >= 0x100 && aFormat <= 0x1FF) {
+      // Reserved range for HAL specific formats.
+      return LOCAL_GL_TEXTURE_EXTERNAL;
+    } else {
+      // This is not super-unreachable, there's a bunch of hypothetical pixel
+      // formats we don't deal with.
+      // We only want to abort in debug builds here, since if we crash here
+      // we'll take down the compositor process and thus the phone. This seems
+      // like undesirable behaviour. We'd rather have a subtle artifact.
+      MOZ_ASSERT(false, "Unknown Android pixel format.");
+      return LOCAL_GL_TEXTURE_EXTERNAL;
+    }
   }
 }
 
 void GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
 {
   CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
   if (mGL && !glCompositor) {
     DeleteTextures();
@@ -655,16 +687,21 @@ GrallocTextureHostOGL::UpdateImpl(const 
 }
 
 void
 GrallocTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                         nsIntRegion*)
 {
   MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc);
 
+  if (mBuffer) {
+    // only done for hacky fix in gecko 23 for bug 862324.
+    RegisterTextureHostAtGrallocBufferActor(nullptr, *mBuffer);
+  }
+
   const SurfaceDescriptorGralloc& desc = aImage.get_SurfaceDescriptorGralloc();
   mGraphicBuffer = GrallocBufferActor::GetFrom(desc);
   mFormat = SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
   mTextureTarget = TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
 
   DeleteTextures();
 
   // only done for hacky fix in gecko 23 for bug 862324.
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -324,17 +324,17 @@ JSObject_to_PObjectWrapperParent(JSConte
     *to = owp;
     return true;
 }
 
 /*static*/ bool
 ObjectWrapperParent::
 JSObject_from_PObjectWrapperParent(JSContext* cx,
                                    const PObjectWrapperParent* from,
-                                   JSMutableHandleObject to)
+                                   JS::MutableHandleObject to)
 {
     const ObjectWrapperParent* owp =
         static_cast<const ObjectWrapperParent*>(from);
     to.set(owp
            ? owp->GetJSObject(cx)
            : JSVAL_TO_OBJECT(JSVAL_NULL));
     return true;
 }
@@ -570,17 +570,17 @@ ObjectWrapperParent::CPOW_NewEnumerate(J
     }
 
     NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
     return JS_FALSE;
 }
 
 /*static*/ JSBool
 ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                     unsigned flags, JSMutableHandleObject objp)
+                                     unsigned flags, JS::MutableHandleObject objp)
 {
     CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
               JSVAL_TO_CSTR(cx, id)));
 
     ObjectWrapperParent* self = Unwrap(cx, obj);
     if (!self)
         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
 
--- a/js/ipc/ObjectWrapperParent.h
+++ b/js/ipc/ObjectWrapperParent.h
@@ -74,17 +74,17 @@ private:
     JSBool NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp);
     JSBool NewEnumerateDestroy(JSContext* cx, jsval state);
     static JSBool
     CPOW_NewEnumerate(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
                       jsval *statep, jsid *idp);
 
     static JSBool
     CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                    JSMutableHandleObject objp);
+                    JS::MutableHandleObject objp);
 
     static JSBool
     CPOW_Convert(JSContext *cx, JSHandleObject obj, JSType type, JSMutableHandleValue vp);
 
     static void
     CPOW_Finalize(js::FreeOp* fop, JSObject* obj);
 
     static JSBool
@@ -101,17 +101,17 @@ private:
                                      jsval* to);
     static bool boolean_from_JSVariant(JSContext* cx, const JSVariant& from,
                                        JSBool* to);
     static bool
     JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from, PObjectWrapperParent** to);
     static bool
     JSObject_from_PObjectWrapperParent(JSContext* cx,
                                        const PObjectWrapperParent* from,
-                                       JSMutableHandleObject to);
+                                       JS::MutableHandleObject to);
     static bool
     jsval_from_PObjectWrapperParent(JSContext* cx,
                                     const PObjectWrapperParent* from,
                                     jsval* to);
 };
 
 template <class StatusOwnerPolicy>
 class AutoCheckOperationBase
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4415,19 +4415,23 @@ if test "$ACCESSIBILITY" -a "$MOZ_ENABLE
     AC_DEFINE_UNQUOTED(ATK_REV_VERSION, $ATK_REV_VERSION)
 fi
 
 
 dnl ========================================================
 dnl ECMAScript Internationalization API Support (uses ICU)
 dnl ========================================================
 
+if test -n "$JS_STANDALONE"; then
+    ENABLE_INTL_API=1
+fi
 MOZ_ARG_ENABLE_BOOL(intl-api,
-[  --enable-intl-api       Enable ECMAScript Internationalization API],
-    ENABLE_INTL_API=1 )
+[  --enable-intl-api       Enable ECMAScript Internationalization API (default=yes for standalone JS)],
+    ENABLE_INTL_API=1,
+    ENABLE_INTL_API= )
 
 dnl Settings for the implementation of the ECMAScript Internationalization API
 if test -n "$ENABLE_INTL_API"; then
     AC_DEFINE(ENABLE_INTL_API)
     # We build ICU as a static library.
     AC_DEFINE(U_STATIC_IMPLEMENTATION)
 
     case "$OS_TARGET" in
@@ -4496,17 +4500,17 @@ if test -n "$ENABLE_INTL_API" ; then
     if test -z "$MOZ_OPTIMIZE"; then
         ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release"
     fi
 
     abs_srcdir=`(cd $srcdir; pwd)`
     mkdir -p $_objdir/intl/icu
     (cd $_objdir/intl/icu; \
      CFLAGS="$ICU_CFLAGS" CPPFLAGS="$ICU_CPPFLAGS" CXXFLAGS="$ICU_CXXFLAGS" \
-            $(SHELL) $abs_srcdir/../../intl/icu/source/runConfigureICU \
+            $SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \
             $ICU_BUILD_OPTS \
             $ICU_TARGET \
             $ICU_LINK_OPTS \
             --enable-extras=no --enable-icuio=no  --enable-layout=no \
             --enable-tests=no --enable-samples=no || exit 1
     ) || exit 1
 fi
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -1317,17 +1317,17 @@ JS_InitCTypesClass(JSContext* cx, JSObje
     return false;
 
 
   // Seal the ctypes object, to prevent modification.
   return JS_FreezeObject(cx, ctypes);
 }
 
 JS_PUBLIC_API(void)
-JS_SetCTypesCallbacks(JSRawObject ctypesObj, JSCTypesCallbacks* callbacks)
+JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks* callbacks)
 {
   JS_ASSERT(callbacks);
   JS_ASSERT(IsCTypesGlobal(ctypesObj));
 
   // Set the callbacks on a reserved slot.
   JS_SetReservedSlot(ctypesObj, SLOT_CALLBACKS, PRIVATE_TO_JSVAL(callbacks));
 }
 
@@ -2286,17 +2286,17 @@ ImplicitConvert(JSContext* cx,
 #include "typedefs.h"
   case TYPE_pointer: {
     if (JSVAL_IS_NULL(val)) {
       // Convert to a null pointer.
       *static_cast<void**>(buffer) = NULL;
       break;
     }
 
-    JSObject* baseType = PointerType::GetBaseType(targetType);
+    JS::Rooted<JSObject*> baseType(cx, PointerType::GetBaseType(targetType));
     if (sourceData) {
       // First, determine if the targetType is ctypes.void_t.ptr.
       TypeCode sourceCode = CType::GetTypeCode(sourceType);
       void* sourceBuffer = CData::GetData(sourceData);
       bool voidptrTarget = CType::GetTypeCode(baseType) == TYPE_void_t;
 
       if (sourceCode == TYPE_pointer && voidptrTarget) {
         // Autoconvert if targetType is ctypes.voidptr_t.
@@ -3742,17 +3742,17 @@ CType::ToSource(JSContext* cx, unsigned 
 }
 
 JSBool
 CType::HasInstance(JSContext* cx, JSHandleObject obj, JSMutableHandleValue v, JSBool* bp)
 {
   JS_ASSERT(CType::IsCType(obj));
 
   jsval slot = JS_GetReservedSlot(obj, SLOT_PROTO);
-  RootedObject prototype(cx, &slot.toObject());
+  JS::Rooted<JSObject*> prototype(cx, &slot.toObject());
   JS_ASSERT(prototype);
   JS_ASSERT(CData::IsCDataProto(prototype));
 
   *bp = JS_FALSE;
   if (JSVAL_IS_PRIMITIVE(v))
     return JS_TRUE;
 
   RootedObject proto(cx, &v.toObject());
@@ -7113,17 +7113,17 @@ JSBool
 CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval *vp)
 {
   CallArgs args = CallArgsFromVp(argc, vp);
   if (args.length() != 0) {
     JS_ReportError(cx, "CDataFinalizer.prototype.forget takes no arguments");
     return JS_FALSE;
   }
 
-  RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
+  JS::Rooted<JSObject*> obj(cx, args.thisv().toObjectOrNull());
   if (!obj)
     return JS_FALSE;
   if (!CDataFinalizer::IsCDataFinalizer(obj)) {
     return TypeError(cx, "a CDataFinalizer", OBJECT_TO_JSVAL(obj));
   }
 
   CDataFinalizer::Private *p = (CDataFinalizer::Private *)
     JS_GetPrivate(obj);
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -53,31 +53,38 @@ StoreBuffer::SlotEdge::inRememberedSet(N
 JS_ALWAYS_INLINE bool
 StoreBuffer::SlotEdge::isNullEdge() const
 {
     return !deref();
 }
 
 /*** MonoTypeBuffer ***/
 
+
+/* How full we allow a store buffer to become before we request a MinorGC. */
+const static double HighwaterRatio = 7.0 / 8.0;
+
 template <typename T>
 bool
 StoreBuffer::MonoTypeBuffer<T>::enable(uint8_t *region, size_t len)
 {
     JS_ASSERT(len % sizeof(T) == 0);
     base = pos = reinterpret_cast<T *>(region);
     top = reinterpret_cast<T *>(region + len);
+    highwater = reinterpret_cast<T *>(region + size_t(double(len) * HighwaterRatio));
+    JS_ASSERT(highwater > base);
+    JS_ASSERT(highwater < top);
     return true;
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::disable()
 {
-    base = pos = top = NULL;
+    base = pos = top = highwater = NULL;
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::clear()
 {
     pos = base;
 }
@@ -92,47 +99,43 @@ StoreBuffer::MonoTypeBuffer<T>::compactN
         if (v->inRememberedSet(nursery))
             *insert++ = *v;
     }
     pos = insert;
 }
 
 template <typename T>
 void
+StoreBuffer::MonoTypeBuffer<T>::compactRemoveDuplicates()
+{
+    JS_ASSERT(duplicates.empty());
+
+    T *insert = base;
+    for (T *v = base; v != pos; ++v) {
+        if (!duplicates.has(v->location())) {
+            *insert++ = *v;
+            /* Failure to insert will leave the set with duplicates. Oh well. */
+            duplicates.put(v->location());
+        }
+    }
+    pos = insert;
+    duplicates.clear();
+}
+
+template <typename T>
+void
 StoreBuffer::MonoTypeBuffer<T>::compact()
 {
 #ifdef JS_GC_ZEAL
     if (owner->runtime->gcVerifyPostData)
         compactNotInSet(&owner->runtime->gcVerifierNursery);
     else
 #endif
         compactNotInSet(&owner->runtime->gcNursery);
-}
-
-template <typename T>
-void
-StoreBuffer::MonoTypeBuffer<T>::put(const T &v)
-{
-    /* Check if we have been enabled. */
-    if (!pos)
-        return;
-
-    /*
-     * Note: it is sometimes valid for a put to happen in the middle of a GC,
-     * e.g. a rekey of a Relocatable may end up here. In general, we do not
-     * care about these new entries or any overflows they cause.
-     */
-    *pos++ = v;
-    if (isFull()) {
-        compact();
-        if (isFull()) {
-            owner->setOverflowed();
-            pos = base;
-        }
-    }
+    compactRemoveDuplicates();
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::mark(JSTracer *trc)
 {
     compact();
     T *cursor = base;
@@ -196,23 +199,16 @@ StoreBuffer::RelocatableMonoTypeBuffer<T
 template <typename T>
 void
 StoreBuffer::RelocatableMonoTypeBuffer<T>::compact()
 {
     compactMoved();
     StoreBuffer::MonoTypeBuffer<T>::compact();
 }
 
-template <typename T>
-void
-StoreBuffer::RelocatableMonoTypeBuffer<T>::unput(const T &v)
-{
-    MonoTypeBuffer<T>::put(v.tagged());
-}
-
 /*** GenericBuffer ***/
 
 bool
 StoreBuffer::GenericBuffer::enable(uint8_t *region, size_t len)
 {
     base = pos = region;
     top = region + len;
     return true;
@@ -331,16 +327,18 @@ StoreBuffer::enable()
 }
 
 void
 StoreBuffer::disable()
 {
     if (!enabled)
         return;
 
+    aboutToOverflow = false;
+
     bufferVal.disable();
     bufferCell.disable();
     bufferSlot.disable();
     bufferRelocVal.disable();
     bufferRelocCell.disable();
     bufferGeneric.disable();
 
     js_free(buffer);
@@ -349,16 +347,18 @@ StoreBuffer::disable()
 }
 
 bool
 StoreBuffer::clear()
 {
     if (!enabled)
         return true;
 
+    aboutToOverflow = false;
+
     bufferVal.clear();
     bufferCell.clear();
     bufferSlot.clear();
     bufferRelocVal.clear();
     bufferRelocCell.clear();
     bufferGeneric.clear();
 
     return true;
@@ -374,16 +374,23 @@ StoreBuffer::mark(JSTracer *trc)
     bufferCell.mark(trc);
     bufferSlot.mark(trc);
     bufferRelocVal.mark(trc);
     bufferRelocCell.mark(trc);
     bufferGeneric.mark(trc);
 }
 
 void
+StoreBuffer::setAboutToOverflow()
+{
+    aboutToOverflow = true;
+    runtime->triggerOperationCallback();
+}
+
+void
 StoreBuffer::setOverflowed()
 {
     JS_ASSERT(enabled);
     overflowed = true;
 }
 
 bool
 StoreBuffer::coalesceForVerification()
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -132,41 +132,79 @@ class StoreBuffer
         friend class StoreBuffer;
 
         StoreBuffer *owner;
 
         T *base;      /* Pointer to the start of the buffer. */
         T *pos;       /* Pointer to the current insertion position. */
         T *top;       /* Pointer to one element after the end. */
 
+        /*
+         * If the buffer's insertion position goes over the high-water-mark,
+         * we trigger a minor GC at the next operation callback.
+         */
+        T *highwater;
+
+        /*
+         * This set stores duplicates found when compacting. We create the set
+         * here, rather than local to the algorithm to avoid malloc overhead in
+         * the common case.
+         */
+        EdgeSet duplicates;
+
         MonoTypeBuffer(StoreBuffer *owner)
           : owner(owner), base(NULL), pos(NULL), top(NULL)
-        {}
+        {
+            duplicates.init();
+        }
 
         MonoTypeBuffer &operator=(const MonoTypeBuffer& other) MOZ_DELETE;
 
         bool enable(uint8_t *region, size_t len);
         void disable();
         void clear();
 
         bool isEmpty() const { return pos == base; }
         bool isFull() const { JS_ASSERT(pos <= top); return pos == top; }
+        bool isAboutToOverflow() const { return pos >= highwater; }
 
         /* Compaction algorithms. */
         template <typename NurseryType>
         void compactNotInSet(NurseryType *nursery);
+        void compactRemoveDuplicates();
 
         /*
          * Attempts to reduce the usage of the buffer by removing unnecessary
          * entries.
          */
         virtual void compact();
 
         /* Add one item to the buffer. */
-        void put(const T &v);
+        void put(const T &v) {
+            /* Check if we have been enabled. */
+            if (!pos)
+                return;
+
+            /*
+             * Note: it is sometimes valid for a put to happen in the middle of a GC,
+             * e.g. a rekey of a Relocatable may end up here. In general, we do not
+             * care about these new entries or any overflows they cause.
+             */
+            *pos++ = v;
+            if (isAboutToOverflow()) {
+                owner->setAboutToOverflow();
+                if (isFull()) {
+                    compact();
+                    if (isFull()) {
+                        owner->setOverflowed();
+                        clear();
+                    }
+                }
+            }
+        }
 
         /* Mark the source of all edges in the store buffer. */
         void mark(JSTracer *trc);
 
         /* For verification. */
         bool accumulateEdges(EdgeSet &edges);
     };
 
@@ -183,17 +221,19 @@ class StoreBuffer
           : MonoTypeBuffer<T>(owner)
         {}
 
         /* Override compaction to filter out removed items. */
         void compactMoved();
         virtual void compact();
 
         /* Record a removal from the buffer. */
-        void unput(const T &v);
+        void unput(const T &v) {
+            MonoTypeBuffer<T>::put(v.tagged());
+        }
     };
 
     class GenericBuffer
     {
         friend class StoreBuffer;
 
         StoreBuffer *owner;
 
@@ -340,16 +380,17 @@ class StoreBuffer
     RelocatableMonoTypeBuffer<ValueEdge> bufferRelocVal;
     RelocatableMonoTypeBuffer<CellPtrEdge> bufferRelocCell;
     GenericBuffer bufferGeneric;
 
     JSRuntime *runtime;
 
     void *buffer;
 
+    bool aboutToOverflow;
     bool overflowed;
     bool enabled;
 
     /* For the verifier. */
     EdgeSet edgeSet;
 
 #ifdef JS_GC_ZEAL
     /* For verification, we approximate an infinitly large buffer. */
@@ -368,32 +409,35 @@ class StoreBuffer
     static const size_t RelocCellBufferSize = 1 * 1024 * sizeof(CellPtrEdge);
     static const size_t GenericBufferSize = 1 * 1024 * sizeof(int);
 #endif
     static const size_t TotalSize = ValueBufferSize + CellBufferSize +
                                     SlotBufferSize + RelocValueBufferSize + RelocCellBufferSize +
                                     GenericBufferSize;
 
     /* For use by our owned buffers. */
+    void setAboutToOverflow();
     void setOverflowed();
 
   public:
     explicit StoreBuffer(JSRuntime *rt)
       : bufferVal(this), bufferCell(this), bufferSlot(this),
         bufferRelocVal(this), bufferRelocCell(this), bufferGeneric(this),
-        runtime(rt), buffer(NULL), overflowed(false), enabled(false)
+        runtime(rt), buffer(NULL), aboutToOverflow(false), overflowed(false),
+        enabled(false)
     {}
 
     bool enable();
     void disable();
     bool isEnabled() { return enabled; }
 
     bool clear();
 
     /* Get the overflowed status. */
+    bool isAboutToOverflow() const { return aboutToOverflow; }
     bool hasOverflowed() const { return overflowed; }
 
     /* Insert a single edge into the buffer/remembered set. */
     void putValue(Value *v) {
         bufferVal.put(v);
     }
     void putCell(Cell **o) {
         bufferCell.put(o);
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -23,20 +23,16 @@
 
 using namespace js;
 using namespace js::gc;
 
 JS::Zone::Zone(JSRuntime *rt)
   : rt(rt),
     allocator(this),
     hold(false),
-#ifdef JSGC_GENERATIONAL
-    gcNursery(),
-    gcStoreBuffer(rt),
-#endif
     ionUsingBarriers_(false),
     active(false),
     gcScheduled(false),
     gcState(NoGC),
     gcPreserveCode(false),
     gcBytes(0),
     gcTriggerBytes(0),
     gcHeapGrowthFactor(3.0),
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -106,21 +106,16 @@ struct Zone : private JS::shadow::Zone, 
 {
     JSRuntime                    *rt;
     js::Allocator                allocator;
 
     js::CompartmentVector        compartments;
 
     bool                         hold;
 
-#ifdef JSGC_GENERATIONAL
-    js::gc::VerifierNursery      gcNursery;
-    js::gc::StoreBuffer          gcStoreBuffer;
-#endif
-
   private:
     bool                         ionUsingBarriers_;
   public:
 
     bool                         active;  // GC flag, whether there are active frames
 
     bool needsBarrier() const {
         return needsBarrier_;
--- a/js/src/ion/AsmJS.cpp
+++ b/js/src/ion/AsmJS.cpp
@@ -2277,17 +2277,17 @@ class FunctionCompiler
 /*****************************************************************************/
 // An AsmJSModule contains the persistent results of asm.js module compilation,
 // viz., the jit code and dynamic link information.
 //
 // An AsmJSModule object is created at the end of module compilation and
 // subsequently owned by an AsmJSModuleClass JSObject.
 
 static void AsmJSModuleObject_finalize(FreeOp *fop, RawObject obj);
-static void AsmJSModuleObject_trace(JSTracer *trc, JSRawObject obj);
+static void AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj);
 
 static const unsigned ASM_CODE_RESERVED_SLOT = 0;
 static const unsigned ASM_CODE_NUM_RESERVED_SLOTS = 1;
 
 static Class AsmJSModuleClass = {
     "AsmJSModuleObject",
     JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(ASM_CODE_NUM_RESERVED_SLOTS),
@@ -2335,17 +2335,17 @@ js::SetAsmJSModuleObject(JSFunction *mod
 
 static void
 AsmJSModuleObject_finalize(FreeOp *fop, RawObject obj)
 {
     fop->delete_(&AsmJSModuleObjectToModule(obj));
 }
 
 static void
-AsmJSModuleObject_trace(JSTracer *trc, JSRawObject obj)
+AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
 {
     AsmJSModuleObjectToModule(obj).trace(trc);
 }
 
 static JSObject *
 NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module)
 {
     JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleClass, NULL, NULL);
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -46,17 +46,17 @@ static JSClass DocumentAllClass = {
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
 JSBool
 document_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                 JSMutableHandleObject objp)
+                 JS::MutableHandleObject objp)
 {
     // If id is "all", resolve document.all=true.
     JS::RootedValue v(cx);
     if (!JS_IdToValue(cx, id, v.address()))
         return false;
     if (JSVAL_IS_STRING(v)) {
         JSString *str = JSVAL_TO_STRING(v);
         JSFlatString *flatStr = JS_FlattenString(cx, str);
--- a/js/src/jsapi-tests/testResolveRecursion.cpp
+++ b/js/src/jsapi-tests/testResolveRecursion.cpp
@@ -64,17 +64,17 @@ struct AutoIncrCounters {
     ~AutoIncrCounters() {
         t->resolveExitCount++;
     }
 
     cls_testResolveRecursion *t;
 };
 
 bool
-doResolve(JSHandleObject obj, JSHandleId id, unsigned flags, JSMutableHandleObject objp)
+doResolve(JSHandleObject obj, JSHandleId id, unsigned flags, JS::MutableHandleObject objp)
 {
     CHECK_EQUAL(resolveExitCount, 0);
     AutoIncrCounters incr(this);
     CHECK_EQUAL(obj, obj1 || obj == obj2);
 
     CHECK(JSID_IS_STRING(id));
 
     JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id));
@@ -123,15 +123,15 @@ doResolve(JSHandleObject obj, JSHandleId
         }
     }
     CHECK(false);
     return false;
 }
 
 static JSBool
 my_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-           JSMutableHandleObject objp)
+           JS::MutableHandleObject objp)
 {
     return static_cast<cls_testResolveRecursion *>(JS_GetPrivate(obj))->
            doResolve(obj, id, flags, objp);
 }
 
 END_TEST(testResolveRecursion)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1469,17 +1469,17 @@ JS_SetWrapObjectCallbacks(JSRuntime *rt,
     JSWrapObjectCallback old = rt->wrapObjectCallback;
     rt->wrapObjectCallback = callback;
     rt->sameCompartmentWrapObjectCallback = sccallback;
     rt->preWrapObjectCallback = precallback;
     return old;
 }
 
 JS_PUBLIC_API(JSCompartment *)
-JS_EnterCompartment(JSContext *cx, JSRawObject target)
+JS_EnterCompartment(JSContext *cx, JSObject *target)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     JSCompartment *oldCompartment = cx->compartment;
     cx->enterCompartment(target->compartment());
     return oldCompartment;
 }
@@ -1496,17 +1496,17 @@ JS_EnterCompartmentOfScript(JSContext *c
 JS_PUBLIC_API(void)
 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     cx->leaveCompartment(oldCompartment);
 }
 
-JSAutoCompartment::JSAutoCompartment(JSContext *cx, JSRawObject target)
+JSAutoCompartment::JSAutoCompartment(JSContext *cx, JSObject *target)
   : cx_(cx),
     oldCompartment_(cx->compartment)
 {
     AssertHeapIsIdleOrIterating(cx_);
     cx_->enterCompartment(target->compartment());
 }
 
 JSAutoCompartment::JSAutoCompartment(JSContext *cx, JSScript *target)
@@ -1773,17 +1773,17 @@ JS_RefreshCrossCompartmentWrappers(JSCon
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalObject(JSContext *cx)
 {
     return cx->maybeDefaultCompartmentObject();
 }
 
 JS_PUBLIC_API(void)
-JS_SetGlobalObject(JSContext *cx, JSRawObject obj)
+JS_SetGlobalObject(JSContext *cx, JSObject *obj)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     cx->setDefaultCompartmentObject(obj);
 }
 
 JS_PUBLIC_API(JSBool)
@@ -2182,17 +2182,17 @@ JS_EnumerateResolvedStandardClasses(JSCo
 }
 
 #undef CLASP
 #undef EAGER_ATOM
 #undef EAGER_CLASS_ATOM
 #undef EAGER_ATOM_CLASP
 
 JS_PUBLIC_API(JSBool)
-JS_GetClassObject(JSContext *cx, JSRawObject obj, JSProtoKey key, JSObject **objpArg)
+JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject **objpArg)
 {
     RootedObject objp(cx, *objpArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     assertSameCompartment(cx, obj);
     if (!js_GetClassObject(cx, obj, key, &objp))
         return false;
@@ -2218,41 +2218,41 @@ JS_IdentifyClassPrototype(JSContext *cx,
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JS_ASSERT(!IsCrossCompartmentWrapper(obj));
     return js_IdentifyClassPrototype(obj);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_GetObjectPrototype(JSContext *cx, JSRawObject forObj)
+JS_GetObjectPrototype(JSContext *cx, JSObject *forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
     return forObj->global().getOrCreateObjectPrototype(cx);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_GetFunctionPrototype(JSContext *cx, JSRawObject forObj)
+JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
     return forObj->global().getOrCreateFunctionPrototype(cx);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_GetGlobalForObject(JSContext *cx, JSRawObject obj)
+JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
 {
     AssertHeapIsIdle(cx);
     assertSameCompartment(cx, obj);
     return &obj->global();
 }
 
 extern JS_PUBLIC_API(JSBool)
-JS_IsGlobalObject(JSRawObject obj)
+JS_IsGlobalObject(JSObject *obj)
 {
     return obj->isGlobal();
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForCompartmentOrNull(JSContext *cx, JSCompartment *c)
 {
     AssertHeapIsIdleOrIterating(cx);
@@ -3355,17 +3355,17 @@ JS_GetConstructor(JSContext *cx, JSObjec
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,
                              proto->getClass()->name);
         return NULL;
     }
     return &cval.toObject();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_GetObjectId(JSContext *cx, JSRawObject obj, jsid *idp)
+JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
 {
     AssertHeapIsIdle(cx);
     assertSameCompartment(cx, obj);
     *idp = OBJECT_TO_JSID(obj);
     return JS_TRUE;
 }
 
 class AutoHoldZone
@@ -3489,29 +3489,29 @@ JS_NewObjectForConstructor(JSContext *cx
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, *vp);
 
     RootedObject obj(cx, JSVAL_TO_OBJECT(*vp));
     return CreateThis(cx, Valueify(clasp), obj);
 }
 
 JS_PUBLIC_API(JSBool)
-JS_IsExtensible(JSRawObject obj)
+JS_IsExtensible(JSObject *obj)
 {
     return obj->isExtensible();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_IsNative(JSRawObject obj)
+JS_IsNative(JSObject *obj)
 {
     return obj->isNative();
 }
 
 JS_PUBLIC_API(JSRuntime *)
-JS_GetObjectRuntime(JSRawObject obj)
+JS_GetObjectRuntime(JSObject *obj)
 {
     return obj->compartment()->rt;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_FreezeObject(JSContext *cx, JSObject *objArg)
 {
     RootedObject obj(cx, objArg);
@@ -4862,17 +4862,17 @@ JS_NewFunctionById(JSContext *cx, JSNati
     assertSameCompartment(cx, parent);
 
     RootedAtom atom(cx, JSID_TO_ATOM(id));
     JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
     return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_CloneFunctionObject(JSContext *cx, JSObject *funobjArg, JSRawObject parentArg)
+JS_CloneFunctionObject(JSContext *cx, JSObject *funobjArg, JSObject *parentArg)
 {
     RootedObject funobj(cx, funobjArg);
     RootedObject parent(cx, parentArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, parent);
     // Note that funobj can be in a different compartment.
 
@@ -4942,32 +4942,32 @@ JS_ObjectIsFunction(JSContext *cx, RawOb
 
 JS_PUBLIC_API(JSBool)
 JS_ObjectIsCallable(JSContext *cx, RawObject obj)
 {
     return obj->isCallable();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_IsNativeFunction(JSRawObject funobj, JSNative call)
+JS_IsNativeFunction(JSObject *funobj, JSNative call)
 {
     if (!funobj->isFunction())
         return false;
     JSFunction *fun = funobj->toFunction();
     return fun->isNative() && fun->native() == call;
 }
 
 extern JS_PUBLIC_API(JSBool)
 JS_IsConstructor(JSFunction *fun)
 {
     return fun->isNativeConstructor() || fun->isInterpretedConstructor();
 }
 
 JS_PUBLIC_API(JSObject*)
-JS_BindCallable(JSContext *cx, JSObject *targetArg, JSRawObject newThis)
+JS_BindCallable(JSContext *cx, JSObject *targetArg, JSObject *newThis)
 {
     RootedObject target(cx, targetArg);
     RootedValue thisArg(cx, ObjectValue(*newThis));
     return js_fun_bind(cx, target, thisArg, NULL, 0);
 }
 
 JSBool
 js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp)
@@ -6233,30 +6233,30 @@ JS_PUBLIC_API(JSBool)
 JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_t *dstlenp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     return InflateStringToBuffer(cx, src, srclen, dst, dstlenp);
 }
 
 JS_PUBLIC_API(char *)
-JS_EncodeString(JSContext *cx, JSRawString str)
+JS_EncodeString(JSContext *cx, JSString *str)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return NULL;
 
     return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
 }
 
 JS_PUBLIC_API(char *)
-JS_EncodeStringToUTF8(JSContext *cx, JSRawString str)
+JS_EncodeStringToUTF8(JSContext *cx, JSString *str)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return NULL;
 
@@ -6711,17 +6711,17 @@ JS_PUBLIC_API(JSObject *)
 JS_NewDateObjectMsec(JSContext *cx, double msec)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     return js_NewDateObjectMsec(cx, msec);
 }
 
 JS_PUBLIC_API(JSBool)
-JS_ObjectIsDate(JSContext *cx, JSRawObject objArg)
+JS_ObjectIsDate(JSContext *cx, JSObject *objArg)
 {
     RootedObject obj(cx, objArg);
     assertSameCompartment(cx, obj);
     return ObjectClassIs(obj, ESClass_Date, cx);
 }
 
 JS_PUBLIC_API(void)
 JS_ClearDateCaches(JSContext *cx)
@@ -7203,17 +7203,17 @@ JS_EncodeScript(JSContext *cx, RawScript
     XDREncoder encoder(cx);
     RootedScript script(cx, scriptArg);
     if (!encoder.codeScript(&script))
         return NULL;
     return encoder.forgetData(lengthp);
 }
 
 JS_PUBLIC_API(void *)
-JS_EncodeInterpretedFunction(JSContext *cx, JSRawObject funobjArg, uint32_t *lengthp)
+JS_EncodeInterpretedFunction(JSContext *cx, JSObject *funobjArg, uint32_t *lengthp)
 {
     XDREncoder encoder(cx);
     RootedObject funobj(cx, funobjArg);
     if (!encoder.codeFunction(&funobj))
         return NULL;
     return encoder.forgetData(lengthp);
 }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -798,29 +798,19 @@ CallNonGenericMethod(JSContext *cx, IsAc
 
 /************************************************************************/
 
 typedef JS::Handle<JSObject*> JSHandleObject;
 typedef JS::Handle<JSString*> JSHandleString;
 typedef JS::Handle<JS::Value> JSHandleValue;
 typedef JS::Handle<jsid> JSHandleId;
 
-typedef JS::MutableHandle<JSObject*>   JSMutableHandleObject;
 typedef JS::MutableHandle<JSFunction*> JSMutableHandleFunction;
-typedef JS::MutableHandle<JSScript*>   JSMutableHandleScript;
 typedef JS::MutableHandle<JSString*>   JSMutableHandleString;
 typedef JS::MutableHandle<JS::Value>   JSMutableHandleValue;
-typedef JS::MutableHandle<jsid>        JSMutableHandleId;
-
-typedef js::RawObject   JSRawObject;
-typedef js::RawFunction JSRawFunction;
-typedef js::RawScript   JSRawScript;
-typedef js::RawString   JSRawString;
-typedef js::RawId       JSRawId;
-typedef js::RawValue    JSRawValue;
 
 /* JSClass operation signatures. */
 
 /*
  * Add or get a property named by id in obj.  Note the jsid id type -- id may
  * be a string (Unicode property identifier) or an int (element index).  The
  * *vp out parameter, on success, is the new property value after the action.
  */
@@ -884,17 +874,17 @@ typedef JSBool
  *    call to this function when enum_op was JSENUMERATE_INIT or
  *    JSENUMERATE_INIT_ALL.
  *
  * The return value is used to indicate success, with a value of JS_FALSE
  * indicating failure.
  */
 typedef JSBool
 (* JSNewEnumerateOp)(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
-                     JSMutableHandleValue statep, JSMutableHandleId idp);
+                     JSMutableHandleValue statep, JS::MutableHandleId idp);
 
 /*
  * The old-style JSClass.enumerate op should define all lazy properties not
  * yet reflected in obj.
  */
 typedef JSBool
 (* JSEnumerateOp)(JSContext *cx, JSHandleObject obj);
 
@@ -922,17 +912,17 @@ typedef JSBool
  * was not resolved; and non-null, referring to obj or one of its prototypes,
  * if id was resolved.  The hook may assume *objp is null on entry.
  *
  * This hook instead of JSResolveOp is called via the JSClass.resolve member
  * if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
  */
 typedef JSBool
 (* JSNewResolveOp)(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                   JSMutableHandleObject objp);
+                   JS::MutableHandleObject objp);
 
 /*
  * Convert obj to the given type, returning true with the resulting value in
  * *vp on success, and returning false on error or exception.
  */
 typedef JSBool
 (* JSConvertOp)(JSContext *cx, JSHandleObject obj, JSType type, JSMutableHandleValue vp);
 
@@ -997,27 +987,27 @@ typedef JSBool
  * state. It must not change state of the object or corresponding native
  * structures. The only exception for this rule is the case when the embedding
  * needs a tight integration with GC. In that case the embedding can check if
  * the traversal is a part of the marking phase through calling
  * JS_IsGCMarkingTracer and apply a special code like emptying caches or
  * marking its native structures.
  */
 typedef void
-(* JSTraceOp)(JSTracer *trc, JSRawObject obj);
+(* JSTraceOp)(JSTracer *trc, JSObject *obj);
 
 /*
  * Callback that JSTraceOp implementation can provide to return a string
  * describing the reference traced with JS_CallTracer.
  */
 typedef void
 (* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize);
 
-typedef JSRawObject
-(* JSWeakmapKeyDelegateOp)(JSRawObject obj);
+typedef JSObject *
+(* JSWeakmapKeyDelegateOp)(JSObject *obj);
 
 /* Callbacks and their arguments. */
 
 typedef enum JSContextOp {
     JSCONTEXT_NEW,
     JSCONTEXT_DESTROY
 } JSContextOp;
 
@@ -1349,17 +1339,17 @@ JSID_IS_OBJECT(jsid id)
 static JS_ALWAYS_INLINE JSObject *
 JSID_TO_OBJECT(jsid id)
 {
     JS_ASSERT(JSID_IS_OBJECT(id));
     return (JSObject *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK);
 }
 
 static JS_ALWAYS_INLINE jsid
-OBJECT_TO_JSID(JSRawObject obj)
+OBJECT_TO_JSID(JSObject *obj)
 {
     jsid id;
     JS_ASSERT(obj != NULL);
     JS_ASSERT(((size_t)obj & JSID_TYPE_MASK) == 0);
     JSID_BITS(id) = ((size_t)obj | JSID_TYPE_OBJECT);
     return id;
 }
 
@@ -2146,24 +2136,24 @@ JS_RefreshCrossCompartmentWrappers(JSCon
  * the corresponding JS_LeaveCompartment call.
  */
 
 class JS_PUBLIC_API(JSAutoCompartment)
 {
     JSContext *cx_;
     JSCompartment *oldCompartment_;
   public:
-    JSAutoCompartment(JSContext *cx, JSRawObject target);
+    JSAutoCompartment(JSContext *cx, JSObject *target);
     JSAutoCompartment(JSContext *cx, JSScript *target);
     ~JSAutoCompartment();
 };
 
 /* NB: This API is infallible; a NULL return value does not indicate error. */
 extern JS_PUBLIC_API(JSCompartment *)
-JS_EnterCompartment(JSContext *cx, JSRawObject target);
+JS_EnterCompartment(JSContext *cx, JSObject *target);
 
 extern JS_PUBLIC_API(void)
 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment);
 
 typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);
 
 /*
  * This function calls |compartmentCallback| on every compartment.  Beware that
@@ -2173,17 +2163,17 @@ typedef void (*JSIterateCompartmentCallb
 extern JS_PUBLIC_API(void)
 JS_IterateCompartments(JSRuntime *rt, void *data,
                        JSIterateCompartmentCallback compartmentCallback);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetGlobalObject(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
-JS_SetGlobalObject(JSContext *cx, JSRawObject obj);
+JS_SetGlobalObject(JSContext *cx, JSObject *obj);
 
 /*
  * Initialize standard JS class constructors, prototypes, and any top-level
  * functions and constants associated with the standard classes (e.g. isNaN
  * for Number).
  *
  * NB: This sets cx's global object to obj if it was null.
  */
@@ -2215,43 +2205,43 @@ JS_EnumerateStandardClasses(JSContext *c
  * JSIdArray if ida is null.  Return the augmented array on success, null on
  * failure with ida (if it was non-null on entry) destroyed.
  */
 extern JS_PUBLIC_API(JSIdArray *)
 JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj,
                                     JSIdArray *ida);
 
 extern JS_PUBLIC_API(JSBool)
-JS_GetClassObject(JSContext *cx, JSRawObject obj, JSProtoKey key, JSObject **objp);
+JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject **objp);
 
 extern JS_PUBLIC_API(JSBool)
 JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JSObject **objp);
 
 extern JS_PUBLIC_API(JSProtoKey)
 JS_IdentifyClassPrototype(JSContext *cx, JSObject *obj);
 
 /*
  * Returns the original value of |Function.prototype| from the global object in
  * which |forObj| was created.
  */
 extern JS_PUBLIC_API(JSObject *)
-JS_GetFunctionPrototype(JSContext *cx, JSRawObject forObj);
+JS_GetFunctionPrototype(JSContext *cx, JSObject *forObj);
 
 /*
  * Returns the original value of |Object.prototype| from the global object in
  * which |forObj| was created.
  */
 extern JS_PUBLIC_API(JSObject *)
-JS_GetObjectPrototype(JSContext *cx, JSRawObject forObj);
+JS_GetObjectPrototype(JSContext *cx, JSObject *forObj);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_GetGlobalForObject(JSContext *cx, JSRawObject obj);
+JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
-JS_IsGlobalObject(JSRawObject obj);
+JS_IsGlobalObject(JSObject *obj);
 
 /*
  * May return NULL, if |c| never had a global (e.g. the atoms compartment), or
  * if |c|'s global has been collected.
  */
 extern JS_PUBLIC_API(JSObject *)
 JS_GetGlobalForCompartmentOrNull(JSContext *cx, JSCompartment *c);
 
@@ -2305,17 +2295,17 @@ typedef struct JSCTypesCallbacks JSCType
 
 /*
  * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
  * pointer to static data that exists for the lifetime of 'ctypesObj', but it
  * may safely be altered after calling this function and without having
  * to call this function again.
  */
 extern JS_PUBLIC_API(void)
-JS_SetCTypesCallbacks(JSRawObject ctypesObj, JSCTypesCallbacks *callbacks);
+JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks *callbacks);
 #endif
 
 typedef JSBool
 (* JSEnumerateDiagnosticMemoryCallback)(void *ptr, size_t length);
 
 /*
  * Enumerate memory regions that contain diagnostic information
  * intended to be included in crash report minidumps.
@@ -3120,56 +3110,56 @@ JS_InitClass(JSContext *cx, JSObject *ob
 /*
  * Set up ctor.prototype = proto and proto.constructor = ctor with the
  * right property flags.
  */
 extern JS_PUBLIC_API(JSBool)
 JS_LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor, JSObject *proto);
 
 extern JS_PUBLIC_API(JSClass *)
-JS_GetClass(JSRawObject obj);
+JS_GetClass(JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
 JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv);
 
 extern JS_PUBLIC_API(JSBool)
 JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
 
 extern JS_PUBLIC_API(void *)
-JS_GetPrivate(JSRawObject obj);
+JS_GetPrivate(JSObject *obj);
 
 extern JS_PUBLIC_API(void)
-JS_SetPrivate(JSRawObject obj, void *data);
+JS_SetPrivate(JSObject *obj, void *data);
 
 extern JS_PUBLIC_API(void *)
 JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
                       jsval *argv);
 
 extern JS_PUBLIC_API(JSBool)
 JS_GetPrototype(JSContext *cx, JSObject *obj, JSObject **protop);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_GetParent(JSRawObject obj);
+JS_GetParent(JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetConstructor(JSContext *cx, JSObject *proto);
 
 /*
  * Get a unique identifier for obj, good for the lifetime of obj (even if it
  * is moved by a copying GC).  Return false on failure (likely out of memory),
  * and true with *idp containing the unique id on success.
  */
 extern JS_PUBLIC_API(JSBool)
-JS_GetObjectId(JSContext *cx, JSRawObject obj, jsid *idp);
+JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
 
 namespace JS {
 
 enum {
     FreshZone,
     SystemZone,
     SpecificZones
 };
@@ -3189,23 +3179,23 @@ extern JS_PUBLIC_API(JSObject *)
 JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
                    JS::ZoneSpecifier zoneSpec = JS::FreshZone);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
 
 /* Queries the [[Extensible]] property of the object. */
 extern JS_PUBLIC_API(JSBool)
-JS_IsExtensible(JSRawObject obj);
+JS_IsExtensible(JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
-JS_IsNative(JSRawObject obj);
+JS_IsNative(JSObject *obj);
 
 extern JS_PUBLIC_API(JSRuntime *)
-JS_GetObjectRuntime(JSRawObject obj);
+JS_GetObjectRuntime(JSObject *obj);
 
 /*
  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
  * proto if proto's actual parameter value is null.
  */
 extern JS_PUBLIC_API(JSObject *)
 JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
                            JSObject *parent);
@@ -3689,20 +3679,20 @@ JS_NextProperty(JSContext *cx, JSObject 
 extern JS_PUBLIC_API(JSBool)
 JS_ArrayIterator(JSContext *cx, unsigned argc, jsval *vp);
 
 extern JS_PUBLIC_API(JSBool)
 JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
                jsval *vp, unsigned *attrsp);
 
 extern JS_PUBLIC_API(jsval)
-JS_GetReservedSlot(JSRawObject obj, uint32_t index);
+JS_GetReservedSlot(JSObject *obj, uint32_t index);
 
 extern JS_PUBLIC_API(void)
-JS_SetReservedSlot(JSRawObject obj, uint32_t index, jsval v);
+JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v);
 
 /************************************************************************/
 
 /*
  * Security protocol.
  */
 struct JSPrincipals {
     /* Don't call "destroy"; use reference counting macros below. */
@@ -3813,35 +3803,35 @@ JS_GetFunctionArity(JSFunction *fun);
 
 /*
  * Infallible predicate to test whether obj is a function object (faster than
  * comparing obj's class name to "Function", but equivalent unless someone has
  * overwritten the "Function" identifier with a different constructor and then
  * created instances using that constructor that might be passed in as obj).
  */
 extern JS_PUBLIC_API(JSBool)
-JS_ObjectIsFunction(JSContext *cx, JSRawObject obj);
+JS_ObjectIsFunction(JSContext *cx, JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
-JS_ObjectIsCallable(JSContext *cx, JSRawObject obj);
+JS_ObjectIsCallable(JSContext *cx, JSObject *obj);
 
 extern JS_PUBLIC_API(JSBool)
-JS_IsNativeFunction(JSRawObject funobj, JSNative call);
+JS_IsNativeFunction(JSObject *funobj, JSNative call);
 
 /* Return whether the given function is a valid constructor. */
 extern JS_PUBLIC_API(JSBool)
 JS_IsConstructor(JSFunction *fun);
 
 /*
  * Bind the given callable to use the given object as "this".
  *
  * If |callable| is not callable, will throw and return NULL.
  */
 extern JS_PUBLIC_API(JSObject*)
-JS_BindCallable(JSContext *cx, JSObject *callable, JSRawObject newThis);
+JS_BindCallable(JSContext *cx, JSObject *callable, JSObject *newThis);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineFunctions(JSContext *cx, JSObject *obj, const JSFunctionSpec *fs);
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
                   unsigned nargs, unsigned attrs);
 
@@ -3854,17 +3844,17 @@ extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunctionById(JSContext *cx, JSObject *obj, jsid id, JSNative call,
                       unsigned nargs, unsigned attrs);
 
 /*
  * Clone a top-level function into a new scope. This function will dynamically
  * fail if funobj was lexically nested inside some other function.
  */
 extern JS_PUBLIC_API(JSObject *)
-JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSRawObject parent);
+JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
 
 /*
  * Given a buffer, return JS_FALSE if the buffer might become a valid
  * javascript statement with the addition of more lines.  Otherwise return
  * JS_TRUE.  The intent is to support interactive compilation - accumulate
  * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
  * the compiler.
  */
@@ -4392,23 +4382,23 @@ JS_PUBLIC_API(JSBool)
 JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
                size_t *dstlenp);
 
 /*
  * A variation on JS_EncodeCharacters where a null terminated string is
  * returned that you are expected to call JS_free on when done.
  */
 JS_PUBLIC_API(char *)
-JS_EncodeString(JSContext *cx, JSRawString str);
+JS_EncodeString(JSContext *cx, JSString *str);
 
 /*
  * Same behavior as JS_EncodeString(), but encode into UTF-8 string
  */
 JS_PUBLIC_API(char *)
-JS_EncodeStringToUTF8(JSContext *cx, JSRawString str);
+JS_EncodeStringToUTF8(JSContext *cx, JSString *str);
 
 /*
  * Get number of bytes in the string encoding (without accounting for a
  * terminating zero bytes. The function returns (size_t) -1 if the string
  * can not be encoded into bytes and reports an error using cx accordingly.
  */
 JS_PUBLIC_API(size_t)
 JS_GetStringEncodingLength(JSContext *cx, JSString *str);
@@ -4819,17 +4809,17 @@ JS_NewDateObject(JSContext *cx, int year
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewDateObjectMsec(JSContext *cx, double msec);
 
 /*
  * Infallible predicate to test whether obj is a date object.
  */
 extern JS_PUBLIC_API(JSBool)
-JS_ObjectIsDate(JSContext *cx, JSRawObject obj);
+JS_ObjectIsDate(JSContext *cx, JSObject *obj);
 
 /*
  * Clears the cache of calculated local time from each Date object.
  * Call to propagate a system timezone change.
  */
 extern JS_PUBLIC_API(void)
 JS_ClearDateCaches(JSContext *cx);
 
@@ -5064,17 +5054,17 @@ JS_DescribeScriptedCaller(JSContext *cx,
 /*
  * Encode/Decode interpreted scripts and functions to/from memory.
  */
 
 extern JS_PUBLIC_API(void *)
 JS_EncodeScript(JSContext *cx, JSScript *script, uint32_t *lengthp);
 
 extern JS_PUBLIC_API(void *)
-JS_EncodeInterpretedFunction(JSContext *cx, JSRawObject funobj, uint32_t *lengthp);
+JS_EncodeInterpretedFunction(JSContext *cx, JSObject *funobj, uint32_t *lengthp);
 
 extern JS_PUBLIC_API(JSScript *)
 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length,
                 JSPrincipals *principals, JSPrincipals *originPrincipals);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
                              JSPrincipals *principals, JSPrincipals *originPrincipals);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2906,17 +2906,17 @@ NewArray(JSContext *cx, uint32_t length,
 {
     gc::AllocKind allocKind = GuessArrayGCKind(length);
     JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayClass));
     allocKind = GetBackgroundAllocKind(allocKind);
 
     NewObjectCache &cache = cx->runtime->newObjectCache;
 
     NewObjectCache::EntryIndex entry = -1;
-    if (newKind != SingletonObject &&
+    if (newKind == GenericObject &&
         cache.lookupGlobal(&ArrayClass, cx->global(), allocKind, &entry))
     {
         RootedObject obj(cx, cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, &ArrayClass)));
         if (obj) {
             /* Fixup the elements pointer and length, which may be incorrect. */
             obj->setFixedElements();
             JSObject::setArrayLength(cx, obj, length);
             if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
@@ -2940,17 +2940,18 @@ NewArray(JSContext *cx, uint32_t length,
      * Get a shape with zero fixed slots, regardless of the size class.
      * See JSObject::createArray.
      */
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayClass, TaggedProto(proto),
                                                       cx->global(), gc::FINALIZE_OBJECT0));
     if (!shape)
         return NULL;
 
-    RootedObject obj(cx, JSObject::createArray(cx, allocKind, gc::DefaultHeap, shape, type, length));
+    RootedObject obj(cx, JSObject::createArray(cx, allocKind, GetInitialHeap(newKind, &ArrayClass),
+                                               shape, type, length));
     if (!obj)
         return NULL;
 
     if (shape->isEmptyShape()) {
         if (!AddLengthProperty(cx, obj))
             return NULL;
         shape = obj->lastProperty();
         EmptyShape::insertInitialShape(cx, shape, proto);
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1103,16 +1103,21 @@ js_InvokeOperationCallback(JSContext *cx
     JS_ATOMIC_SET(&rt->interrupt, 0);
 
     /* IonMonkey sets its stack limit to NULL to trigger operaton callbacks. */
     rt->resetIonStackLimit();
 
     if (rt->gcIsNeeded)
         GCSlice(rt, GC_NORMAL, rt->gcTriggerReason);
 
+#ifdef JSGC_GENERATIONAL
+    if (rt->gcStoreBuffer.isAboutToOverflow())
+        MinorGC(rt, JS::gcreason::FULL_STORE_BUFFER);
+#endif
+
 #ifdef JS_ION
     /*
      * A worker thread may have set the callback after finishing an Ion
      * compilation.
      */
     ion::AttachFinishedCompilations(cx);
 #endif
 
--- a/js/src/jsdate.h
+++ b/js/src/jsdate.h
@@ -44,30 +44,30 @@ js_NewDateObjectMsec(JSContext* cx, doub
  * due to the 0-based month numbering copied into JS from Java (java.util.Date
  * in 1995).
  */
 extern JS_FRIEND_API(JSObject *)
 js_NewDateObject(JSContext* cx, int year, int mon, int mday,
                  int hour, int min, int sec);
 
 extern JS_FRIEND_API(int)
-js_DateGetYear(JSContext *cx, JSRawObject obj);
+js_DateGetYear(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(int)
-js_DateGetMonth(JSContext *cx, JSRawObject obj);
+js_DateGetMonth(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(int)
-js_DateGetDate(JSContext *cx, JSRawObject obj);
+js_DateGetDate(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(int)
-js_DateGetHours(JSContext *cx, JSRawObject obj);
+js_DateGetHours(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(int)
-js_DateGetMinutes(JSContext *cx, JSRawObject obj);
+js_DateGetMinutes(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(int)
-js_DateGetSeconds(JSRawObject obj);
+js_DateGetSeconds(JSObject *obj);
 
 /* Date constructor native. Exposed only so the JIT can know its address. */
 JSBool
 js_Date(JSContext *cx, unsigned argc, js::Value *vp);
 
 #endif /* jsdate_h___ */
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -31,20 +31,20 @@
 
 extern JS_FRIEND_API(void)
 JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
 
 extern JS_FRIEND_API(JSString *)
 JS_GetAnonymousString(JSRuntime *rt);
 
 extern JS_FRIEND_API(JSObject *)
-JS_FindCompilationScope(JSContext *cx, JSRawObject obj);
+JS_FindCompilationScope(JSContext *cx, JSObject *obj);
 
 extern JS_FRIEND_API(JSFunction *)
-JS_GetObjectFunction(JSRawObject obj);
+JS_GetObjectFunction(JSObject *obj);
 
 extern JS_FRIEND_API(JSBool)
 JS_SplicePrototype(JSContext *cx, JSObject *obj, JSObject *proto);
 
 extern JS_FRIEND_API(JSObject *)
 JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
 
 extern JS_FRIEND_API(uint32_t)
@@ -865,17 +865,17 @@ uint32_t GetListBaseExpandoSlot();
 /*
  * Detect whether the internal date value is NaN.  (Because failure is
  * out-of-band for js_DateGet*)
  */
 extern JS_FRIEND_API(JSBool)
 js_DateIsValid(JSObject* obj);
 
 extern JS_FRIEND_API(double)
-js_DateGetMsecSinceEpoch(JSRawObject obj);
+js_DateGetMsecSinceEpoch(JSObject *obj);
 
 /* Implemented in jscntxt.cpp. */
 
 /*
  * Report an exception, which is currently realized as a printf-style format
  * string and its arguments.
  */
 typedef enum JSErrNum {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1272,17 +1272,17 @@ js::NewObjectWithGivenProto(JSContext *c
     RootedObject parent(cx, parent_);
 
     if (CanBeFinalizedInBackground(allocKind, clasp))
         allocKind = GetBackgroundAllocKind(allocKind);
 
     NewObjectCache &cache = cx->runtime->newObjectCache;
 
     NewObjectCache::EntryIndex entry = -1;
-    if (proto.isObject() && newKind != SingletonObject &&
+    if (proto.isObject() && newKind == GenericObject &&
         (!parent || parent == proto.toObject()->getParent()) && !proto.toObject()->isGlobal())
     {
         if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
             JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
             if (obj)
                 return obj;
         }
     }
@@ -1330,17 +1330,17 @@ js::NewObjectWithClassProtoCommon(JSCont
      * stored in an immutable slot on the global (except for ClearScope, which
      * will flush the new object cache).
      */
     JSProtoKey protoKey = GetClassProtoKey(clasp);
 
     NewObjectCache &cache = cx->runtime->newObjectCache;
 
     NewObjectCache::EntryIndex entry = -1;
-    if (parentArg->isGlobal() && protoKey != JSProto_Null && newKind != SingletonObject) {
+    if (parentArg->isGlobal() && protoKey != JSProto_Null && newKind == GenericObject) {
         if (cache.lookupGlobal(clasp, &parentArg->asGlobal(), allocKind, &entry)) {
             JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
             if (obj)
                 return obj;
         }
     }
 
     RootedObject parent(cx, parentArg);
@@ -1372,17 +1372,17 @@ js::NewObjectWithType(JSContext *cx, Han
 
     JS_ASSERT(allocKind <= gc::FINALIZE_OBJECT_LAST);
     if (CanBeFinalizedInBackground(allocKind, &ObjectClass))
         allocKind = GetBackgroundAllocKind(allocKind);
 
     NewObjectCache &cache = cx->runtime->newObjectCache;
 
     NewObjectCache::EntryIndex entry = -1;
-    if (parent == type->proto->getParent() && newKind != SingletonObject) {
+    if (parent == type->proto->getParent() && newKind == GenericObject) {
         if (cache.lookupType(&ObjectClass, type, allocKind, &entry)) {
             JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, &ObjectClass));
             if (obj)
                 return obj;
         }
     }
 
     JSObject *obj = NewObject(cx, &ObjectClass, type, parent, allocKind, newKind);
@@ -4650,17 +4650,17 @@ js::DefaultValue(JSContext *cx, HandleOb
     RootedValue val(cx, ObjectValue(*obj));
     js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, val, str,
                          (hint == JSTYPE_VOID) ? "primitive type" : TypeStrings[hint]);
     return false;
 }
 
 JS_FRIEND_API(JSBool)
 JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
-                  JSMutableHandleValue statep, JSMutableHandleId idp)
+                  JSMutableHandleValue statep, JS::MutableHandleId idp)
 {
     /* If the class has a custom JSCLASS_NEW_ENUMERATE hook, call it. */
     Class *clasp = obj->getClass();
     JSEnumerateOp enumerate = clasp->enumerate;
     if (clasp->flags & JSCLASS_NEW_ENUMERATE) {
         JS_ASSERT(enumerate != JS_EnumerateStub);
         return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
     }
--- a/js/src/perf/jsperf.cpp
+++ b/js/src/perf/jsperf.cpp
@@ -220,17 +220,17 @@ GetPMFromThis(JSContext* cx, jsval* vp)
         return 0;
     return (PerfMeasurement*)
         JS_GetInstancePrivate(cx, this_, &pm_class, JS_ARGV(cx, vp));
 }
 
 namespace JS {
 
 JSObject*
-RegisterPerfMeasurement(JSContext *cx, JSRawObject global)
+RegisterPerfMeasurement(JSContext *cx, JSObject *global)
 {
     RootedObject prototype(cx);
     prototype = JS_InitClass(cx, global, NULL /* parent */,
                              &pm_class, pm_construct, 1,
                              pm_props, pm_fns, 0, 0);
     if (!prototype)
         return 0;
 
--- a/js/src/perf/jsperf.h
+++ b/js/src/perf/jsperf.h
@@ -110,17 +110,17 @@ class JS_FRIEND_API(PerfMeasurement)
     static bool canMeasureSomething();
 };
 
 /* Inject a Javascript wrapper around the above C++ class into the
  * Javascript object passed as an argument (this will normally be a
  * global object).  The JS-visible API is identical to the C++ API.
  */
 extern JS_FRIEND_API(JSObject*)
-    RegisterPerfMeasurement(JSContext *cx, JSRawObject global);
+    RegisterPerfMeasurement(JSContext *cx, JSObject *global);
 
 /*
  * Given a jsval which contains an instance of the aforementioned
  * wrapper class, extract the C++ object.  Returns NULL if the
  * jsval is not an instance of the wrapper.
  */
 extern JS_FRIEND_API(PerfMeasurement*)
     ExtractPerfMeasurement(jsval wrapper);
--- a/js/src/vm/Xdr.cpp
+++ b/js/src/vm/Xdr.cpp
@@ -95,17 +95,17 @@ VersionCheck(XDRState<mode> *xdr)
         return false;
     }
 
     return true;
 }
 
 template<XDRMode mode>
 bool
-XDRState<mode>::codeFunction(JSMutableHandleObject objp)
+XDRState<mode>::codeFunction(MutableHandleObject objp)
 {
     if (mode == XDR_DECODE)
         objp.set(NULL);
 
     if (!VersionCheck(this))
         return false;
 
     return XDRInterpretedFunction(this, NullPtr(), NullPtr(), objp);
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -203,18 +203,18 @@ class XDRState {
         } else {
             *sp = buf.readCString();
         }
         return true;
     }
 
     bool codeChars(jschar *chars, size_t nchars);
 
-    bool codeFunction(JSMutableHandleObject objp);
-    bool codeScript(JSMutableHandleScript scriptp);
+    bool codeFunction(JS::MutableHandleObject objp);
+    bool codeScript(MutableHandleScript scriptp);
 
     void initScriptPrincipals(JSScript *script) {
         JS_ASSERT(mode == XDR_DECODE);
 
         /* The origin principals must be normalized at this point. */
         JS_ASSERT_IF(principals, originPrincipals);
         JS_ASSERT(!script->originPrincipals);
         if (principals)
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -932,17 +932,17 @@ env_enumerate(JSContext *cx, JSHandleObj
     }
 
     reflected = true;
     return true;
 }
 
 static JSBool
 env_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-            JSMutableHandleObject objp)
+            JS::MutableHandleObject objp)
 {
     JSString *idstr, *valstr;
 
     jsval idval;
     if (!JS_IdToValue(cx, id, &idval))
         return false;
 
     idstr = JS_ValueToString(cx, idval);
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -19,16 +19,17 @@
 #include "nsPrintfCString.h"
 #include "prsystem.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsLayoutStatics.h"
 #include "nsContentUtils.h"
 #include "nsCCUncollectableMarker.h"
+#include "nsCycleCollectorUtils.h"
 #include "nsScriptLoader.h"
 #include "jsfriendapi.h"
 #include "js/MemoryMetrics.h"
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Attributes.h"
 #include "AccessCheck.h"
@@ -483,18 +484,18 @@ NoteJSHolder(void *holder, nsScriptObjec
 // static
 void
 XPCJSRuntime::SuspectWrappedNative(XPCWrappedNative *wrapper,
                                    nsCycleCollectionTraversalCallback &cb)
 {
     if (!wrapper->IsValid() || wrapper->IsWrapperExpired())
         return;
 
-    NS_ASSERTION(NS_IsMainThread() || NS_IsCycleCollectorThread(),
-                 "Suspecting wrapped natives from non-CC thread");
+    MOZ_ASSERT(NS_IsMainThread() || NS_IsCycleCollectorThread(),
+               "Suspecting wrapped natives from non-CC thread");
 
     // Only record objects that might be part of a cycle as roots, unless
     // the callback wants all traces (a debug feature).
     JSObject* obj = wrapper->GetFlatJSObjectPreserveColor();
     if (xpc_IsGrayGCThing(obj) || cb.WantAllTraces())
         cb.NoteJSRoot(obj);
 }
 
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -1008,17 +1008,17 @@ XPC_WN_Helper_HasInstance(JSContext *cx,
 static void
 XPC_WN_Helper_Finalize(js::FreeOp *fop, JSObject *obj)
 {
     WrappedNativeFinalize(fop, obj, WN_HELPER);
 }
 
 static JSBool
 XPC_WN_Helper_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
-                         JSMutableHandleObject objp)
+                         MutableHandleObject objp)
 {
     nsresult rv = NS_OK;
     bool retval = true;
     RootedObject obj2FromScriptable(cx);
     if (IS_SLIM_WRAPPER(obj)) {
         XPCNativeScriptableInfo *si =
             GetSlimWrapperProto(obj)->GetScriptableInfo();
         if (!si->GetFlags().WantNewResolve())
@@ -1146,17 +1146,17 @@ XPC_WN_Helper_NewResolve(JSContext *cx, 
         if ( DONT_ENUM_STATICS )
             use enumerate stub - don't use this JSOp thing at all
         else
             do shared enumerate - don't use this JSOp thing at all
 */
 
 JSBool
 XPC_WN_JSOp_Enumerate(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
-                      JSMutableHandleValue statep, JSMutableHandleId idp)
+                      JSMutableHandleValue statep, MutableHandleId idp)
 {
     js::Class *clazz = js::GetObjectClass(obj);
     if (!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base) {
         // obj must be a prototype object or a wrapper w/o a
         // helper. Short circuit this call to the default
         // implementation.
 
         return JS_EnumerateState(cx, obj, enum_op, statep, idp);
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -33,16 +33,18 @@
 
 #include "XPCQuickStubs.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/TextDecoderBinding.h"
 #include "mozilla/dom/TextEncoderBinding.h"
 
 #include "nsWrapperCacheInlines.h"
+#include "nsCycleCollector.h"
+#include "nsCycleCollectorUtils.h"
 #include "nsDOMMutationObserver.h"
 #include "nsICycleCollectorListener.h"
 #include "nsThread.h"
 #include "mozilla/XPTInterfaceInfoManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace xpc;
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -103,17 +103,17 @@
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 #include "js/HeapAPI.h"
 #include "jswrapper.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsCycleCollector.h"
+#include "nsCycleCollectionJSRuntime.h"
 #include "nsDebug.h"
 #include "nsISupports.h"
 #include "nsIServiceManager.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsISupportsPrimitives.h"
 #include "nsMemory.h"
@@ -1457,17 +1457,17 @@ extern js::Class XPC_WN_NoHelper_Proto_J
 extern JSBool
 XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp);
 
 extern JSBool
 XPC_WN_GetterSetter(JSContext *cx, unsigned argc, jsval *vp);
 
 extern JSBool
 XPC_WN_JSOp_Enumerate(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op,
-                      JSMutableHandleValue statep, JSMutableHandleId idp);
+                      JSMutableHandleValue statep, JS::MutableHandleId idp);
 
 extern JSObject*
 XPC_WN_JSOp_ThisObject(JSContext *cx, JSHandleObject obj);
 
 // Macros to initialize Object or Function like XPC_WN classes
 #define XPC_WN_WithCall_ObjectOps                                             \
     {                                                                         \
         nullptr, /* lookupGeneric */                                          \
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -493,16 +493,19 @@ inline bool IsDOMProxy(JSObject *obj, co
 inline bool IsDOMProxy(JSObject *obj)
 {
     return IsDOMProxy(obj, js::GetObjectClass(obj));
 }
 
 typedef JSObject*
 (*DefineInterface)(JSContext *cx, JSObject *global, jsid id, bool *enabled);
 
+typedef JSObject*
+(*ConstructNavigatorProperty)(JSContext *cx, JS::Handle<JSObject*> naviObj);
+
 typedef bool
 (*PrefEnabled)();
 
 extern bool
 DefineStaticJSVals(JSContext *cx);
 void
 Register(nsScriptNameSpaceManager* aNameSpaceManager);
 
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -27,17 +27,16 @@
 #include "nsBlockFrame.h"
 #include "nsISelectionController.h"
 #include "nsDisplayList.h"
 #include "nsCaret.h"
 #include "nsTextFrame.h"
 #include "nsXULPopupManager.h"
 #include "nsMenuPopupFrame.h"
 #include "nsTextFragment.h"
-#include "nsThemeConstants.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Selection.h"
 #include <algorithm>
 
 // The bidi indicator hangs off the caret to one side, to show which
 // direction the typing is in. It needs to be at least 2x2 to avoid looking like 
 // an insignificant dot
@@ -522,36 +521,16 @@ void nsCaret::PaintCaret(nsDisplayListBu
   if (aForFrame->GetType() == nsGkAtoms::textFrame &&
       (NS_FAILED(aForFrame->GetOffsets(startOffset, endOffset)) ||
       startOffset > contentOffset ||
       endOffset < contentOffset)) {
     return;
   }
   nscolor foregroundColor = aForFrame->GetCaretColorAt(contentOffset);
 
-  // Only draw the native caret if the foreground color matches that of
-  // -moz-fieldtext (the color of the text in a textbox). If it doesn't match
-  // we are likely in contenteditable or a custom widget and we risk being hard to see
-  // against the background. In that case, fall back to the CSS color.
-  nsPresContext* presContext = aForFrame->PresContext();
-
-  if (GetHookRect().IsEmpty() && presContext) {
-    nsITheme *theme = presContext->GetTheme();
-    if (theme && theme->ThemeSupportsWidget(presContext, aForFrame, NS_THEME_TEXTFIELD_CARET)) {
-      nscolor fieldText;
-      nsresult rv = LookAndFeel::GetColor(LookAndFeel::eColorID__moz_fieldtext,
-                                          &fieldText);
-      if (NS_SUCCEEDED(rv) && fieldText == foregroundColor) {
-        theme->DrawWidgetBackground(aCtx, aForFrame, NS_THEME_TEXTFIELD_CARET,
-                                    drawCaretRect, drawCaretRect);
-        return;
-      }
-    }
-  }
-
   aCtx->SetColor(foregroundColor);
   aCtx->FillRect(drawCaretRect);
   if (!GetHookRect().IsEmpty())
     aCtx->FillRect(GetHookRect() + aOffset);
 }
 
 
 //-----------------------------------------------------------------------------
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -95,17 +95,16 @@
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsVolumeService.h"
 using namespace mozilla::system;
 #endif
 
 #include "nsError.h"
 
-#include "nsCycleCollector.h"
 #include "nsJSEnvironment.h"
 #include "nsContentSink.h"
 #include "nsFrameMessageManager.h"
 #include "nsRefreshDriver.h"
 #include "nsDOMMutationObserver.h"
 #include "nsHyphenationManager.h"
 #include "nsEditorSpellCheck.h"
 #include "nsWindowMemoryReporter.h"
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -335,115 +335,38 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBlockFra
 
 nsSplittableType
 nsBlockFrame::GetSplittableType() const
 {
   return NS_FRAME_SPLITTABLE_NON_RECTANGULAR;
 }
 
 #ifdef DEBUG
-NS_METHOD
+void
 nsBlockFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", mParent);
-#endif
-  if (HasView()) {
-    fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
-  }
-  if (GetNextSibling()) {
-    fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
-  }
-
-  // Output the flow linkage
-  if (nullptr != GetPrevInFlow()) {
-    fprintf(out, " prev-in-flow=%p", static_cast<void*>(GetPrevInFlow()));
-  }
-  if (nullptr != GetNextInFlow()) {
-    fprintf(out, " next-in-flow=%p", static_cast<void*>(GetNextInFlow()));
-  }
-
-  void* IBsibling = Properties().Get(IBSplitSpecialSibling());
-  if (IBsibling) {
-    fprintf(out, " IBSplitSpecialSibling=%p", IBsibling);
-  }
-  void* IBprevsibling = Properties().Get(IBSplitSpecialPrevSibling());
-  if (IBprevsibling) {
-    fprintf(out, " IBSplitSpecialPrevSibling=%p", IBprevsibling);
-  }
-
-  if (nullptr != mContent) {
-    fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  }
-
-  // Output the rect and state
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  nsBlockFrame* f = const_cast<nsBlockFrame*>(this);
-  if (f->HasOverflowAreas()) {
-    nsRect overflowArea = f->GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = f->GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  int32_t numInlineLines = 0;
-  int32_t numBlockLines = 0;
-  if (!mLines.empty()) {
-    const_line_iterator line = begin_lines(), line_end = end_lines();
-    for ( ; line != line_end; ++line) {
-      if (line->IsBlock())
-        numBlockLines++;
-      else
-        numInlineLines++;
-    }
-  }
-  fprintf(out, " sc=%p(i=%d,b=%d)",
-          static_cast<void*>(mStyleContext), numInlineLines, numBlockLines);
-  nsIAtom* pseudoTag = mStyleContext->GetPseudo();
-  if (pseudoTag) {
-    nsAutoString atomString;
-    pseudoTag->ToString(atomString);
-    fprintf(out, " pst=%s",
-            NS_LossyConvertUTF16toASCII(atomString).get());
-  }
-  if (IsTransformed()) {
-    fprintf(out, " transformed");
-  }
-  if (ChildrenHavePerspective()) {
-    fprintf(out, " perspective");
-  }
-  if (Preserves3DChildren()) {
-    fprintf(out, " preserves-3d-children");
-  }
-  if (Preserves3D()) {
-    fprintf(out, " preserves-3d");
-  }
+  ListGeneric(out, aIndent, aFlags);
+
   fputs("<\n", out);
 
   aIndent++;
 
   // Output the lines
   if (!mLines.empty()) {
     const_line_iterator line = begin_lines(), line_end = end_lines();
     for ( ; line != line_end; ++line) {
       line->List(out, aIndent, aFlags);
     }
   }
 
   // Output the overflow lines.
   const FrameLines* overflowLines = GetOverflowLines();
   if (overflowLines && !overflowLines->mLines.empty()) {
     IndentBy(out, aIndent);
-    fputs("Overflow-lines<\n", out);
+    fprintf(out, "Overflow-lines %p/%p <\n", overflowLines, &overflowLines->mFrames);
     const_line_iterator line = overflowLines->mLines.begin(),
                         line_end = overflowLines->mLines.end();
     for ( ; line != line_end; ++line) {
       line->List(out, aIndent + 1, aFlags);
     }
     IndentBy(out, aIndent);
     fputs(">\n", out);
   }
@@ -452,31 +375,30 @@ nsBlockFrame::List(FILE* out, int32_t aI
   // skip the overflow list - we printed the overflow lines above
   ChildListIterator lists(this);
   ChildListIDs skip(kPrincipalList | kOverflowList);
   for (; !lists.IsDone(); lists.Next()) {
     if (skip.Contains(lists.CurrentID())) {
       continue;
     }
     IndentBy(out, aIndent);
-    fprintf(out, "%s<\n", mozilla::layout::ChildListName(lists.CurrentID()));
+    fprintf(out, "%s %p <\n", mozilla::layout::ChildListName(lists.CurrentID()),
+            &GetChildList(lists.CurrentID()));
     nsFrameList::Enumerator childFrames(lists.CurrentList());
     for (; !childFrames.AtEnd(); childFrames.Next()) {
       nsIFrame* kid = childFrames.get();
       kid->List(out, aIndent + 1, aFlags);
     }
     IndentBy(out, aIndent);
     fputs(">\n", out);
   }
 
   aIndent--;
   IndentBy(out, aIndent);
   fputs(">\n", out);
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP_(nsFrameState)
 nsBlockFrame::GetDebugStateBits() const
 {
   // We don't want to include our cursor flag in the bits the
   // regression tester looks at
   return nsBlockFrameSuper::GetDebugStateBits() & ~NS_BLOCK_HAS_LINE_CURSOR;
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -164,17 +164,17 @@ public:
              ~(nsIFrame::eCanContainOverflowContainers |
                nsIFrame::eBlockFrame));
   }
 
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
 
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
   NS_IMETHOD_(nsFrameState) GetDebugStateBits() const;
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1790,89 +1790,48 @@ nsOverflowContinuationTracker::Finish(ns
     f = nif;
   }
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // Debugging
 
 #ifdef DEBUG
-NS_IMETHODIMP
+void
 nsContainerFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", static_cast<void*>(mParent));
-#endif
-  if (HasView()) {
-    fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
-  }
-  if (GetNextSibling()) {
-    fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
-  }
-  if (nullptr != GetPrevContinuation()) {
-    fprintf(out, " prev-continuation=%p", static_cast<void*>(GetPrevContinuation()));
-  }
-  if (nullptr != GetNextContinuation()) {
-    fprintf(out, " next-continuation=%p", static_cast<void*>(GetNextContinuation()));
-  }
-  void* IBsibling = Properties().Get(IBSplitSpecialSibling());
-  if (IBsibling) {
-    fprintf(out, " IBSplitSpecialSibling=%p", IBsibling);
-  }
-  void* IBprevsibling = Properties().Get(IBSplitSpecialPrevSibling());
-  if (IBprevsibling) {
-    fprintf(out, " IBSplitSpecialPrevSibling=%p", IBprevsibling);
-  }
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  nsContainerFrame* f = const_cast<nsContainerFrame*>(this);
-  if (f->HasOverflowAreas()) {
-    nsRect overflowArea = f->GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = f->GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
-  nsIAtom* pseudoTag = mStyleContext->GetPseudo();
-  if (pseudoTag) {
-    nsAutoString atomString;
-    pseudoTag->ToString(atomString);
-    fprintf(out, " pst=%s",
-            NS_LossyConvertUTF16toASCII(atomString).get());
-  }
+  ListGeneric(out, aIndent, aFlags);
 
   // Output the children
   bool outputOneList = false;
   ChildListIterator lists(this);
   for (; !lists.IsDone(); lists.Next()) {
     if (outputOneList) {
       IndentBy(out, aIndent);
     }
-    outputOneList = true;
-    fputs(mozilla::layout::ChildListName(lists.CurrentID()), out);
+    if (lists.CurrentID() != kPrincipalList) {
+      if (!outputOneList) {
+        fputs("\n", out);
+        IndentBy(out, aIndent);
+      }
+      fputs(mozilla::layout::ChildListName(lists.CurrentID()), out);
+      fprintf(out, " %p ", &GetChildList(lists.CurrentID()));
+    }
     fputs("<\n", out);
     nsFrameList::Enumerator childFrames(lists.CurrentList());
     for (; !childFrames.AtEnd(); childFrames.Next()) {
       nsIFrame* kid = childFrames.get();
       // Verify the child frame's parent frame pointer is correct
       NS_ASSERTION(kid->GetParent() == this, "bad parent frame pointer");
 
       // Have the child frame list
       kid->List(out, aIndent + 1, aFlags);
     }
     IndentBy(out, aIndent);
     fputs(">\n", out);
+    outputOneList = true;
   }
 
   if (!outputOneList) {
     fputs("<>\n", out);
   }
-
-  return NS_OK;
 }
 #endif
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -71,17 +71,17 @@ public:
   virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
 
   virtual bool IsLeaf() const;
   virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) MOZ_OVERRIDE;
   
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
 #endif  
 
   // nsContainerFrame methods
 
   /**
    * Helper method to create next-in-flows if necessary. If aFrame
    * already has a next-in-flow then this method does
    * nothing. Otherwise, a new continuation frame is created and
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -200,23 +200,23 @@ nsFrame::GetLogModuleInfo()
 {
   if (nullptr == gLogModule) {
     gLogModule = PR_NewLogModule("frame");
   }
   return gLogModule;
 }
 
 void
-nsFrame::DumpFrameTree(nsIFrame* aFrame)
+nsIFrame::DumpFrameTree(nsIFrame* aFrame)
 {
     RootFrameList(aFrame->PresContext(), stdout, 0);
 }
 
 void
-nsFrame::RootFrameList(nsPresContext* aPresContext, FILE* out, int32_t aIndent)
+nsIFrame::RootFrameList(nsPresContext* aPresContext, FILE* out, int32_t aIndent)
 {
   if (!aPresContext || !out)
     return;
 
   nsIPresShell *shell = aPresContext->GetPresShell();
   if (shell) {
     nsIFrame* frame = shell->FrameManager()->GetRootFrame();
     if(frame) {
@@ -5272,52 +5272,92 @@ int32_t nsFrame::ContentIndexInContainer
 void
 DebugListFrameTree(nsIFrame* aFrame)
 {
   ((nsFrame*)aFrame)->List(stdout, 0);
 }
 
 
 // Debugging
-NS_IMETHODIMP
-nsFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
+void
+nsIFrame::ListGeneric(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
   IndentBy(out, aIndent);
   ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", static_cast<void*>(mParent));
-#endif
   if (HasView()) {
     fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
   }
+  if (GetNextSibling()) {
+    fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
+  }
+  if (GetPrevContinuation()) {
+    bool fluid = GetPrevInFlow() == GetPrevContinuation();
+    fprintf(out, " prev-%s=%p", fluid?"in-flow":"continuation",
+            static_cast<void*>(GetPrevContinuation()));
+  }
+  if (GetNextContinuation()) {
+    bool fluid = GetNextInFlow() == GetNextContinuation();
+    fprintf(out, " next-%s=%p", fluid?"in-flow":"continuation",
+            static_cast<void*>(GetNextContinuation()));
+  }
+  void* IBsibling = Properties().Get(IBSplitSpecialSibling());
+  if (IBsibling) {
+    fprintf(out, " IBSplitSpecialSibling=%p", IBsibling);
+  }
+  void* IBprevsibling = Properties().Get(IBSplitSpecialPrevSibling());
+  if (IBprevsibling) {
+    fprintf(out, " IBSplitSpecialPrevSibling=%p", IBprevsibling);
+  }
   fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
+  nsIFrame* f = const_cast<nsIFrame*>(this);
+  if (f->HasOverflowAreas()) {
+    nsRect vo = f->GetVisualOverflowRect();
+    if (!vo.IsEqualEdges(mRect)) {
+      fprintf(out, " vis-overflow=%d,%d,%d,%d", vo.x, vo.y, vo.width, vo.height);
+    }
+    nsRect so = f->GetScrollableOverflowRect();
+    if (!so.IsEqualEdges(mRect)) {
+      fprintf(out, " scr-overflow=%d,%d,%d,%d", so.x, so.y, so.width, so.height);
+    }
+  }
   if (0 != mState) {
     fprintf(out, " [state=%016llx]", (unsigned long long)mState);
   }
-  nsIFrame* prevInFlow = GetPrevInFlow();
-  nsIFrame* nextInFlow = GetNextInFlow();
-  if (nullptr != prevInFlow) {
-    fprintf(out, " prev-in-flow=%p", static_cast<void*>(prevInFlow));
-  }
-  if (nullptr != nextInFlow) {
-    fprintf(out, " next-in-flow=%p", static_cast<void*>(nextInFlow));
-  }
-  fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  nsFrame* f = const_cast<nsFrame*>(this);
-  if (f->HasOverflowAreas()) {
-    nsRect overflowArea = f->GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = f->GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
+  if (IsTransformed()) {
+    fprintf(out, " transformed");
+  }
+  if (ChildrenHavePerspective()) {
+    fprintf(out, " perspective");
+  }
+  if (Preserves3DChildren()) {
+    fprintf(out, " preserves-3d-children");
+  }
+  if (Preserves3D()) {
+    fprintf(out, " preserves-3d");
+  }
+  if (mContent) {
+    fprintf(out, " [content=%p]", static_cast<void*>(mContent));
+  }
+  fprintf(out, " [sc=%p", static_cast<void*>(mStyleContext));
+  if (mStyleContext) {
+    nsIAtom* pseudoTag = mStyleContext->GetPseudo();
+    if (pseudoTag) {
+      nsAutoString atomString;
+      pseudoTag->ToString(atomString);
+      fprintf(out, "%s", NS_LossyConvertUTF16toASCII(atomString).get());
+    }
+  }
+  fputs("]", out);
+}
+
+void
+nsIFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
+{
+  ListGeneric(out, aIndent, aFlags);
   fputs("\n", out);
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("Frame"), aResult);
 }
 
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -439,31 +439,16 @@ public:
   // Helper function that verifies that each frame in the list has the
   // NS_FRAME_IS_DIRTY bit set
   static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
 
   // Helper function to return the index in parent of the frame's content
   // object. Returns -1 on error or if the frame doesn't have a content object
   static int32_t ContentIndexInContainer(const nsIFrame* aFrame);
 
-  static void IndentBy(FILE* out, int32_t aIndent) {
-    while (--aIndent >= 0) fputs("  ", out);
-  }
-  
-  void ListTag(FILE* out) const {
-    ListTag(out, this);
-  }
-
-  static void ListTag(FILE* out, const nsIFrame* aFrame) {
-    nsAutoString tmp;
-    aFrame->GetFrameName(tmp);
-    fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
-    fprintf(out, "@%p", static_cast<const void*>(aFrame));
-  }
-
   static void XMLQuote(nsString& aString);
 
   /**
    * Dump out the "base classes" regression data. This should dump
    * out the interior data, not the "frame" XML container. And it
    * should call the base classes same named method before doing
    * anything specific in a derived class. This means that derived
    * classes need not override DumpRegressionData unless they need
@@ -671,28 +656,16 @@ private:
                      bool aMoveFrame = true);
 
   NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
 
   virtual nsILineIterator* GetLineIterator();
 
 #ifdef DEBUG
 public:
-  // Formerly the nsIFrameDebug interface
-
-  NS_IMETHOD  List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
-  /**
-   * lists the frames beginning from the root frame
-   * - calls root frame's List(...)
-   */
-  static void RootFrameList(nsPresContext* aPresContext,
-                            FILE* out, int32_t aIndent);
-
-  static void DumpFrameTree(nsIFrame* aFrame);
-
   /**
    * Get a printable from of the name of the frame type.
    * XXX This should be eliminated and we use GetType() instead...
    */
   NS_IMETHOD  GetFrameName(nsAString& aResult) const;
   /**
    * Return the state bits that are relevant to regression tests (that
    * is, those bits which indicate a real difference when they differ
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -142,19 +142,20 @@ protected:
 class nsHTMLFramesetBlankFrame : public nsLeafFrame
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsHTMLFramesetBlankFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out,
-                  int32_t aIndent,
-                  uint32_t aFlags = 0) const MOZ_OVERRIDE;
+  NS_IMETHOD GetFrameName(nsAString& aResult) const
+  {
+    return MakeFrameName(NS_LITERAL_STRING("FramesetBlank"), aResult);
+  }
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
@@ -1706,28 +1707,16 @@ public:
 void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
                                    nsRenderingContext* aCtx)
 {
   nscolor white = NS_RGB(255,255,255);
   aCtx->SetColor(white);
   aCtx->FillRect(mVisibleRect);
 }
 
-#ifdef DEBUG
-NS_IMETHODIMP
-nsHTMLFramesetBlankFrame::List(FILE*    out,
-                               int32_t  aIndent,
-                               uint32_t aFlags) const
-{
-  IndentBy(out, aIndent);
-  fprintf(out, "%p BLANK \n", (void*)this);
-  return nsLeafFrame::List(out, aIndent, aFlags);
-}
-#endif
-
 void
 nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists)
 {
   aLists.Content()->AppendNewToTop(
     new (aBuilder) nsDisplayFramesetBlank(aBuilder, this));
 }
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -3123,21 +3123,42 @@ private:
   /**
    * Returns true if any overflow changed.
    */
   bool SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
   nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const int32_t aAPD) const;
 
 #ifdef DEBUG
 public:
-  // Formerly nsIFrameDebug
+  static void IndentBy(FILE* out, int32_t aIndent) {
+    while (--aIndent >= 0) fputs("  ", out);
+  }
+  void ListTag(FILE* out) const {
+    ListTag(out, this);
+  }
+  static void ListTag(FILE* out, const nsIFrame* aFrame) {
+    nsAutoString tmp;
+    aFrame->GetFrameName(tmp);
+    fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
+    fprintf(out, "@%p", static_cast<const void*>(aFrame));
+  }
+  void ListGeneric(FILE* out, int32_t aIndent, uint32_t aFlags) const;
   enum {
     TRAVERSE_SUBDOCUMENT_FRAMES = 0x01
   };
-  NS_IMETHOD  List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const = 0;
+  virtual void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
+  /**
+   * lists the frames beginning from the root frame
+   * - calls root frame's List(...)
+   */
+  static void RootFrameList(nsPresContext* aPresContext,
+                            FILE* out, int32_t aIndent);
+  static void DumpFrameTree(nsIFrame* aFrame);
+
+
   NS_IMETHOD  GetFrameName(nsAString& aResult) const = 0;
   NS_IMETHOD_(nsFrameState)  GetDebugStateBits() const = 0;
   NS_IMETHOD  DumpRegressionData(nsPresContext* aPresContext,
                                  FILE* out, int32_t aIndent) = 0;
 #endif
 };
 
 //----------------------------------------------------------------------
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1729,50 +1729,36 @@ nsImageFrame::GetType() const
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsImageFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("ImageFrame"), aResult);
 }
 
-NS_IMETHODIMP
+void
 nsImageFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", mParent);
-#endif
-  if (HasView()) {
-    fprintf(out, " [view=%p]", (void*)GetView());
-  }
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  fprintf(out, " [content=%p]", (void*)mContent);
-  fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
+  ListGeneric(out, aIndent, aFlags);
 
   // output the img src url
   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
   if (imageLoader) {
     nsCOMPtr<imgIRequest> currentRequest;
     imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                             getter_AddRefs(currentRequest));
     if (currentRequest) {
       nsCOMPtr<nsIURI> uri;
       currentRequest->GetURI(getter_AddRefs(uri));
       nsAutoCString uristr;
       uri->GetAsciiSpec(uristr);
       fprintf(out, " [src=%s]", uristr.get());
     }
   }
   fputs("\n", out);
-  return NS_OK;
 }
 #endif
 
 int
 nsImageFrame::GetSkipSides() const
 {
   int skip = 0;
   if (nullptr != GetPrevInFlow()) {
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -108,17 +108,17 @@ public:
 
   virtual bool IsFrameOfType(uint32_t aFlags) const
   {
     return ImageFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
   }
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
 #endif
 
   virtual int GetSkipSides() const MOZ_OVERRIDE;
 
   nsresult GetIntrinsicImageSize(nsSize& aSize);
 
   static void ReleaseGlobals() {
     if (gIconLoad) {
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -234,18 +234,20 @@ nsLineBox::List(FILE* out, int32_t aInde
   fprintf(out, "line %p: count=%d state=%s ",
           static_cast<const void*>(this), GetChildCount(),
           StateToString(cbuf, sizeof(cbuf)));
   if (IsBlock() && !GetCarriedOutBottomMargin().IsZero()) {
     fprintf(out, "bm=%d ", GetCarriedOutBottomMargin().get());
   }
   fprintf(out, "{%d,%d,%d,%d} ",
           mBounds.x, mBounds.y, mBounds.width, mBounds.height);
-  if (mData) {
-    fprintf(out, "vis-overflow={%d,%d,%d,%d} scr-overflow={%d,%d,%d,%d} ",
+  if (mData &&
+      (!mData->mOverflowAreas.VisualOverflow().IsEqualEdges(mBounds) ||
+       !mData->mOverflowAreas.ScrollableOverflow().IsEqualEdges(mBounds))) {
+    fprintf(out, "vis-overflow=%d,%d,%d,%d scr-overflow=%d,%d,%d,%d ",
             mData->mOverflowAreas.VisualOverflow().x,
             mData->mOverflowAreas.VisualOverflow().y,
             mData->mOverflowAreas.VisualOverflow().width,
             mData->mOverflowAreas.VisualOverflow().height,
             mData->mOverflowAreas.ScrollableOverflow().x,
             mData->mOverflowAreas.ScrollableOverflow().y,
             mData->mOverflowAreas.ScrollableOverflow().width,
             mData->mOverflowAreas.ScrollableOverflow().height);
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -198,42 +198,20 @@ nsPlaceholderFrame::BuildDisplayList(nsD
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsPlaceholderFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("Placeholder"), aResult);
 }
 
-NS_IMETHODIMP
+void
 nsPlaceholderFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-  if (HasView()) {
-    fprintf(out, " [view=%p]", (void*)GetView());
-  }
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  nsIFrame* prevInFlow = GetPrevInFlow();
-  nsIFrame* nextInFlow = GetNextInFlow();
-  if (prevInFlow) {
-    fprintf(out, " prev-in-flow=%p", static_cast<void*>(prevInFlow));
-  }
-  if (nextInFlow) {
-    fprintf(out, " next-in-flow=%p", static_cast<void*>(nextInFlow));
-  }
-  if (mContent) {
-    fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  }
-  if (mStyleContext) {
-    fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
-  }
+  ListGeneric(out, aIndent, aFlags);
+
   if (mOutOfFlowFrame) {
     fprintf(out, " outOfFlowFrame=");
     nsFrame::ListTag(out, mOutOfFlowFrame);
   }
   fputs("\n", out);
-  return NS_OK;
 }
 #endif // DEBUG
--- a/layout/generic/nsPlaceholderFrame.h
+++ b/layout/generic/nsPlaceholderFrame.h
@@ -107,17 +107,17 @@ public:
 
 #if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 #endif // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF)
   
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif // DEBUG
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::placeholderFrame
    */
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -499,60 +499,29 @@ nsSubDocumentFrame::GetIntrinsicHeight()
   NS_ASSERTION(ObtainIntrinsicSizeFrame() == nullptr,
                "Intrinsic height should come from the embedded document.");
 
   // Use 150px, for compatibility with IE, and per CSS2.1 draft.
   return nsPresContext::CSSPixelsToAppUnits(150);
 }
 
 #ifdef DEBUG
-NS_IMETHODIMP
+void
 nsSubDocumentFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", static_cast<void*>(mParent));
-#endif
-  if (HasView()) {
-    fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
-  }
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  nsIFrame* prevInFlow = GetPrevInFlow();
-  nsIFrame* nextInFlow = GetNextInFlow();
-  if (nullptr != prevInFlow) {
-    fprintf(out, " prev-in-flow=%p", static_cast<void*>(prevInFlow));
-  }
-  if (nullptr != nextInFlow) {
-    fprintf(out, " next-in-flow=%p", static_cast<void*>(nextInFlow));
-  }
-  fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  nsSubDocumentFrame* f = const_cast<nsSubDocumentFrame*>(this);
-  if (f->HasOverflowAreas()) {
-    nsRect overflowArea = f->GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = f->GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
+  ListGeneric(out, aIndent, aFlags);
   fputs("\n", out);
 
+  nsSubDocumentFrame* f = const_cast<nsSubDocumentFrame*>(this);
   if (aFlags & TRAVERSE_SUBDOCUMENT_FRAMES) {
     nsIFrame* subdocRootFrame = f->GetSubdocumentRootFrame();
     if (subdocRootFrame) {
       subdocRootFrame->List(out, aIndent + 1);
     }
   }
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP nsSubDocumentFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("FrameOuter"), aResult);
 }
 #endif
 
--- a/layout/generic/nsSubDocumentFrame.h
+++ b/layout/generic/nsSubDocumentFrame.h
@@ -19,17 +19,17 @@ class nsSubDocumentFrame : public nsLeaf
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsSubDocumentFrame)
   NS_DECL_FRAMEARENA_HELPERS
 
   nsSubDocumentFrame(nsStyleContext* aContext);
 
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
 
   NS_DECL_QUERYFRAME
 
   virtual nsIAtom* GetType() const;
 
   virtual bool IsFrameOfType(uint32_t aFlags) const
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -117,17 +117,17 @@ public:
     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
                                              nsIFrame::eLineParticipant));
   }
 
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
 
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const;
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
   NS_IMETHOD_(nsFrameState) GetDebugStateBits() const ;
 #endif
   
   virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
   ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint &aPoint);
 
   /**
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -8319,71 +8319,32 @@ nsTextFrame::GetFrameName(nsAString& aRe
 NS_IMETHODIMP_(nsFrameState)
 nsTextFrame::GetDebugStateBits() const
 {
   // mask out our emptystate flags; those are just caches
   return nsFrame::GetDebugStateBits() &
     ~(TEXT_WHITESPACE_FLAGS | TEXT_REFLOW_FLAGS);
 }
 
-NS_IMETHODIMP
+void
 nsTextFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  // Output the tag
-  IndentBy(out, aIndent);
-  ListTag(out);
-  if (HasView()) {
-    fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
-  }
+  ListGeneric(out, aIndent, aFlags);
+
   fprintf(out, " [run=%p]", static_cast<void*>(mTextRun));
 
   // Output the first/last content offset and prev/next in flow info
   bool isComplete = uint32_t(GetContentEnd()) == GetContent()->TextLength();
-  fprintf(out, "[%d,%d,%c] ", 
-          GetContentOffset(), GetContentLength(),
+  fprintf(out, "[%d,%d,%c] ", GetContentOffset(), GetContentLength(),
           isComplete ? 'T':'F');
   
-  if (GetNextSibling()) {
-    fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
-  }
-  nsIFrame* prevContinuation = GetPrevContinuation();
-  if (nullptr != prevContinuation) {
-    fprintf(out, " prev-continuation=%p", static_cast<void*>(prevContinuation));
-  }
-  if (nullptr != mNextContinuation) {
-    fprintf(out, " next-continuation=%p", static_cast<void*>(mNextContinuation));
-  }
-
-  // Output the rect and state
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  fprintf(out, " [state=%016llx]", (unsigned long long)mState);
   if (IsSelected()) {
     fprintf(out, " SELECTED");
   }
-  fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  if (HasOverflowAreas()) {
-    nsRect overflowArea = GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]",
-            overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]",
-            overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  fprintf(out, " sc=%p", static_cast<void*>(mStyleContext));
-  nsIAtom* pseudoTag = mStyleContext->GetPseudo();
-  if (pseudoTag) {
-    nsAutoString atomString;
-    pseudoTag->ToString(atomString);
-    fprintf(out, " pst=%s",
-            NS_LossyConvertUTF16toASCII(atomString).get());
-  }
   fputs("\n", out);
-  return NS_OK;
 }
 #endif
 
 void
 nsTextFrame::AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd)
 {
   AddStateBits(NS_FRAME_IS_BIDI);
   mContent->DeleteProperty(nsGkAtoms::flowlength);
--- a/layout/mathml/tests/test_bug553917.html
+++ b/layout/mathml/tests/test_bug553917.html
@@ -4,18 +4,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <html>
   <head>
     <title>Test for Bug 553917</title>
     <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     <script type="application/javascript">
-      SimpleTest.expectAssertions(204);
-
       var stringBundleService = 
         SpecialPowers.Cc["@mozilla.org/intl/stringbundle;1"]
                     .getService(SpecialPowers.Ci.nsIStringBundleService);
       var g_bundl =
         stringBundleService.createBundle("chrome://global/locale/mathml/mathml.properties");
       
       var g_errorInfo = {
       /*<math><mroot></mroot></math>
@@ -73,21 +71,24 @@ https://bugzilla.mozilla.org/show_bug.cg
       
       var g_errorTypes = ["ChildCountIncorrect","DeprecatedSupersededBy","AttributeParsingError",
                           "AttributeParsingErrorNoTag","LengthParsingError", "MMultiscriptsErrors",
                           "UnitlessValuesAreDeprecated"];
       
       function getErrorMessage(name,idx)
       {
         if (name != "MMultiscriptsErrors") {
-          return g_bundl.formatStringFromName(name,g_errorInfo[name].args[idx], 
-                                            g_errorInfo[name].args[idx].length);
-        }
-        else {
-          return g_bundl.formatStringFromName(g_errorInfo[name].args[idx],[],0);
+          var formatParams = g_errorInfo[name].args[idx];
+          if (formatParams.length > 0) {
+            return g_bundl.formatStringFromName(name,formatParams,formatParams.length);
+          } else {
+            return g_bundl.GetStringFromName(name);
+          }
+        } else {
+          return g_bundl.GetStringFromName(g_errorInfo[name].args[idx]);
         }
       }
     
     /** Checks the roll call to see if all expected error messages were present. */
     function processRollCall()
     {
       for (var i=0; i<g_errorTypes.length;i++) {
         for (var j = 0; j < g_errorInfo[g_errorTypes[i]].status.length; j++) {
--- a/layout/xul/base/src/nsPopupSetFrame.cpp
+++ b/layout/xul/base/src/nsPopupSetFrame.cpp
@@ -142,60 +142,20 @@ nsPopupSetFrame::AddPopupFrameList(nsFra
                  e.get()->GetType() == nsGkAtoms::menuPopupFrame,
                  "adding wrong type of frame in popupset's ::popupList");
   }
 #endif
   mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
 }
 
 #ifdef DEBUG
-NS_IMETHODIMP
+void
 nsPopupSetFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
 {
-  IndentBy(out, aIndent);
-  ListTag(out);
-#ifdef DEBUG_waterson
-  fprintf(out, " [parent=%p]", static_cast<void*>(mParent));
-#endif
-  if (HasView()) {
-    fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
-  }
-  if (GetNextSibling()) {
-    fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
-  }
-  if (nullptr != GetPrevContinuation()) {
-    fprintf(out, " prev-continuation=%p", static_cast<void*>(GetPrevContinuation()));
-  }
-  if (nullptr != GetNextContinuation()) {
-    fprintf(out, " next-continuation=%p", static_cast<void*>(GetNextContinuation()));
-  }
-  fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
-  if (0 != mState) {
-    fprintf(out, " [state=%016llx]", (unsigned long long)mState);
-  }
-  fprintf(out, " [content=%p]", static_cast<void*>(mContent));
-  nsPopupSetFrame* f = const_cast<nsPopupSetFrame*>(this);
-  if (f->HasOverflowAreas()) {
-    nsRect overflowArea = f->GetVisualOverflowRect();
-    fprintf(out, " [vis-overflow=%d,%d,%d,%d]",
-            overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-    overflowArea = f->GetScrollableOverflowRect();
-    fprintf(out, " [scr-overflow=%d,%d,%d,%d]",
-            overflowArea.x, overflowArea.y,
-            overflowArea.width, overflowArea.height);
-  }
-  fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
-  nsIAtom* pseudoTag = mStyleContext->GetPseudo();
-  if (pseudoTag) {
-    nsAutoString atomString;
-    pseudoTag->ToString(atomString);
-    fprintf(out, " pst=%s",
-            NS_LossyConvertUTF16toASCII(atomString).get());
-  }
+  ListGeneric(out, aIndent, aFlags);
 
   // Output the children
   bool outputOneList = false;
   ChildListIterator lists(this);
   for (; !lists.IsDone(); lists.Next()) {
     if (outputOneList) {
       IndentBy(out, aIndent);
     }
@@ -236,12 +196,10 @@ nsPopupSetFrame::List(FILE* out, int32_t
     IndentBy(out, aIndent);
     fputs(">\n", out);
     outputOneList = true;
   }
 
   if (!outputOneList) {
     fputs("<>\n", out);
   }
-
-  return NS_OK;
 }
 #endif
--- a/layout/xul/base/src/nsPopupSetFrame.h
+++ b/layout/xul/base/src/nsPopupSetFrame.h
@@ -39,17 +39,17 @@ public:
   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
 
   // Used to destroy our popup frames.
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
-  NS_IMETHOD List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
+  void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
       return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult);
   }
 #endif
 
 protected:
   void AddPopupFrameList(nsFrameList& aPopupFrameList);
--- a/mobile/android/base/resources/drawable/action_bar_button_inverse.xml
+++ b/mobile/android/base/resources/drawable/action_bar_button_inverse.xml
@@ -1,17 +1,23 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <item android:state_pressed="true"
-          android:drawable="@color/highlight_dark"/>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="@color/highlight_dark" />
+        </shape>
+    </item>
 
     <item android:state_focused="true"
-          android:state_pressed="false"
-          android:drawable="@color/highlight_dark_focused"/>
+          android:state_pressed="false">
+        <shape>
+            <solid android:color="@color/highlight_dark_focused" />
+        </shape>
+    </item>
 
     <item android:drawable="@android:color/transparent"/>
 
 </selector>
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -7,18 +7,16 @@ tail =
 [test_307_redirect.js]
 [test_NetUtil.js]
 [test_URIs.js]
 [test_aboutblank.js]
 [test_assoc.js]
 [test_auth_jar.js]
 [test_auth_proxy.js]
 [test_authentication.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_authpromptwrapper.js]
 [test_backgroundfilesaver.js]
 [test_bug203271.js]
 [test_bug248970_cache.js]
 [test_bug248970_cookie.js]
 [test_bug261425.js]
 [test_bug263127.js]
 [test_bug282432.js]
@@ -40,56 +38,44 @@ skip-if = os == "android"
 [test_bug411952.js]
 [test_bug412945.js]
 [test_bug414122.js]
 [test_bug427957.js]
 [test_bug429347.js]
 [test_bug455311.js]
 [test_bug455598.js]
 [test_bug468426.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_bug468594.js]
 [test_bug470716.js]
 [test_bug479413.js]
 [test_bug479485.js]
 [test_bug482601.js]
 [test_bug484684.js]
 [test_bug490095.js]
 [test_bug504014.js]
 [test_bug510359.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_bug515583.js]
 [test_bug528292.js]
 [test_bug536324_64bit_content_length.js]
 [test_bug540566.js]
 [test_bug543805.js]
 [test_bug553970.js]
 [test_bug561042.js]
 [test_bug561276.js]
 [test_bug580508.js]
 [test_bug586908.js]
 [test_bug596443.js]
 [test_bug618835.js]
 [test_bug633743.js]
 [test_bug650995.js]
 [test_bug652761.js]
 [test_bug651100.js]
-# Bug 675044: test fails consistently on Android
-fail-if = os == "android"
 [test_bug654926.js]
-# Bug 675049: test fails consistently on Android
-fail-if = os == "android"
 [test_bug654926_doom_and_read.js]
-# Bug 675049: test fails consistently on Android
-fail-if = os == "android"
 [test_bug654926_test_seek.js]
-# Bug 675049: test fails consistently on Android
-fail-if = os == "android"
 [test_bug659569.js]
 [test_bug660066.js]
 [test_bug667907.js]
 [test_bug667818.js]
 [test_bug669001.js]
 [test_bug712914_secinfo_validation.js]
 [test_bug722299.js]
 [test_bug770243.js]
@@ -106,39 +92,23 @@ fail-if = os == "android"
 [test_data_protocol.js]
 [test_dns_service.js]
 [test_dns_localredirect.js]
 [test_duplicate_headers.js]
 [test_event_sink.js]
 [test_extract_charset_from_content_type.js]
 [test_force_sniffing.js]
 [test_fallback_no-cache-entry_canceled.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_no-cache-entry_passing.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_redirect-to-different-origin_canceled.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_redirect-to-different-origin_passing.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_request-error_canceled.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_request-error_passing.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_response-error_canceled.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_fallback_response-error_passing.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
 [test_file_partial_inputstream.js]
 [test_file_protocol.js]
 [test_filestreams.js]
 [test_gre_resources.js]
 [test_gzipped_206.js]
 [test_head.js]
 [test_header_Accept-Language.js]
 [test_headers.js]
@@ -173,33 +143,37 @@ skip-if = os == "win"
 [test_proxy-failover_passing.js]
 [test_proxy-replace_canceled.js]
 [test_proxy-replace_passing.js]
 [test_psl.js]
 [test_range_requests.js]
 [test_readline.js]
 [test_redirect-caching_canceled.js]
 [test_redirect-caching_failure.js]
+# Bug 675039: test fails consistently on Android
+fail-if = os == "android"
 [test_redirect-caching_passing.js]
 [test_redirect_canceled.js]
 [test_redirect_failure.js]
+# Bug 675039: test fails consistently on Android
+fail-if = os == "android"
 [test_redirect_from_script.js]
 [test_redirect_passing.js]
 [test_redirect_loop.js]
 [test_redirect_baduri.js]
 [test_reentrancy.js]
 [test_reopen.js]
 [test_resumable_channel.js]
 [test_resumable_truncate.js]
 [test_safeoutputstream.js]
 [test_simple.js]
 [test_sockettransportsvc_available.js]
 [test_socks.js]
-# Bug 675039: test hangs consistently on Android
-skip-if = os == "android"
+# Bug 675039: test fails consistently on Android
+fail-if = os == "android"
 [test_spdy.js]
 # spdy unit tests require us to have node available to run the spdy server
 run-if = hasNode
 [test_speculative_connect.js]
 [test_standardurl.js]
 [test_standardurl_port.js]
 [test_streamcopier.js]
 [test_traceable_channel.js]
--- a/testing/marionette/client/setup.py
+++ b/testing/marionette/client/setup.py
@@ -1,25 +1,25 @@
 import os
 from setuptools import setup, find_packages
 
-version = '0.5.25'
+version = '0.5.26'
 
 # get documentation from the README
 try:
     here = os.path.dirname(os.path.abspath(__file__))
     description = file(os.path.join(here, 'README.md')).read()
 except (OSError, IOError):
     description = ''
 
 # dependencies
-deps = ['manifestdestiny', 'mozhttpd >= 0.3',
-        'mozprocess >= 0.6', 'mozrunner >= 5.11',
-        'mozdevice >= 0.12', 'moznetwork >= 0.21',
-        'mozcrash >= 0.5']
+deps = ['manifestdestiny', 'mozhttpd >= 0.5',
+        'mozprocess >= 0.9', 'mozrunner >= 5.15',
+        'mozdevice >= 0.22', 'moznetwork >= 0.21',
+        'mozcrash >= 0.5', 'mozprofile >= 0.7']
 
 setup(name='marionette_client',
       version=version,
       description="Marionette test automation client",
       long_description=description,
       classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       keywords='mozilla',
       author='Jonathan Griffin',
--- a/testing/marionette/marionette-elements.js
+++ b/testing/marionette/marionette-elements.js
@@ -66,17 +66,21 @@ ElementManager.prototype = {
   * @param nsIDOMElement element
   *        The element to add
   *
   * @return string
   *        Returns the server-assigned reference ID
   */
   addToKnownElements: function EM_addToKnownElements(element) {
     for (let i in this.seenItems) {
-      let foundEl = this.seenItems[i].get();
+      let foundEl = null;
+      try {
+        foundEl = this.seenItems[i].get();
+      }
+      catch(e) {}
       if (foundEl) {
         if (XPCNativeWrapper(foundEl) == XPCNativeWrapper(element)) {
           return i;
         }
       }
       else {
         //cleanup reference to GC'd element
         delete this.seenItems[i];
@@ -98,17 +102,23 @@ ElementManager.prototype = {
    * @returns nsIDOMElement
    *        Returns the element or throws Exception if not found
    */
   getKnownElement: function EM_getKnownElement(id, win) {
     let el = this.seenItems[id];
     if (!el) {
       throw new ElementException("Element has not been seen before", 17, null);
     }
-    el = el.get();
+    try {
+      el = el.get();
+    }
+    catch(e) {
+      el = null;
+      delete this.seenItems[id];
+    }
     // use XPCNativeWrapper to compare elements; see bug 834266
     if (!el || !(XPCNativeWrapper(el).ownerDocument == XPCNativeWrapper(win).document)) {
       throw new ElementException("Stale element reference", 10, null);
     }
     return el;
   },
   
   /**
--- a/testing/xpcshell/xpcshell_android.ini
+++ b/testing/xpcshell/xpcshell_android.ini
@@ -1,5 +1,16 @@
 ; This Source Code Form is subject to the terms of the Mozilla Public
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+[include:chrome/test/unit/xpcshell.ini]
+[include:intl/locale/tests/unit/xpcshell.ini]
+[include:netwerk/cookie/test/unit/xpcshell.ini]
+[include:modules/libjar/zipwriter/test/unit/xpcshell.ini]
+[include:parser/xml/test/unit/xpcshell.ini]
+[include:image/test/unit/xpcshell.ini]
+[include:testing/xpcshell/example/unit/xpcshell.ini]
+[include:xpcom/tests/unit/xpcshell.ini]
+[include:netwerk/test/unit/xpcshell.ini]
+[include:rdf/tests/unit/xpcshell.ini]
 [include:gfx/tests/unit/xpcshell.ini]
+
--- a/toolkit/content/plugins.html
+++ b/toolkit/content/plugins.html
@@ -56,24 +56,24 @@
    * any plug-ins that would be active otherwise.  In contrast, one would
    * use "true" in the case of ASD instead of restarting)
    */
   navigator.plugins.refresh(false);
 
   AddonManager.getAddonsByTypes(["plugin"], function (aPlugins) {
     var fragment = document.createDocumentFragment();
 
-    // "Enabled plugins"
+    // "Installed plugins"
     var id, label;
     if (aPlugins.length > 0) {
       id = "plugs";
-      label = "enabledplugins_label";
+      label = "installedplugins_label";
     } else {
       id = "noplugs";
-      label = "nopluginsareenabled_label";
+      label = "nopluginsareinstalled_label";
     }
     var enabledplugins = document.createElement("h1");
     enabledplugins.setAttribute("id", id);
     enabledplugins.appendChild(document.createTextNode(pluginsbundle.GetStringFromName(label)));
     fragment.appendChild(enabledplugins);
 
     // "Find updates for installed plugins at " ...
     var findpluginupdates = document.createElement("div");
--- a/widget/gtk2/gtk2drawing.c
+++ b/widget/gtk2/gtk2drawing.c
@@ -1539,33 +1539,16 @@ moz_gtk_vpaned_paint(GdkDrawable* drawab
                      GTK_SHADOW_NONE, cliprect, gVPanedWidget, "paned",
                      rect->x, rect->y, rect->width, rect->height,
                      GTK_ORIENTATION_HORIZONTAL);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_caret_paint(GdkDrawable* drawable, GdkRectangle* rect,
-                    GdkRectangle* cliprect, GtkTextDirection direction)
-{
-    GdkRectangle location = *rect;
-    if (direction == GTK_TEXT_DIR_RTL) {
-        /* gtk_draw_insertion_cursor ignores location.width */
-        location.x = rect->x + rect->width;
-    }
-
-    ensure_entry_widget();
-    gtk_draw_insertion_cursor(gEntryWidget, drawable, cliprect,
-                              &location, TRUE, direction, FALSE);
-
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
 moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect,
                     GdkRectangle* cliprect, GtkWidgetState* state,
                     GtkWidget* widget, GtkTextDirection direction)
 {
     GtkStateType bg_state = state->disabled ?
                                 GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
     gint x, y, width = rect->width, height = rect->height;
     GtkStyle* style;
@@ -2995,17 +2978,16 @@ moz_gtk_get_widget_border(GtkThemeWidget
     case MOZ_GTK_TOOLTIP:
     case MOZ_GTK_WINDOW:
     case MOZ_GTK_RESIZER:
     case MOZ_GTK_MENUARROW:
     case MOZ_GTK_TOOLBARBUTTON_ARROW:
     case MOZ_GTK_TOOLBAR:
     case MOZ_GTK_MENUBAR:
     case MOZ_GTK_TAB_SCROLLARROW:
-    case MOZ_GTK_ENTRY_CARET:
         *left = *top = *right = *bottom = 0;
         return MOZ_GTK_SUCCESS;
     default:
         g_warning("Unsupported widget type: %d", widget);
         return MOZ_GTK_UNKNOWN_WIDGET;
     }
 
     *right = *left = XTHICKNESS(w->style);
@@ -3278,19 +3260,16 @@ moz_gtk_widget_paint(GtkThemeWidgetType 
         return moz_gtk_expander_paint(drawable, rect, cliprect, state,
                                       (GtkExpanderStyle) flags, direction);
         break;
     case MOZ_GTK_ENTRY:
         ensure_entry_widget();
         return moz_gtk_entry_paint(drawable, rect, cliprect, state,
                                    gEntryWidget, direction);
         break;
-    case MOZ_GTK_ENTRY_CARET:
-        return moz_gtk_caret_paint(drawable, rect, cliprect, direction);
-        break;
     case MOZ_GTK_DROPDOWN:
         return moz_gtk_combo_box_paint(drawable, rect, cliprect, state,
                                        (gboolean) flags, direction);
         break;
     case MOZ_GTK_DROPDOWN_ARROW:
         return moz_gtk_combo_box_entry_button_paint(drawable, rect, cliprect,
                                                     state, flags, direction);
         break;
--- a/widget/gtk2/gtk3drawing.c
+++ b/widget/gtk2/gtk3drawing.c
@@ -1406,33 +1406,16 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec
     gtk_render_handle(style, cr,
                       rect->x, rect->y, rect->width, rect->height);                     
     gtk_style_context_restore(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
-moz_gtk_caret_paint(cairo_t *cr, GdkRectangle* rect,
-                    GtkTextDirection direction)
-{
-    GdkRectangle location = *rect;
-
-    if (direction == GTK_TEXT_DIR_RTL) {
-        /* gtk_draw_insertion_cursor ignores location.width */
-        location.x = rect->x + rect->width;
-    }
-
-    ensure_entry_widget();
-    gtk_draw_insertion_cursor(gEntryWidget, cr,
-                              &location, TRUE, direction, FALSE);
-    return MOZ_GTK_SUCCESS;
-}
-
-static gint
 moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
                     GtkWidgetState* state,
                     GtkWidget* widget, GtkTextDirection direction)
 {
     gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
     GtkStyleContext* style;
     gboolean interior_focus;
     gint focus_width;
@@ -2814,17 +2797,16 @@ moz_gtk_get_widget_border(GtkThemeWidget
     case MOZ_GTK_TOOLTIP:
     case MOZ_GTK_WINDOW:
     case MOZ_GTK_RESIZER:
     case MOZ_GTK_MENUARROW:
     case MOZ_GTK_TOOLBARBUTTON_ARROW:
     case MOZ_GTK_TOOLBAR:
     case MOZ_GTK_MENUBAR:
     case MOZ_GTK_TAB_SCROLLARROW:
-    case MOZ_GTK_ENTRY_CARET:
         *left = *top = *right = *bottom = 0;
         return MOZ_GTK_SUCCESS;
     default:
         g_warning("Unsupported widget type: %d", widget);
         return MOZ_GTK_UNKNOWN_WIDGET;
     }
     /* TODO - we're still missing some widget implementations */
     if (!w) {
@@ -3110,19 +3092,16 @@ moz_gtk_widget_paint(GtkThemeWidgetType 
         return moz_gtk_expander_paint(cr, rect, state,
                                       (GtkExpanderStyle) flags, direction);
         break;
     case MOZ_GTK_ENTRY:
         ensure_entry_widget();
         return moz_gtk_entry_paint(cr, rect, state,
                                    gEntryWidget, direction);
         break;
-    case MOZ_GTK_ENTRY_CARET:
-        return moz_gtk_caret_paint(cr, rect, direction);
-        break;
     case MOZ_GTK_DROPDOWN:
         return moz_gtk_combo_box_paint(cr, rect, state,
                                        (gboolean) flags, direction);
         break;
     case MOZ_GTK_DROPDOWN_ARROW:
         return moz_gtk_combo_box_entry_button_paint(cr, rect, cliprect,
                                                     state, flags, direction);
         break;
--- a/widget/gtk2/gtkdrawing.h
+++ b/widget/gtk2/gtkdrawing.h
@@ -110,18 +110,16 @@ typedef enum {
   MOZ_GTK_SPINBUTTON,
   MOZ_GTK_SPINBUTTON_UP,
   MOZ_GTK_SPINBUTTON_DOWN,
   MOZ_GTK_SPINBUTTON_ENTRY,
   /* Paints the gripper of a GtkHandleBox. */
   MOZ_GTK_GRIPPER,
   /* Paints a GtkEntry. */
   MOZ_GTK_ENTRY,
-  /* Paints the native caret (or in GTK-speak: insertion cursor) */
-  MOZ_GTK_ENTRY_CARET,
   /* Paints a GtkOptionMenu. */
   MOZ_GTK_DROPDOWN,
   /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
   MOZ_GTK_DROPDOWN_ARROW,
   /* Paints an entry in an editable option menu */
   MOZ_GTK_DROPDOWN_ENTRY,
   /* Paints the container part of a GtkCheckButton. */
   MOZ_GTK_CHECKBUTTON_CONTAINER,
--- a/widget/gtk2/nsNativeThemeGTK.cpp
+++ b/widget/gtk2/nsNativeThemeGTK.cpp
@@ -440,19 +440,16 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
     break;
   case NS_THEME_RESIZER:
     aGtkWidgetType = MOZ_GTK_RESIZER;
     break;
   case NS_THEME_TEXTFIELD:
   case NS_THEME_TEXTFIELD_MULTILINE:
     aGtkWidgetType = MOZ_GTK_ENTRY;
     break;
-  case NS_THEME_TEXTFIELD_CARET:
-    aGtkWidgetType = MOZ_GTK_ENTRY_CARET;
-    break;
   case NS_THEME_LISTBOX:
   case NS_THEME_TREEVIEW:
     aGtkWidgetType = MOZ_GTK_TREEVIEW;
     break;
   case NS_THEME_TREEVIEW_HEADER_CELL:
     if (aWidgetFlags) {
       // In this case, the flag denotes whether the header is the sorted one or not
       if (GetTreeSortDirection(aFrame) == eTreeSortDirection_Natural)
@@ -1390,17 +1387,16 @@ nsNativeThemeGTK::ThemeSupportsWidget(ns
   case NS_THEME_SCROLLBAR_BUTTON_LEFT:
   case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
   case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
   case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
   case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
   case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
   case NS_THEME_TEXTFIELD:
   case NS_THEME_TEXTFIELD_MULTILINE:
-  case NS_THEME_TEXTFIELD_CARET:
   case NS_THEME_DROPDOWN_TEXTFIELD:
   case NS_THEME_RANGE:
   case NS_THEME_RANGE_THUMB:
   case NS_THEME_SCALE_HORIZONTAL:
   case NS_THEME_SCALE_THUMB_HORIZONTAL:
   case NS_THEME_SCALE_VERTICAL:
   case NS_THEME_SCALE_THUMB_VERTICAL:
     // case NS_THEME_SCALE_THUMB_START:
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -92,16 +92,17 @@
 #endif
 #endif
 
 #include "base/process_util.h"
 
 /* This must occur *after* base/process_util.h to avoid typedefs conflicts. */
 #include "mozilla/Util.h"
 
+#include "nsCycleCollectionJSRuntime.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCycleCollectorUtils.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsBaseHashtable.h"
 #include "nsHashKeys.h"
 #include "nsDeque.h"
 #include "nsCycleCollector.h"
 #include "nsThreadUtils.h"
@@ -517,20 +518,18 @@ public:
               mBlockEnd(nullptr)
         {
             MOZ_ASSERT(aPool.mBlocks == nullptr && aPool.mLast == nullptr,
                        "pool not empty");
         }
         PtrInfo *Add(void *aPointer, nsCycleCollectionParticipant *aParticipant)
         {
             if (mNext == mBlockEnd) {
-                Block *block;
-                if (!(*mNextBlock = block =
-                        static_cast<Block*>(NS_Alloc(sizeof(Block)))))
-                    return nullptr;
+                Block *block = static_cast<Block*>(NS_Alloc(sizeof(Block)));
+                *mNextBlock = block;
                 mNext = block->mEntries;
                 mBlockEnd = block->mEntries + BlockSize;
                 block->mNext = nullptr;
                 mNextBlock = &block->mNext;
             }
             return new (mNext++) PtrInfo(aPointer, aParticipant);
         }
     private:
@@ -683,38 +682,56 @@ private:
         Block() : mNext(nullptr) {
             // Ensure Block is the right size (see above).
             MOZ_STATIC_ASSERT(
                 sizeof(Block) == 16384 ||       // 32-bit
                 sizeof(Block) == 32768,         // 64-bit
                 "ill-sized nsPurpleBuffer::Block"
             );
         }
-        void StaticAsserts();
+
+        template <class PurpleVisitor>
+        void VisitEntries(nsPurpleBuffer &aBuffer, PurpleVisitor &aVisitor)
+        {
+            nsPurpleBufferEntry *eEnd = ArrayEnd(mEntries);
+            for (nsPurpleBufferEntry *e = mEntries; e != eEnd; ++e) {
+                if (!(uintptr_t(e->mObject) & uintptr_t(1))) {
+                    aVisitor.Visit(aBuffer, e);
+                }
+            }
+        }
     };
-public:
     // This class wraps a linked list of the elements in the purple
     // buffer.
 
     nsCycleCollectorParams &mParams;
     uint32_t mCount;
     Block mFirstBlock;
     nsPurpleBufferEntry *mFreeList;
 
+public:
     nsPurpleBuffer(nsCycleCollectorParams &params)
         : mParams(params)
     {
         InitBlocks();
     }
 
     ~nsPurpleBuffer()
     {
         FreeBlocks();
     }
 
+    template <class PurpleVisitor>
+    void VisitEntries(PurpleVisitor &aVisitor)
+    {
+        for (Block *b = &mFirstBlock; b; b = b->mNext) {
+            b->VisitEntries(*this, aVisitor);
+        }
+    }
+
     void InitBlocks()
     {
         mCount = 0;
         mFreeList = nullptr;
         StartBlock(&mFirstBlock);
     }
 
     void StartBlock(Block *aBlock)
@@ -742,35 +759,35 @@ public:
                 UnmarkRemainingPurple(b);
             Block *next = b->mNext;
             delete b;
             b = next;
         }
         mFirstBlock.mNext = nullptr;
     }
 
+    struct UnmarkRemainingPurpleVisitor
+    {
+        void
+        Visit(nsPurpleBuffer &aBuffer, nsPurpleBufferEntry *aEntry)
+        {
+            if (aEntry->mObject) {
+                void *obj = aEntry->mObject;
+                nsCycleCollectionParticipant *cp = aEntry->mParticipant;
+                CanonicalizeParticipant(&obj, &cp);
+                cp->UnmarkIfPurple(obj);
+                --aBuffer.mCount;
+            }
+        }
+    };
+
     void UnmarkRemainingPurple(Block *b)
     {
-        for (nsPurpleBufferEntry *e = b->mEntries,
-                              *eEnd = ArrayEnd(b->mEntries);
-             e != eEnd; ++e) {
-            if (!(uintptr_t(e->mObject) & uintptr_t(1))) {
-                // This is a real entry (rather than something on the
-                // free list).
-                if (e->mObject) {
-                    void *obj = e->mObject;
-                    nsCycleCollectionParticipant *cp = e->mParticipant;
-                    CanonicalizeParticipant(&obj, &cp);
-                    cp->UnmarkIfPurple(obj);
-                }
-
-                if (--mCount == 0)
-                    break;
-            }
-        }
+        UnmarkRemainingPurpleVisitor visitor;
+        b->VisitEntries(*this, visitor);
     }
 
     void SelectPointers(GCGraphBuilder &builder);
 
     // RemoveSkippable removes entries from the purple buffer if
     // nsPurpleBufferEntry::mObject is null or if the object's
     // nsXPCOMCycleCollectionParticipant::CanSkip() returns true or
     // if nsPurpleBufferEntry::mNotPurple is true.
@@ -853,42 +870,48 @@ public:
 
         return n;
     }
 };
 
 static bool
 AddPurpleRoot(GCGraphBuilder &builder, void *root, nsCycleCollectionParticipant *cp);
 
+struct SelectPointersVisitor
+{
+    SelectPointersVisitor(GCGraphBuilder &aBuilder)
+        : mBuilder(aBuilder)
+    {}
+
+    void
+    Visit(nsPurpleBuffer &aBuffer, nsPurpleBufferEntry *aEntry)
+    {
+        if (aEntry->mObject && aEntry->mNotPurple) {
+            void* o = aEntry->mObject;
+            nsCycleCollectionParticipant* cp = aEntry->mParticipant;
+            CanonicalizeParticipant(&o, &cp);
+            cp->UnmarkIfPurple(o);
+            aBuffer.Remove(aEntry);
+        } else if (!aEntry->mObject ||
+                   AddPurpleRoot(mBuilder, aEntry->mObject, aEntry->mParticipant)) {
+            aBuffer.Remove(aEntry);
+        }
+    }
+
+private:
+    GCGraphBuilder &mBuilder;
+};
+
 void
 nsPurpleBuffer::SelectPointers(GCGraphBuilder &aBuilder)
 {
-    // Walk through all the blocks.
-    for (Block *b = &mFirstBlock; b; b = b->mNext) {
-        for (nsPurpleBufferEntry *e = b->mEntries,
-                              *eEnd = ArrayEnd(b->mEntries);
-            e != eEnd; ++e) {
-            if (!(uintptr_t(e->mObject) & uintptr_t(1))) {
-                // This is a real entry (rather than something on the
-                // free list).
-                if (e->mObject && e->mNotPurple) {
-                    void* o = e->mObject;
-                    nsCycleCollectionParticipant* cp = e->mParticipant;
-                    CanonicalizeParticipant(&o, &cp);
-                    cp->UnmarkIfPurple(o);
-                    Remove(e);
-                } else if (!e->mObject || AddPurpleRoot(aBuilder, e->mObject,
-                                                        e->mParticipant)) {
-                    Remove(e);
-                }
-            }
-        }
-    }
-
-    NS_WARN_IF_FALSE(mCount == 0, "AddPurpleRoot failed");
+    SelectPointersVisitor visitor(aBuilder);
+    VisitEntries(visitor);
+
+    MOZ_ASSERT(mCount == 0, "AddPurpleRoot failed");
     if (mCount == 0) {
         FreeBlocks();
         InitBlocks();
     }
 }
 
 class nsCycleCollector;
 
@@ -1848,20 +1871,16 @@ GCGraphBuilder::AddNode(void *s, nsCycle
     PtrToNodeEntry *e = static_cast<PtrToNodeEntry*>(PL_DHashTableOperate(&mPtrToNodeMap, s, PL_DHASH_ADD));
     if (!e)
         return nullptr;
 
     PtrInfo *result;
     if (!e->mNode) {
         // New entry.
         result = mNodeBuilder.Add(s, aParticipant);
-        if (!result) {
-            PL_DHashTableRawRemove(&mPtrToNodeMap, e);
-            return nullptr;
-        }
         e->mNode = result;
     } else {
         result = e->mNode;
         MOZ_ASSERT(result->mParticipant == aParticipant,
                    "nsCycleCollectionParticipant shouldn't change!");
     }
     return result;
 }
@@ -2114,41 +2133,48 @@ ChildFinder::NoteJSChild(void *child)
 static bool
 MayHaveChild(void *o, nsCycleCollectionParticipant* cp)
 {
     ChildFinder cf;
     cp->Traverse(o, cf);
     return cf.MayHaveChild();
 }
 
+class RemoveSkippableVisitor
+{
+public:
+    RemoveSkippableVisitor(bool aRemoveChildlessNodes)
+        : mRemoveChildlessNodes(aRemoveChildlessNodes)
+    {}
+
+    void
+    Visit(nsPurpleBuffer &aBuffer, nsPurpleBufferEntry *aEntry)
+    {
+        if (aEntry->mObject) {
+            void *o = aEntry->mObject;
+            nsCycleCollectionParticipant *cp = aEntry->mParticipant;
+            CanonicalizeParticipant(&o, &cp);
+            if (!aEntry->mNotPurple && !cp->CanSkip(o, false) &&
+                (!mRemoveChildlessNodes || MayHaveChild(o, cp))) {
+                return;
+            }
+            cp->UnmarkIfPurple(o);
+        }
+        aBuffer.Remove(aEntry);
+    }
+
+private:
+    bool mRemoveChildlessNodes;
+};
+
 void
 nsPurpleBuffer::RemoveSkippable(bool removeChildlessNodes)
 {
-    // Walk through all the blocks.
-    for (Block *b = &mFirstBlock; b; b = b->mNext) {
-        for (nsPurpleBufferEntry *e = b->mEntries,
-                              *eEnd = ArrayEnd(b->mEntries);
-            e != eEnd; ++e) {
-            if (!(uintptr_t(e->mObject) & uintptr_t(1))) {
-                // This is a real entry (rather than something on the
-                // free list).
-                if (e->mObject) {
-                    void *o = e->mObject;
-                    nsCycleCollectionParticipant *cp = e->mParticipant;
-                    CanonicalizeParticipant(&o, &cp);
-                    if (!e->mNotPurple && !cp->CanSkip(o, false) &&
-                        (!removeChildlessNodes || MayHaveChild(o, cp))) {
-                        continue;
-                    }
-                    cp->UnmarkIfPurple(o);
-                }
-                Remove(e);
-            }
-        }
-    }
+    RemoveSkippableVisitor visitor(removeChildlessNodes);
+    VisitEntries(visitor);
 }
 
 void 
 nsCycleCollector::SelectPurple(GCGraphBuilder &builder)
 {
     mPurpleBuf.SelectPointers(builder);
 }
 
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -1,20 +1,19 @@
 /* -*- 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 nsCycleCollector_h__
 #define nsCycleCollector_h__
 
-class nsISupports;
+class nsCycleCollectionJSRuntime;
 class nsICycleCollectorListener;
-class nsCycleCollectionParticipant;
-class nsCycleCollectionTraversalCallback;
+class nsISupports;
 
 // Contains various stats about the cycle collection.
 class nsCycleCollectorResults
 {
 public:
     nsCycleCollectorResults() :
         mForcedGC(false), mVisitedRefCounted(0), mVisitedGCed(0),
         mFreedRefCounted(0), mFreedGCed(0) {}
@@ -44,60 +43,18 @@ void nsCycleCollector_forgetSkippable(bo
 
 void nsCycleCollector_collect(bool aMergeCompartments,
                               nsCycleCollectorResults *aResults,
                               nsICycleCollectorListener *aListener);
 uint32_t nsCycleCollector_suspectedCount();
 void nsCycleCollector_shutdownThreads();
 void nsCycleCollector_shutdown();
 
-// Various methods the cycle collector needs to deal with Javascript.
-struct nsCycleCollectionJSRuntime
-{
-    virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb) = 0;
-
-    /**
-     * Called before/after transitioning to/from the main thread.
-     *
-     * NotifyLeaveMainThread may return 'false' to prevent the cycle collector
-     * from leaving the main thread.
-     */
-    virtual bool NotifyLeaveMainThread() = 0;
-    virtual void NotifyEnterCycleCollectionThread() = 0;
-    virtual void NotifyLeaveCycleCollectionThread() = 0;
-    virtual void NotifyEnterMainThread() = 0;
-
-    /**
-     * Unmark gray any weak map values, as needed.
-     */
-    virtual void FixWeakMappingGrayBits() = 0;
-
-    /**
-     * Should we force a JavaScript GC before a CC?
-     */
-    virtual bool NeedCollect() = 0;
-
-    /**
-     * Runs the JavaScript GC. |reason| is a gcreason::Reason from jsfriendapi.h.
-     */
-    virtual void Collect(uint32_t reason) = 0;
-
-    /**
-     * Get the JS cycle collection participant.
-     */
-    virtual nsCycleCollectionParticipant *GetParticipant() = 0;
-
-#ifdef DEBUG
-    virtual void SetObjectToUnlink(void* aObject) = 0;
-    virtual void AssertNoObjectsToTrace(void* aPossibleJSHolder) = 0;
-#endif
-};
-
 // Helpers for interacting with JS
-void nsCycleCollector_registerJSRuntime(nsCycleCollectionJSRuntime *rt);
+void nsCycleCollector_registerJSRuntime(nsCycleCollectionJSRuntime *aRt);
 void nsCycleCollector_forgetJSRuntime();
 
 #define NS_CYCLE_COLLECTOR_LOGGER_CID \
 { 0x58be81b4, 0x39d2, 0x437c, \
 { 0x94, 0xea, 0xae, 0xde, 0x2c, 0x62, 0x08, 0xd3 } }
 
 extern nsresult
 nsCycleCollectorLoggerConstructor(nsISupports* outer,
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -10,16 +10,17 @@
 #include "nsXULAppAPI.h"
 
 #include "nsXPCOMPrivate.h"
 #include "nsXPCOMCIDInternal.h"
 
 #include "nsStaticComponents.h"
 #include "prlink.h"
 
+#include "nsCycleCollector.h"
 #include "nsObserverList.h"
 #include "nsObserverService.h"
 #include "nsProperties.h"
 #include "nsPersistentProperties.h"
 #include "nsScriptableInputStream.h"
 #include "nsBinaryStream.h"
 #include "nsStorageStream.h"
 #include "nsPipe.h"
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -32,16 +32,17 @@ SDK_HEADERS = \
 		nsArrayUtils.h \
 		nsBaseHashtable.h \
 		nsCOMArray.h \
 		nsCOMPtr.h \
 		nsCRTGlue.h \
 		nsCategoryCache.h \
 		nsClassHashtable.h \
 		nsComponentManagerUtils.h \
+		nsCycleCollectionJSRuntime.h \
 		nsCycleCollectionParticipant.h \
 		nsCycleCollectorUtils.h \
 		nsDataHashtable.h \
 		nsDebug.h \
 		nsDeque.h \
 		nsEnumeratorUtils.h \
 		nsHashKeys.h \
 		nsIClassInfoImpl.h \
copy from xpcom/base/nsCycleCollector.h
copy to xpcom/glue/nsCycleCollectionJSRuntime.h
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/glue/nsCycleCollectionJSRuntime.h
@@ -1,107 +1,55 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef nsCycleCollector_h__
-#define nsCycleCollector_h__
+#ifndef nsCycleCollectionJSRuntime_h__
+#define nsCycleCollectionJSRuntime_h__
 
-class nsISupports;
-class nsICycleCollectorListener;
 class nsCycleCollectionParticipant;
 class nsCycleCollectionTraversalCallback;
 
-// Contains various stats about the cycle collection.
-class nsCycleCollectorResults
-{
-public:
-    nsCycleCollectorResults() :
-        mForcedGC(false), mVisitedRefCounted(0), mVisitedGCed(0),
-        mFreedRefCounted(0), mFreedGCed(0) {}
-    bool mForcedGC;
-    uint32_t mVisitedRefCounted;
-    uint32_t mVisitedGCed;
-    uint32_t mFreedRefCounted;
-    uint32_t mFreedGCed;
-};
-
-bool nsCycleCollector_init();
-
-enum CCThreadingModel {
-    CCSingleThread,
-    CCWithTraverseThread
-};
-
-nsresult nsCycleCollector_startup(CCThreadingModel aThreadingModel);
-
-typedef void (*CC_BeforeUnlinkCallback)(void);
-void nsCycleCollector_setBeforeUnlinkCallback(CC_BeforeUnlinkCallback aCB);
-
-typedef void (*CC_ForgetSkippableCallback)(void);
-void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB);
-
-void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false);
-
-void nsCycleCollector_collect(bool aMergeCompartments,
-                              nsCycleCollectorResults *aResults,
-                              nsICycleCollectorListener *aListener);
-uint32_t nsCycleCollector_suspectedCount();
-void nsCycleCollector_shutdownThreads();
-void nsCycleCollector_shutdown();
-
 // Various methods the cycle collector needs to deal with Javascript.
 struct nsCycleCollectionJSRuntime
 {
-    virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb) = 0;
+  virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &aCb) = 0;
 
-    /**
-     * Called before/after transitioning to/from the main thread.
-     *
-     * NotifyLeaveMainThread may return 'false' to prevent the cycle collector
-     * from leaving the main thread.
-     */
-    virtual bool NotifyLeaveMainThread() = 0;
-    virtual void NotifyEnterCycleCollectionThread() = 0;
-    virtual void NotifyLeaveCycleCollectionThread() = 0;
-    virtual void NotifyEnterMainThread() = 0;
+  /**
+   * Called before/after transitioning to/from the main thread.
+   *
+   * NotifyLeaveMainThread may return 'false' to prevent the cycle collector
+   * from leaving the main thread.
+   */
+  virtual bool NotifyLeaveMainThread() = 0;
+  virtual void NotifyEnterCycleCollectionThread() = 0;
+  virtual void NotifyLeaveCycleCollectionThread() = 0;
+  virtual void NotifyEnterMainThread() = 0;
 
-    /**
-     * Unmark gray any weak map values, as needed.
-     */
-    virtual void FixWeakMappingGrayBits() = 0;
+  /**
+   * Unmark gray any weak map values, as needed.
+   */
+  virtual void FixWeakMappingGrayBits() = 0;
 
-    /**
-     * Should we force a JavaScript GC before a CC?
-     */
-    virtual bool NeedCollect() = 0;
+  /**
+   * Should we force a JavaScript GC before a CC?
+   */
+  virtual bool NeedCollect() = 0;
 
-    /**
-     * Runs the JavaScript GC. |reason| is a gcreason::Reason from jsfriendapi.h.
-     */
-    virtual void Collect(uint32_t reason) = 0;
+  /**
+   * Runs the JavaScript GC. |reason| is a gcreason::Reason from jsfriendapi.h.
+   */
+  virtual void Collect(uint32_t aReason) = 0;
 
-    /**
-     * Get the JS cycle collection participant.
-     */
-    virtual nsCycleCollectionParticipant *GetParticipant() = 0;
+  /**
+   * Get the JS cycle collection participant.
+   */
+  virtual nsCycleCollectionParticipant *GetParticipant() = 0;
 
 #ifdef DEBUG
-    virtual void SetObjectToUnlink(void* aObject) = 0;
-    virtual void AssertNoObjectsToTrace(void* aPossibleJSHolder) = 0;
+  virtual void SetObjectToUnlink(void* aObject) = 0;
+  virtual void AssertNoObjectsToTrace(void* aPossibleJSHolder) = 0;
 #endif
 };
 
-// Helpers for interacting with JS
-void nsCycleCollector_registerJSRuntime(nsCycleCollectionJSRuntime *rt);
-void nsCycleCollector_forgetJSRuntime();
-
-#define NS_CYCLE_COLLECTOR_LOGGER_CID \
-{ 0x58be81b4, 0x39d2, 0x437c, \
-{ 0x94, 0xea, 0xae, 0xde, 0x2c, 0x62, 0x08, 0xd3 } }
-
-extern nsresult
-nsCycleCollectorLoggerConstructor(nsISupports* outer,
-                                  const nsIID& aIID,
-                                  void* *aInstancePtr);
-
-#endif // nsCycleCollector_h__
+#endif // nsCycleCollectionJSRuntime_h__
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -744,19 +744,16 @@ struct Skippable
 #define NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class)               \
     static NS_METHOD_(void) UnmarkIfPurpleImpl(void *p)                        \
     {                                                                          \
         _class *tmp = static_cast<_class *>(p);                                \
         if (MOZ_LIKELY(tmp->mRefCnt.HasPurpleBufferEntry()))                   \
             tmp->mRefCnt.ReleasePurpleBufferEntry();                           \
     }
 
-#define NS_DECL_CYCLE_COLLECTION_STUB_UNMARK_IF_PURPLE(_class)                 \
-    static NS_METHOD_(void) UnmarkIfPurpleImpl(void *p) {}
-
 #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class)                          \
   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
    : public nsCycleCollectionParticipant                                       \
   {                                                                            \
      NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                        \
      NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class)                  \
      static nsCycleCollectionParticipant* GetParticipant()                     \
      {                                                                         \
@@ -783,33 +780,16 @@ struct Skippable
         ::Type participant = {                                                 \
           NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(                \
             NS_CYCLE_COLLECTION_CLASSNAME(_class))                             \
         };                                                                     \
       return NS_PARTICIPANT_AS(nsScriptObjectTracer, &participant);            \
     }                                  \
   };
 
-#define NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class)                   \
-  class NS_CYCLE_COLLECTION_INNERCLASS                                         \
-   : public nsCycleCollectionParticipant                                       \
-  {                                                                            \
-     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                        \
-     NS_DECL_CYCLE_COLLECTION_STUB_UNMARK_IF_PURPLE(_class)                    \
-    static nsCycleCollectionParticipant* GetParticipant()                      \
-    {                                                                          \
-      static const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)>  \
-        ::Type p = {                                                           \
-          NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(                              \
-              NS_CYCLE_COLLECTION_CLASSNAME(_class))                           \
-        };                                                                     \
-      return NS_PARTICIPANT_AS(nsCycleCollectionParticipant, &p);              \
-    }                                                                          \
-  };
-
 #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function)           \
   NS_METHOD                                                                    \
   NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootImpl(void *p)                     \
   {                                                                            \
     _class *tmp = static_cast<_class*>(p);                                     \
     tmp->_root_function();                                                     \
     return NS_OK;                                                              \
   }
--- a/xpcom/glue/nsISupportsImpl.h
+++ b/xpcom/glue/nsISupportsImpl.h
@@ -18,22 +18,23 @@
 #ifndef nsISupportsUtils_h__
 #include "nsISupportsUtils.h"
 #endif
 
 
 #if !defined(XPCOM_GLUE_AVOID_NSPR)
 #include "prthread.h" /* needed for thread-safety checks */
 #include "nsAtomicRefcnt.h" /* for NS_Atomic{Increment,Decrement}Refcnt */
-#endif
+#ifdef DEBUG
+#include "nsCycleCollectorUtils.h" /* for NS_IsCycleCollectorThread */
+#endif // DEBUG
+#endif // !XPCOM_GLUE_AVOID_NSPR
 
 #include "nsDebug.h"
 #include "nsTraceRefcnt.h"
-#include "nsCycleCollector.h"
-#include "nsCycleCollectorUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Likely.h"
 
 inline nsISupports*
 ToSupports(nsISupports* p)
 {
     return p;
--- a/xpcom/tests/unit/xpcshell.ini
+++ b/xpcom/tests/unit/xpcshell.ini
@@ -2,39 +2,43 @@
 head = head_xpcom.js
 tail = 
 
 [test_bug121341.js]
 [test_bug325418.js]
 [test_bug332389.js]
 [test_bug333505.js]
 [test_bug364285-1.js]
-# Bug 676998: test fails consistently on Android
-fail-if = os == "android"
 [test_bug374754.js]
 [test_bug476919.js]
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_bug478086.js]
 [test_bug656331.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
 [test_bug725015.js]
 [test_compmgr_warnings.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
 [test_file_createUnique.js]
 [test_file_equality.js]
 [test_hidden_files.js]
 [test_home.js]
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_iniProcessor.js]
 [test_ioutil.js]
 [test_localfile.js]
 [test_mac_bundle.js]
 [test_nsIMutableArray.js]
 [test_nsIProcess.js]
 skip-if = os == "win" # bug 582821
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
 [test_nsIProcess_stress.js]
 # bug 676412, test isn't needed on windows
 # bug 704368: test causes harness to be killed on debug Linux64
 skip-if = os == "win" || (os == "linux" && debug && bits == 64)
 [test_pipe.js]
 [test_storagestream.js]
 [test_streams.js]
 [test_seek_multiplex.js]
@@ -46,8 +50,10 @@ fail-if = os == "android"
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_versioncomparator.js]
 [test_comp_no_aslr.js]
 skip-if = os != "win"
 [test_windows_shortcut.js]
 [test_bug745466.js]
 skip-if = os == "win"
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"