Merge last green PGO from inbound to mozilla-central
authorJustin Wood <Callek@gmail.com>
Mon, 16 Jan 2012 22:27:53 -0500
changeset 84606 34572943a3e44c327984dd4d671df580eb521223
parent 84563 12091526e9d07038eeb31a9ff459156c57c53d84 (current diff)
parent 84605 7ea3311b5e6c2465baf167d3e6dc55998c0ae1fb (diff)
child 84607 0e7d183d0d121962ba0caaf2462c32c4b09a2c2d
push id21865
push userCallek@gmail.com
push dateTue, 17 Jan 2012 03:28:17 +0000
treeherdermozilla-central@34572943a3e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
first release with
nightly linux32
34572943a3e4 / 12.0a1 / 20120117031056 / files
nightly linux64
34572943a3e4 / 12.0a1 / 20120117031056 / files
nightly mac
34572943a3e4 / 12.0a1 / 20120117031056 / files
nightly win32
34572943a3e4 / 12.0a1 / 20120117031056 / files
nightly win64
34572943a3e4 / 12.0a1 / 20120117031056 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last green PGO from inbound to mozilla-central
browser/components/migration/src/nsProfileMigrator.cpp
browser/components/migration/src/nsProfileMigrator.h
--- a/.gitignore
+++ b/.gitignore
@@ -34,8 +34,14 @@ js/src/configure
 js/src/autom4te.cache
 # SpiderMonkey test result logs
 js/src/tests/results-*.html
 js/src/tests/results-*.txt
 
 # Java HTML5 parser classes
 parser/html/java/htmlparser/
 parser/html/java/javaparser/
+
+# Ignore the files and directory that Eclipse IDE creates
+/.project
+/.cproject
+/.settings/
+
--- a/.hgignore
+++ b/.hgignore
@@ -34,8 +34,14 @@
 # SpiderMonkey test result logs
 ^js/src/tests/results-.*\.(html|txt)$
 
 # Java HTML5 parser classes
 ^parser/html/java/(html|java)parser/
 
 # SVN directories
 \.svn/
+
+# Ignore the files and directory that Eclipse IDE creates
+^\.project$
+^\.cproject$
+^\.settings$
+
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -891,25 +891,25 @@ PreInit()
     return;
 
   DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, nsnull);
   if (!bus)
     return;
 
   dbus_connection_set_exit_on_disconnect(bus, FALSE);
 
+  static const char* iface = "org.a11y.Status";
+  static const char* member = "IsEnabled";
   DBusMessage *message;
   message = dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus",
                                          "org.freedesktop.DBus.Properties",
                                          "Get");
   if (!message)
     goto dbus_done;
 
-  static const char* iface = "org.a11y.Status";
-  static const char* member = "IsEnabled";
   dbus_message_append_args(message, DBUS_TYPE_STRING, &iface,
                            DBUS_TYPE_STRING, &member, DBUS_TYPE_INVALID);
   dbus_connection_send_with_reply(bus, message, &sPendingCall, 1000);
   dbus_message_unref(message);
 
 dbus_done:
   dbus_connection_unref(bus);
 #endif
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -40,32 +40,32 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/events
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# test_docload.xul, docload_wnd.xul, test_scroll.xul disabled for misusing <tabbrowser> (bug 715857)
+
 _TEST_FILES =\
 		docload_wnd.html \
-		docload_wnd.xul \
 		focus.html \
 		scroll.html \
 		test_aria_alert.html \
 		test_aria_menu.html \
 		test_aria_objattr.html \
 		test_aria_statechange.html \
 		test_attrs.html \
 		test_caretmove.html \
 		test_caretmove.xul \
 		test_coalescence.html \
 		test_contextmenu.html \
 		test_docload.html \
-		test_docload.xul \
 		test_dragndrop.html \
 		test_flush.html \
 		test_focus_aria_activedescendant.html \
 		test_focus_autocomplete.xul \
 		test_focus_browserui.xul \
 		test_focus_contextmenu.xul \
 		test_focus_controls.html \
 		test_focus_dialog.html \
@@ -76,17 +76,16 @@ include $(topsrcdir)/config/rules.mk
 		test_focus_menu.xul \
 		test_focus_name.html \
 		test_focus_selects.html \
 		test_focus_tabbox.xul \
 		test_focus_tree.xul \
 		test_menu.xul \
 		test_mutation.html \
 		test_mutation.xhtml \
-		test_scroll.xul \
 		test_selection_aria.html \
 		test_selection.html \
 		test_selection.xul \
 		test_statechange.html \
 		test_text_alg.html \
 		test_text.html \
 		test_textattrchange.html \
 		test_tree.xul \
--- a/accessible/tests/mochitest/name/Makefile.in
+++ b/accessible/tests/mochitest/name/Makefile.in
@@ -40,26 +40,26 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/name
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# test_nsRootAcc.xul, nsRootAcc_wnd.xul disabled for misusing <tabbrowser> (bug 715857)
+
 _TEST_FILES =\
 		general.css \
 		general.xbl \
 		markup.js \
-		nsRootAcc_wnd.xul \
 		test_button.html \
 		test_general.html \
 		test_general.xul \
 		test_link.html \
 		test_list.html \
 		test_markup.html \
-		test_nsRootAcc.xul \
 		test_tree.xul \
 		markuprules.xml \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/relations/Makefile.in
+++ b/accessible/tests/mochitest/relations/Makefile.in
@@ -40,18 +40,19 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/relations
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# test_tabbrowser.xul disabled for misusing <tabbrowser> (bug 715857)
+
 _TEST_FILES =\
 		test_general.html \
 		test_general.xul \
-		test_tabbrowser.xul \
 		test_tree.xul \
 		test_update.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/tree/Makefile.in
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -40,16 +40,18 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/tree
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# test_tabbrowser.xul disabled for misusing <tabbrowser> (bug 715857)
+
 _TEST_FILES =\
 		dockids.html \
 	$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
 		test_aria_globals.html \
 		test_aria_imgmap.html \
 		test_aria_presentation.html \
 		test_button.xul \
 		test_canvas.html \
@@ -65,17 +67,16 @@ include $(topsrcdir)/config/rules.mk
 		test_iframe.html \
 		test_img.html \
 		test_invalidationlist.html \
 		test_list.html \
 		test_map.html \
 		test_media.html \
 		test_select.html \
 		test_tabbox.xul \
-		test_tabbrowser.xul \
 		test_table.html \
 		test_tree.xul \
 		test_txtcntr.html \
 		test_txtctrl.html \
 		test_txtctrl.xul \
 		wnd.xul \
 		$(NULL)
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2842,21 +2842,19 @@
           let visible = this.visible;
 
           document.getElementById("menu_closeWindow").hidden = !visible;
           document.getElementById("menu_close").setAttribute("label",
             this.tabbrowser.mStringBundle.getString(visible ? "tabs.closeTab" : "tabs.close"));
 
           goSetCommandEnabled("cmd_ToggleTabsOnTop", visible);
 
-          if (window.TabsOnTop)
-            TabsOnTop.syncUI();
-
-          if (window.TabsInTitlebar)
-            TabsInTitlebar.allowedBy("tabs-visible", visible);
+          TabsOnTop.syncUI();
+
+          TabsInTitlebar.allowedBy("tabs-visible", visible);
         ]]></body>
       </method>
 
       <method name="updateVisibility">
         <body><![CDATA[
           if (this.childNodes.length - this.tabbrowser._removingTabs.length == 1)
             this.visible = window.toolbar.visible &&
                            !Services.prefs.getBoolPref("browser.tabs.autoHide");
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -44,17 +44,16 @@
 #if defined(XP_WIN)
 #include "nsWindowsShellService.h"
 #elif defined(XP_MACOSX)
 #include "nsMacShellService.h"
 #elif defined(MOZ_WIDGET_GTK2)
 #include "nsGNOMEShellService.h"
 #endif
 
-#include "nsProfileMigrator.h"
 #if defined(XP_WIN) && !defined(__MINGW32__)
 #include "nsIEProfileMigrator.h"
 #elif defined(XP_MACOSX)
 #include "nsSafariProfileMigrator.h"
 #endif
 
 #include "rdf.h"
 #include "nsFeedSniffer.h"
@@ -72,17 +71,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(Directory
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
 #elif defined(MOZ_WIDGET_GTK2)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
 #endif
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileMigrator)
 #if defined(XP_WIN) && !defined(__MINGW32__)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEProfileMigrator)
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafariProfileMigrator)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
 
@@ -91,17 +89,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPr
 NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID);
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #elif defined(MOZ_WIDGET_GTK2)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
 NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
-NS_DEFINE_NAMED_CID(NS_FIREFOX_PROFILEMIGRATOR_CID);
 #if defined(XP_WIN) && !defined(__MINGW32__)
 NS_DEFINE_NAMED_CID(NS_WINIEPROFILEMIGRATOR_CID);
 #elif defined(XP_MACOSX)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_SAFARIPROFILEMIGRATOR_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
 
@@ -109,17 +106,16 @@ static const mozilla::Module::CIDEntry k
     { &kNS_BROWSERDIRECTORYPROVIDER_CID, false, NULL, DirectoryProviderConstructor },
 #if defined(XP_WIN)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsWindowsShellServiceConstructor },
 #elif defined(MOZ_WIDGET_GTK2)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsGNOMEShellServiceConstructor },
 #endif
     { &kNS_FEEDSNIFFER_CID, false, NULL, nsFeedSnifferConstructor },
     { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, NULL, AboutRedirector::Create },
-    { &kNS_FIREFOX_PROFILEMIGRATOR_CID, false, NULL, nsProfileMigratorConstructor },
 #if defined(XP_WIN) && !defined(__MINGW32__)
     { &kNS_WINIEPROFILEMIGRATOR_CID, false, NULL, nsIEProfileMigratorConstructor },
 #elif defined(XP_MACOSX)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsMacShellServiceConstructor },
     { &kNS_SAFARIPROFILEMIGRATOR_CID, false, NULL, nsSafariProfileMigratorConstructor },
 #endif
     { &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
     { NULL }
@@ -143,17 +139,16 @@ static const mozilla::Module::ContractID
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifdef MOZ_SERVICES_SYNC
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #endif
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
-    { NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
 #if defined(XP_WIN) && !defined(__MINGW32__)
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie", &kNS_WINIEPROFILEMIGRATOR_CID },
 #elif defined(XP_MACOSX)
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "safari", &kNS_SAFARIPROFILEMIGRATOR_CID },
 #endif
     { NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
     { NULL }
--- a/browser/components/migration/src/BrowserProfileMigrators.manifest
+++ b/browser/components/migration/src/BrowserProfileMigrators.manifest
@@ -1,4 +1,6 @@
-component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
-component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}
+component {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} ProfileMigrator.js
+contract @mozilla.org/toolkit/profile-migrator;1 {6F8BB968-C14F-4D6F-9733-6C6737B35DCE}
+component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
+contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
+component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
+contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -44,31 +44,31 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= migration
 LIBRARY_NAME	= migration_s
 FORCE_STATIC_LIB = 1
 ifndef MOZ_MEMORY
 USE_STATIC_LIBS = 1
 endif
 
 
-CPPSRCS  = nsProfileMigrator.cpp \
-           nsBrowserProfileMigratorUtils.cpp \
+CPPSRCS  = nsBrowserProfileMigratorUtils.cpp \
            $(NULL)
 
 ifeq ($(OS_ARCH)_$(GNU_CXX),WINNT_)
 CPPSRCS += nsIEProfileMigrator.cpp \
            $(NULL)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += nsSafariProfileMigrator.cpp \
            $(NULL)
 endif            
 
 EXTRA_PP_COMPONENTS = \
+  ProfileMigrator.js \
   ChromeProfileMigrator.js \
   FirefoxProfileMigrator.js \
   $(NULL)
 
 EXTRA_COMPONENTS = \
 	BrowserProfileMigrators.manifest \
 	$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/src/ProfileMigrator.js
@@ -0,0 +1,141 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
+
+function ProfileMigrator() {
+}
+
+ProfileMigrator.prototype = {
+  migrate: function PM_migrate(aStartup) {
+    // By opening the wizard with a supplied migrator, it will automatically
+    // migrate from it.
+    let [key, migrator] = this._getDefaultMigrator();
+    if (!key)
+        return;
+
+    let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+    params.appendElement(this._toCString(key), false);
+    params.appendElement(migrator, false);
+    params.appendElement(aStartup, false);
+
+    Services.ww.openWindow(null,
+                           "chrome://browser/content/migration/migration.xul",
+                           "_blank",
+                           "chrome,dialog,modal,centerscreen,titlebar",
+                           params);
+  },
+
+  _toCString: function PM__toCString(aStr) {
+    let cstr = Cc["@mozilla.org/supports-cstring;1"].
+               createInstance(Ci.nsISupportsCString);
+    cstr.data = aStr;
+    return cstr;
+  },
+
+  _getMigratorIfSourceExists: function PM__getMigratorIfSourceExists(aKey) {
+    let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
+    let migrator = Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
+    if (migrator.sourceExists)
+      return migrator;
+    return null;
+  },
+
+  // We don't yet support checking for the default browser on all platforms,
+  // needless to say we don't have migrators for all browsers.  Thus, for each
+  // platform, there's a fallback list of migrators used in these cases.
+  _PLATFORM_FALLBACK_LIST:
+#ifdef XP_WIN
+     ["ie", "chrome", /* safari */],
+#elifdef XP_MACOSX
+     ["safari", "chrome"],
+#else
+     ["chrome"],
+#endif
+
+  _getDefaultMigrator: function PM__getDefaultMigrator() {
+    let migratorsOrdered = Array.slice(this._PLATFORM_FALLBACK_LIST);
+    let defaultBrowser = "";
+#ifdef XP_WIN
+    try {
+      const REG_KEY = "SOFTWARE\\Classes\\HTTP\\shell\\open\\command";
+      let regKey = Cc["@mozilla.org/windows-registry-key;1"].
+                   createInstance(Ci.nsIWindowsRegKey);
+      regKey.open(regKey.ROOT_KEY_LOCAL_MACHINE, REG_KEY,
+                  regKey.ACCESS_READ);
+      let value = regKey.readStringValue("").toLowerCase();      
+      let pathMatches = value.match(/^"?(.+?\.exe)"?/);
+      if (!pathMatches) {
+        throw new Error("Could not extract path from " +
+                        REG_KEY + "(" + value + ")");
+      }
+ 
+      // We want to find out what the default browser is but the path in and of
+      // itself isn't enough.  Why? Because sometimes on Windows paths get
+      // truncated like so: C:\PROGRA~1\MOZILL~2\MOZILL~1.EXE.  How do we know
+      // what product that is? Mozilla's file objects do nothing to 'normalize'
+      // the path so we need to attain an actual product descriptor from the
+      // file somehow, and in this case it means getting the "InternalName"
+      // field of the file's VERSIONINFO resource. 
+      //
+      // In the file's resource segment there is a VERSIONINFO section that is
+      // laid out like this:
+      //
+      // VERSIONINFO
+      //   StringFileInfo
+      //     <TranslationID>
+      //       InternalName           "iexplore"
+      //   VarFileInfo
+      //     Translation              <TranslationID>
+      //
+      // By Querying the VERSIONINFO section for its Tranlations, we can find
+      // out where the InternalName lives (A file can have more than one
+      // translation of its VERSIONINFO segment, but we just assume the first
+      // one).
+      let file = FileUtils.File(pathMatches[1])
+                          .QueryInterface(Ci.nsILocalFileWin);
+      switch (file.getVersionInfoField("InternalName").toLowerCase()) {
+        case "iexplore":
+          defaultBrowser = "ie";
+          break;
+        case "chrome":
+          defaultBrowser = "chrome";
+          break;
+      }
+    }
+    catch (ex) {
+      Cu.reportError("Could not retrieve default browser: " + ex);
+    }
+#endif
+
+    // If we found the default browser and we have support for that browser,
+    // make sure to check it before any other browser, by moving it to the head
+    // of the array.
+    if (defaultBrowser)
+      migratorsOrdered.sort(function(a, b) b == defaultBrowser ? 1 : 0);
+
+    for (let i = 0; i < migratorsOrdered.length; i++) {
+      let migrator = this._getMigratorIfSourceExists(migratorsOrdered[i]);
+      if (migrator)
+        return [migratorsOrdered[i], migrator];
+    }
+
+    return ["", null];
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIProfileMigrator]),
+  classDescription: "Profile Migrator",
+  contractID: "@mozilla.org/toolkit/profile-migrator;1",
+  classID: Components.ID("6F8BB968-C14F-4D6F-9733-6C6737B35DCE")
+};
+
+let NSGetFactory = XPCOMUtils.generateNSGetFactory([ProfileMigrator]);
deleted file mode 100644
--- a/browser/components/migration/src/nsProfileMigrator.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is The Browser Profile Migrator.
- *
- * The Initial Developer of the Original Code is Ben Goodger.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Ben Goodger <ben@bengoodger.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsProfileMigrator.h"
-
-#include "nsIBrowserProfileMigrator.h"
-#include "nsIComponentManager.h"
-#include "nsIDOMWindow.h"
-#include "nsILocalFile.h"
-#include "nsIObserverService.h"
-#include "nsIProperties.h"
-#include "nsIServiceManager.h"
-#include "nsISupportsPrimitives.h"
-#include "nsIMutableArray.h"
-#include "nsIToolkitProfile.h"
-#include "nsIToolkitProfileService.h"
-#include "nsIWindowWatcher.h"
-
-#include "nsCOMPtr.h"
-#include "nsBrowserCompsCID.h"
-#include "nsComponentManagerUtils.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsServiceManagerUtils.h"
-
-#include "nsStringAPI.h"
-#include "nsUnicharUtils.h"
-#ifdef XP_WIN
-#include <windows.h>
-#include "nsIWindowsRegKey.h"
-#include "nsILocalFileWin.h"
-#else
-#include <limits.h>
-#endif
-
-#include "nsAutoPtr.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// nsIProfileMigrator
-
-#define MIGRATION_WIZARD_FE_URL "chrome://browser/content/migration/migration.xul"
-#define MIGRATION_WIZARD_FE_FEATURES "chrome,dialog,modal,centerscreen,titlebar"
-
-NS_IMETHODIMP
-nsProfileMigrator::Migrate(nsIProfileStartup* aStartup)
-{
-  nsresult rv;
-
-  nsCAutoString key;
-  nsCOMPtr<nsIBrowserProfileMigrator> bpm;
-
-  rv = GetDefaultBrowserMigratorKey(key, bpm);
-  if (NS_FAILED(rv)) return rv;
-
-  if (!bpm) {
-    nsCAutoString contractID(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX);
-    contractID.Append(key);
-
-    bpm = do_CreateInstance(contractID.get());
-    if (!bpm) return NS_ERROR_FAILURE;
-  }
-
-  bool sourceExists;
-  bpm->GetSourceExists(&sourceExists);
-  if (!sourceExists) {
-#ifdef XP_WIN
-    // The "Default Browser" key in the registry was set to a browser for which
-    // no profile data exists. On Windows, this means the Default Browser settings
-    // in the registry are bad, and we should just fall back to IE in this case.
-    bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie");
-#else
-    return NS_ERROR_FAILURE;
-#endif
-  }
-
-  nsCOMPtr<nsISupportsCString> cstr
-    (do_CreateInstance("@mozilla.org/supports-cstring;1"));
-  if (!cstr) return NS_ERROR_OUT_OF_MEMORY;
-  cstr->SetData(key);
-
-  // By opening the Migration FE with a supplied bpm, it will automatically
-  // migrate from it. 
-  nsCOMPtr<nsIWindowWatcher> ww(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
-  nsCOMPtr<nsIMutableArray> params = do_CreateInstance(NS_ARRAY_CONTRACTID);
-  if (!ww || !params) return NS_ERROR_FAILURE;
-
-  params->AppendElement(cstr, false);
-  params->AppendElement(bpm, false);
-  params->AppendElement(aStartup, false);
-
-  nsCOMPtr<nsIDOMWindow> migrateWizard;
-  return ww->OpenWindow(nsnull, 
-                        MIGRATION_WIZARD_FE_URL,
-                        "_blank",
-                        MIGRATION_WIZARD_FE_FEATURES,
-                        params,
-                        getter_AddRefs(migrateWizard));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// nsProfileMigrator
-
-NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
-
-#ifdef XP_WIN
-
-#define INTERNAL_NAME_IEXPLORE        "iexplore"
-#define INTERNAL_NAME_MOZILLA_SUITE   "apprunner"
-#define INTERNAL_NAME_CHROME          "chrome"
-#define INTERNAL_NAME_FIREFOX         "firefox"
-#endif
-
-nsresult
-nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
-                                                nsCOMPtr<nsIBrowserProfileMigrator>& bpm)
-{
-#if XP_WIN
-
-  nsCOMPtr<nsIWindowsRegKey> regKey = 
-    do_CreateInstance("@mozilla.org/windows-registry-key;1");
-  if (!regKey)
-    return NS_ERROR_FAILURE;
-
-  NS_NAMED_LITERAL_STRING(kCommandKey,
-                          "SOFTWARE\\Classes\\HTTP\\shell\\open\\command");
-
-  if (NS_FAILED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
-                             kCommandKey, nsIWindowsRegKey::ACCESS_READ)))
-    return NS_ERROR_FAILURE;
-
-  nsAutoString value;
-  if (NS_FAILED(regKey->ReadStringValue(EmptyString(), value)))
-    return NS_ERROR_FAILURE;
-
-  PRInt32 len = value.Find(NS_LITERAL_STRING(".exe"), CaseInsensitiveCompare);
-  if (len == -1)
-    return NS_ERROR_FAILURE;
-
-  // Move past ".exe"
-  len += 4;
-
-  PRUint32 start = 0;
-  // skip an opening quotation mark if present
-  if (value.get()[1] != ':') {
-    start = 1;
-    --len;
-  }
-
-  const nsDependentSubstring filePath(Substring(value, start, len)); 
-
-  // We want to find out what the default browser is but the path in and of itself
-  // isn't enough. Why? Because sometimes on Windows paths get truncated like so:
-  // C:\PROGRA~1\MOZILL~2\MOZILL~1.EXE
-  // How do we know what product that is? Mozilla or Mozilla Firebird? etc. Mozilla's
-  // file objects do nothing to 'normalize' the path so we need to attain an actual
-  // product descriptor from the file somehow, and in this case it means getting
-  // the "InternalName" field of the file's VERSIONINFO resource. 
-  //
-  // In the file's resource segment there is a VERSIONINFO section that is laid 
-  // out like this:
-  //
-  // VERSIONINFO
-  //   StringFileInfo
-  //     <TranslationID>
-  //       InternalName           "iexplore"
-  //   VarFileInfo
-  //     Translation              <TranslationID>
-  //
-  // By Querying the VERSIONINFO section for its Tranlations, we can find out where
-  // the InternalName lives. (A file can have more than one translation of its 
-  // VERSIONINFO segment, but we just assume the first one). 
-
-  nsCOMPtr<nsILocalFile> lf;
-  NS_NewLocalFile(filePath, true, getter_AddRefs(lf));
-  if (!lf)
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsILocalFileWin> lfw = do_QueryInterface(lf); 
-  if (!lfw)
-    return NS_ERROR_FAILURE;
-
-  nsAutoString internalName;
-  if (NS_FAILED(lfw->GetVersionInfoField("InternalName", internalName)))
-    return NS_ERROR_FAILURE;
-
-  if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_IEXPLORE)) {
-    aKey = "ie";
-    return NS_OK;
-  }
-  else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_CHROME)) {
-    aKey = "chrome";
-    return NS_OK;
-  }
-  else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_FIREFOX)) {
-    aKey = "firefox";
-    return NS_OK;
-  }
-
-#else
-  bool exists = false;
-#define CHECK_MIGRATOR(browser) do {\
-  bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX browser);\
-  if (bpm)\
-    bpm->GetSourceExists(&exists);\
-  if (exists) {\
-    aKey = browser;\
-    return NS_OK;\
-  }} while(0)
-
-#if defined(XP_MACOSX)
-  CHECK_MIGRATOR("safari");
-#endif
-  CHECK_MIGRATOR("chrome");
-  CHECK_MIGRATOR("firefox");
-
-#undef CHECK_MIGRATOR
-#endif
-  return NS_ERROR_FAILURE;
-}
deleted file mode 100644
--- a/browser/components/migration/src/nsProfileMigrator.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is The Browser Profile Migrator.
- *
- * The Initial Developer of the Original Code is Ben Goodger.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Ben Goodger <ben@bengoodger.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
- 
-#ifndef profilemigrator___h___
-#define profilemigrator___h___
-
-#include "nsIBrowserProfileMigrator.h"
-#include "nsIProfileMigrator.h"
-#include "nsCOMPtr.h"
-
-#define NS_FIREFOX_PROFILEMIGRATOR_CID \
-{ 0x4ca3c946, 0x5408, 0x49f0, { 0x9e, 0xca, 0x3a, 0x97, 0xd5, 0xc6, 0x77, 0x50 } }
-
-class nsProfileMigrator : public nsIProfileMigrator
-{
-public:
-  NS_DECL_NSIPROFILEMIGRATOR
-  NS_DECL_ISUPPORTS
-
-  nsProfileMigrator() { }
-
-protected:
-  ~nsProfileMigrator() { }
-
-  nsresult GetDefaultBrowserMigratorKey(nsACString& key,
-                                        nsCOMPtr<nsIBrowserProfileMigrator>& bpm);
-};
-
-#endif
-
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -35,16 +35,18 @@
 #
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
+FAIL_ON_WARNINGS = 1
+
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconcvs_s
 LIBXUL_LIBRARY  = 1
 
 EXPORTS = \
 	CustomQS_Canvas2D.h \
@@ -55,18 +57,16 @@ CPPSRCS	= \
 	CanvasImageCache.cpp \
 	CanvasUtils.cpp \
 	nsCanvasRenderingContext2D.cpp \
 	nsCanvasRenderingContext2DAzure.cpp \
 	DocumentRendererParent.cpp \
 	DocumentRendererChild.cpp \
 	$(NULL)
 
-# Canvas 3D Pieces
-
 ifdef MOZ_WEBGL
 
 CPPSRCS += \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextValidate.cpp \
 	WebGLExtensionStandardDerivatives.cpp \
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -496,19 +496,19 @@ WebGLContext::SetDimensions(PRInt32 widt
     // know if creating the new context will succeed.
     DestroyResourcesAndContext();
 
     // Get some prefs for some preferred/overriden things
     NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
     bool forceOSMesa =
         Preferences::GetBool("webgl.force_osmesa", false);
+#ifdef XP_WIN
     bool preferEGL =
         Preferences::GetBool("webgl.prefer-egl", false);
-#ifdef XP_WIN
     bool preferOpenGL =
         Preferences::GetBool("webgl.prefer-native-gl", false);
 #endif
     bool forceEnabled =
         Preferences::GetBool("webgl.force-enabled", false);
     bool disabled =
         Preferences::GetBool("webgl.disabled", false);
     bool verbose =
@@ -561,43 +561,52 @@ WebGLContext::SetDimensions(PRInt32 widt
         gfxInfo &&
         NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
         if (status == nsIGfxInfo::FEATURE_NO_INFO || forceMSAA) {
             PRUint32 msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
             format.samples = msaaLevel*msaaLevel;
         }
     }
 
+#ifdef XP_WIN
     if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
         preferEGL = true;
     }
+#endif
 
     // Ask GfxInfo about what we should use
     bool useOpenGL = true;
+
+#ifdef XP_WIN
     bool useANGLE = true;
+#endif
 
     if (gfxInfo && !forceEnabled) {
         if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_OPENGL, &status))) {
             if (status != nsIGfxInfo::FEATURE_NO_INFO) {
                 useOpenGL = false;
             }
         }
+#ifdef XP_WIN
         if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_ANGLE, &status))) {
             if (status != nsIGfxInfo::FEATURE_NO_INFO) {
                 useANGLE = false;
             }
         }
+#endif
     }
 
+#ifdef XP_WIN
     // allow forcing GL and not EGL/ANGLE
     if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
         preferEGL = false;
         useANGLE = false;
         useOpenGL = true;
     }
+#endif
 
     // if we're forcing osmesa, do it first
     if (forceOSMesa) {
         gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
         if (!gl || !InitAndValidateGL()) {
             LogMessage("OSMesa forced, but creating context failed -- aborting!");
             return NS_ERROR_FAILURE;
         }
@@ -609,45 +618,42 @@ WebGLContext::SetDimensions(PRInt32 widt
     if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
         gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
         if (gl) {
             if (InitAndValidateGL()) {
                 if (useANGLE) {
                     gl->SetFlushGuaranteesResolve(true);
                 }
             } else {
-                gl = nsnull;
+                LogMessage("Error during ANGLE OpenGL ES initialization");
+                return NS_ERROR_FAILURE;
             }
         }
     }
-
-    // if it failed, then try the default provider, whatever that is
-    if (!gl && useOpenGL) {
-        gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
-        if (gl && !InitAndValidateGL()) {
-            gl = nsnull;
-        }
-    }
-#else
-    // other platforms just use whatever the default is
-    if (!gl && useOpenGL) {
-        gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
-        if (gl && !InitAndValidateGL()) {
-            gl = nsnull;
-        }
-    }
 #endif
 
+    // try the default provider, whatever that is
+    if (!gl && useOpenGL) {
+        gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
+        if (gl && !InitAndValidateGL()) {
+            LogMessage("Error during OpenGL initialization");
+            return NS_ERROR_FAILURE;
+        }
+    }
+
     // finally, try OSMesa
     if (!gl) {
         gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
-        if (!gl || !InitAndValidateGL()) {
-            gl = nsnull;
-        } else {
-            LogMessage("Using software rendering via OSMesa (THIS WILL BE SLOW)");
+        if (gl) {
+            if (!InitAndValidateGL()) {
+                LogMessage("Error during OSMesa initialization");
+                return NS_ERROR_FAILURE;
+            } else {
+                LogMessage("Using software rendering via OSMesa (THIS WILL BE SLOW)");
+            }
         }
     }
 
     if (!gl) {
         LogMessage("Can't get a usable WebGL context");
         return NS_ERROR_FAILURE;
     }
 
@@ -1013,20 +1019,22 @@ void
 WebGLContext::ForceClearFramebufferWithDefaultValues(PRUint32 mask, const nsIntRect& viewportRect)
 {
     MakeContextCurrent();
 
     bool initializeColorBuffer = 0 != (mask & LOCAL_GL_COLOR_BUFFER_BIT);
     bool initializeDepthBuffer = 0 != (mask & LOCAL_GL_DEPTH_BUFFER_BIT);
     bool initializeStencilBuffer = 0 != (mask & LOCAL_GL_STENCIL_BUFFER_BIT);
 
+    // fun GL fact: no need to worry about the viewport here, glViewport is just setting up a coordinates transformation,
+    // it doesn't affect glClear at all
+
     // prepare GL state for clearing
     gl->fDisable(LOCAL_GL_SCISSOR_TEST);
     gl->fDisable(LOCAL_GL_DITHER);
-    gl->PushViewportRect(viewportRect);
 
     if (initializeColorBuffer) {
         gl->fColorMask(1, 1, 1, 1);
         gl->fClearColor(0.f, 0.f, 0.f, 0.f);
     }
 
     if (initializeDepthBuffer) {
         gl->fDepthMask(1);
@@ -1059,18 +1067,16 @@ WebGLContext::ForceClearFramebufferWithD
     }
 
     if (initializeStencilBuffer) {
         gl->fStencilMaskSeparate(LOCAL_GL_FRONT, mStencilWriteMaskFront);
         gl->fStencilMaskSeparate(LOCAL_GL_BACK, mStencilWriteMaskBack);
         gl->fClearStencil(mStencilClearValue);
     }
 
-    gl->PopViewportRect();
-
     if (mDitherEnabled)
         gl->fEnable(LOCAL_GL_DITHER);
     else
         gl->fDisable(LOCAL_GL_DITHER);
 
     if (mScissorTestEnabled)
         gl->fEnable(LOCAL_GL_SCISSOR_TEST);
     else
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1444,17 +1444,17 @@ WebGLContext::UndoFakeVertexAttrib0()
         return;
 
     gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mAttribBuffers[0].buf ? mAttribBuffers[0].buf->GLName() : 0);
     gl->fVertexAttribPointer(0,
                              mAttribBuffers[0].size,
                              mAttribBuffers[0].type,
                              mAttribBuffers[0].normalized,
                              mAttribBuffers[0].stride,
-                             (const GLvoid *) mAttribBuffers[0].byteOffset);
+                             reinterpret_cast<const GLvoid *>(mAttribBuffers[0].byteOffset));
 
     gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
 }
 
 bool
 WebGLContext::NeedFakeBlack()
 {
     // handle this case first, it's the generic case
@@ -1703,17 +1703,17 @@ WebGLContext::DrawElements(WebGLenum mod
         EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_maxIndexPlusOne.value()))
         return NS_OK;
 
     SetupRobustnessTimer();
-    gl->fDrawElements(mode, count, type, (GLvoid*) (byteOffset));
+    gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
 
     UndoFakeVertexAttrib0();
     UnbindFakeBlackTextures();
 
     mBackbufferClearingStatus = BackbufferClearingStatus::HasBeenDrawnTo;
     Invalidate();
 
     return NS_OK;
@@ -4695,17 +4695,17 @@ WebGLContext::VertexAttribPointer(WebGLu
     vd.byteOffset = byteOffset;
     vd.type = type;
     vd.normalized = normalized;
 
     MakeContextCurrent();
 
     gl->fVertexAttribPointer(index, size, type, normalized,
                              stride,
-                             (void*) (byteOffset));
+                             reinterpret_cast<void*>(byteOffset));
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D(PRInt32)
 {
     if (!IsContextStable())
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -3076,18 +3076,16 @@ struct NS_STACK_CLASS nsCanvasBidiProces
       if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL) {
         nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
           FillGlyphs(scaledFont, buffer,
                       nsCanvasRenderingContext2DAzure::GeneralPattern().
                         ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_FILL, mCtx->mTarget),
                       DrawOptions(mState->globalAlpha, mCtx->UsedOperation()));
       } else if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_STROKE) {
         RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
-            
-        Matrix oldTransform = mCtx->mTarget->GetTransform();
 
         const ContextState& state = *mState;
         nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
           Stroke(path, nsCanvasRenderingContext2DAzure::GeneralPattern().
                     ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_STROKE, mCtx->mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 state.lineCap, state.miterLimit,
                                 state.dash.Length(),
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -2575,17 +2575,17 @@ PluginInstanceChild::MaybeCreatePlatform
             return true;
         }
 #endif
         // For image layer surface we should always create helper surface
         createHelperSurface = true;
         // Check if we can create helper surface with non-default visual
         visual = gfxXlibSurface::FindVisual(screen,
             static_cast<gfxImageSurface*>(mCurrentSurface.get())->Format());
-        if (visual && defaultVisual != visual && !supportNonDefaultVisual) {
+        if (!visual || (defaultVisual != visual && !supportNonDefaultVisual)) {
             visual = defaultVisual;
             mDoAlphaExtraction = mIsTransparent;
         }
     }
 
     if (createHelperSurface) {
         if (!visual) {
             NS_ERROR("Need X falback surface, but visual failed");
--- a/dom/wifi/nsWifiWorker.js
+++ b/dom/wifi/nsWifiWorker.js
@@ -46,16 +46,23 @@ Cu.import("resource://gre/modules/XPCOMU
 
 const DEBUG = true; // set to false to suppress debug messages
 
 const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1";
 const WIFIWORKER_CID        = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}");
 
 const WIFIWORKER_WORKER     = "resource://gre/modules/network_worker.js";
 
+// A note about errors and error handling in this file:
+// The libraries that we use in this file are intended for C code. For
+// C code, it is natural to return -1 for errors and 0 for success.
+// Therefore, the code that interacts directly with the worker uses this
+// convention (note: command functions do get boolean results since the
+// command always succeeds and we do a string/boolean check for the
+// expected results).
 var WifiManager = (function() {
   var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
   var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
 
   // Callbacks to invoke when a reply arrives from the controlWorker.
   var controlCallbacks = Object.create(null);
   var idgen = 0;
 
@@ -501,16 +508,47 @@ var WifiManager = (function() {
     retryTimer = null;
     notify("supplicantlost");
   }
 
   manager.start = function() {
     connectToSupplicant(connectCallback);
   }
 
+  function onconnected() {
+    runDhcp(manager.ifname, function (data) {
+      if (!data) {
+        debug("DHCP failed to run");
+        return;
+      }
+      setProperty("net.dns1", ipToString(data.dns1), function(ok) {
+        if (!ok) {
+          debug("Unable to set net.dns1");
+          return;
+        }
+        setProperty("net.dns2", ipToString(data.dns2), function(ok) {
+          if (!ok) {
+            debug("Unable to set net.dns2");
+            return;
+          }
+          getProperty("net.dnschange", "0", function(value) {
+            if (value === null) {
+              debug("Unable to get net.dnschange");
+              return;
+            }
+            setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
+              if (!ok)
+                debug("Unable to set net.dnschange");
+            });
+          });
+        });
+      });
+    });
+  }
+
   var supplicantStatesMap = ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING",
                              "FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", "COMPLETED",
                              "DORMANT", "UNINITIALIZED"];
   var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" };
 
   // handle events sent to us by the event worker
   function handleEvent(event) {
     debug("Event coming in: " + event);
@@ -564,16 +602,17 @@ var WifiManager = (function() {
       notify("statechange", { state: "DISCONNECTED" });
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) {
       // Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]
       var bssid = eventData.split(" ")[4];
       var id = eventData.substr(eventData.indexOf("id=")).split(" ")[0];
       notify("statechange", { state: "CONNECTED", BSSID: bssid, id: id });
+      onconnected();
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
       debug("Notifying of scn results available");
       notify("scanresultsavailable");
       return true;
     }
     // unknown event
@@ -586,22 +625,47 @@ var WifiManager = (function() {
   // Public interface of the wifi service
   manager.setWifiEnabled = function(enable, callback) {
     var targetState = enable ? "ENABLED" : "DISABLED";
     if (enable == targetState)
       return true;
     if (enable && airplaneMode)
       return false;
     if (enable) {
-      loadDriver(function (ok) {
-        (ok === 0) ? startSupplicant(callback) : callback(-1);
+      loadDriver(function (status) {
+        if (status < 0) {
+          callback(status);
+          return;
+        }
+        startSupplicant(function (status) {
+          if (status < 0) {
+            callback(status);
+            return;
+          }
+          getProperty("wifi.interface", "tiwlan0", function (ifname) {
+            if (!ifname) {
+              callback(-1);
+              return;
+            }
+            manager.ifname = ifname;
+            enableInterface(ifname, function (ok) {
+              callback(ok ? 0 : -1);
+            });
+          });
+        });
       });
     } else {
-      stopSupplicant(function (ok) {
-        (ok === 0) ? unloadDriver(callback) : callback(-1);
+      stopSupplicant(function (status) {
+        if (ok < 0) {
+          callback(-1);
+          return;
+        }
+        disableInterface(manager.ifname, function (ok) {
+          unloadDriver(callback);
+        });
       });
     }
   }
 
   manager.disconnect = disconnectCommand;
   manager.reconnect = reconnectCommand;
   manager.reassociate = reassociateCommand;
 
@@ -695,60 +759,17 @@ var WifiManager = (function() {
   function ipToString(n) {
     return String((n & (0xff << 24)) >> 24) + "." +
                  ((n & (0xff << 16)) >> 16) + "." +
                  ((n & (0xff <<  8)) >>  8) + "." +
                  ((n & (0xff <<  0)) >>  0);
   }
 
   manager.enableNetwork = function(netId, disableOthers, callback) {
-    getProperty("wifi.interface", "tiwlan0", function (ifname) {
-      if (!ifname) {
-        callback(false);
-        return;
-      }
-      enableInterface(ifname, function (ok) {
-        if (!ok) {
-          callback(false);
-          return;
-        }
-        enableNetworkCommand(netId, disableOthers, function (ok) {
-          if (!ok) {
-            disableInterface(ifname, function () {
-              callback(false);
-            });
-            return;
-          }
-          runDhcp(ifname, function (data) {
-            debug("After running dhcp, got data: " + uneval(data));
-            if (!data) {
-              disableInterface(ifname, function() {
-                callback(false);
-              });
-              return;
-            }
-            setProperty("net.dns1", ipToString(data.dns1), function(ok) {
-              if (!ok) {
-                callback(false);
-                return;
-              }
-              getProperty("net.dnschange", "0", function(value) {
-                if (value === null) {
-                  callback(false);
-                  return;
-                }
-                setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
-                  callback(ok);
-                });
-              });
-            });
-          });
-        });
-      });
-    });
+    enableNetworkCommand(netId, disableOthers, callback);
   }
   manager.disableNetwork = function(netId, callback) {
     disableNetworkCommand(netId, callback);
   }
   manager.getMacAddress = getMacAddressCommand;
   manager.getScanResults = scanResultsCommand;
   return manager;
 })();
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/crashtests/639736-1.xhtml
@@ -0,0 +1,14 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<script>
+
+function boom()
+{
+  try { document.execCommand("removeformat", false, null); } catch(e) { }
+  document.adoptNode(document.documentElement);
+}
+
+</script>
+</head>
+<body onload="boom();"><td contenteditable="true" /></body>
+</html>
--- a/editor/libeditor/html/crashtests/crashtests.list
+++ b/editor/libeditor/html/crashtests/crashtests.list
@@ -17,11 +17,12 @@ load 499844-1.html
 load 503709-1.xhtml
 load 513375-1.xhtml
 load 535632-1.xhtml
 load 574558-1.xhtml
 load 582138-1.xhtml
 load 612565-1.html
 asserts(0-6) load 615015-1.html # Bug 439258
 load 615450-1.html
+load 639736-1.xhtml
 load 643786-1.html
 load 682650-1.html
 load 716456-1.html
--- a/editor/libeditor/text/tests/test_bug597331.html
+++ b/editor/libeditor/text/tests/test_bug597331.html
@@ -26,16 +26,17 @@ line3
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function() {
   SimpleTest.executeSoon(function() {
     var t = document.querySelector("textarea");
     t.focus();
     t.selectionStart = 4;
     t.selectionEnd = 4;
     SimpleTest.executeSoon(function() {
+      t.getBoundingClientRect(); // flush layout
       var before = snapshotWindow(window, true);
       t.selectionStart = 5;
       t.selectionEnd = 5;
       t.addEventListener("keydown", function() {
         t.removeEventListener("keydown", arguments.callee, false);
 
         SimpleTest.executeSoon(function() {
           t.style.display = 'block';
--- a/editor/libeditor/text/tests/test_bug600570.html
+++ b/editor/libeditor/text/tests/test_bug600570.html
@@ -26,16 +26,17 @@ aaa
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(function() {
   var t = document.querySelector("textarea");
   t.value = "[aaa\nbbb]";
   t.focus();
   synthesizeKey("A", {accelKey: true});
 
   SimpleTest.executeSoon(function() {
+    t.getBoundingClientRect(); // flush layout
     var afterSetValue = snapshotWindow(window);
 
     t.value = t.defaultValue;
 
     t.selectionStart = 0;
     t.selectionEnd = 4;
     SimpleTest.waitForClipboard("aaa\n",
       function() {
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -63,22 +63,17 @@
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 
 void
 CanvasLayerOGL::Destroy()
 {
   if (!mDestroyed) {
-    if (mTexture) {
-      GLContext *cx = mOGLManager->glForResources();
-      cx->MakeCurrent();
-      cx->fDeleteTextures(1, &mTexture);
-    }
-
+    CleanupResources();
     mDestroyed = true;
   }
 }
 
 void
 CanvasLayerOGL::Initialize(const Data& aData)
 {
   NS_ASSERTION(mCanvasSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
@@ -247,22 +242,27 @@ CanvasLayerOGL::RenderLayer(int aPreviou
     mCanvasGLContext->GetContextType() == gl()->GetContextType();
 
   nsIntRect drawRect = mBounds;
 
   if (useGLContext) {
     gl()->BindTex2DOffscreen(mCanvasGLContext);
     program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(), true);
   } else if (mDelayedUpdates) {
-    NS_ABORT_IF_FALSE(mCanvasSurface, "WebGL canvases should always be using full texture upload");
+    NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
     
     drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
 
+    nsRefPtr<gfxASurface> surf = mCanvasSurface;
+    if (mDrawTarget) {
+      surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
+    }
+
     mLayerProgram =
-      gl()->UploadSurfaceToTexture(mCanvasSurface,
+      gl()->UploadSurfaceToTexture(surf,
                                    nsIntRect(0, 0, drawRect.width, drawRect.height),
                                    mTexture,
                                    true,
                                    drawRect.TopLeft());
   }
 
   if (!program) {
     program = mOGLManager->GetColorTextureLayerProgram(mLayerProgram);
@@ -291,16 +291,26 @@ CanvasLayerOGL::RenderLayer(int aPreviou
   }
 #endif
 
   if (useGLContext) {
     gl()->UnbindTex2DOffscreen(mCanvasGLContext);
   }
 }
 
+void
+CanvasLayerOGL::CleanupResources()
+{
+  if (mTexture) {
+    GLContext* cx = mOGLManager->glForResources();
+    cx->MakeCurrent();
+    cx->fDeleteTextures(1, &mTexture);
+  }
+}
+
 
 ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
   : ShadowCanvasLayer(aManager, nsnull)
   , LayerOGL(aManager)
   , mNeedsYFlip(false)
 {
   mImplData = static_cast<LayerOGL*>(this);
 }
@@ -406,8 +416,14 @@ ShadowCanvasLayerOGL::RenderLayer(int aP
 
   mTexImage->BeginTileIteration();
   do {
     TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
     program->SetLayerQuadRect(mTexImage->GetTileRect());
     mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
   } while (mTexImage->NextTile());
 }
+
+void
+ShadowCanvasLayerOGL::CleanupResources()
+{
+  DestroyFrontBuffer();
+}
--- a/gfx/layers/opengl/CanvasLayerOGL.h
+++ b/gfx/layers/opengl/CanvasLayerOGL.h
@@ -70,16 +70,17 @@ public:
   // CanvasLayer implementation
   virtual void Initialize(const Data& aData);
 
   // LayerOGL implementation
   virtual void Destroy();
   virtual Layer* GetLayer() { return this; }
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources();
 
 protected:
   void UpdateSurface();
 
   nsRefPtr<gfxASurface> mCanvasSurface;
   nsRefPtr<GLContext> mCanvasGLContext;
   gl::ShaderProgramType mLayerProgram;
   RefPtr<gfx::DrawTarget> mDrawTarget;
@@ -123,16 +124,17 @@ public:
 
   virtual void Disconnect();
 
   // LayerOGL impl
   void Destroy();
   Layer* GetLayer();
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources();
 
 private:
   nsRefPtr<TextureImage> mTexImage;
 
   bool mNeedsYFlip;
 };
 
 } /* layers */
--- a/gfx/layers/opengl/ColorLayerOGL.h
+++ b/gfx/layers/opengl/ColorLayerOGL.h
@@ -60,16 +60,17 @@ public:
 
   // LayerOGL Implementation
   virtual Layer* GetLayer() { return this; }
 
   virtual void Destroy() { mDestroyed = true; }
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources() {};
 };
 
 class ShadowColorLayerOGL : public ShadowColorLayer,
                             public LayerOGL
 {
 public:
   ShadowColorLayerOGL(LayerManagerOGL *aManager)
     : ShadowColorLayer(aManager, NULL)
@@ -81,13 +82,14 @@ public:
 
   // LayerOGL Implementation
   virtual Layer* GetLayer() { return this; }
 
   virtual void Destroy() { mDestroyed = true; }
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources() {};
 };
 
 } /* layers */
 } /* mozilla */
 #endif /* GFX_COLORLAYEROGL_H */
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -128,16 +128,26 @@ ContainerDestroy(Container* aContainer)
     while (aContainer->mFirstChild) {
       aContainer->GetFirstChildOGL()->Destroy();
       aContainer->RemoveChild(aContainer->mFirstChild);
     }
     aContainer->mDestroyed = true;
   }
 }
 
+template<class Container>
+static void
+ContainerCleanupResources(Container* aContainer)
+{
+  for (Layer* l = aContainer->GetFirstChild(); l; l = l->GetNextSibling()) {
+    LayerOGL* layerToRender = static_cast<LayerOGL*>(l->ImplData());
+    layerToRender->CleanupResources();
+  }
+}
+
 static inline LayerOGL*
 GetNextSibling(LayerOGL* aLayer)
 {
    Layer* layer = aLayer->GetLayer()->GetNextSibling();
    return layer ? static_cast<LayerOGL*>(layer->
                                          ImplData())
                  : nsnull;
 }
@@ -329,16 +339,21 @@ ContainerLayerOGL::GetFirstChildOGL()
 
 void
 ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
                                const nsIntPoint& aOffset)
 {
   ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
 }
 
+void
+ContainerLayerOGL::CleanupResources()
+{
+  ContainerCleanupResources(this);
+}
 
 ShadowContainerLayerOGL::ShadowContainerLayerOGL(LayerManagerOGL *aManager)
   : ShadowContainerLayer(aManager, NULL)
   , LayerOGL(aManager)
 {
   mImplData = static_cast<LayerOGL*>(this);
 }
  
@@ -376,11 +391,16 @@ ShadowContainerLayerOGL::GetFirstChildOG
  
 void
 ShadowContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
                                      const nsIntPoint& aOffset)
 {
   ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
 }
 
+void
+ShadowContainerLayerOGL::CleanupResources()
+{
+  ContainerCleanupResources(this);
+}
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/ContainerLayerOGL.h
+++ b/gfx/layers/opengl/ContainerLayerOGL.h
@@ -91,16 +91,18 @@ public:
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
 
   virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
   {
     DefaultComputeEffectiveTransforms(aTransformToSurface);
   }
+
+  virtual void CleanupResources();
 };
 
 class ShadowContainerLayerOGL : public ShadowContainerLayer,
                                 public LayerOGL
 {
   template<class Container>
   friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
   template<class Container>
@@ -130,14 +132,16 @@ public:
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
 
   virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
   {
     DefaultComputeEffectiveTransforms(aTransformToSurface);
   }
+
+  virtual void CleanupResources();
 };
 
 } /* layers */
 } /* mozilla */
 
 #endif /* GFX_CONTAINERLAYEROGL_H */
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -929,17 +929,17 @@ ShadowImageLayerOGL::Disconnect()
   Destroy();
 }
 
 void
 ShadowImageLayerOGL::Destroy()
 {
   if (!mDestroyed) {
     mDestroyed = true;
-    mTexImage = nsnull;
+    CleanupResources();
   }
 }
 
 Layer*
 ShadowImageLayerOGL::GetLayer()
 {
   return this;
 }
@@ -990,11 +990,16 @@ ShadowImageLayerOGL::RenderLayer(int aPr
     yuvProgram->SetRenderOffset(aOffset);
 
     mOGLManager->BindAndDrawQuadWithTextureRect(yuvProgram,
                                                 mPictureRect,
                                                 nsIntSize(mSize.width, mSize.height));
  }
 }
 
+void
+ShadowImageLayerOGL::CleanupResources()
+{
+  mTexImage = nsnull;
+}
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/ImageLayerOGL.h
+++ b/gfx/layers/opengl/ImageLayerOGL.h
@@ -175,16 +175,17 @@ public:
   ~ImageLayerOGL() { Destroy(); }
 
   // LayerOGL Implementation
   virtual void Destroy() { mDestroyed = true; }
   virtual Layer* GetLayer();
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources() {}
 };
 
 class THEBES_API PlanarYCbCrImageOGL : public PlanarYCbCrImage
 {
   typedef mozilla::gl::GLContext GLContext;
 
 public:
   PlanarYCbCrImageOGL(LayerManagerOGL *aManager,
@@ -261,16 +262,18 @@ public:
   // LayerOGL impl
   virtual void Destroy();
 
   virtual Layer* GetLayer();
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
 
+  virtual void CleanupResources();
+
 private:
   bool Init(const SharedImage& aFront);
 
   nsRefPtr<TextureImage> mTexImage;
   GLTexture mYUVTexture[3];
   gfxIntSize mSize;
   gfxIntSize mCbCrSize;
   nsIntRect mPictureRect;
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -115,16 +115,20 @@ LayerManagerOGL::Destroy()
 }
 
 void
 LayerManagerOGL::CleanupResources()
 {
   if (!mGLContext)
     return;
 
+  if (mRoot) {
+    RootLayer()->CleanupResources();
+  }
+
   nsRefPtr<GLContext> ctx = mGLContext->GetSharedContext();
   if (!ctx) {
     ctx = mGLContext;
   }
 
   ctx->MakeCurrent();
 
   for (unsigned int i = 0; i < mPrograms.Length(); ++i)
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -534,16 +534,17 @@ public:
 
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset) = 0;
 
   typedef mozilla::gl::GLContext GLContext;
 
   LayerManagerOGL* OGLManager() const { return mOGLManager; }
   GLContext *gl() const { return mOGLManager->gl(); }
+  virtual void CleanupResources() = 0;
 
 protected:
   LayerManagerOGL *mOGLManager;
   bool mDestroyed;
 };
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -814,16 +814,21 @@ ThebesLayerOGL::GetLayer()
 }
 
 bool
 ThebesLayerOGL::IsEmpty()
 {
   return !mBuffer;
 }
 
+void
+ThebesLayerOGL::CleanupResources()
+{
+  mBuffer = nsnull;
+}
 
 class ShadowBufferOGL : public ThebesLayerBufferOGL
 {
 public:
   ShadowBufferOGL(ShadowThebesLayerOGL* aLayer)
     : ThebesLayerBufferOGL(aLayer, aLayer)
   {}
 
@@ -960,10 +965,16 @@ ShadowThebesLayerOGL::RenderLayer(int aP
 
   mOGLManager->MakeCurrent();
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 
   gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
   mBuffer->RenderTo(aOffset, mOGLManager, 0);
 }
 
+void
+ShadowThebesLayerOGL::CleanupResources()
+{
+  DestroyFrontBuffer();
+}
+
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/ThebesLayerOGL.h
+++ b/gfx/layers/opengl/ThebesLayerOGL.h
@@ -70,16 +70,17 @@ public:
   void InvalidateRegion(const nsIntRegion& aRegion);
 
   /** LayerOGL implementation */
   void Destroy();
   Layer* GetLayer();
   virtual bool IsEmpty();
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources();
 
 private:
   friend class BasicBufferOGL;
 
   bool CreateSurface();
 
   nsRefPtr<Buffer> mBuffer;
 };
@@ -100,16 +101,17 @@ public:
   virtual void Disconnect();
 
   // LayerOGL impl
   void Destroy();
   Layer* GetLayer();
   virtual bool IsEmpty();
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
+  virtual void CleanupResources();
 
 private:
   nsRefPtr<ShadowBufferOGL> mBuffer;
 };
 
 } /* layers */
 } /* mozilla */
 #endif /* GFX_THEBESLAYEROGL_H */
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -86,17 +86,25 @@ namespace gc {
 struct Arena;
 
 /*
  * This must be an upper bound, but we do not need the least upper bound, so
  * we just exclude non-background objects.
  */
 const size_t MAX_BACKGROUND_FINALIZE_KINDS = FINALIZE_LIMIT - FINALIZE_OBJECT_LIMIT / 2;
 
+/*
+ * Default pagesize is 8192 on Solaris SPARC.
+ * Do not use JS_CPU_SPARC here, this header is used outside JS.
+ */ 
+#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
+const size_t ArenaShift = 13;
+#else
 const size_t ArenaShift = 12;
+#endif
 const size_t ArenaSize = size_t(1) << ArenaShift;
 const size_t ArenaMask = ArenaSize - 1;
 
 /*
  * This is the maximum number of arenas we allow in the FreeCommitted state
  * before we trigger a GC_SHRINK to release free arenas to the OS.
  */
 const static uint32_t FreeCommittedArenasThreshold = (32 << 20) / ArenaSize;
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -5025,17 +5025,17 @@ mjit::Compiler::jsop_setprop(PropertyNam
     /*
      * If this is a SETNAME to a variable of a non-reentrant outer function,
      * set the variable's slot directly for the active call object.
      */
     if (cx->typeInferenceEnabled() && js_CodeSpec[*PC].format & JOF_NAME) {
         ScriptAnalysis::NameAccess access =
             analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
         if (access.nesting) {
-            /* Use a SavedReg so it isn't clobbered by the stub call. */
+            /* Use a SavedReg so it isn't clobbered by sync or the stub call. */
             RegisterID nameReg = frame.allocReg(Registers::SavedRegs).reg();
             Address address = frame.loadNameAddress(access, nameReg);
 
 #ifdef JSGC_INCREMENTAL_MJ
             /* Write barrier. */
             if (cx->compartment->needsBarrier()) {
                 stubcc.linkExit(masm.jump(), Uses(0));
                 stubcc.leave();
@@ -5072,28 +5072,28 @@ mjit::Compiler::jsop_setprop(PropertyNam
             types->addFreeze(cx);
             uint32_t slot = propertyTypes->definiteSlot();
             RegisterID reg = frame.tempRegForData(lhs);
             bool isObject = lhs->isTypeKnown();
             MaybeJump notObject;
             if (!isObject)
                 notObject = frame.testObject(Assembler::NotEqual, lhs);
 #ifdef JSGC_INCREMENTAL_MJ
-            frame.pinReg(reg);
             if (cx->compartment->needsBarrier() && propertyTypes->needsBarrier(cx)) {
                 /* Write barrier. */
+                frame.pinReg(reg);
                 Jump j = masm.testGCThing(Address(reg, JSObject::getFixedSlotOffset(slot)));
                 stubcc.linkExit(j, Uses(0));
                 stubcc.leave();
                 stubcc.masm.addPtr(Imm32(JSObject::getFixedSlotOffset(slot)),
                                    reg, Registers::ArgReg1);
                 OOL_STUBCALL(stubs::GCThingWriteBarrier, REJOIN_NONE);
                 stubcc.rejoin(Changes(0));
+                frame.unpinReg(reg);
             }
-            frame.unpinReg(reg);
 #endif
             if (!isObject) {
                 stubcc.linkExit(notObject.get(), Uses(2));
                 stubcc.leave();
                 stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
                 OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
             }
             frame.storeTo(rhs, Address(reg, JSObject::getFixedSlotOffset(slot)), popGuaranteed);
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -1166,27 +1166,36 @@ mjit::Compiler::jsop_setelem_dense()
      */
     types::TypeSet *types = frame.extra(obj).types;
     if (cx->compartment->needsBarrier() && (!types || types->propertyNeedsBarrier(cx, JSID_VOID))) {
         Label barrierStart = stubcc.masm.label();
         stubcc.linkExitDirect(masm.jump(), barrierStart);
 
         /*
          * The sync call below can potentially clobber key.reg() and slotsReg.
-         * So we save and restore them. Additionally, the WriteBarrier stub can
-         * clobber both registers. The rejoin call will restore key.reg() but
-         * not slotsReg. So we restore it again after the stub call.
+         * We pin key.reg() to avoid it being clobbered. If |hoisted| is true,
+         * we can also pin slotsReg. If not, then slotsReg is owned by the
+         * compiler and we save in manually to VMFrame::scratch.
+         *
+         * Additionally, the WriteBarrier stub can clobber both registers. The
+         * rejoin call will restore key.reg() but not slotsReg. So we save
+         * slotsReg in the frame and restore it after the stub call.
          */
         stubcc.masm.storePtr(slotsReg, FrameAddress(offsetof(VMFrame, scratch)));
+        if (hoisted)
+            frame.pinReg(slotsReg);
         if (!key.isConstant())
-            stubcc.masm.push(key.reg());
+            frame.pinReg(key.reg());
         frame.sync(stubcc.masm, Uses(3));
         if (!key.isConstant())
-            stubcc.masm.pop(key.reg());
-        stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
+            frame.unpinReg(key.reg());
+        if (hoisted)
+            frame.unpinReg(slotsReg);
+        else
+            stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
 
         if (key.isConstant())
             stubcc.masm.lea(Address(slotsReg, key.index() * sizeof(Value)), Registers::ArgReg1);
         else
             stubcc.masm.lea(BaseIndex(slotsReg, key.reg(), masm.JSVAL_SCALE), Registers::ArgReg1);
         OOL_STUBCALL(stubs::WriteBarrier, REJOIN_NONE);
         stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
         stubcc.rejoin(Changes(0));
--- a/js/src/methodjit/ImmutableSync.cpp
+++ b/js/src/methodjit/ImmutableSync.cpp
@@ -43,17 +43,17 @@
 #include "FrameState.h"
 #include "FrameState-inl.h"
 #include "ImmutableSync.h"
 
 using namespace js;
 using namespace js::mjit;
 
 ImmutableSync::ImmutableSync()
-  : cx(NULL), entries(NULL), frame(NULL), avail(Registers::AvailRegs), generation(0)
+  : cx(NULL), entries(NULL), frame(NULL), avail(Registers::TempRegs), generation(0)
 {
 }
 
 ImmutableSync::~ImmutableSync()
 {
     if (cx)
         cx->free_(entries);
 }
@@ -66,17 +66,17 @@ ImmutableSync::init(JSContext *cx, const
 
     entries = (SyncEntry *)cx->calloc_(sizeof(SyncEntry) * nentries);
     return !!entries;
 }
 
 void
 ImmutableSync::reset(Assembler *masm, Registers avail, FrameEntry *top, FrameEntry *bottom)
 {
-    this->avail = avail;
+    this->avail = avail & Registers::TempRegs;
     this->masm = masm;
     this->top = top;
     this->bottom = bottom;
     this->generation++;
     memset(regs, 0, sizeof(regs));
 }
 
 inline JSC::MacroAssembler::RegisterID
@@ -86,17 +86,17 @@ ImmutableSync::doAllocReg()
         return avail.takeAnyReg().reg();
 
     uint32_t lastResort = FrameState::InvalidIndex;
     uint32_t evictFromFrame = FrameState::InvalidIndex;
 
     /* Find something to evict. */
     for (uint32_t i = 0; i < Registers::TotalRegisters; i++) {
         RegisterID reg = RegisterID(i);
-        if (!(Registers::maskReg(reg) & Registers::AvailRegs))
+        if (!(Registers::maskReg(reg) & Registers::TempRegs))
             continue;
 
         if (frame->regstate(reg).isPinned())
             continue;
 
         lastResort = i;
 
         if (!regs[i]) {
@@ -146,23 +146,24 @@ ImmutableSync::doAllocReg()
     return reg;
 }
 
 JSC::MacroAssembler::RegisterID
 ImmutableSync::allocReg()
 {
     RegisterID reg = doAllocReg();
     JS_ASSERT(!frame->regstate(reg).isPinned());
+    JS_ASSERT(!Registers::isSaved(reg));
     return reg;
 }
 
 void
 ImmutableSync::freeReg(JSC::MacroAssembler::RegisterID reg)
 {
-    if (!frame->regstate(reg).isPinned())
+    if (!frame->regstate(reg).isPinned() && !Registers::isSaved(reg))
         avail.putReg(reg);
 }
 
 inline ImmutableSync::SyncEntry &
 ImmutableSync::entryFor(FrameEntry *fe)
 {
     JS_ASSERT(fe <= top || frame->isTemporary(fe));
     SyncEntry &e = entries[fe - frame->entries];
--- a/js/src/methodjit/MachineRegs.h
+++ b/js/src/methodjit/MachineRegs.h
@@ -568,16 +568,20 @@ struct Registers {
     void takeRegUnchecked(AnyRegisterID reg) {
         freeMask &= ~(1 << reg.reg_);
     }
 
     bool operator ==(const Registers &other) {
         return freeMask == other.freeMask;
     }
 
+    Registers operator &(const Registers &other) {
+        return Registers(freeMask & other.freeMask);
+    }
+
     uint32_t freeMask;
 };
 
 static const JSC::MacroAssembler::RegisterID JSFrameReg = Registers::JSFrameReg;
 
 AnyRegisterID
 AnyRegisterID::fromRaw(unsigned reg_)
 {
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -384,17 +384,20 @@ SharedDefineSetter(JSContext *cx, uintN 
 {
     return DefineGetterOrSetter(cx, argc, false, vp);
 }
 
 
 JSBool
 xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags,
                        PRUint32 ifacec, const nsIID **interfaces,
-                       PRUint32 tableSize, const xpc_qsHashEntry *table)
+                       PRUint32 tableSize, const xpc_qsHashEntry *table,
+                       const xpc_qsPropertySpec *propspecs,
+                       const xpc_qsFunctionSpec *funcspecs,
+                       const char *stringTable)
 {
     /*
      * Walk interfaces in reverse order to behave like XPConnect when a
      * feature is defined in more than one of the interfaces.
      *
      * XPCNativeSet::FindMethod returns the first matching feature it finds,
      * searching the interfaces forward.  Here, definitions toward the
      * front of 'interfaces' overwrite those toward the back.
@@ -403,36 +406,36 @@ xpc_qsDefineQuickStubs(JSContext *cx, JS
     for (uint32_t i = ifacec; i-- != 0;) {
         const nsID &iid = *interfaces[i];
         const xpc_qsHashEntry *entry =
             LookupInterfaceOrAncestor(tableSize, table, iid);
 
         if (entry) {
             for (;;) {
                 // Define quick stubs for attributes.
-                const xpc_qsPropertySpec *ps = entry->properties;
-                if (ps) {
-                    for (; ps->name; ps++) {
-                        definedProperty = true;
-                        if (!JS_DefineProperty(cx, proto, ps->name, JSVAL_VOID,
-                                               ps->getter, ps->setter,
-                                               flags | JSPROP_SHARED))
-                            return false;
-                    }
+                const xpc_qsPropertySpec *ps = propspecs + entry->prop_index;
+                const xpc_qsPropertySpec *ps_end = ps + entry->n_props;
+                for ( ; ps < ps_end; ++ps) {
+                    definedProperty = true;
+                    if (!JS_DefineProperty(cx, proto,
+                                           stringTable + ps->name_index,
+                                           JSVAL_VOID, ps->getter, ps->setter,
+                                           flags | JSPROP_SHARED)) 
+                        return false;
                 }
 
                 // Define quick stubs for methods.
-                const xpc_qsFunctionSpec *fs = entry->functions;
-                if (fs) {
-                    for (; fs->name; fs++) {
-                        if (!JS_DefineFunction(cx, proto, fs->name,
-                                               reinterpret_cast<JSNative>(fs->native),
-                                               fs->arity, flags))
-                            return false;
-                    }
+                const xpc_qsFunctionSpec *fs = funcspecs + entry->func_index;
+                const xpc_qsFunctionSpec *fs_end = fs + entry->n_funcs;
+                for ( ; fs < fs_end; ++fs) {
+                    if (!JS_DefineFunction(cx, proto,
+                                           stringTable + fs->name_index,
+                                           reinterpret_cast<JSNative>(fs->native),
+                                           fs->arity, flags))
+                        return false;
                 }
 
                 // Next.
                 size_t j = entry->parentInterface;
                 if (j == XPC_QS_NULL_INDEX)
                     break;
                 entry = table + j;
             }
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -44,45 +44,41 @@
 #include "xpcprivate.h"
 
 #include "nsINode.h"
 
 /* XPCQuickStubs.h - Support functions used only by quick stubs. */
 
 class XPCCallContext;
 
-#define XPC_QS_NULL_INDEX  ((size_t) -1)
+#define XPC_QS_NULL_INDEX  ((uint16_t) -1)
 
 struct xpc_qsPropertySpec {
-    const char *name;
+    uint16_t name_index;
     JSPropertyOp getter;
     JSStrictPropertyOp setter;
 };
 
 struct xpc_qsFunctionSpec {
-    const char *name;
+    uint16_t name_index;
+    uint16_t arity;
     JSNative native;
-    uintN arity;
-};
-
-struct xpc_qsTraceableSpec {
-    const char *name;
-    JSNative native;
-    uintN arity;
 };
 
 /** A table mapping interfaces to quick stubs. */
 struct xpc_qsHashEntry {
     nsID iid;
-    const xpc_qsPropertySpec *properties;
-    const xpc_qsFunctionSpec *functions;
+    uint16_t prop_index;
+    uint16_t n_props;
+    uint16_t func_index;
+    uint16_t n_funcs;
     // These last two fields index to other entries in the same table.
     // XPC_QS_NULL_ENTRY indicates there are no more entries in the chain.
-    size_t parentInterface;
-    size_t chain;
+    uint16_t parentInterface;
+    uint16_t chain;
 };
 
 inline nsISupports*
 ToSupports(nsISupports *p)
 {
     return p;
 }
 
@@ -159,17 +155,20 @@ public:
         aObject.forget();
     }
   }
 };
 
 JSBool
 xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN extraFlags,
                        PRUint32 ifacec, const nsIID **interfaces,
-                       PRUint32 tableSize, const xpc_qsHashEntry *table);
+                       PRUint32 tableSize, const xpc_qsHashEntry *table,
+                       const xpc_qsPropertySpec *propspecs,
+                       const xpc_qsFunctionSpec *funcspecs,
+                       const char *stringTable);
 
 /** Raise an exception on @a cx and return false. */
 JSBool
 xpc_qsThrow(JSContext *cx, nsresult rv);
 
 /**
  * Fail after an XPCOM getter or setter returned rv.
  *
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -120,18 +120,16 @@
 
 import xpidl
 import header
 import os, re
 import sys
 
 # === Preliminaries
 
-MAX_TRACEABLE_NATIVE_ARGS = 8
-
 # --makedepend-output support.
 make_dependencies = []
 make_targets = []
 
 def warn(msg):
     sys.stderr.write(msg + '\n')
 
 def unaliasType(t):
@@ -384,16 +382,48 @@ def writeHeaderFile(filename, name):
                 "  " + name + "_ClearInterfaces();\n"
                 "}\n\n"
                 "#endif\n")
     finally:
         f.close()
 
 # === Generating the source file
 
+class StringTable:
+    def __init__(self):
+        self.current_index = 0;
+        self.table = {}
+        self.reverse_table = {}
+
+    def c_strlen(self, string):
+        return len(string) + 1
+
+    def stringIndex(self, string):
+        if string in self.table:
+            return self.table[string]
+        else:
+            result = self.current_index
+            self.table[string] = result
+            self.current_index += self.c_strlen(string)
+            return result
+
+    def writeDefinition(self, f, name):
+        entries = self.table.items()
+        entries.sort(key=lambda x:x[1])
+        # Avoid null-in-string warnings with GCC and potentially
+        # overlong string constants; write everything out the long way.
+        def explodeToCharArray(string):
+            return ", ".join(map(lambda x:"'%s'" % x, string))
+        f.write("static const char %s[] = {\n" % name)
+        for (string, offset) in entries[:-1]:
+            f.write("  /* %5d */ %s, '\\0',\n"
+                    % (offset, explodeToCharArray(string)))
+        f.write("  /* %5d */ %s, '\\0' };\n\n"
+                % (entries[-1][1], explodeToCharArray(entries[-1][0])))
+
 def substitute(template, vals):
     """ Simple replacement for string.Template, which isn't in Python 2.3. """
     def replacement(match):
         return vals[match.group(1)]
     return re.sub(r'\${(\w+)}', replacement, template)
 
 # From JSData2Native.
 argumentUnboxingTemplates = {
@@ -1043,89 +1073,66 @@ def writeQuickStub(f, customMethodCalls,
 
     # Epilog.
     f.write("}\n\n")
 
     # Now write out the call to the template function.
     if customMethodCall is not None:
         f.write(callTemplate)
 
-def writeAttrStubs(f, customMethodCalls, attr):
+def writeAttrStubs(f, customMethodCalls, stringtable, attr):
     cmc = customMethodCalls.get(attr.iface.name + "_" + header.methodNativeName(attr), None)
     custom = cmc and cmc.get('skipgen', False)
 
     getterName = (attr.iface.name + '_'
                   + header.attributeNativeName(attr, True))
     if not custom:
         writeQuickStub(f, customMethodCalls, attr, getterName)
     if attr.readonly:
         setterName = 'xpc_qsGetterOnlyPropertyStub'
     else:
         setterName = (attr.iface.name + '_'
                       + header.attributeNativeName(attr, False))
         if not custom:
             writeQuickStub(f, customMethodCalls, attr, setterName, isSetter=True)
 
-    ps = ('{"%s", %s, %s}'
-          % (attr.name, getterName, setterName))
+    ps = ('{%d, %s, %s}'
+          % (stringtable.stringIndex(attr.name), getterName, setterName))
     return ps
 
-def writeMethodStub(f, customMethodCalls, method):
+def writeMethodStub(f, customMethodCalls, stringtable, method):
     """ Write a method stub to `f`. Return an xpc_qsFunctionSpec initializer. """
 
     cmc = customMethodCalls.get(method.iface.name + "_" + header.methodNativeName(method), None)
     custom = cmc and cmc.get('skipgen', False)
 
     stubName = method.iface.name + '_' + header.methodNativeName(method)
     if not custom:
         writeQuickStub(f, customMethodCalls, method, stubName)
-    fs = '{"%s", %s, %d}' % (method.name, stubName, len(method.params))
+    fs = '{%d, %d, %s}' % (stringtable.stringIndex(method.name),
+                           len(method.params), stubName)
     return fs
 
-def writeTraceableStub(f, customMethodCalls, method):
-    """ Write a method stub to `f`. Return an xpc_qsTraceableSpec initializer. """
-
-    cmc = customMethodCalls.get(method.iface.name + "_" + header.methodNativeName(method), None)
-    custom = cmc and cmc.get('skipgen', False)
-
-    stubName = method.iface.name + '_' + header.methodNativeName(method)
-    if not custom:
-        writeTraceableQuickStub(f, customMethodCalls, method, stubName)
-    fs = '{"%s", %s, %d}' % (method.name,
-                             "JS_DATA_TO_FUNC_PTR(JSNative, &%s_trcinfo)" % stubName,
-                             len(method.params))
-    return fs
-
-def writeStubsForInterface(f, customMethodCalls, iface):
+def writeStubsForInterface(f, customMethodCalls, stringtable, iface):
     f.write("// === interface %s\n\n" % iface.name)
     propspecs = []
     funcspecs = []
     for member in iface.stubMembers:
         if member.kind == 'attribute':
-            ps = writeAttrStubs(f, customMethodCalls, member)
+            ps = writeAttrStubs(f, customMethodCalls, stringtable, member)
             propspecs.append(ps)
         elif member.kind == 'method':
-            fs = writeMethodStub(f, customMethodCalls, member)
+            fs = writeMethodStub(f, customMethodCalls, stringtable, member)
             funcspecs.append(fs)
         else:
             raise TypeError('expected attribute or method, not %r'
                             % member.__class__.__name__)
 
-    if propspecs:
-        f.write("static const xpc_qsPropertySpec %s_properties[] = {\n"
-                % iface.name)
-        for ps in propspecs:
-            f.write("    %s,\n" % ps)
-        f.write("    {nsnull}};\n")
-    if funcspecs:
-        f.write("static const xpc_qsFunctionSpec %s_functions[] = {\n" % iface.name)
-        for fs in funcspecs:
-            f.write("    %s,\n" % fs)
-        f.write("    {nsnull}};\n")
-    f.write('\n\n')
+    iface.propspecs = propspecs
+    iface.funcspecs = funcspecs
 
 def hashIID(iid):
     # See nsIDKey::HashCode in nsHashtable.h.
     return int(iid[:8], 16)
 
 uuid_re = re.compile(r'^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$')
 
 def writeResultXPCInterfacesArray(f, conf, resulttypes):
@@ -1148,19 +1155,42 @@ def writeResultXPCInterfacesArray(f, con
     f.write("}\n\n")
     i = 0
     for type in resulttypes:
         f.write("static const PRUint32 k_%s = %d;\n" % (type, i))
         i += 1
     if count > 0:
         f.write("\n\n")
 
-def writeDefiner(f, conf, interfaces):
+def writeSpecs(f, elementType, varname, spec_type, spec_indices, interfaces):
+    index = 0
+    f.write("static const %s %s[] = {\n" % (elementType, varname))
+    for iface in interfaces:
+        specs = getattr(iface, spec_type)
+        if specs:
+            spec_indices[iface.name] = index
+            f.write("    // %s (index %d)\n" % (iface.name,index))
+            for s in specs:
+                f.write("    %s,\n" % s)
+            index += len(specs)
+    f.write("};\n\n")
+
+def writeDefiner(f, conf, stringtable, interfaces):
     f.write("// === Definer\n\n")
 
+    # Write out the properties and functions
+    propspecs_indices = {}
+    funcspecs_indices = {}
+    prop_array_name = "all_properties"
+    func_array_name = "all_functions"
+    writeSpecs(f, "xpc_qsPropertySpec", prop_array_name,
+               "propspecs", propspecs_indices, interfaces)
+    writeSpecs(f, "xpc_qsFunctionSpec", func_array_name,
+               "funcspecs", funcspecs_indices, interfaces)
+
     # generate the static hash table
     loadFactor = 0.6
     size = int(len(interfaces) / loadFactor)
     buckets = [[] for i in range(size)]
     for iface in interfaces:
         # This if-statement discards interfaces specified with
         # "nsInterfaceName.*" that don't have any stub-able members.
         if iface.stubMembers:
@@ -1175,43 +1205,43 @@ def writeDefiner(f, conf, interfaces):
     for i, bucket in enumerate(buckets):
         if bucket:
             entryIndexes[bucket[0].attributes.uuid] = i
             for iface in bucket[1:]:
                 entryIndexes[iface.attributes.uuid] = arraySize
                 arraySize += 1
 
     entries = ["    {{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, "
-               "nsnull, nsnull, XPC_QS_NULL_INDEX, XPC_QS_NULL_INDEX}"
+               "0, 0, 0, 0, XPC_QS_NULL_INDEX, XPC_QS_NULL_INDEX}"
                for i in range(arraySize)]
     for i, bucket in enumerate(buckets):
         for j, iface in enumerate(bucket):
             # iid field
             uuid = iface.attributes.uuid.lower()
             m = uuid_re.match(uuid)
             assert m is not None
             m0, m1, m2, m3, m4 = m.groups()
             m3arr = ('{0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}'
                      % (m3[0:2], m3[2:4], m4[0:2], m4[2:4],
                         m4[4:6], m4[6:8], m4[8:10], m4[10:12]))
             iid = ('{0x%s, 0x%s, 0x%s, %s}' % (m0, m1, m2, m3arr))
 
-            # properties field
-            properties = "nsnull"
-            for member in iface.stubMembers:
-                if member.kind == 'attribute':
-                    properties = iface.name + "_properties"
-                    break
+            # properties fields
+            prop_index = 0
+            prop_n_entries = 0
+            if iface.propspecs:
+                prop_index = propspecs_indices[iface.name]
+                prop_n_entries = len(iface.propspecs)
 
-            # member field
-            functions = "nsnull"
-            for member in iface.stubMembers:
-                if member.kind == 'method':
-                    functions = iface.name + "_functions"
-                    break
+            # member fields
+            func_index = 0
+            func_n_entries = 0
+            if iface.funcspecs:
+                func_index = funcspecs_indices[iface.name]
+                func_n_entries = len(iface.funcspecs)
 
             # parentInterface field
             baseName = iface.base
             while baseName is not None:
                 piface = iface.idl.getName(baseName, None)
                 k = entryIndexes.get(piface.attributes.uuid)
                 if k is not None:
                     parentInterface = str(k)
@@ -1223,31 +1253,45 @@ def writeDefiner(f, conf, interfaces):
             # chain field
             if j == len(bucket) - 1:
                 chain = "XPC_QS_NULL_INDEX"
             else:
                 k = entryIndexes[bucket[j+1].attributes.uuid]
                 chain = str(k)
 
             # add entry
-            entry = "    {%s, %s, %s, %s, %s}" % (
-                iid, properties, functions, parentInterface, chain)
+            entry = "    /* %s */ {%s, %d, %d, %d, %d, %s, %s}" % (
+                iface.name, iid, prop_index, prop_n_entries,
+                func_index, func_n_entries, parentInterface, chain)
             entries[entryIndexes[iface.attributes.uuid]] = entry
 
     f.write("static const xpc_qsHashEntry tableData[] = {\n")
     f.write(",\n".join(entries))
     f.write("\n    };\n\n")
+    f.write("// Make sure our table indices aren't overflowed\n"
+            "PR_STATIC_ASSERT((sizeof(tableData) / sizeof(tableData[0])) < (1 << (8 * sizeof(tableData[0].parentInterface))));\n"
+            "PR_STATIC_ASSERT((sizeof(tableData) / sizeof(tableData[0])) < (1 << (8 * sizeof(tableData[0].chain))));\n\n")
+
+    # The string table for property and method names.
+    table_name = "stringtab"
+    stringtable.writeDefinition(f, table_name)
+    structNames = [prop_array_name, func_array_name]
+    for name in structNames:
+        f.write("PR_STATIC_ASSERT(sizeof(%s) < (1 << (8 * sizeof(%s[0].name_index))));\n"
+                % (table_name, name))
+    f.write("\n")
 
     # the definer function (entry point to this quick stubs file)
     f.write("JSBool %s_DefineQuickStubs(" % conf.name)
     f.write("JSContext *cx, JSObject *proto, uintN flags, PRUint32 count, "
             "const nsID **iids)\n"
             "{\n")
     f.write("    return xpc_qsDefineQuickStubs("
-            "cx, proto, flags, count, iids, %d, tableData);\n" % size)
+            "cx, proto, flags, count, iids, %d, tableData, %s, %s, %s);\n" % (
+            size, prop_array_name, func_array_name, table_name))
     f.write("}\n\n\n")
 
 
 stubTopTemplate = '''\
 /* THIS FILE IS AUTOGENERATED - DO NOT EDIT */
 #include "jsapi.h"
 #include "qsWinUndefs.h"
 #include "prtypes.h"
@@ -1306,19 +1350,20 @@ def writeStubFile(filename, headerFilena
             resulttypes.extend(writeIncludesForInterface(iface))
         resulttypes.extend(conf.customReturnInterfaces)
         for customInclude in conf.customIncludes:
             f.write('#include "%s"\n' % customInclude)
         f.write("\n\n")
         writeResultXPCInterfacesArray(f, conf, frozenset(resulttypes))
         for customQS in conf.customQuickStubs:
             f.write('#include "%s"\n' % customQS)
+        stringtable = StringTable()
         for iface in interfaces:
-            writeStubsForInterface(f, conf.customMethodCalls, iface)
-        writeDefiner(f, conf, interfaces)
+            writeStubsForInterface(f, conf.customMethodCalls, stringtable, iface)
+        writeDefiner(f, conf, stringtable, interfaces)
     finally:
         f.close()
 
 def makeQuote(filename):
     return filename.replace(' ', '\\ ')  # enjoy!
 
 def writeMakeDependOutput(filename):
     print "Creating makedepend file", filename
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -105,29 +105,16 @@ class nsAnimationManager;
 class nsRefreshDriver;
 class imgIContainer;
 class nsIDOMMediaQueryList;
 
 #ifdef MOZ_REFLOW_PERF
 class nsRenderingContext;
 #endif
 
-enum nsWidgetType {
-  eWidgetType_Button  	= 1,
-  eWidgetType_Checkbox	= 2,
-  eWidgetType_Radio			= 3,
-  eWidgetType_Text			= 4
-};
-
-enum nsLanguageSpecificTransformType {
-  eLanguageSpecificTransformType_Unknown = -1,
-  eLanguageSpecificTransformType_None = 0,
-  eLanguageSpecificTransformType_Japanese
-};
-
 // supported values for cached bool types
 enum nsPresContext_CachedBoolPrefType {
   kPresContext_UseDocumentColors = 1,
   kPresContext_UseDocumentFonts,
   kPresContext_UnderlineLinks
 };
 
 // supported values for cached integer pref types
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -230,16 +230,17 @@ fails-if(Android) random-if(gtk2Widget) 
 == text-layout-01.svg text-layout-01-ref.svg
 == text-layout-02.svg text-layout-02-ref.svg
 == text-layout-03.svg text-layout-03-ref.svg
 == text-layout-04.svg text-layout-04-ref.svg
 == text-layout-05.svg text-layout-05-ref.svg
 == text-scale-01.svg text-scale-01-ref.svg
 == text-stroke-scaling-01.svg text-stroke-scaling-01-ref.svg
 == stroke-dasharray-and-pathLength-01.svg pass.svg
+== stroke-dasharray-and-text-01.svg stroke-dasharray-and-text-01-ref.svg 
 == stroke-linecap-square-w-zero-length-segs-01.svg pass.svg
 == stroke-linecap-square-w-zero-length-segs-02.svg pass.svg
 == textPath-01.svg textPath-01-ref.svg
 == textPath-02.svg pass.svg
 == text-style-01a.svg text-style-01-ref.svg
 == text-style-01b.svg text-style-01-ref.svg
 == text-style-01c.svg text-style-01-ref.svg
 == text-style-01d.svg text-style-01-ref.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/stroke-dasharray-and-text-01-ref.svg
@@ -0,0 +1,10 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Test stroke-dasharray with text and zooming</title>
+  <g fill="none" stroke-width="2" stroke="black" stroke-dasharray="20">
+    <text font-size="100" x="100" y="100">|</text>
+  </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/stroke-dasharray-and-text-01.svg
@@ -0,0 +1,10 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" reftest-zoom="2">
+  <title>Test stroke-dasharray with text and zooming</title>
+  <g fill="none" stroke-width="1" stroke="black" stroke-dasharray="10">
+    <text font-size="50" x="50" y="50">|</text>
+  </g>
+</svg>
--- a/layout/svg/base/src/nsSVGGeometryFrame.cpp
+++ b/layout/svg/base/src/nsSVGGeometryFrame.cpp
@@ -95,83 +95,59 @@ nsSVGGeometryFrame::GetStrokeWidth()
                                      mContent->GetParent() : mContent);
 
   return
     nsSVGUtils::CoordToFloat(PresContext(),
                              ctx,
                              GetStyleSVG()->mStrokeWidth);
 }
 
-nsresult
-nsSVGGeometryFrame::GetStrokeDashArray(gfxFloat **aDashes, PRUint32 *aCount)
+bool
+nsSVGGeometryFrame::GetStrokeDashData(FallibleTArray<gfxFloat>& dashes,
+                                      gfxFloat *dashOffset)
 {
-  nsSVGElement *ctx = static_cast<nsSVGElement*>
-                                 (mContent->IsNodeOfType(nsINode::eTEXT) ?
-                                     mContent->GetParent() : mContent);
-  *aDashes = nsnull;
-  *aCount = 0;
-
   PRUint32 count = GetStyleSVG()->mStrokeDasharrayLength;
-  gfxFloat *dashes = nsnull;
-
-  if (count) {
-    const nsStyleCoord *dasharray = GetStyleSVG()->mStrokeDasharray;
-    nsPresContext *presContext = PresContext();
-    gfxFloat totalLength = 0.0f;
-
-    gfxFloat pathScale = 1.0;
-
-    if (mContent->Tag() == nsGkAtoms::path) {
-      pathScale = static_cast<nsSVGPathElement*>(mContent)->
-                    GetPathLengthScale(nsSVGPathElement::eForStroking);
-      if (pathScale <= 0) {
-        return NS_OK;
-      }
-    }
-
-    dashes = new gfxFloat[count];
-    if (dashes) {
-      for (PRUint32 i = 0; i < count; i++) {
-        dashes[i] =
-          nsSVGUtils::CoordToFloat(presContext,
-                                   ctx,
-                                   dasharray[i]) * pathScale;
-        if (dashes[i] < 0.0f) {
-          delete [] dashes;
-          return NS_OK;
-        }
-        totalLength += dashes[i];
-      }
-    } else {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (totalLength == 0.0f) {
-      delete [] dashes;
-      return NS_OK;
-    }
-
-    *aDashes = dashes;
-    *aCount = count;
+  if (!count || !dashes.SetLength(count)) {
+    return false;
   }
 
-  return NS_OK;
-}
+  gfxFloat pathScale = 1.0;
 
-float
-nsSVGGeometryFrame::GetStrokeDashoffset()
-{
+  if (mContent->Tag() == nsGkAtoms::path) {
+    pathScale = static_cast<nsSVGPathElement*>(mContent)->
+                  GetPathLengthScale(nsSVGPathElement::eForStroking);
+    if (pathScale <= 0) {
+      return false;
+    }
+  }
+  
   nsSVGElement *ctx = static_cast<nsSVGElement*>
                                  (mContent->IsNodeOfType(nsINode::eTEXT) ?
                                      mContent->GetParent() : mContent);
 
-  return
-    nsSVGUtils::CoordToFloat(PresContext(),
-                             ctx,
-                             GetStyleSVG()->mStrokeDashoffset);
+  const nsStyleCoord *dasharray = GetStyleSVG()->mStrokeDasharray;
+  nsPresContext *presContext = PresContext();
+  gfxFloat totalLength = 0.0;
+
+  for (PRUint32 i = 0; i < count; i++) {
+    dashes[i] =
+      nsSVGUtils::CoordToFloat(presContext,
+                               ctx,
+                               dasharray[i]) * pathScale;
+    if (dashes[i] < 0.0) {
+      return false;
+    }
+    totalLength += dashes[i];
+  }
+
+  *dashOffset = nsSVGUtils::CoordToFloat(presContext,
+                                         ctx,
+                                         GetStyleSVG()->mStrokeDashoffset);
+
+  return (totalLength > 0.0);
 }
 
 PRUint16
 nsSVGGeometryFrame::GetClipRule()
 {
   return GetStyleSVG()->mClipRule;
 }
 
@@ -299,22 +275,20 @@ nsSVGGeometryFrame::SetupCairoStrokeGeom
   }
 }
 
 void
 nsSVGGeometryFrame::SetupCairoStrokeHitGeometry(gfxContext *aContext)
 {
   SetupCairoStrokeGeometry(aContext);
 
-  gfxFloat *dashArray;
-  PRUint32 count;
-  GetStrokeDashArray(&dashArray, &count);
-  if (count > 0) {
-    aContext->SetDash(dashArray, count, GetStrokeDashoffset());
-    delete [] dashArray;
+  AutoFallibleTArray<gfxFloat, 10> dashes;
+  gfxFloat dashOffset;
+  if (GetStrokeDashData(dashes, &dashOffset)) {
+    aContext->SetDash(dashes.Elements(), dashes.Length(), dashOffset);
   }
 }
 
 bool
 nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext)
 {
   if (!HasStroke()) {
     return false;
--- a/layout/svg/base/src/nsSVGGeometryFrame.h
+++ b/layout/svg/base/src/nsSVGGeometryFrame.h
@@ -111,18 +111,17 @@ protected:
    * This function returns a set of bit flags indicating which parts of the
    * element (fill, stroke, bounds) should intercept pointer events. It takes
    * into account the type of element and the value of the 'pointer-events'
    * property on the element.
    */
   virtual PRUint16 GetHitTestFlags();
 
 private:
-  nsresult GetStrokeDashArray(double **arr, PRUint32 *count);
-  float GetStrokeDashoffset();
+  bool GetStrokeDashData(FallibleTArray<gfxFloat>& dashes, gfxFloat *dashOffset);
 
   /**
    * Returns the given 'fill-opacity' or 'stroke-opacity' value multiplied by
    * the value of the 'opacity' property if it's possible to avoid the expense
    * of creating and compositing an offscreen surface for 'opacity' by
    * combining 'opacity' with the 'fill-opacity'/'stroke-opacity'. If not, the
    * given 'fill-opacity'/'stroke-opacity' is returned unmodified.
    */
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp
+++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp
@@ -132,18 +132,26 @@ public:
    */
   bool SetupForDirectTextRunMetrics(gfxContext *aContext) {
     return SetupForDirectTextRun(aContext, mMetricsScale);
   }
   /**
    * We are scaling the glyphs up/down to the size we want so we need to
    * inverse scale the outline widths of those glyphs so they are invariant
    */
-  void SetLineWidthForDrawing(gfxContext *aContext) {
+  void SetLineWidthAndDashesForDrawing(gfxContext *aContext) {
     aContext->SetLineWidth(aContext->CurrentLineWidth() / mDrawScale);
+    AutoFallibleTArray<gfxFloat, 10> dashes;
+    gfxFloat dashOffset;
+    if (aContext->CurrentDash(dashes, &dashOffset)) {
+      for (PRUint32 i = 0; i <  dashes.Length(); i++) {
+        dashes[i] /= mDrawScale;
+      }
+      aContext->SetDash(dashes.Elements(), dashes.Length(), dashOffset / mDrawScale);
+    }
   }
 
   /**
    * Returns the index of the next cluster in the string that should be drawn,
    * or InvalidCluster() (i.e. PRUint32(-1)) if there is no such cluster.
    */
   PRUint32 NextCluster();
 
@@ -541,17 +549,17 @@ nsSVGGlyphFrame::NotifyRedrawUnsuspended
 
   return NS_OK;
 }
 
 void
 nsSVGGlyphFrame::AddCharactersToPath(CharacterIterator *aIter,
                                      gfxContext *aContext)
 {
-  aIter->SetLineWidthForDrawing(aContext);
+  aIter->SetLineWidthAndDashesForDrawing(aContext);
   if (aIter->SetupForDirectTextRunDrawing(aContext)) {
     mTextRun->DrawToPath(aContext, gfxPoint(0, 0), 0,
                          mTextRun->GetLength(), nsnull, nsnull);
     return;
   }
 
   PRUint32 i;
   while ((i = aIter->NextCluster()) != aIter->InvalidCluster()) {
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -67,16 +67,17 @@ import android.view.inputmethod.EditorIn
 import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ExpandableListView;
 import android.widget.ImageButton;
 import android.widget.RelativeLayout;
 import android.widget.ListView;
+import android.widget.Toast;
 
 import java.util.Map;
 
 import org.mozilla.gecko.db.BrowserDB.URLColumns;
 import org.mozilla.gecko.db.BrowserDB;
 
 import org.json.JSONArray;
 import org.json.JSONObject;
@@ -426,16 +427,21 @@ public class AwesomeBar extends Activity
             mContextMenuSubject = null;
             return;
         }
 
         mContextMenuSubject = selectedItem;
 
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.awesomebar_contextmenu, menu);
+        
+        if (view != (ListView)findViewById(R.id.bookmarks_list)) {
+            MenuItem removeBookmarkItem = menu.findItem(R.id.remove_bookmark);
+            removeBookmarkItem.setVisible(false);
+        }
 
         menu.setHeaderTitle(title);
     }
 
     @Override
     public boolean onContextItemSelected(MenuItem item) {
         if (mContextMenuSubject == null)
             return false;
@@ -459,16 +465,22 @@ public class AwesomeBar extends Activity
 
         mContextMenuSubject = null;
 
         switch (item.getItemId()) {
             case R.id.open_new_tab: {
                 GeckoApp.mAppContext.loadUrl(url, AwesomeBar.Type.ADD);
                 break;
             }
+            case R.id.remove_bookmark: {
+                ContentResolver resolver = Tabs.getInstance().getContentResolver();
+                BrowserDB.removeBookmark(resolver, url);
+                Toast.makeText(this, R.string.bookmark_removed, Toast.LENGTH_SHORT).show();
+                break;
+            }
             case R.id.add_to_launcher: {
                 Bitmap bitmap = null;
                 if (b != null)
                     bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
     
                 GeckoAppShell.createShortcut(title, url, bitmap, "");
                 break;
             }
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -36,16 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.gecko;
 
 import android.content.ContentResolver;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.Bitmap;
+import android.os.AsyncTask;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.graphics.Bitmap;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.ByteArrayOutputStream;
@@ -72,16 +73,17 @@ public class Tab {
     private List<HistoryEntry> mHistory;
     private int mHistoryIndex;
     private int mParentId;
     private boolean mExternal;
     private boolean mLoading;
     private boolean mBookmark;
     private HashMap<String, DoorHanger> mDoorHangers;
     private long mFaviconLoadId;
+    private CheckBookmarkTask mCheckBookmarkTask;
     private String mDocumentURI;
     private String mContentType;
 
     static class HistoryEntry {
         public final String mUri;   // must never be null
         public String mTitle;       // must never be null
 
         public HistoryEntry(String uri, String title) {
@@ -269,17 +271,25 @@ public class Tab {
         Log.i(LOGTAG, "Updated favicon URL for tab with id: " + mId);
     }
 
     public void updateSecurityMode(String mode) {
         mSecurityMode = mode;
     }
 
     private void updateBookmark() {
-        new CheckBookmarkTask().execute();
+        GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
+            public void run() {
+                if (mCheckBookmarkTask != null)
+                    mCheckBookmarkTask.cancel(false);
+
+                mCheckBookmarkTask = new CheckBookmarkTask(getURL());
+                mCheckBookmarkTask.execute();
+            }
+        });
     }
 
     public void addBookmark() {
         new AddBookmarkTask().execute();
     }
 
     public void removeBookmark() {
         new RemoveBookmarkTask().execute();
@@ -389,26 +399,48 @@ public class Tab {
             }
             mHistoryIndex = index;
         } else if (event.equals("Purge")) {
             mHistory.clear();
             mHistoryIndex = -1;
         }
     }
 
-    private class CheckBookmarkTask extends GeckoAsyncTask<Void, Void, Boolean> {
+    private class CheckBookmarkTask extends AsyncTask<Void, Void, Boolean> {
+        private final String mUrl;
+
+        public CheckBookmarkTask(String url) {
+            mUrl = url;
+        }
+
         @Override
         protected Boolean doInBackground(Void... unused) {
             ContentResolver resolver = Tabs.getInstance().getContentResolver();
-            return BrowserDB.isBookmark(resolver, getURL());
+            return BrowserDB.isBookmark(resolver, mUrl);
+        }
+
+        @Override
+        protected void onCancelled() {
+            mCheckBookmarkTask = null;
         }
 
         @Override
-        protected void onPostExecute(Boolean isBookmark) {
-            setBookmark(isBookmark.booleanValue());
+        protected void onPostExecute(final Boolean isBookmark) {
+            mCheckBookmarkTask = null;
+
+            GeckoApp.mAppContext.runOnUiThread(new Runnable() {
+                public void run() {
+                    // Ignore this task if it's not about the current
+                    // tab URL anymore.
+                    if (!mUrl.equals(getURL()))
+                        return;
+
+                    setBookmark(isBookmark.booleanValue());
+                }
+            });
         }
     }
 
     private class AddBookmarkTask extends GeckoAsyncTask<Void, Void, Void> {
         @Override
         protected Void doInBackground(Void... unused) {
             ContentResolver resolver = Tabs.getInstance().getContentResolver();
             BrowserDB.addBookmark(resolver, getTitle(), getURL());
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -71,16 +71,17 @@
 
 <!ENTITY addons "Add-ons">
 <!ENTITY downloads "Downloads">
 
 <!ENTITY share "Share">
 <!ENTITY save_as_pdf "Save as PDF">
 
 <!ENTITY contextmenu_open_new_tab "Open in New Tab">
+<!ENTITY contextmenu_remove_bookmark "Remove">
 <!ENTITY contextmenu_add_to_launcher "Add to Home Screen">
 <!ENTITY contextmenu_share "Share">
 
 <!ENTITY site_settings_title        "Clear Site Settings">
 <!ENTITY site_settings_cancel       "Cancel">
 <!ENTITY site_settings_clear        "Clear">
 <!ENTITY site_settings_no_settings  "There are no settings to clear.">
 
--- a/mobile/android/base/resources/menu/awesomebar_contextmenu.xml
+++ b/mobile/android/base/resources/menu/awesomebar_contextmenu.xml
@@ -2,12 +2,15 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item android:id="@+id/open_new_tab"
           android:title="@string/contextmenu_open_new_tab"/>
 
     <item android:id="@+id/share"
           android:title="@string/contextmenu_share"/>
 
+    <item android:id="@+id/remove_bookmark"
+          android:title="@string/contextmenu_remove_bookmark"/>
+
     <item android:id="@+id/add_to_launcher"
           android:title="@string/contextmenu_add_to_launcher"/>
 
 </menu>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -79,16 +79,17 @@
   <string name="downloads">&downloads;</string>
 
   <string name="site_settings_title">&site_settings_title;</string>
   <string name="site_settings_cancel">&site_settings_cancel;</string>
   <string name="site_settings_clear">&site_settings_clear;</string>
   <string name="site_settings_no_settings">&site_settings_no_settings;</string>
 
   <string name="contextmenu_open_new_tab">&contextmenu_open_new_tab;</string>
+  <string name="contextmenu_remove_bookmark">&contextmenu_remove_bookmark;</string>
   <string name="contextmenu_add_to_launcher">&contextmenu_add_to_launcher;</string>
   <string name="contextmenu_share">&contextmenu_share;</string>
 
   <string name="pref_use_master_password">&pref_use_master_password;</string>
   <string name="masterpassword_create_title">&masterpassword_create_title;</string>
   <string name="masterpassword_remove_title">&masterpassword_remove_title;</string>
   <string name="masterpassword_password">&masterpassword_password;</string>
   <string name="masterpassword_confirm">&masterpassword_confirm;</string>
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -2841,17 +2841,17 @@ var XPInstallObserver = {
   onInstallEnded: function(aInstall, aAddon) {
     let needsRestart = false;
     if (aInstall.existingAddon && (aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE))
       needsRestart = true;
     else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
       needsRestart = true;
 
     if (needsRestart) {
-      buttons = [{
+      let buttons = [{
         label: Strings.browser.GetStringFromName("notificationRestart.button"),
         callback: function() {
           // Notify all windows that an application quit has been requested
           let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
           Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
 
           // If nothing aborted, quit the app
           if (cancelQuit.data == false) {
--- a/mobile/android/confvars.sh
+++ b/mobile/android/confvars.sh
@@ -40,17 +40,17 @@ MOZ_APP_VENDOR=Mozilla
 
 MOZ_APP_VERSION=12.0a1
 
 MOZ_BRANDING_DIRECTORY=mobile/android/branding/unofficial
 MOZ_OFFICIAL_BRANDING_DIRECTORY=mobile/android/branding/official
 # MOZ_APP_DISPLAYNAME is set by branding/configure.sh
 
 MOZ_SAFE_BROWSING=
-MOZ_SERVICES_SYNC=1
+MOZ_SERVICES_SYNC=
 
 MOZ_DISABLE_DOMCRYPTO=1
 
 if test "$LIBXUL_SDK"; then
 MOZ_XULRUNNER=1
 else
 MOZ_XULRUNNER=
 MOZ_PLACES=1
--- a/modules/libjar/nsJARFactory.cpp
+++ b/modules/libjar/nsJARFactory.cpp
@@ -46,23 +46,20 @@
 #include "plstr.h"
 #include "prlog.h"
 
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsIJARFactory.h"
-#include "nsRecyclingAllocator.h"
 #include "nsJARProtocolHandler.h"
 #include "nsJARURI.h"
 #include "nsJAR.h"
 
-extern nsRecyclingAllocator *gZlibAllocator;
-
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJAR)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsZipReaderCache)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsJARProtocolHandler,
                                          nsJARProtocolHandler::GetSingleton)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJARURI)
 
 NS_DEFINE_NAMED_CID(NS_ZIPREADER_CID);
 NS_DEFINE_NAMED_CID(NS_ZIPREADERCACHE_CID);
@@ -82,18 +79,16 @@ static const mozilla::Module::ContractID
     { "@mozilla.org/libjar/zip-reader-cache;1", &kNS_ZIPREADERCACHE_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar", &kNS_JARPROTOCOLHANDLER_CID },
     { NULL }
 };
 
 // Jar module shutdown hook
 static void nsJarShutdown()
 {
-    // Release cached buffers from zlib allocator
-    delete gZlibAllocator;
     NS_IF_RELEASE(gJarHandler);
 }
 
 static const mozilla::Module kJARModule = {
     mozilla::Module::kVersion,
     kJARCIDs,
     kJARContracts,
     NULL,
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -47,36 +47,29 @@
  *
  * The underlying nsZipArchive is NOT thread-safe. Do not pass references
  * or pointers to it across thread boundaries.
  */
 
 #define READTYPE  PRInt32
 #include "zlib.h"
 #include "nsISupportsUtils.h"
-#include "nsRecyclingAllocator.h"
 #include "prio.h"
 #include "plstr.h"
 #include "prlog.h"
 #include "stdlib.h"
 #include "nsWildCard.h"
 #include "nsZipArchive.h"
 #include "nsString.h"
 #include "mozilla/FunctionTimer.h"
 #include "prenv.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #endif
 
-/**
- * Global allocator used with zlib. Destroyed in module shutdown.
- */
-#define NBUCKETS 6
-nsRecyclingAllocator *gZlibAllocator = NULL;
-
 // For placement new used for arena allocations of zip file list
 #include NEW_H
 #define ZIP_ARENABLOCKSIZE (1*1024)
 
 #ifdef XP_UNIX
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <limits.h>
@@ -113,56 +106,24 @@ static const PRUint16 kSyntheticDate = (
 static PRUint16 xtoint(const PRUint8 *ii);
 static PRUint32 xtolong(const PRUint8 *ll);
 static PRUint32 HashName(const char* aName, PRUint16 nameLen);
 #ifdef XP_UNIX
 static nsresult ResolveSymlink(const char *path);
 #endif
 
 //***********************************************************
-// Allocators for use with zlib
-//
-// Use a recycling allocator, for re-use of of the zlib buffers.
 // For every inflation the following allocations are done:
-// zlibAlloc(1, 9520)
-// zlibAlloc(32768, 1)
+// malloc(1 * 9520)
+// malloc(32768 * 1)
 //***********************************************************
 
-static void *
-zlibAlloc(void *opaque, uInt items, uInt size)
-{
-  nsRecyclingAllocator *zallocator = (nsRecyclingAllocator *)opaque;
-  if (zallocator) {
-    return gZlibAllocator->Malloc(items * size);
-  }
-  return malloc(items * size);
-}
-
-static void
-zlibFree(void *opaque, void *ptr)
-{
-  nsRecyclingAllocator *zallocator = (nsRecyclingAllocator *)opaque;
-  if (zallocator)
-    zallocator->Free(ptr);
-  else
-    free(ptr);
-}
-
 nsresult gZlibInit(z_stream *zs)
 {
   memset(zs, 0, sizeof(z_stream));
-  //-- ensure we have our zlib allocator for better performance
-  if (!gZlibAllocator) {
-    gZlibAllocator = new nsRecyclingAllocator(NBUCKETS, NS_DEFAULT_RECYCLE_TIMEOUT, "libjar");
-  }
-  if (gZlibAllocator) {
-    zs->zalloc = zlibAlloc;
-    zs->zfree = zlibFree;
-    zs->opaque = gZlibAllocator;
-  }
   int zerr = inflateInit2(zs, -MAX_WBITS);
   if (zerr != Z_OK) return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 nsZipHandle::nsZipHandle()
   : mFileData(nsnull)
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -70,28 +70,32 @@ public:
   ~TelemetryImpl();
   
   static bool CanRecord();
   static already_AddRefed<nsITelemetry> CreateTelemetryInstance();
   static void ShutdownTelemetry();
   static void RecordSlowStatement(const nsACString &statement,
                                   const nsACString &dbName,
                                   PRUint32 delay);
+  static nsresult GetHistogramEnumId(const char *name, Telemetry::ID *id);
   struct StmtStats {
     PRUint32 hitCount;
     PRUint32 totalTime;
   };
   typedef nsBaseHashtableET<nsCStringHashKey, StmtStats> SlowSQLEntryType;
 
 private:
   bool AddSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread);
 
   // Like GetHistogramById, but returns the underlying C++ object, not the JS one.
   nsresult GetHistogramByName(const nsACString &name, Histogram **ret);
-  // This is used for speedy JS string->Telemetry::ID conversions
+  bool ShouldReflectHistogram(Histogram *h);
+  void IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs);
+  typedef StatisticsRecorder::Histograms::iterator HistogramIterator;
+  // This is used for speedy string->Telemetry::ID conversions
   typedef nsBaseHashtableET<nsCharPtrHashKey, Telemetry::ID> CharPtrEntryType;
   typedef nsTHashtable<CharPtrEntryType> HistogramMapType;
   HistogramMapType mHistogramMap;
   bool mCanRecord;
   static TelemetryImpl *sTelemetry;
   nsTHashtable<SlowSQLEntryType> mSlowSQLOnMainThread;
   nsTHashtable<SlowSQLEntryType> mSlowSQLOnOtherThread;
   nsTHashtable<nsCStringHashKey> mTrackedDBs;
@@ -128,16 +132,17 @@ const TelemetryHistogram gHistograms[] =
 #define HISTOGRAM(id, min, max, bucket_count, histogram_type, comment) \
   { NS_STRINGIFY(id), min, max, bucket_count, \
     nsITelemetry::HISTOGRAM_ ## histogram_type, comment },
 
 #include "TelemetryHistograms.h"
 
 #undef HISTOGRAM
 };
+bool gCorruptHistograms[Telemetry::HistogramCount];
 
 bool
 TelemetryHistogramType(Histogram *h, PRUint32 *result)
 {
   switch (h->histogram_type()) {
   case Histogram::HISTOGRAM:
     *result = nsITelemetry::HISTOGRAM_EXPONENTIAL;
     break;
@@ -210,42 +215,54 @@ FillRanges(JSContext *cx, JSObject *arra
 {
   for (size_t i = 0; i < h->bucket_count(); i++) {
     if (!JS_DefineElement(cx, array, i, INT_TO_JSVAL(h->ranges(i)), NULL, NULL, JSPROP_ENUMERATE))
       return false;
   }
   return true;
 }
 
-JSBool
+enum reflectStatus {
+  REFLECT_OK,
+  REFLECT_CORRUPT,
+  REFLECT_FAILURE
+};
+
+enum reflectStatus
 ReflectHistogramSnapshot(JSContext *cx, JSObject *obj, Histogram *h)
 {
   Histogram::SampleSet ss;
   h->SnapshotSample(&ss);
+
+  // We don't want to reflect corrupt histograms.
+  if (h->FindCorruption(ss) != Histogram::NO_INCONSISTENCIES) {
+    return REFLECT_CORRUPT;
+  }
+
   JSObject *counts_array;
   JSObject *rarray;
   const size_t count = h->bucket_count();
   if (!(JS_DefineProperty(cx, obj, "min", INT_TO_JSVAL(h->declared_min()), NULL, NULL, JSPROP_ENUMERATE)
         && JS_DefineProperty(cx, obj, "max", INT_TO_JSVAL(h->declared_max()), NULL, NULL, JSPROP_ENUMERATE)
         && JS_DefineProperty(cx, obj, "histogram_type", INT_TO_JSVAL(h->histogram_type()), NULL, NULL, JSPROP_ENUMERATE)
         && JS_DefineProperty(cx, obj, "sum", DOUBLE_TO_JSVAL(ss.sum()), NULL, NULL, JSPROP_ENUMERATE)
         && (rarray = JS_NewArrayObject(cx, count, NULL))
         && JS_DefineProperty(cx, obj, "ranges", OBJECT_TO_JSVAL(rarray), NULL, NULL, JSPROP_ENUMERATE)
         && FillRanges(cx, rarray, h)
         && (counts_array = JS_NewArrayObject(cx, count, NULL))
         && JS_DefineProperty(cx, obj, "counts", OBJECT_TO_JSVAL(counts_array), NULL, NULL, JSPROP_ENUMERATE)
         )) {
-    return JS_FALSE;
+    return REFLECT_FAILURE;
   }
   for (size_t i = 0; i < count; i++) {
     if (!JS_DefineElement(cx, counts_array, i, INT_TO_JSVAL(ss.counts(i)), NULL, NULL, JSPROP_ENUMERATE)) {
-      return JS_FALSE;
+      return REFLECT_FAILURE;
     }
   }
-  return JS_TRUE;
+  return REFLECT_OK;
 }
 
 JSBool
 JSHistogram_Add(JSContext *cx, uintN argc, jsval *vp)
 {
   if (!argc) {
     JS_ReportError(cx, "Expected one argument");
     return JS_FALSE;
@@ -285,18 +302,30 @@ JSHistogram_Snapshot(JSContext *cx, uint
   if (!obj) {
     return JS_FALSE;
   }
 
   Histogram *h = static_cast<Histogram*>(JS_GetPrivate(cx, obj));
   JSObject *snapshot = JS_NewObject(cx, NULL, NULL, NULL);
   if (!snapshot)
     return JS_FALSE;
-  JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(snapshot));
-  return ReflectHistogramSnapshot(cx, snapshot, h);
+
+  switch (ReflectHistogramSnapshot(cx, snapshot, h)) {
+  case REFLECT_FAILURE:
+    return JS_FALSE;
+  case REFLECT_CORRUPT:
+    JS_ReportError(cx, "Histogram is corrupt");
+    return JS_FALSE;
+  case REFLECT_OK:
+    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(snapshot));
+    return JS_TRUE;
+  default:
+    MOZ_NOT_REACHED("unhandled reflection status");
+    return JS_FALSE;
+  }
 }
 
 nsresult 
 WrapAndReturnHistogram(Histogram *h, JSContext *cx, jsval *ret)
 {
   static JSClass JSHistogram_class = {
     "JSHistogram",  /* name */
     JSCLASS_HAS_PRIVATE, /* flags */
@@ -407,38 +436,55 @@ TelemetryImpl::AddSQLInfo(JSContext *cx,
   PRUint32 num = sqlMap->EnumerateEntries(StatementEnumerator,
                                           static_cast<void*>(&args));
   if (num != sqlMap->Count())
     return false;
 
   return true;
 }
 
+nsresult
+TelemetryImpl::GetHistogramEnumId(const char *name, Telemetry::ID *id)
+{
+  if (!sTelemetry) {
+    return NS_ERROR_FAILURE;
+  }
 
-nsresult
-TelemetryImpl::GetHistogramByName(const nsACString &name, Histogram **ret)
-{
   // Cache names
   // Note the histogram names are statically allocated
-  if (!mHistogramMap.Count()) {
+  TelemetryImpl::HistogramMapType *map = &sTelemetry->mHistogramMap;
+  if (!map->Count()) {
     for (PRUint32 i = 0; i < Telemetry::HistogramCount; i++) {
-      CharPtrEntryType *entry = mHistogramMap.PutEntry(gHistograms[i].id);
+      CharPtrEntryType *entry = map->PutEntry(gHistograms[i].id);
       if (NS_UNLIKELY(!entry)) {
-        mHistogramMap.Clear();
+        map->Clear();
         return NS_ERROR_OUT_OF_MEMORY;
       }
       entry->mData = (Telemetry::ID) i;
     }
   }
 
-  CharPtrEntryType *entry = mHistogramMap.GetEntry(PromiseFlatCString(name).get());
-  if (!entry)
-    return NS_ERROR_FAILURE;
+  CharPtrEntryType *entry = map->GetEntry(name);
+  if (!entry) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  *id = entry->mData;
+  return NS_OK;
+}
 
-  nsresult rv = GetHistogramByEnumId(entry->mData, ret);
+nsresult
+TelemetryImpl::GetHistogramByName(const nsACString &name, Histogram **ret)
+{
+  Telemetry::ID id;
+  nsresult rv = GetHistogramEnumId(PromiseFlatCString(name).get(), &id);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  rv = GetHistogramByEnumId(id, ret);
   if (NS_FAILED(rv))
     return rv;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::HistogramFrom(const nsACString &name, const nsACString &existing_name,
@@ -462,35 +508,123 @@ TelemetryImpl::HistogramFrom(const nsACS
     return rv;
 
   Histogram::SampleSet ss;
   existing->SnapshotSample(&ss);
   clone->AddSampleSet(ss);
   return WrapAndReturnHistogram(clone, cx, ret);
 }
 
+void
+TelemetryImpl::IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs)
+{
+  for (HistogramIterator it = hs.begin(); it != hs.end(); ++it) {
+    Histogram *h = *it;
+
+    Telemetry::ID id;
+    nsresult rv = GetHistogramEnumId(h->histogram_name().c_str(), &id);
+    // This histogram isn't a static histogram, just ignore it.
+    if (NS_FAILED(rv)) {
+      continue;
+    }
+
+    if (gCorruptHistograms[id]) {
+      continue;
+    }
+
+    Histogram::SampleSet ss;
+    h->SnapshotSample(&ss);
+    Histogram::Inconsistencies check = h->FindCorruption(ss);
+    bool corrupt = (check != Histogram::NO_INCONSISTENCIES);
+
+    if (corrupt) {
+      Telemetry::ID corruptID = Telemetry::HistogramCount;
+      if (check & Histogram::RANGE_CHECKSUM_ERROR) {
+        corruptID = Telemetry::RANGE_CHECKSUM_ERRORS;
+      } else if (check & Histogram::BUCKET_ORDER_ERROR) {
+        corruptID = Telemetry::BUCKET_ORDER_ERRORS;
+      } else if (check & Histogram::COUNT_HIGH_ERROR) {
+        corruptID = Telemetry::TOTAL_COUNT_HIGH_ERRORS;
+      } else if (check & Histogram::COUNT_LOW_ERROR) {
+        corruptID = Telemetry::TOTAL_COUNT_LOW_ERRORS;
+      }
+      Telemetry::Accumulate(corruptID, 1);
+    }
+
+    gCorruptHistograms[id] = corrupt;
+  }
+}
+
+bool
+TelemetryImpl::ShouldReflectHistogram(Histogram *h)
+{
+  const char *name = h->histogram_name().c_str();
+  Telemetry::ID id;
+  nsresult rv = GetHistogramEnumId(name, &id);
+  if (NS_FAILED(rv)) {
+    // GetHistogramEnumId generally should not fail.  But a lookup
+    // failure shouldn't prevent us from reflecting histograms into JS.
+    //
+    // However, these two histograms are created by Histogram itself for
+    // tracking corruption.  We have our own histograms for that, so
+    // ignore these two.
+    if (strcmp(name, "Histogram.InconsistentCountHigh") == 0
+        || strcmp(name, "Histogram.InconsistentCountLow") == 0) {
+      return false;
+    }
+    return true;
+  } else {
+    return !gCorruptHistograms[id];
+  }
+}
+
 NS_IMETHODIMP
 TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret)
 {
   JSObject *root_obj = JS_NewObject(cx, NULL, NULL, NULL);
   if (!root_obj)
     return NS_ERROR_FAILURE;
   *ret = OBJECT_TO_JSVAL(root_obj);
 
-  StatisticsRecorder::Histograms h;
-  StatisticsRecorder::GetHistograms(&h);
-  for (StatisticsRecorder::Histograms::iterator it = h.begin(); it != h.end();++it) {
+  StatisticsRecorder::Histograms hs;
+  StatisticsRecorder::GetHistograms(&hs);
+
+  // We identify corrupt histograms first, rather than interspersing it
+  // in the loop below, to ensure that our corruption statistics don't
+  // depend on histogram enumeration order.
+  //
+  // Of course, we hope that all of these corruption-statistics
+  // histograms are not themselves corrupt...
+  IdentifyCorruptHistograms(hs);
+
+  // OK, now we can actually reflect things.
+  for (HistogramIterator it = hs.begin(); it != hs.end(); ++it) {
     Histogram *h = *it;
+    if (!ShouldReflectHistogram(h)) {
+      continue;
+    }
+
     JSObject *hobj = JS_NewObject(cx, NULL, NULL, NULL);
-    if (!(hobj
-          && JS_DefineProperty(cx, root_obj, h->histogram_name().c_str(),
-                               OBJECT_TO_JSVAL(hobj), NULL, NULL, JSPROP_ENUMERATE)
-          && ReflectHistogramSnapshot(cx, hobj, h))) {
+    if (!hobj) {
       return NS_ERROR_FAILURE;
     }
+    switch (ReflectHistogramSnapshot(cx, hobj, h)) {
+    case REFLECT_CORRUPT:
+      // We can still hit this case even if ShouldReflectHistograms
+      // returns true.  The histogram lies outside of our control
+      // somehow; just skip it.
+      continue;
+    case REFLECT_FAILURE:
+      return NS_ERROR_FAILURE;
+    case REFLECT_OK:
+      if (!JS_DefineProperty(cx, root_obj, h->histogram_name().c_str(),
+                             OBJECT_TO_JSVAL(hobj), NULL, NULL, JSPROP_ENUMERATE)) {
+        return NS_ERROR_FAILURE;
+      }
+    }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelemetryImpl::GetSlowSQL(JSContext *cx, jsval *ret)
 {
   JSObject *root_obj = JS_NewObject(cx, NULL, NULL, NULL);
--- a/toolkit/components/telemetry/TelemetryHistograms.h
+++ b/toolkit/components/telemetry/TelemetryHistograms.h
@@ -336,10 +336,17 @@ HISTOGRAM(DOM_TIMERS_FIRED_PER_NATIVE_TI
 
 DOMSTORAGE_KEY_VAL_SIZE(GLOBAL, "global")
 DOMSTORAGE_KEY_VAL_SIZE(LOCAL, "local")
 DOMSTORAGE_KEY_VAL_SIZE(SESSION, "session")
 
 #undef DOMSTORAGE_KEY_VAL_SIZE
 #undef DOMSTORAGE_HISTOGRAM
 
+/**
+ * Telemetry telemetry.
+ */
+HISTOGRAM(RANGE_CHECKSUM_ERRORS, 1, 3000, 10, EXPONENTIAL, "Number of histograms with range checksum errors")
+HISTOGRAM(BUCKET_ORDER_ERRORS, 1, 3000, 10, EXPONENTIAL, "Number of histograms with bucket order errors")
+HISTOGRAM(TOTAL_COUNT_HIGH_ERRORS, 1, 3000, 10, EXPONENTIAL, "Number of histograms with total count high errors")
+HISTOGRAM(TOTAL_COUNT_LOW_ERRORS, 1, 3000, 10, EXPONENTIAL, "Number of histograms with total count low errors")
 
 #undef HISTOGRAM_BOOLEAN
--- a/toolkit/profile/nsIProfileMigrator.idl
+++ b/toolkit/profile/nsIProfileMigrator.idl
@@ -68,28 +68,29 @@ interface nsIProfileStartup : nsISupport
  * @provider Application (Profile-migration code)
  * @client   Toolkit (Startup code)
  * @obtainable service, contractid("@mozilla.org/toolkit/profile-migrator;1")
  */
 [scriptable, uuid(24ce8b9d-b7ff-4279-aef4-26e158f03e34)]
 interface nsIProfileMigrator : nsISupports 
 {
   /**
-   * Do profile migration.
+   * Migrate data from an outside source, if possible.  Does nothing
+   * otherwise.
    *
    * When this method is called, a default profile has been created;
    * XPCOM has been initialized such that compreg.dat is in the
    * profile; the directory service does *not* return a key for
    * NS_APP_USER_PROFILE_50_DIR or any of the keys depending on an active
    * profile. To figure out the directory of the "current" profile, use
    * aStartup.directory.
    *
    * If your migrator needs to access services that use the profile (to
    * set profile prefs or bookmarks, for example), use aStartup.doStartup.
    *
-   * The startup code ignores COM exceptions thrown from this method.
+   * @note The startup code ignores COM exceptions thrown from this method.
    */
   void migrate(in nsIProfileStartup aStartup);
 };  
 
 %{C++
 #define NS_PROFILEMIGRATOR_CONTRACTID "@mozilla.org/toolkit/profile-migrator;1"
 %}
--- a/tools/profiler/nsProfiler.cpp
+++ b/tools/profiler/nsProfiler.cpp
@@ -119,17 +119,19 @@ nsProfiler::GetFeatures(PRUint32 *aCount
 
   const char **features = SAMPLER_GET_FEATURES();
   if (!features) {
     *aCount = 0;
     *aFeatures = nsnull;
     return NS_OK;
   }
 
-  while (features[++len]);
+  while (features[len]) {
+    len++;
+  }
 
   char **featureList = static_cast<char **>
                        (nsMemory::Alloc(len * sizeof(char*)));
 
   for (size_t i = 0; i < len; i++) {
     PRUint32 strLen = strlen(features[i]);
     featureList[i] = static_cast<char *>
                          (nsMemory::Clone(features[i], (strLen + 1) * sizeof(char)));
--- a/tools/profiler/sps/TableTicker.cpp
+++ b/tools/profiler/sps/TableTicker.cpp
@@ -240,16 +240,17 @@ class TableTicker: public Sampler {
               const char** aFeatures, uint32_t aFeatureCount)
     : Sampler(aInterval, true)
     , mProfile(aEntrySize)
     , mStack(aStack)
     , mSaveRequested(false)
   {
     mUseStackWalk = hasFeature(aFeatures, aFeatureCount, "stackwalk");
     mProfile.addTag(ProfileEntry('m', "Start"));
+    mJankOnly = hasFeature(aFeatures, aFeatureCount, "jank");
   }
 
   ~TableTicker() { if (IsActive()) Stop(); }
 
   virtual void SampleStack(TickSample* sample) {}
 
   // Called within a signal. This function must be reentrant
   virtual void Tick(TickSample* sample);
@@ -271,16 +272,17 @@ class TableTicker: public Sampler {
   {
     return &mProfile;
   }
  private:
   Profile mProfile;
   Stack *mStack;
   bool mSaveRequested;
   bool mUseStackWalk;
+  bool mJankOnly;
 };
 
 /**
  * This is an event used to save the profile on the main thread
  * to be sure that it is not being modified while saving.
  */
 class SaveProfileTask : public nsRunnable {
 public:
@@ -375,27 +377,41 @@ void TableTicker::Tick(TickSample* sampl
   int i = 0;
   const char *marker = mStack->getMarker(i++);
   for (int i = 0; marker != NULL; i++) {
     mProfile.addTag(ProfileEntry('m', marker));
     marker = mStack->getMarker(i++);
   }
   mStack->mQueueClearMarker = true;
 
-#ifdef USE_BACKTRACE
-  if (mUseStackWalk) {
-    doBacktrace(mProfile);
-  } else {
-    doSampleStackTrace(mStack, mProfile, sample);
+  bool recordSample = true;
+  if (mJankOnly) {
+    recordSample = false;
+    // only record the events when we have a we haven't seen a tracer event for 100ms
+    if (!sLastTracerEvent.IsNull()) {
+      TimeDuration delta = sample->timestamp - sLastTracerEvent;
+      if (delta.ToMilliseconds() > 100.0) {
+          recordSample = true;
+      }
+    }
   }
+
+  if (recordSample) {
+#ifdef USE_BACKTRACE
+    if (mUseStackWalk) {
+      doBacktrace(mProfile);
+    } else {
+      doSampleStackTrace(mStack, mProfile, sample);
+    }
 #else
-  doSampleStackTrace(mStack, mProfile, sample);
+    doSampleStackTrace(mStack, mProfile, sample);
 #endif
+  }
 
-  if (!sLastTracerEvent.IsNull() && sample) {
+  if (!mJankOnly && !sLastTracerEvent.IsNull() && sample) {
     TimeDuration delta = sample->timestamp - sLastTracerEvent;
     mProfile.addTag(ProfileEntry('r', delta.ToMilliseconds()));
   }
 }
 
 string ProfileEntry::TagToString(Profile *profile)
 {
   string tag = "";
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -178,21 +178,16 @@ PRLogModuleInfo* nsExternalHelperAppServ
 #define LOG(args) PR_LOG(mLog, 3, args)
 #define LOG_ENABLED() PR_LOG_TEST(mLog, 3)
 
 static const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF[] =
   "browser.helperApps.neverAsk.saveToDisk";
 static const char NEVER_ASK_FOR_OPEN_FILE_PREF[] =
   "browser.helperApps.neverAsk.openFile";
 
-/**
- * Contains a pointer to the helper app service, set in its constructor
- */
-nsExternalHelperAppService* gExtProtSvc;
-
 // Helper functions for Content-Disposition headers
 
 /**
  * Given a URI fragment, unescape it
  * @param aFragment The string to unescape
  * @param aURI The URI from which this fragment is taken. Only its character set
  *             will be used.
  * @param aResult [out] Unescaped string.
@@ -537,17 +532,16 @@ NS_IMPL_ISUPPORTS6(
   nsIExternalProtocolService,
   nsIMIMEService,
   nsIObserver,
   nsISupportsWeakReference)
 
 nsExternalHelperAppService::nsExternalHelperAppService() :
   mInPrivateBrowsing(false)
 {
-  gExtProtSvc = this;
 }
 nsresult nsExternalHelperAppService::Init()
 {
   nsCOMPtr<nsIPrivateBrowsingService> pbs =
     do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
   if (pbs) {
     pbs->GetPrivateBrowsingEnabled(&mInPrivateBrowsing);
   }
@@ -567,17 +561,16 @@ nsresult nsExternalHelperAppService::Ini
 
   nsresult rv = obs->AddObserver(this, "profile-before-change", true);
   NS_ENSURE_SUCCESS(rv, rv);
   return obs->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
 }
 
 nsExternalHelperAppService::~nsExternalHelperAppService()
 {
-  gExtProtSvc = nsnull;
 }
 
 static PRInt64 GetContentLengthAsInt64(nsIRequest *request)
 {
   PRInt64 contentLength = -1;
   nsresult rv;
   nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(request, &rv));
   if (props)
@@ -642,17 +635,18 @@ NS_IMETHODIMP nsExternalHelperAppService
                                                   disp,
                                                   aForceSave, contentLength,
                                                   IPC::URI(referrer));
     ExternalHelperAppChild *childListener = static_cast<ExternalHelperAppChild *>(pc);
 
     NS_ADDREF(*aStreamListener = childListener);
 
     nsRefPtr<nsExternalAppHandler> handler =
-      new nsExternalAppHandler(nsnull, EmptyCString(), aWindowContext, fileName,
+      new nsExternalAppHandler(nsnull, EmptyCString(), aWindowContext, this,
+                               fileName,
                                reason, aForceSave);
     if (!handler)
       return NS_ERROR_OUT_OF_MEMORY;
     
     childListener->SetHandler(handler);
 
     return NS_OK;
   }
@@ -755,16 +749,17 @@ NS_IMETHODIMP nsExternalHelperAppService
   // We want the mimeInfo's primary extension to pass it to
   // nsExternalAppHandler
   nsCAutoString buf;
   mimeInfo->GetPrimaryExtension(buf);
 
   nsExternalAppHandler * handler = new nsExternalAppHandler(mimeInfo,
                                                             buf,
                                                             aWindowContext,
+                                                            this,
                                                             fileName,
                                                             reason,
                                                             aForceSave);
   if (!handler)
     return NS_ERROR_OUT_OF_MEMORY;
   NS_ADDREF(*aStreamListener = handler);
   
   return NS_OK;
@@ -1115,16 +1110,17 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHand
    NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher)   
    NS_INTERFACE_MAP_ENTRY(nsICancelable)
    NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
                                            const nsCSubstring& aTempFileExtension,
                                            nsIInterfaceRequestor* aWindowContext,
+                                           nsExternalHelperAppService *aExtProtSvc,
                                            const nsAString& aSuggestedFilename,
                                            PRUint32 aReason, bool aForceSave)
 : mMimeInfo(aMIMEInfo)
 , mWindowContext(aWindowContext)
 , mWindowToClose(nsnull)
 , mSuggestedFileName(aSuggestedFilename)
 , mForceSave(aForceSave)
 , mCanceled(false)
@@ -1133,16 +1129,17 @@ nsExternalAppHandler::nsExternalAppHandl
 , mStopRequestIssued(false)
 , mProgressListenerInitialized(false)
 , mReason(aReason)
 , mContentLength(-1)
 , mProgress(0)
 , mDataBuffer(nsnull)
 , mKeepRequestAlive(false)
 , mRequest(nsnull)
+, mExtProtSvc(aExtProtSvc)
 {
 
   // make sure the extention includes the '.'
   if (!aTempFileExtension.IsEmpty() && aTempFileExtension.First() != '.')
     mTempFileExtension = PRUnichar('.');
   AppendUTF8toUTF16(aTempFileExtension, mTempFileExtension);
 
   // replace platform specific path separator and illegal characters to avoid any confusion
@@ -1160,29 +1157,24 @@ nsExternalAppHandler::nsExternalAppHandl
   for (PRUint32 i = 0; i < ArrayLength(unsafeBidiCharacters); ++i) {
     mSuggestedFileName.ReplaceChar(unsafeBidiCharacters[i], '_');
     mTempFileExtension.ReplaceChar(unsafeBidiCharacters[i], '_');
   }
   
   // Make sure extension is correct.
   EnsureSuggestedFileName();
 
-  gExtProtSvc->AddRef();
-
   mBufferSize = Preferences::GetUint("network.buffer.cache.size", 4096);
   mDataBuffer = (char*) malloc(mBufferSize);
   if (!mDataBuffer)
     return;
 }
 
 nsExternalAppHandler::~nsExternalAppHandler()
 {
-  // Not using NS_RELEASE, since we don't want to set gExtProtSvc to NULL
-  gExtProtSvc->Release();
-
   if (mDataBuffer)
     free(mDataBuffer);
 }
 
 NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener2 * aWebProgressListener)
 { 
   // this call back means we've successfully brought up the 
   // progress window so set the appropriate flag, even though
@@ -1508,18 +1500,17 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
           bool hasMore;
           rv = encEnum->HasMore(&hasMore);
           if (NS_SUCCEEDED(rv) && hasMore)
           {
             nsCAutoString encType;
             rv = encEnum->GetNext(encType);
             if (NS_SUCCEEDED(rv) && !encType.IsEmpty())
             {
-              NS_ASSERTION(gExtProtSvc, "Where did the service go?");
-              gExtProtSvc->ApplyDecodingForExtension(extension, encType,
+              mExtProtSvc->ApplyDecodingForExtension(extension, encType,
                                                      &applyConversion);
             }
           }
         }
       }    
     }
 
     encChannel->SetApplyConversion( applyConversion );
@@ -1565,17 +1556,16 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
   mMimeInfo->GetAlwaysAskBeforeHandling(&alwaysAsk);
   if (alwaysAsk)
   {
     // But we *don't* ask if this mimeInfo didn't come from
     // our user configuration datastore and the user has said
     // at some point in the distant past that they don't
     // want to be asked.  The latter fact would have been
     // stored in pref strings back in the old days.
-    NS_ASSERTION(gExtProtSvc, "Service gone away!?");
 
     bool mimeTypeIsInDatastore = false;
     nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
     if (handlerSvc)
       handlerSvc->Exists(mMimeInfo, &mimeTypeIsInDatastore);
     if (!handlerSvc || !mimeTypeIsInDatastore)
     {
       nsCAutoString MIMEType;
@@ -1910,17 +1900,17 @@ nsresult nsExternalAppHandler::ExecuteDe
       if (action == nsIMIMEInfo::useHelperApp ||
           action == nsIMIMEInfo::useSystemDefault)
       {
         rv = OpenWithApplication();
       }
       else if(action == nsIMIMEInfo::saveToDisk)
       {
         nsCOMPtr<nsILocalFile> destfile(do_QueryInterface(mFinalFileDestination));
-        gExtProtSvc->FixFilePermissions(destfile);
+        mExtProtSvc->FixFilePermissions(destfile);
       }
     }
 
     // Notify dialog that download is complete.
     // By waiting till this point, it ensures that the progress dialog doesn't indicate
     // success until we're really done.
     if(mWebProgressListener)
     {
@@ -2224,33 +2214,32 @@ nsresult nsExternalAppHandler::OpenWithA
 #if !defined(XP_MACOSX)
                            true);
 #else
                            false);
 #endif
 
     // make the tmp file readonly so users won't edit it and lose the changes
     // only if we're going to delete the file
-    if (deleteTempFileOnExit || gExtProtSvc->InPrivateBrowsing())
+    if (deleteTempFileOnExit || mExtProtSvc->InPrivateBrowsing())
       mFinalFileDestination->SetPermissions(0400);
 
     rv = mMimeInfo->LaunchWithFile(mFinalFileDestination);
     if (NS_FAILED(rv))
     {
       // Send error notification.
       nsAutoString path;
       mFinalFileDestination->GetPath(path);
       SendStatusChange(kLaunchError, rv, nsnull, path);
       Cancel(rv); // Cancel, and clean up temp file.
     }
     // Always schedule files to be deleted at the end of the private browsing
     // mode, regardless of the value of the pref.
-    else if (deleteTempFileOnExit || gExtProtSvc->InPrivateBrowsing()) {
-      NS_ASSERTION(gExtProtSvc, "Service gone away!?");
-      gExtProtSvc->DeleteTemporaryFileOnExit(mFinalFileDestination);
+    else if (deleteTempFileOnExit || mExtProtSvc->InPrivateBrowsing()) {
+      mExtProtSvc->DeleteTemporaryFileOnExit(mFinalFileDestination);
     }
   }
 
   return rv;
 }
 
 // LaunchWithApplication should only be called by the helper app dialog which allows
 // the user to say launch with application or save to disk. It doesn't actually 
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -68,16 +68,17 @@
 #include "nsITimer.h"
 
 #include "nsIHandlerService.h"
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
 #include "nsCOMArray.h"
 #include "nsWeakReference.h"
 #include "nsIPrompt.h"
+#include "nsAutoPtr.h"
 
 class nsExternalAppHandler;
 class nsIMIMEInfo;
 class nsITransfer;
 class nsIDOMWindow;
 
 /**
  * The helper app service. Responsible for handling content that Mozilla
@@ -255,22 +256,24 @@ public:
   NS_DECL_NSITIMERCALLBACK
 
   /**
    * @param aMIMEInfo      MIMEInfo object, representing the type of the
    *                       content that should be handled
    * @param aFileExtension The extension we need to append to our temp file,
    *                       INCLUDING the ".". e.g. .mp3
    * @param aWindowContext Window context, as passed to DoContent
+   * @param mExtProtSvc    nsExternalHelperAppService on creation
    * @param aFileName      The filename to use
    * @param aReason        A constant from nsIHelperAppLauncherDialog indicating
    *                       why the request is handled by a helper app.
    */
   nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, const nsCSubstring& aFileExtension,
                        nsIInterfaceRequestor * aWindowContext,
+                       nsExternalHelperAppService * aExtProtSvc,
                        const nsAString& aFilename,
                        PRUint32 aReason, bool aForceSave);
 
   ~nsExternalAppHandler();
 
 protected:
   nsCOMPtr<nsIFile> mTempFile;
   nsCOMPtr<nsIURI> mSourceUrl;
@@ -442,13 +445,13 @@ protected:
   bool mKeepRequestAlive;
 
   /**
    * The request that's being loaded. Initialized in OnStartRequest.
    * Nulled out in OnStopRequest or once we know what we're doing
    * with the data, whichever happens later.
    */
   nsCOMPtr<nsIRequest> mRequest;
+
+  nsRefPtr<nsExternalHelperAppService> mExtProtSvc;
 };
 
-extern NS_HIDDEN_(nsExternalHelperAppService*) gExtProtSvc;
-
 #endif // nsExternalHelperAppService_h__
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -371,18 +371,19 @@ nsExternalProtocolHandler::AllowPort(PRI
 // returns TRUE if the OS can handle this protocol scheme and false otherwise.
 bool nsExternalProtocolHandler::HaveExternalProtocolHandler(nsIURI * aURI)
 {
   bool haveHandler = false;
   if (aURI)
   {
     nsCAutoString scheme;
     aURI->GetScheme(scheme);
-    if (gExtProtSvc)
-      gExtProtSvc->ExternalProtocolHandlerExists(scheme.get(), &haveHandler);
+    nsCOMPtr<nsIExternalProtocolService> extProtSvc(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
+    if (extProtSvc)
+      extProtSvc->ExternalProtocolHandlerExists(scheme.get(), &haveHandler);
   }
 
   return haveHandler;
 }
 
 NS_IMETHODIMP nsExternalProtocolHandler::GetProtocolFlags(PRUint32 *aUritype)
 {
     // Make it norelative since it is a simple uri
@@ -433,16 +434,17 @@ NS_IMETHODIMP nsExternalProtocolHandler:
   return NS_ERROR_UNKNOWN_PROTOCOL;
 }
 
 ///////////////////////////////////////////////////////////////////////
 // External protocol handler interface implementation
 //////////////////////////////////////////////////////////////////////
 NS_IMETHODIMP nsExternalProtocolHandler::ExternalAppExistsForScheme(const nsACString& aScheme, bool *_retval)
 {
-  if (gExtProtSvc)
-    return gExtProtSvc->ExternalProtocolHandlerExists(
+  nsCOMPtr<nsIExternalProtocolService> extProtSvc(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
+  if (extProtSvc)
+    return extProtSvc->ExternalProtocolHandlerExists(
       PromiseFlatCString(aScheme).get(), _retval);
 
   // In case we don't have external protocol service.
   *_retval = false;
   return NS_OK;
 }
--- a/uriloader/exthandler/nsExternalProtocolHandler.h
+++ b/uriloader/exthandler/nsExternalProtocolHandler.h
@@ -59,13 +59,12 @@ public:
 
 	nsExternalProtocolHandler();
 	~nsExternalProtocolHandler();
 
 protected:
   // helper function
   bool HaveExternalProtocolHandler(nsIURI * aURI);
 	nsCString	m_schemeName;
-  nsCOMPtr<nsIExternalProtocolService> m_extProtService;
 };
 
 #endif // nsExternalProtocolHandler_h___
 
--- a/xpcom/build/Services.cpp
+++ b/xpcom/build/Services.cpp
@@ -59,25 +59,30 @@ using namespace mozilla::services;
 
 /*
  * Define a global variable and a getter for every service in ServiceList.
  * eg. gIOService and GetIOService()
  */
 #define MOZ_SERVICE(NAME, TYPE, CONTRACT_ID)                            \
   static TYPE* g##NAME = nsnull;                                        \
                                                                         \
-  already_AddRefed<TYPE>                                         \
+  already_AddRefed<TYPE>                                                \
   mozilla::services::Get##NAME()                                        \
   {                                                                     \
     if (!g##NAME) {                                                     \
       nsCOMPtr<TYPE> os = do_GetService(CONTRACT_ID);                   \
       g##NAME = os.forget().get();                                      \
     }                                                                   \
     NS_IF_ADDREF(g##NAME);                                              \
     return g##NAME;                                                     \
+  }                                                                     \
+  NS_EXPORT_(already_AddRefed<TYPE>)                                    \
+  mozilla::services::_external_Get##NAME()                              \
+  {                                                                     \
+    return Get##NAME();                                                 \
   }
 
 #include "ServiceList.h"
 #undef MOZ_SERVICE
 
 /**
  * Clears service cache, sets gXPCOMShuttingDown
  */
--- a/xpcom/build/Services.h
+++ b/xpcom/build/Services.h
@@ -47,16 +47,31 @@
 
 #include "ServiceList.h"
 #undef MOZ_SERVICE
 #undef MOZ_USE_NAMESPACE
 
 namespace mozilla {
 namespace services {
 
-#define MOZ_SERVICE(NAME, TYPE, SERVICE_CID) already_AddRefed<TYPE> Get##NAME();
+#ifdef MOZILLA_INTERNAL_API
+#define MOZ_SERVICE(NAME, TYPE, SERVICE_CID)                        \
+    already_AddRefed<TYPE> Get##NAME();                             \
+    NS_EXPORT_(already_AddRefed<TYPE>) _external_Get##NAME();
+
 #include "ServiceList.h"
 #undef MOZ_SERVICE
+#else
+#define MOZ_SERVICE(NAME, TYPE, SERVICE_CID)                        \
+    NS_IMPORT_(already_AddRefed<TYPE>) _external_Get##NAME();       \
+    inline already_AddRefed<TYPE> Get##NAME()                       \
+    {                                                               \
+        return _external_Get##NAME();                               \
+    }
+
+#include "ServiceList.h"
+#undef MOZ_SERVICE
+#endif
 
 } // namespace services
 } // namespace mozilla
 
 #endif
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -712,18 +712,16 @@ ShutdownXPCOM(nsIServiceManager* servMgr
     if (nsComponentManagerImpl::gComponentManager) {
       nsrefcnt cnt;
       NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
       NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
     }
     nsComponentManagerImpl::gComponentManager = nsnull;
     nsCategoryManager::Destroy();
 
-    ShutdownSpecialSystemDirectory();
-
     NS_PurgeAtomTable();
 
     NS_IF_RELEASE(gDebug);
 
     if (sIOThread) {
         delete sIOThread;
         sIOThread = nsnull;
     }
--- a/xpcom/io/SpecialSystemDirectory.cpp
+++ b/xpcom/io/SpecialSystemDirectory.cpp
@@ -96,42 +96,28 @@
 
 #ifdef XP_WIN
 typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
                                                DWORD dwFlags,
                                                HANDLE hToken,
                                                PWSTR *ppszPath);
 
 static nsGetKnownFolderPath gGetKnownFolderPath = NULL;
-
-static HINSTANCE gShell32DLLInst = NULL;
 #endif
 
 void StartupSpecialSystemDirectory()
 {
 #if defined (XP_WIN)
     // SHGetKnownFolderPath is only available on Windows Vista
     // so that we need to use GetProcAddress to get the pointer.
-    gShell32DLLInst = LoadLibraryW(L"shell32.dll");
-    if(gShell32DLLInst)
+    HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
+    if(hShell32DLLInst)
     {
         gGetKnownFolderPath = (nsGetKnownFolderPath)
-            GetProcAddress(gShell32DLLInst, "SHGetKnownFolderPath");
-    }
-#endif
-}
-
-void ShutdownSpecialSystemDirectory()
-{
-#if defined (XP_WIN)
-    if (gShell32DLLInst)
-    {
-        FreeLibrary(gShell32DLLInst);
-        gShell32DLLInst = NULL;
-        gGetKnownFolderPath = NULL;
+            GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
     }
 #endif
 }
 
 #if defined (XP_WIN)
 
 static nsresult GetKnownFolder(GUID* guid, nsILocalFile** aFile)
 {
--- a/xpcom/io/SpecialSystemDirectory.h
+++ b/xpcom/io/SpecialSystemDirectory.h
@@ -46,17 +46,16 @@
 
 #ifdef MOZ_WIDGET_COCOA
 #include <Carbon/Carbon.h>
 #include "nsILocalFileMac.h"
 #include "prenv.h"
 #endif
 
 extern void StartupSpecialSystemDirectory();
-extern void ShutdownSpecialSystemDirectory();
 
 
 enum SystemDirectories {
   OS_DriveDirectory         =   1,   
   OS_TemporaryDirectory     =   2,   
   OS_CurrentProcessDirectory=   3,   
   OS_CurrentWorkingDirectory=   4,
   XPCOM_CurrentProcessComponentDirectory=   5,   
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -103,17 +103,16 @@ unsigned char *_mbsstr( const unsigned c
 #endif
 
 #ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
 #endif
 
 ILCreateFromPathWPtr nsLocalFile::sILCreateFromPathW = NULL;
 SHOpenFolderAndSelectItemsPtr nsLocalFile::sSHOpenFolderAndSelectItems = NULL;
-PRLibrary *nsLocalFile::sLibShell = NULL;
 
 class nsDriveEnumerator : public nsISimpleEnumerator
 {
 public:
     nsDriveEnumerator();
     virtual ~nsDriveEnumerator();
     NS_DECL_ISUPPORTS
     NS_DECL_NSISIMPLEENUMERATOR
@@ -2768,17 +2767,17 @@ nsLocalFile::RevealClassic()
   return NS_OK;
 }
 
 nsresult 
 nsLocalFile::RevealUsingShell()
 {
   // All of these shell32.dll related pointers should be non NULL 
   // on XP and later.
-  if (!sLibShell || !sILCreateFromPathW || !sSHOpenFolderAndSelectItems) {
+  if (!sILCreateFromPathW || !sSHOpenFolderAndSelectItems) {
     return NS_ERROR_FAILURE;
   }
 
   bool isDirectory;
   nsresult rv = IsDirectory(&isDirectory);
   NS_ENSURE_SUCCESS(rv, rv);
 
   HRESULT hr;
@@ -3129,36 +3128,33 @@ nsLocalFile::GetHashCode(PRUint32 *aResu
 void
 nsLocalFile::GlobalInit()
 {
     nsresult rv = NS_CreateShortcutResolver();
     NS_ASSERTION(NS_SUCCEEDED(rv), "Shortcut resolver could not be created");
 
     // shell32.dll should be loaded already, so we are not actually 
     // loading the library here.
-    sLibShell = PR_LoadLibrary("shell32.dll");
-    if (sLibShell) {
+    HMODULE hLibShell = GetModuleHandleW(L"shell32.dll");
+    if (hLibShell) {
       // ILCreateFromPathW is available in XP and up.
       sILCreateFromPathW = (ILCreateFromPathWPtr) 
-                           PR_FindFunctionSymbol(sLibShell, 
-                                                 "ILCreateFromPathW");
+                            GetProcAddress(hLibShell, 
+                                           "ILCreateFromPathW");
 
       // SHOpenFolderAndSelectItems is available in XP and up.
       sSHOpenFolderAndSelectItems = (SHOpenFolderAndSelectItemsPtr) 
-                                     PR_FindFunctionSymbol(sLibShell, 
-                                                           "SHOpenFolderAndSelectItems");
+                                     GetProcAddress(hLibShell, 
+                                                    "SHOpenFolderAndSelectItems");
     }
 }
 
 void
 nsLocalFile::GlobalShutdown()
 {
-    if (sLibShell) {
-      PR_UnloadLibrary(sLibShell);
-    }
     NS_DestroyShortcutResolver();
 }
 
 NS_IMPL_ISUPPORTS1(nsDriveEnumerator, nsISimpleEnumerator)
 
 nsDriveEnumerator::nsDriveEnumerator()
 {
 }
--- a/xpcom/io/nsLocalFileWin.h
+++ b/xpcom/io/nsLocalFileWin.h
@@ -128,12 +128,11 @@ private:
     nsresult HasFileAttribute(DWORD fileAttrib, bool *_retval);
     nsresult AppendInternal(const nsAFlatString &node,
                             bool multipleComponents);
     nsresult RevealClassic(); // Reveals the path using explorer.exe cmdline
     nsresult RevealUsingShell(); // Uses newer shell API to reveal the path
 
     static ILCreateFromPathWPtr sILCreateFromPathW;
     static SHOpenFolderAndSelectItemsPtr sSHOpenFolderAndSelectItems;
-    static PRLibrary *sLibShell;
 };
 
 #endif