author | Justin 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 id | 21865 |
push user | Callek@gmail.com |
push date | Tue, 17 Jan 2012 03:28:17 +0000 |
treeherder | mozilla-central@34572943a3e4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 12.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
12.0a1
/
20120117031056
/
pushlog to previous
nightly linux64
12.0a1
/
20120117031056
/
pushlog to previous
nightly mac
12.0a1
/
20120117031056
/
pushlog to previous
nightly win32
12.0a1
/
20120117031056
/
pushlog to previous
nightly win64
12.0a1
/
20120117031056
/
pushlog to previous
|
browser/components/migration/src/nsProfileMigrator.cpp | file | annotate | diff | comparison | revisions | |
browser/components/migration/src/nsProfileMigrator.h | file | annotate | diff | comparison | revisions |
--- 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