xpcom/build/nsXPComInit.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/build/nsXPComInit.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1059 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* vim:set ts=4 sw=4 sts=4 ci et: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "base/basictypes.h"
    1.11 +
    1.12 +#include "mozilla/Atomics.h"
    1.13 +#include "mozilla/Poison.h"
    1.14 +#include "mozilla/Preferences.h"
    1.15 +#include "mozilla/XPCOM.h"
    1.16 +#include "nsXULAppAPI.h"
    1.17 +
    1.18 +#include "nsXPCOMPrivate.h"
    1.19 +#include "nsXPCOMCIDInternal.h"
    1.20 +
    1.21 +#include "mozilla/layers/ImageBridgeChild.h"
    1.22 +#include "mozilla/layers/CompositorParent.h"
    1.23 +
    1.24 +#include "prlink.h"
    1.25 +
    1.26 +#include "nsCycleCollector.h"
    1.27 +#include "nsObserverList.h"
    1.28 +#include "nsObserverService.h"
    1.29 +#include "nsProperties.h"
    1.30 +#include "nsPersistentProperties.h"
    1.31 +#include "nsScriptableInputStream.h"
    1.32 +#include "nsBinaryStream.h"
    1.33 +#include "nsStorageStream.h"
    1.34 +#include "nsPipe.h"
    1.35 +#include "nsScriptableBase64Encoder.h"
    1.36 +
    1.37 +#include "nsMemoryImpl.h"
    1.38 +#include "nsDebugImpl.h"
    1.39 +#include "nsTraceRefcnt.h"
    1.40 +#include "nsErrorService.h"
    1.41 +
    1.42 +#include "nsSupportsArray.h"
    1.43 +#include "nsArray.h"
    1.44 +#include "nsINIParserImpl.h"
    1.45 +#include "nsSupportsPrimitives.h"
    1.46 +#include "nsConsoleService.h"
    1.47 +
    1.48 +#include "nsIJSRuntimeService.h"
    1.49 +
    1.50 +#include "nsComponentManager.h"
    1.51 +#include "nsCategoryManagerUtils.h"
    1.52 +#include "nsIServiceManager.h"
    1.53 +
    1.54 +#include "nsThreadManager.h"
    1.55 +#include "nsThreadPool.h"
    1.56 +
    1.57 +#include "xptinfo.h"
    1.58 +#include "nsIInterfaceInfoManager.h"
    1.59 +#include "xptiprivate.h"
    1.60 +#include "mozilla/XPTInterfaceInfoManager.h"
    1.61 +
    1.62 +#include "nsTimerImpl.h"
    1.63 +#include "TimerThread.h"
    1.64 +
    1.65 +#include "nsThread.h"
    1.66 +#include "nsProcess.h"
    1.67 +#include "nsEnvironment.h"
    1.68 +#include "nsVersionComparatorImpl.h"
    1.69 +
    1.70 +#include "nsIFile.h"
    1.71 +#include "nsLocalFile.h"
    1.72 +#if defined(XP_UNIX)
    1.73 +#include "nsNativeCharsetUtils.h"
    1.74 +#endif
    1.75 +#include "nsDirectoryService.h"
    1.76 +#include "nsDirectoryServiceDefs.h"
    1.77 +#include "nsCategoryManager.h"
    1.78 +#include "nsICategoryManager.h"
    1.79 +#include "nsMultiplexInputStream.h"
    1.80 +
    1.81 +#include "nsStringStream.h"
    1.82 +extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
    1.83 +
    1.84 +#include "nsAtomService.h"
    1.85 +#include "nsAtomTable.h"
    1.86 +#include "nsISupportsImpl.h"
    1.87 +
    1.88 +#include "nsHashPropertyBag.h"
    1.89 +
    1.90 +#include "nsUnicharInputStream.h"
    1.91 +#include "nsVariant.h"
    1.92 +
    1.93 +#include "nsUUIDGenerator.h"
    1.94 +
    1.95 +#include "nsIOUtil.h"
    1.96 +
    1.97 +#include "SpecialSystemDirectory.h"
    1.98 +
    1.99 +#if defined(XP_WIN)
   1.100 +#include "nsWindowsRegKey.h"
   1.101 +#endif
   1.102 +
   1.103 +#ifdef MOZ_WIDGET_COCOA
   1.104 +#include "nsMacUtilsImpl.h"
   1.105 +#endif
   1.106 +
   1.107 +#include "nsSystemInfo.h"
   1.108 +#include "nsMemoryReporterManager.h"
   1.109 +#include "nsMemoryInfoDumper.h"
   1.110 +#include "nsSecurityConsoleMessage.h"
   1.111 +#include "nsMessageLoop.h"
   1.112 +
   1.113 +#include "nsStatusReporterManager.h"
   1.114 +
   1.115 +#include <locale.h>
   1.116 +#include "mozilla/Services.h"
   1.117 +#include "mozilla/Omnijar.h"
   1.118 +#include "mozilla/HangMonitor.h"
   1.119 +#include "mozilla/Telemetry.h"
   1.120 +#include "mozilla/BackgroundHangMonitor.h"
   1.121 +
   1.122 +#include "nsChromeRegistry.h"
   1.123 +#include "nsChromeProtocolHandler.h"
   1.124 +#include "mozilla/PoisonIOInterposer.h"
   1.125 +#include "mozilla/LateWriteChecks.h"
   1.126 +
   1.127 +#include "mozilla/scache/StartupCache.h"
   1.128 +
   1.129 +#include "base/at_exit.h"
   1.130 +#include "base/command_line.h"
   1.131 +#include "base/message_loop.h"
   1.132 +
   1.133 +#include "mozilla/ipc/BrowserProcessSubThread.h"
   1.134 +#include "mozilla/AvailableMemoryTracker.h"
   1.135 +#include "mozilla/ClearOnShutdown.h"
   1.136 +#include "mozilla/SystemMemoryReporter.h"
   1.137 +
   1.138 +#ifdef MOZ_VISUAL_EVENT_TRACER
   1.139 +#include "mozilla/VisualEventTracer.h"
   1.140 +#endif
   1.141 +
   1.142 +#include "ogg/ogg.h"
   1.143 +#if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
   1.144 +#include "vpx_mem/vpx_mem.h"
   1.145 +#endif
   1.146 +#ifdef MOZ_WEBM
   1.147 +#include "nestegg/nestegg.h"
   1.148 +#endif
   1.149 +
   1.150 +#include "GeckoProfiler.h"
   1.151 +
   1.152 +#include "jsapi.h"
   1.153 +
   1.154 +using namespace mozilla;
   1.155 +using base::AtExitManager;
   1.156 +using mozilla::ipc::BrowserProcessSubThread;
   1.157 +#ifdef MOZ_VISUAL_EVENT_TRACER
   1.158 +using mozilla::eventtracer::VisualEventTracer;
   1.159 +#endif
   1.160 +
   1.161 +namespace {
   1.162 +
   1.163 +static AtExitManager* sExitManager;
   1.164 +static MessageLoop* sMessageLoop;
   1.165 +static bool sCommandLineWasInitialized;
   1.166 +static BrowserProcessSubThread* sIOThread;
   1.167 +static BackgroundHangMonitor* sMainHangMonitor;
   1.168 +
   1.169 +} /* anonymous namespace */
   1.170 +
   1.171 +// Registry Factory creation function defined in nsRegistry.cpp
   1.172 +// We hook into this function locally to create and register the registry
   1.173 +// Since noone outside xpcom needs to know about this and nsRegistry.cpp
   1.174 +// does not have a local include file, we are putting this definition
   1.175 +// here rather than in nsIRegistry.h
   1.176 +extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
   1.177 +extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
   1.178 +
   1.179 +#ifdef XP_WIN
   1.180 +extern nsresult CreateAnonTempFileRemover();
   1.181 +#endif
   1.182 +
   1.183 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
   1.184 +
   1.185 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
   1.186 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
   1.187 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
   1.188 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
   1.189 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
   1.190 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
   1.191 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
   1.192 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
   1.193 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
   1.194 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
   1.195 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
   1.196 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
   1.197 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
   1.198 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
   1.199 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
   1.200 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
   1.201 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
   1.202 +
   1.203 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
   1.204 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
   1.205 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
   1.206 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
   1.207 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
   1.208 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
   1.209 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
   1.210 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
   1.211 +#ifdef MOZ_VISUAL_EVENT_TRACER
   1.212 +NS_GENERIC_FACTORY_CONSTRUCTOR(VisualEventTracer)
   1.213 +#endif
   1.214 +
   1.215 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
   1.216 +
   1.217 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBag)
   1.218 +
   1.219 +NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsProperties)
   1.220 +
   1.221 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
   1.222 +
   1.223 +#ifdef MOZ_WIDGET_COCOA
   1.224 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
   1.225 +#endif
   1.226 +
   1.227 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
   1.228 +
   1.229 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemoryReporterManager, Init)
   1.230 +
   1.231 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryInfoDumper)
   1.232 +
   1.233 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStatusReporterManager, Init)
   1.234 +
   1.235 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
   1.236 +
   1.237 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecurityConsoleMessage)
   1.238 +
   1.239 +static nsresult
   1.240 +nsThreadManagerGetSingleton(nsISupports* outer,
   1.241 +                            const nsIID& aIID,
   1.242 +                            void* *aInstancePtr)
   1.243 +{
   1.244 +    NS_ASSERTION(aInstancePtr, "null outptr");
   1.245 +    if (NS_WARN_IF(outer))
   1.246 +        return NS_ERROR_NO_AGGREGATION;
   1.247 +
   1.248 +    return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
   1.249 +}
   1.250 +
   1.251 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
   1.252 +
   1.253 +static nsresult
   1.254 +nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
   1.255 +                                       const nsIID& aIID,
   1.256 +                                       void* *aInstancePtr)
   1.257 +{
   1.258 +    NS_ASSERTION(aInstancePtr, "null outptr");
   1.259 +    if (NS_WARN_IF(outer))
   1.260 +        return NS_ERROR_NO_AGGREGATION;
   1.261 +
   1.262 +    nsCOMPtr<nsIInterfaceInfoManager> iim
   1.263 +        (XPTInterfaceInfoManager::GetSingleton());
   1.264 +    if (!iim)
   1.265 +        return NS_ERROR_FAILURE;
   1.266 +
   1.267 +    return iim->QueryInterface(aIID, aInstancePtr);
   1.268 +}
   1.269 +
   1.270 +nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
   1.271 +bool gXPCOMShuttingDown = false;
   1.272 +bool gXPCOMThreadsShutDown = false;
   1.273 +
   1.274 +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
   1.275 +static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
   1.276 +static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
   1.277 +
   1.278 +NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
   1.279 +NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
   1.280 +
   1.281 +NS_DEFINE_NAMED_CID(NS_SECURITY_CONSOLE_MESSAGE_CID);
   1.282 +
   1.283 +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
   1.284 +                                         nsChromeRegistry::GetSingleton)
   1.285 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
   1.286 +
   1.287 +#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
   1.288 +
   1.289 +static already_AddRefed<nsIFactory>
   1.290 +CreateINIParserFactory(const mozilla::Module& module,
   1.291 +                       const mozilla::Module::CIDEntry& entry)
   1.292 +{
   1.293 +    nsCOMPtr<nsIFactory> f = new nsINIParserFactory();
   1.294 +    return f.forget();
   1.295 +}
   1.296 +
   1.297 +static already_AddRefed<nsIFactory>
   1.298 +CreateUnicharStreamFactory(const mozilla::Module& module,
   1.299 +                           const mozilla::Module::CIDEntry& entry)
   1.300 +{
   1.301 +    return already_AddRefed<nsIFactory>(
   1.302 +            nsSimpleUnicharStreamFactory::GetInstance());
   1.303 +}
   1.304 +
   1.305 +#define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
   1.306 +#include "XPCOMModule.inc"
   1.307 +#undef COMPONENT
   1.308 +
   1.309 +#define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, nullptr, Ctor },
   1.310 +const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
   1.311 +    { &kComponentManagerCID, true, nullptr, nsComponentManagerImpl::Create },
   1.312 +    { &kINIParserFactoryCID, false, CreateINIParserFactory },
   1.313 +    { &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
   1.314 +#include "XPCOMModule.inc"
   1.315 +    { &kNS_CHROMEREGISTRY_CID, false, nullptr, nsChromeRegistryConstructor },
   1.316 +    { &kNS_CHROMEPROTOCOLHANDLER_CID, false, nullptr, nsChromeProtocolHandlerConstructor },
   1.317 +    { &kNS_SECURITY_CONSOLE_MESSAGE_CID, false, nullptr, nsSecurityConsoleMessageConstructor },
   1.318 +    { nullptr }
   1.319 +};
   1.320 +#undef COMPONENT
   1.321 +
   1.322 +#define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
   1.323 +const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
   1.324 +#include "XPCOMModule.inc"
   1.325 +    { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
   1.326 +    { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
   1.327 +    { NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
   1.328 +    { NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID, &kNS_SECURITY_CONSOLE_MESSAGE_CID },
   1.329 +    { nullptr }
   1.330 +};
   1.331 +#undef COMPONENT
   1.332 +
   1.333 +const mozilla::Module kXPCOMModule = { mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts };
   1.334 +
   1.335 +// gDebug will be freed during shutdown.
   1.336 +static nsIDebug* gDebug = nullptr;
   1.337 +
   1.338 +EXPORT_XPCOM_API(nsresult)
   1.339 +NS_GetDebug(nsIDebug** result)
   1.340 +{
   1.341 +    return nsDebugImpl::Create(nullptr,
   1.342 +                               NS_GET_IID(nsIDebug),
   1.343 +                               (void**) result);
   1.344 +}
   1.345 +
   1.346 +EXPORT_XPCOM_API(nsresult)
   1.347 +NS_InitXPCOM(nsIServiceManager* *result,
   1.348 +                             nsIFile* binDirectory)
   1.349 +{
   1.350 +    return NS_InitXPCOM2(result, binDirectory, nullptr);
   1.351 +}
   1.352 +
   1.353 +class ICUReporter MOZ_FINAL : public nsIMemoryReporter,
   1.354 +                              public CountingAllocatorBase<ICUReporter>
   1.355 +{
   1.356 +public:
   1.357 +    NS_DECL_ISUPPORTS
   1.358 +
   1.359 +    static void* Alloc(const void*, size_t size)
   1.360 +    {
   1.361 +        return CountingMalloc(size);
   1.362 +    }
   1.363 +
   1.364 +    static void* Realloc(const void*, void* p, size_t size)
   1.365 +    {
   1.366 +        return CountingRealloc(p, size);
   1.367 +    }
   1.368 +
   1.369 +    static void Free(const void*, void* p)
   1.370 +    {
   1.371 +        return CountingFree(p);
   1.372 +    }
   1.373 +
   1.374 +private:
   1.375 +    NS_IMETHODIMP
   1.376 +    CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   1.377 +    {
   1.378 +        return MOZ_COLLECT_REPORT(
   1.379 +            "explicit/icu", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   1.380 +            "Memory used by ICU, a Unicode and globalization support library.");
   1.381 +    }
   1.382 +};
   1.383 +
   1.384 +NS_IMPL_ISUPPORTS(ICUReporter, nsIMemoryReporter)
   1.385 +
   1.386 +/* static */ template<> Atomic<size_t> CountingAllocatorBase<ICUReporter>::sAmount(0);
   1.387 +
   1.388 +class OggReporter MOZ_FINAL : public nsIMemoryReporter,
   1.389 +                              public CountingAllocatorBase<OggReporter>
   1.390 +{
   1.391 +public:
   1.392 +    NS_DECL_ISUPPORTS
   1.393 +
   1.394 +private:
   1.395 +    NS_IMETHODIMP
   1.396 +    CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   1.397 +    {
   1.398 +        return MOZ_COLLECT_REPORT(
   1.399 +            "explicit/media/libogg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   1.400 +            "Memory allocated through libogg for Ogg, Theora, and related media files.");
   1.401 +    }
   1.402 +};
   1.403 +
   1.404 +NS_IMPL_ISUPPORTS(OggReporter, nsIMemoryReporter)
   1.405 +
   1.406 +/* static */ template<> Atomic<size_t> CountingAllocatorBase<OggReporter>::sAmount(0);
   1.407 +
   1.408 +#ifdef MOZ_VPX
   1.409 +class VPXReporter MOZ_FINAL : public nsIMemoryReporter,
   1.410 +                              public CountingAllocatorBase<VPXReporter>
   1.411 +{
   1.412 +public:
   1.413 +    NS_DECL_ISUPPORTS
   1.414 +
   1.415 +private:
   1.416 +    NS_IMETHODIMP
   1.417 +    CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   1.418 +    {
   1.419 +        return MOZ_COLLECT_REPORT(
   1.420 +            "explicit/media/libvpx", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   1.421 +            "Memory allocated through libvpx for WebM media files.");
   1.422 +    }
   1.423 +};
   1.424 +
   1.425 +NS_IMPL_ISUPPORTS(VPXReporter, nsIMemoryReporter)
   1.426 +
   1.427 +/* static */ template<> Atomic<size_t> CountingAllocatorBase<VPXReporter>::sAmount(0);
   1.428 +#endif /* MOZ_VPX */
   1.429 +
   1.430 +#ifdef MOZ_WEBM
   1.431 +class NesteggReporter MOZ_FINAL : public nsIMemoryReporter
   1.432 +                                , public CountingAllocatorBase<NesteggReporter>
   1.433 +{
   1.434 +public:
   1.435 +    NS_DECL_ISUPPORTS
   1.436 +
   1.437 +private:
   1.438 +    NS_IMETHODIMP
   1.439 +    CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   1.440 +    {
   1.441 +        return MOZ_COLLECT_REPORT(
   1.442 +            "explicit/media/libnestegg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   1.443 +            "Memory allocated through libnestegg for WebM media files.");
   1.444 +    }
   1.445 +};
   1.446 +
   1.447 +NS_IMPL_ISUPPORTS(NesteggReporter, nsIMemoryReporter)
   1.448 +
   1.449 +/* static */ template<> Atomic<size_t> CountingAllocatorBase<NesteggReporter>::sAmount(0);
   1.450 +#endif /* MOZ_WEBM */
   1.451 +
   1.452 +// Anonymous namespace for customizing the default locale that JavaScript
   1.453 +// uses, according to the value of the "javascript.default_locale" pref.
   1.454 +// The current default locale can be detected in JavaScript by calling
   1.455 +// `Intl.DateTimeFormat().resolvedOptions().locale`
   1.456 +namespace {
   1.457 +
   1.458 +#define DEFAULT_LOCALE_PREF "javascript.default_locale"
   1.459 +
   1.460 +static char* sSystemLocale;
   1.461 +static char* sJSLocale;
   1.462 +
   1.463 +// Returns a pointer to the current JS Runtime.
   1.464 +static
   1.465 +JSRuntime* GetRuntime() {
   1.466 +  nsresult rv;
   1.467 +  nsCOMPtr<nsIJSRuntimeService> rts = do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
   1.468 +  if (NS_FAILED(rv)) return NULL;
   1.469 +  JSRuntime* rt;
   1.470 +  rts->GetRuntime(&rt);
   1.471 +  return rt;
   1.472 +}
   1.473 +
   1.474 +// Takes the "javascript.default_locale" pref value and applies it. If the locale
   1.475 +// is empty, we fall back to the default system and JS locales.
   1.476 +static
   1.477 +void DefaultLocaleChangedCallback(const char* /* pref */, void* /* closure */) {
   1.478 +  // Get a pointer to the default JS Runtime.
   1.479 +  JSRuntime* rt = GetRuntime();
   1.480 +  if (rt) {
   1.481 +    // Read the pref, which may contain a custom default locale to be used in JavaScript.
   1.482 +    nsAutoCString prefLocale;
   1.483 +    mozilla::Preferences::GetCString(DEFAULT_LOCALE_PREF, &prefLocale);
   1.484 +    // Set the application-wide C-locale. Needed for Date.toLocaleFormat().
   1.485 +    setlocale(LC_ALL, prefLocale.IsEmpty() ? sSystemLocale : prefLocale.get());
   1.486 +    // Now override the JavaScript Runtime Locale that is used by the Intl API
   1.487 +    // as well as Date.toLocaleString, Number.toLocaleString, and String.localeCompare.
   1.488 +    JS_SetDefaultLocale(rt, prefLocale.IsEmpty() ? sJSLocale : prefLocale.get());
   1.489 +  }
   1.490 +}
   1.491 +
   1.492 +static
   1.493 +void StartWatchingDefaultLocalePref() {
   1.494 +  // Get the default system locale. To be used if pref is not available.
   1.495 +  sSystemLocale = strdup(setlocale(LC_ALL,NULL));
   1.496 +  // Store the default JavaScript locale.
   1.497 +  JSRuntime* rt = GetRuntime();
   1.498 +  if (rt) {
   1.499 +    sJSLocale = strdup(JS_GetDefaultLocale(rt));
   1.500 +  }
   1.501 +  // Now keep the locale updated with the current pref value.
   1.502 +  mozilla::Preferences::RegisterCallbackAndCall(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF);
   1.503 +}
   1.504 +
   1.505 +static
   1.506 +void StopWatchingDefaultLocalePref() {
   1.507 +  mozilla::Preferences::UnregisterCallback(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF);
   1.508 +  if (sSystemLocale) free(sSystemLocale);
   1.509 +  if (sJSLocale) JS_free(nullptr, sJSLocale);
   1.510 +}
   1.511 +
   1.512 +} // anonymous namespace for locale pref
   1.513 +
   1.514 +EXPORT_XPCOM_API(nsresult)
   1.515 +NS_InitXPCOM2(nsIServiceManager* *result,
   1.516 +              nsIFile* binDirectory,
   1.517 +              nsIDirectoryServiceProvider* appFileLocationProvider)
   1.518 +{
   1.519 +    mozPoisonValueInit();
   1.520 +
   1.521 +    char aLocal;
   1.522 +    profiler_init(&aLocal);
   1.523 +    nsresult rv = NS_OK;
   1.524 +
   1.525 +     // We are not shutting down
   1.526 +    gXPCOMShuttingDown = false;
   1.527 +
   1.528 +    // Initialize the available memory tracker before other threads have had a
   1.529 +    // chance to start up, because the initialization is not thread-safe.
   1.530 +    mozilla::AvailableMemoryTracker::Init();
   1.531 +
   1.532 +#ifdef XP_UNIX
   1.533 +    // Discover the current value of the umask, and save it where
   1.534 +    // nsSystemInfo::Init can retrieve it when necessary.  There is no way
   1.535 +    // to read the umask without changing it, and the setting is process-
   1.536 +    // global, so this must be done while we are still single-threaded; the
   1.537 +    // nsSystemInfo object is typically created much later, when some piece
   1.538 +    // of chrome JS wants it.  The system call is specified as unable to fail.
   1.539 +    nsSystemInfo::gUserUmask = ::umask(0777);
   1.540 +    ::umask(nsSystemInfo::gUserUmask);
   1.541 +#endif
   1.542 +
   1.543 +    NS_LogInit();
   1.544 +
   1.545 +    // Set up chromium libs
   1.546 +    NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
   1.547 +
   1.548 +    if (!AtExitManager::AlreadyRegistered()) {
   1.549 +        sExitManager = new AtExitManager();
   1.550 +    }
   1.551 +
   1.552 +    if (!MessageLoop::current()) {
   1.553 +        sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
   1.554 +        sMessageLoop->set_thread_name("Gecko");
   1.555 +        // Set experimental values for main thread hangs:
   1.556 +        // 512ms for transient hangs and 8192ms for permanent hangs
   1.557 +        sMessageLoop->set_hang_timeouts(512, 8192);
   1.558 +    }
   1.559 +
   1.560 +    if (XRE_GetProcessType() == GeckoProcessType_Default &&
   1.561 +        !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
   1.562 +        scoped_ptr<BrowserProcessSubThread> ioThread(
   1.563 +            new BrowserProcessSubThread(BrowserProcessSubThread::IO));
   1.564 +
   1.565 +        base::Thread::Options options;
   1.566 +        options.message_loop_type = MessageLoop::TYPE_IO;
   1.567 +        if (NS_WARN_IF(!ioThread->StartWithOptions(options)))
   1.568 +            return NS_ERROR_FAILURE;
   1.569 +
   1.570 +        sIOThread = ioThread.release();
   1.571 +    }
   1.572 +
   1.573 +    // Establish the main thread here.
   1.574 +    rv = nsThreadManager::get()->Init();
   1.575 +    if (NS_WARN_IF(NS_FAILED(rv)))
   1.576 +        return rv;
   1.577 +
   1.578 +    // Set up the timer globals/timer thread
   1.579 +    rv = nsTimerImpl::Startup();
   1.580 +    if (NS_WARN_IF(NS_FAILED(rv)))
   1.581 +        return rv;
   1.582 +
   1.583 +#ifndef ANDROID
   1.584 +    // If the locale hasn't already been setup by our embedder,
   1.585 +    // get us out of the "C" locale and into the system
   1.586 +    if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0)
   1.587 +        setlocale(LC_ALL, "");
   1.588 +#endif
   1.589 +
   1.590 +#if defined(XP_UNIX)
   1.591 +    NS_StartupNativeCharsetUtils();
   1.592 +#endif
   1.593 +
   1.594 +    NS_StartupLocalFile();
   1.595 +
   1.596 +    StartupSpecialSystemDirectory();
   1.597 +
   1.598 +    nsDirectoryService::RealInit();
   1.599 +
   1.600 +    bool value;
   1.601 +
   1.602 +    if (binDirectory)
   1.603 +    {
   1.604 +        rv = binDirectory->IsDirectory(&value);
   1.605 +
   1.606 +        if (NS_SUCCEEDED(rv) && value) {
   1.607 +            nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
   1.608 +        }
   1.609 +    }
   1.610 +
   1.611 +    if (appFileLocationProvider) {
   1.612 +        rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
   1.613 +        if (NS_FAILED(rv)) return rv;
   1.614 +    }
   1.615 +
   1.616 +    nsCOMPtr<nsIFile> xpcomLib;
   1.617 +
   1.618 +    nsDirectoryService::gService->Get(NS_GRE_DIR,
   1.619 +                                      NS_GET_IID(nsIFile),
   1.620 +                                      getter_AddRefs(xpcomLib));
   1.621 +
   1.622 +    if (xpcomLib) {
   1.623 +        xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
   1.624 +        nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
   1.625 +    }
   1.626 +
   1.627 +    if (!mozilla::Omnijar::IsInitialized()) {
   1.628 +        mozilla::Omnijar::Init();
   1.629 +    }
   1.630 +
   1.631 +    if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
   1.632 +#ifdef OS_WIN
   1.633 +        CommandLine::Init(0, nullptr);
   1.634 +#else
   1.635 +        nsCOMPtr<nsIFile> binaryFile;
   1.636 +        nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
   1.637 +                                          NS_GET_IID(nsIFile),
   1.638 +                                          getter_AddRefs(binaryFile));
   1.639 +        if (NS_WARN_IF(!binaryFile))
   1.640 +            return NS_ERROR_FAILURE;
   1.641 +
   1.642 +        rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
   1.643 +        if (NS_WARN_IF(NS_FAILED(rv)))
   1.644 +            return rv;
   1.645 +
   1.646 +        nsCString binaryPath;
   1.647 +        rv = binaryFile->GetNativePath(binaryPath);
   1.648 +        if (NS_WARN_IF(NS_FAILED(rv)))
   1.649 +            return rv;
   1.650 +
   1.651 +        static char const *const argv = { strdup(binaryPath.get()) };
   1.652 +        CommandLine::Init(1, &argv);
   1.653 +#endif
   1.654 +    }
   1.655 +
   1.656 +    NS_ASSERTION(nsComponentManagerImpl::gComponentManager == nullptr, "CompMgr not null at init");
   1.657 +
   1.658 +    // Create the Component/Service Manager
   1.659 +    nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
   1.660 +    NS_ADDREF(nsComponentManagerImpl::gComponentManager);
   1.661 +
   1.662 +    // Global cycle collector initialization.
   1.663 +    if (!nsCycleCollector_init()) {
   1.664 +        return NS_ERROR_UNEXPECTED;
   1.665 +    }
   1.666 +
   1.667 +    // And start it up for this thread too.
   1.668 +    nsCycleCollector_startup();
   1.669 +
   1.670 +    // Register ICU memory functions.  This really shouldn't be necessary: the
   1.671 +    // JS engine should do this on its own inside JS_Init, and memory-reporting
   1.672 +    // code should call a JSAPI function to observe ICU memory usage.  But we
   1.673 +    // can't define the alloc/free functions in the JS engine, because it can't
   1.674 +    // depend on the XPCOM-based memory reporting goop.  So for now, we have
   1.675 +    // this oddness.
   1.676 +    mozilla::SetICUMemoryFunctions();
   1.677 +
   1.678 +    // Do the same for libogg.
   1.679 +    ogg_set_mem_functions(OggReporter::CountingMalloc,
   1.680 +                          OggReporter::CountingCalloc,
   1.681 +                          OggReporter::CountingRealloc,
   1.682 +                          OggReporter::CountingFree);
   1.683 +
   1.684 +#if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
   1.685 +    // And for VPX.
   1.686 +    vpx_mem_set_functions(VPXReporter::CountingMalloc,
   1.687 +                          VPXReporter::CountingCalloc,
   1.688 +                          VPXReporter::CountingRealloc,
   1.689 +                          VPXReporter::CountingFree,
   1.690 +                          memcpy,
   1.691 +                          memset,
   1.692 +                          memmove);
   1.693 +#endif
   1.694 +
   1.695 +#ifdef MOZ_WEBM
   1.696 +    // And for libnestegg.
   1.697 +    nestegg_set_halloc_func(NesteggReporter::CountingRealloc);
   1.698 +#endif
   1.699 +
   1.700 +    // Initialize the JS engine.
   1.701 +    if (!JS_Init()) {
   1.702 +        NS_RUNTIMEABORT("JS_Init failed");
   1.703 +    }
   1.704 +
   1.705 +    rv = nsComponentManagerImpl::gComponentManager->Init();
   1.706 +    if (NS_FAILED(rv))
   1.707 +    {
   1.708 +        NS_RELEASE(nsComponentManagerImpl::gComponentManager);
   1.709 +        return rv;
   1.710 +    }
   1.711 +
   1.712 +    if (result) {
   1.713 +        NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
   1.714 +    }
   1.715 +
   1.716 +    // The iimanager constructor searches and registers XPT files.
   1.717 +    // (We trigger the singleton's lazy construction here to make that happen.)
   1.718 +    (void) XPTInterfaceInfoManager::GetSingleton();
   1.719 +
   1.720 +    // After autoreg, but before we actually instantiate any components,
   1.721 +    // add any services listed in the "xpcom-directory-providers" category
   1.722 +    // to the directory service.
   1.723 +    nsDirectoryService::gService->RegisterCategoryProviders();
   1.724 +
   1.725 +    // Force layout to spin up so that nsContentUtils is available for cx stack
   1.726 +    // munging.
   1.727 +    nsCOMPtr<nsISupports> componentLoader = do_GetService("@mozilla.org/moz/jsloader;1");
   1.728 +
   1.729 +    mozilla::scache::StartupCache::GetSingleton();
   1.730 +    mozilla::AvailableMemoryTracker::Activate();
   1.731 +
   1.732 +    // Notify observers of xpcom autoregistration start
   1.733 +    NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
   1.734 +                                  nullptr,
   1.735 +                                  NS_XPCOM_STARTUP_OBSERVER_ID);
   1.736 +#ifdef XP_WIN
   1.737 +    CreateAnonTempFileRemover();
   1.738 +#endif
   1.739 +
   1.740 +    // We only want the SystemMemoryReporter running in one process, because it
   1.741 +    // profiles the entire system.  The main process is the obvious place for
   1.742 +    // it.
   1.743 +    if (XRE_GetProcessType() == GeckoProcessType_Default) {
   1.744 +        mozilla::SystemMemoryReporter::Init();
   1.745 +    }
   1.746 +
   1.747 +    // The memory reporter manager is up and running -- register our reporters.
   1.748 +    RegisterStrongMemoryReporter(new ICUReporter());
   1.749 +    RegisterStrongMemoryReporter(new OggReporter());
   1.750 +#ifdef MOZ_VPX
   1.751 +    RegisterStrongMemoryReporter(new VPXReporter());
   1.752 +#endif
   1.753 +#ifdef MOZ_WEBM
   1.754 +    RegisterStrongMemoryReporter(new NesteggReporter());
   1.755 +#endif
   1.756 +
   1.757 +    mozilla::Telemetry::Init();
   1.758 +
   1.759 +    mozilla::HangMonitor::Startup();
   1.760 +    mozilla::BackgroundHangMonitor::Startup();
   1.761 +
   1.762 +    const MessageLoop* const loop = MessageLoop::current();
   1.763 +    sMainHangMonitor = new mozilla::BackgroundHangMonitor(
   1.764 +        loop->thread_name().c_str(),
   1.765 +        loop->transient_hang_timeout(),
   1.766 +        loop->permanent_hang_timeout());
   1.767 +
   1.768 +#ifdef MOZ_VISUAL_EVENT_TRACER
   1.769 +    mozilla::eventtracer::Init();
   1.770 +#endif
   1.771 +
   1.772 +    // Start watching the javascript.default_locale pref.
   1.773 +    StartWatchingDefaultLocalePref();
   1.774 +    return NS_OK;
   1.775 +}
   1.776 +
   1.777 +
   1.778 +//
   1.779 +// NS_ShutdownXPCOM()
   1.780 +//
   1.781 +// The shutdown sequence for xpcom would be
   1.782 +//
   1.783 +// - Notify "xpcom-shutdown" for modules to release primary (root) references
   1.784 +// - Shutdown XPCOM timers
   1.785 +// - Notify "xpcom-shutdown-threads" for thread joins
   1.786 +// - Shutdown the event queues
   1.787 +// - Release the Global Service Manager
   1.788 +//   - Release all service instances held by the global service manager
   1.789 +//   - Release the Global Service Manager itself
   1.790 +// - Release the Component Manager
   1.791 +//   - Release all factories cached by the Component Manager
   1.792 +//   - Notify module loaders to shut down
   1.793 +//   - Unload Libraries
   1.794 +//   - Release Contractid Cache held by Component Manager
   1.795 +//   - Release dll abstraction held by Component Manager
   1.796 +//   - Release the Registry held by Component Manager
   1.797 +//   - Finally, release the component manager itself
   1.798 +//
   1.799 +EXPORT_XPCOM_API(nsresult)
   1.800 +NS_ShutdownXPCOM(nsIServiceManager* servMgr)
   1.801 +{
   1.802 +    return mozilla::ShutdownXPCOM(servMgr);
   1.803 +}
   1.804 +
   1.805 +namespace mozilla {
   1.806 +
   1.807 +void
   1.808 +SetICUMemoryFunctions()
   1.809 +{
   1.810 +    static bool sICUReporterInitialized = false;
   1.811 +    if (!sICUReporterInitialized) {
   1.812 +        if (!JS_SetICUMemoryFunctions(ICUReporter::Alloc, ICUReporter::Realloc,
   1.813 +                                      ICUReporter::Free)) {
   1.814 +            NS_RUNTIMEABORT("JS_SetICUMemoryFunctions failed.");
   1.815 +        }
   1.816 +        sICUReporterInitialized = true;
   1.817 +    }
   1.818 +}
   1.819 +
   1.820 +nsresult
   1.821 +ShutdownXPCOM(nsIServiceManager* servMgr)
   1.822 +{
   1.823 +    // Make sure the hang monitor is enabled for shutdown.
   1.824 +    HangMonitor::NotifyActivity();
   1.825 +
   1.826 +    if (!NS_IsMainThread()) {
   1.827 +        NS_RUNTIMEABORT("Shutdown on wrong thread");
   1.828 +    }
   1.829 +
   1.830 +    nsresult rv;
   1.831 +    nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
   1.832 +
   1.833 +    // Notify observers of xpcom shutting down
   1.834 +    {
   1.835 +        // Block it so that the COMPtr will get deleted before we hit
   1.836 +        // servicemanager shutdown
   1.837 +
   1.838 +        nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
   1.839 +        if (NS_WARN_IF(!thread))
   1.840 +            return NS_ERROR_UNEXPECTED;
   1.841 +
   1.842 +        nsRefPtr<nsObserverService> observerService;
   1.843 +        CallGetService("@mozilla.org/observer-service;1",
   1.844 +                       (nsObserverService**) getter_AddRefs(observerService));
   1.845 +
   1.846 +        if (observerService)
   1.847 +        {
   1.848 +            (void) observerService->
   1.849 +                NotifyObservers(nullptr, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
   1.850 +                                nullptr);
   1.851 +
   1.852 +            nsCOMPtr<nsIServiceManager> mgr;
   1.853 +            rv = NS_GetServiceManager(getter_AddRefs(mgr));
   1.854 +            if (NS_SUCCEEDED(rv))
   1.855 +            {
   1.856 +                (void) observerService->
   1.857 +                    NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
   1.858 +                                    nullptr);
   1.859 +            }
   1.860 +        }
   1.861 +
   1.862 +        // This must happen after the shutdown of media and widgets, which
   1.863 +        // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
   1.864 +        layers::ImageBridgeChild::ShutDown();
   1.865 +
   1.866 +        NS_ProcessPendingEvents(thread);
   1.867 +        mozilla::scache::StartupCache::DeleteSingleton();
   1.868 +        if (observerService)
   1.869 +            (void) observerService->
   1.870 +                NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
   1.871 +                                nullptr);
   1.872 +
   1.873 +        layers::CompositorParent::ShutDown();
   1.874 +
   1.875 +        gXPCOMThreadsShutDown = true;
   1.876 +        NS_ProcessPendingEvents(thread);
   1.877 +
   1.878 +        // Shutdown the timer thread and all timers that might still be alive before
   1.879 +        // shutting down the component manager
   1.880 +        nsTimerImpl::Shutdown();
   1.881 +
   1.882 +        NS_ProcessPendingEvents(thread);
   1.883 +
   1.884 +        // Shutdown all remaining threads.  This method does not return until
   1.885 +        // all threads created using the thread manager (with the exception of
   1.886 +        // the main thread) have exited.
   1.887 +        nsThreadManager::get()->Shutdown();
   1.888 +
   1.889 +        NS_ProcessPendingEvents(thread);
   1.890 +
   1.891 +        HangMonitor::NotifyActivity();
   1.892 +
   1.893 +        // Late-write checks needs to find the profile directory, so it has to
   1.894 +        // be initialized before mozilla::services::Shutdown or (because of
   1.895 +        // xpcshell tests replacing the service) modules being unloaded.
   1.896 +        mozilla::InitLateWriteChecks();
   1.897 +
   1.898 +        // We save the "xpcom-shutdown-loaders" observers to notify after
   1.899 +        // the observerservice is gone.
   1.900 +        if (observerService) {
   1.901 +            observerService->
   1.902 +                EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
   1.903 +                                   getter_AddRefs(moduleLoaders));
   1.904 +
   1.905 +            observerService->Shutdown();
   1.906 +        }
   1.907 +    }
   1.908 +
   1.909 +    // Free ClearOnShutdown()'ed smart pointers.  This needs to happen *after*
   1.910 +    // we've finished notifying observers of XPCOM shutdown, because shutdown
   1.911 +    // observers themselves might call ClearOnShutdown().
   1.912 +    mozilla::KillClearOnShutdown();
   1.913 +
   1.914 +    // XPCOM is officially in shutdown mode NOW
   1.915 +    // Set this only after the observers have been notified as this
   1.916 +    // will cause servicemanager to become inaccessible.
   1.917 +    mozilla::services::Shutdown();
   1.918 +
   1.919 +#ifdef DEBUG_dougt
   1.920 +    fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
   1.921 +#endif
   1.922 +    // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
   1.923 +    // here again:
   1.924 +    NS_IF_RELEASE(servMgr);
   1.925 +
   1.926 +    // Shutdown global servicemanager
   1.927 +    if (nsComponentManagerImpl::gComponentManager) {
   1.928 +        nsComponentManagerImpl::gComponentManager->FreeServices();
   1.929 +    }
   1.930 +
   1.931 +    // Release the directory service
   1.932 +    NS_IF_RELEASE(nsDirectoryService::gService);
   1.933 +
   1.934 +    if (moduleLoaders) {
   1.935 +        bool more;
   1.936 +        nsCOMPtr<nsISupports> el;
   1.937 +        while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
   1.938 +               more) {
   1.939 +            moduleLoaders->GetNext(getter_AddRefs(el));
   1.940 +
   1.941 +            // Don't worry about weak-reference observers here: there is
   1.942 +            // no reason for weak-ref observers to register for
   1.943 +            // xpcom-shutdown-loaders
   1.944 +
   1.945 +            // FIXME: This can cause harmless writes from sqlite committing
   1.946 +            // log files. We have to ignore them before we can move
   1.947 +            // the mozilla::PoisonWrite call before this point. See bug
   1.948 +            // 834945 for the details.
   1.949 +            nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
   1.950 +            if (obs)
   1.951 +                (void) obs->Observe(nullptr,
   1.952 +                                    NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
   1.953 +                                    nullptr);
   1.954 +        }
   1.955 +
   1.956 +        moduleLoaders = nullptr;
   1.957 +    }
   1.958 +
   1.959 +    nsCycleCollector_shutdown();
   1.960 +
   1.961 +    PROFILER_MARKER("Shutdown xpcom");
   1.962 +    // If we are doing any shutdown checks, poison writes.
   1.963 +    if (gShutdownChecks != SCM_NOTHING) {
   1.964 +#ifdef XP_MACOSX
   1.965 +        mozilla::OnlyReportDirtyWrites();
   1.966 +#endif /* XP_MACOSX */
   1.967 +        mozilla::BeginLateWriteChecks();
   1.968 +    }
   1.969 +
   1.970 +    // Shutdown nsLocalFile string conversion
   1.971 +    NS_ShutdownLocalFile();
   1.972 +#ifdef XP_UNIX
   1.973 +    NS_ShutdownNativeCharsetUtils();
   1.974 +#endif
   1.975 +
   1.976 +    // Shutdown xpcom. This will release all loaders and cause others holding
   1.977 +    // a refcount to the component manager to release it.
   1.978 +    if (nsComponentManagerImpl::gComponentManager) {
   1.979 +        rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
   1.980 +        NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
   1.981 +    } else {
   1.982 +        NS_WARNING("Component Manager was never created ...");
   1.983 +    }
   1.984 +
   1.985 +#ifdef MOZ_ENABLE_PROFILER_SPS
   1.986 +    // In optimized builds we don't do shutdown collections by default, so
   1.987 +    // uncollected (garbage) objects may keep the nsXPConnect singleton alive,
   1.988 +    // and its XPCJSRuntime along with it. However, we still destroy various
   1.989 +    // bits of state in JS_ShutDown(), so we need to make sure the profiler
   1.990 +    // can't access them when it shuts down. This call nulls out the
   1.991 +    // JS pseudo-stack's internal reference to the main thread JSRuntime,
   1.992 +    // duplicating the call in XPCJSRuntime::~XPCJSRuntime() in case that
   1.993 +    // never fired.
   1.994 +    if (PseudoStack *stack = mozilla_get_pseudo_stack()) {
   1.995 +        stack->sampleRuntime(nullptr);
   1.996 +    }
   1.997 +#endif
   1.998 +
   1.999 +    // Shut down the JS engine.
  1.1000 +    JS_ShutDown();
  1.1001 +
  1.1002 +    // Release our own singletons
  1.1003 +    // Do this _after_ shutting down the component manager, because the
  1.1004 +    // JS component loader will use XPConnect to call nsIModule::canUnload,
  1.1005 +    // and that will spin up the InterfaceInfoManager again -- bad mojo
  1.1006 +    XPTInterfaceInfoManager::FreeInterfaceInfoManager();
  1.1007 +
  1.1008 +    // Finally, release the component manager last because it unloads the
  1.1009 +    // libraries:
  1.1010 +    if (nsComponentManagerImpl::gComponentManager) {
  1.1011 +      nsrefcnt cnt;
  1.1012 +      NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
  1.1013 +      NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
  1.1014 +    }
  1.1015 +    nsComponentManagerImpl::gComponentManager = nullptr;
  1.1016 +    nsCategoryManager::Destroy();
  1.1017 +
  1.1018 +    NS_PurgeAtomTable();
  1.1019 +
  1.1020 +    NS_IF_RELEASE(gDebug);
  1.1021 +
  1.1022 +    if (sIOThread) {
  1.1023 +        delete sIOThread;
  1.1024 +        sIOThread = nullptr;
  1.1025 +    }
  1.1026 +    if (sMessageLoop) {
  1.1027 +        delete sMessageLoop;
  1.1028 +        sMessageLoop = nullptr;
  1.1029 +    }
  1.1030 +    if (sCommandLineWasInitialized) {
  1.1031 +        CommandLine::Terminate();
  1.1032 +        sCommandLineWasInitialized = false;
  1.1033 +    }
  1.1034 +    if (sExitManager) {
  1.1035 +        delete sExitManager;
  1.1036 +        sExitManager = nullptr;
  1.1037 +    }
  1.1038 +
  1.1039 +    StopWatchingDefaultLocalePref();
  1.1040 +
  1.1041 +    Omnijar::CleanUp();
  1.1042 +
  1.1043 +    HangMonitor::Shutdown();
  1.1044 +
  1.1045 +    if (sMainHangMonitor) {
  1.1046 +        delete sMainHangMonitor;
  1.1047 +        sMainHangMonitor = nullptr;
  1.1048 +    }
  1.1049 +    BackgroundHangMonitor::Shutdown();
  1.1050 +
  1.1051 +#ifdef MOZ_VISUAL_EVENT_TRACER
  1.1052 +    eventtracer::Shutdown();
  1.1053 +#endif
  1.1054 +
  1.1055 +    profiler_shutdown();
  1.1056 +
  1.1057 +    NS_LogTerm();
  1.1058 +
  1.1059 +    return NS_OK;
  1.1060 +}
  1.1061 +
  1.1062 +} // namespace mozilla

mercurial