/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Registry Factory creation function defined in nsRegistry.cpp // We hook into this function locally to create and register the registry // Since noone outside xpcom needs to know about this and nsRegistry.cpp // does not have a local include file, we are putting this definition // here rather than in nsIRegistry.h extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory); extern nsresult NS_CategoryManagerGetFactory(nsIFactory**);
class ICUReporter final : public nsIMemoryReporter, public mozilla::CountingAllocatorBase<ICUReporter> { public:
NS_DECL_ISUPPORTS
staticvoid* Alloc(constvoid*, size_t aSize) { void* result = CountingMalloc(aSize); if (result == nullptr) {
MOZ_CRASH("Ran out of memory while allocating for ICU");
} return result;
}
staticvoid* Realloc(constvoid*, void* aPtr, size_t aSize) { void* result = CountingRealloc(aPtr, aSize); if (result == nullptr) {
MOZ_CRASH("Ran out of memory while reallocating for ICU");
} return result;
}
private:
NS_IMETHOD
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) override {
MOZ_COLLECT_REPORT( "explicit/icu", KIND_HEAP, UNITS_BYTES, MemoryAllocated(), "Memory used by ICU, a Unicode and globalization support library.");
return NS_OK;
}
~ICUReporter() = default;
};
NS_IMPL_ISUPPORTS(ICUReporter, nsIMemoryReporter)
class OggReporter final : public nsIMemoryReporter, public mozilla::CountingAllocatorBase<OggReporter> { public:
NS_DECL_ISUPPORTS
private:
NS_IMETHOD
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) override {
MOZ_COLLECT_REPORT( "explicit/media/libogg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(), "Memory allocated through libogg for Ogg, and related media " "files.");
return NS_OK;
}
~OggReporter() = default;
};
NS_IMPL_ISUPPORTS(OggReporter, nsIMemoryReporter)
staticbool sInitializedJS = false;
staticvoid InitializeJS() { #ifdefined(ENABLE_WASM_SIMD) && \
(defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)) // Update static engine preferences, such as AVX, before // `JS_InitWithFailureDiagnostic` is called.
JS::SetAVXEnabled(mozilla::StaticPrefs::javascript_options_wasm_simd_avx()); #endif
if (XRE_IsParentProcess() &&
mozilla::StaticPrefs::javascript_options_main_process_disable_jit()) {
JS::DisableJitBackend();
}
// Set all JS::Prefs.
SET_JS_PREFS_FROM_BROWSER_PREFS;
constchar* jsInitFailureReason = JS_InitWithFailureDiagnostic(); if (jsInitFailureReason) {
MOZ_CRASH_UNSAFE(jsInitFailureReason);
}
}
// Note that on OSX, aBinDirectory will point to .app/Contents/Resources/browser
EXPORT_XPCOM_API(nsresult)
NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory,
nsIDirectoryServiceProvider* aAppFileLocationProvider, bool aInitJSContext) { staticbool sInitialized = false; if (sInitialized) {
XPCOM_INIT_FATAL("!sInitialized", NS_ERROR_FAILURE)
}
sInitialized = true;
NS_LogInit();
NS_InitAtomTable();
// We don't have the arguments by hand here. If logging has already been // initialized by a previous call to LogModule::Init with the arguments // passed, passing (0, nullptr) is alright here.
mozilla::LogModule::Init(0, nullptr);
GkRust_Init();
nsresult rv = NS_OK;
// We are not shutting down
gXPCOMShuttingDown = false;
#ifdef XP_UNIX // Discover the current value of the umask, and save it where // nsSystemInfo::Init can retrieve it when necessary. There is no way // to read the umask without changing it, and the setting is process- // global, so this must be done while we are still single-threaded; the // nsSystemInfo object is typically created much later, when some piece // of chrome JS wants it. The system call is specified as unable to fail.
nsSystemInfo::gUserUmask = ::umask(0777);
::umask(nsSystemInfo::gUserUmask); #endif
// Set up chromium libs
NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
if (!AtExitManager::AlreadyRegistered()) {
sExitManager = new AtExitManager();
}
MessageLoop* messageLoop = MessageLoop::current(); if (!messageLoop) {
sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_PARENT);
sMessageLoop->set_thread_name("Gecko"); // Set experimental values for main thread hangs: // 128ms for transient hangs and 8192ms for permanent hangs
sMessageLoop->set_hang_timeouts(128, 8192);
} elseif (messageLoop->type() == MessageLoop::TYPE_MOZILLA_CHILD) {
messageLoop->set_thread_name("Gecko_Child");
messageLoop->set_hang_timeouts(128, 8192);
}
// Start the IPC I/O thread in the parent process. We'll have already started // the IPC I/O thread if we're in a content process. if (XRE_IsParentProcess()) {
sIOThread = new IOThreadParent();
}
MOZ_ASSERT(mozilla::ipc::IOThread::Get(), "An IOThread has been started");
// Establish the main thread here.
rv = nsThreadManager::get().Init(); if (NS_WARN_IF(NS_FAILED(rv))) {
XPCOM_INIT_FATAL("nsThreadManager::get().Init()", rv)
}
// Initialise the profiler
AUTO_PROFILER_INIT2;
// Set up the timer globals/timer thread
rv = nsTimerImpl::Startup(); if (NS_WARN_IF(NS_FAILED(rv))) {
XPCOM_INIT_FATAL("nsTimerImpl::Startup()", rv)
}
#ifndef ANDROID // If the locale hasn't already been setup by our embedder, // get us out of the "C" locale and into the system if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
setlocale(LC_ALL, "");
} #endif
nsDirectoryService::RealInit();
bool value;
if (aBinDirectory) {
rv = aBinDirectory->IsDirectory(&value);
if (NS_SUCCEEDED(rv) && value) {
nsDirectoryService::gService->SetCurrentProcessDirectory(aBinDirectory);
}
}
if (aAppFileLocationProvider) {
rv = nsDirectoryService::gService->RegisterProvider(
aAppFileLocationProvider); if (NS_FAILED(rv)) {
XPCOM_INIT_FATAL("nsDirectoryService::gService->RegisterProvider()", rv)
}
}
if (!mozilla::Omnijar::IsInitialized()) { // If you added a new process type that uses NS_InitXPCOM, and you're // *sure* you don't want NS_InitMinimalXPCOM: in addition to everything // else you'll probably have to do, please add it to the case in // GeckoChildProcessHost.cpp which sets the greomni/appomni flags.
MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsContentProcess());
// Note that the Omnijar::FallibleInit does not fail but returns NS_OK if // the file is not found at all, as this is an expected possible way of // running with an unpacked modules directory.
nsresult rv = mozilla::Omnijar::FallibleInit(); if (NS_FAILED(rv)) {
XPCOM_INIT_FATAL("Omnijar::Init()", NS_ERROR_OMNIJAR_CORRUPT)
}
}
NS_ASSERTION(nsComponentManagerImpl::gComponentManager == nullptr, "CompMgr not null at init");
// Create the Component/Service Manager
nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
NS_ADDREF(nsComponentManagerImpl::gComponentManager);
// Global cycle collector initialization. if (!nsCycleCollector_init()) {
XPCOM_INIT_FATAL("nsCycleCollector_init()", NS_ERROR_UNEXPECTED)
}
// And start it up for this thread too.
nsCycleCollector_startup();
// Register ICU memory functions. This really shouldn't be necessary: the // JS engine should do this on its own inside JS_Init, and memory-reporting // code should call a JSAPI function to observe ICU memory usage. But we // can't define the alloc/free functions in the JS engine, because it can't // depend on the XPCOM-based memory reporting goop. So for now, we have // this oddness.
mozilla::SetICUMemoryFunctions();
// Do the same for libogg.
ogg_set_mem_functions(
OggReporter::CountingMalloc, OggReporter::CountingCalloc,
OggReporter::CountingRealloc, OggReporter::CountingFree);
// Initialize the JS engine.
InitializeJS();
sInitializedJS = true;
rv = nsComponentManagerImpl::gComponentManager->Init(); if (NS_FAILED(rv)) {
NS_RELEASE(nsComponentManagerImpl::gComponentManager);
XPCOM_INIT_FATAL("gComponentManager->Init()", rv)
}
if (aResult) {
NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager);
}
#ifdef MOZ_PHC // This is the earliest possible moment we can start PHC while still being // able to read prefs.
mozilla::InitPHCState(); #endif
#ifdef MOZ_MEMORY // We did set up our main thread earlier and can read prefs now.
mozilla::TaskController::SetupIdleMemoryCleanup(); #endif
// After autoreg, but before we actually instantiate any components, // add any services listed in the "xpcom-directory-providers" category // to the directory service.
nsDirectoryService::gService->RegisterCategoryProviders();
// Now that both the profiler and directory services have been started // we can find the download directory, where the profiler can write // profiles if necessary
profiler_lookup_async_signal_dump_directory();
// Init mozilla::SharedThreadPool (which needs the service manager).
mozilla::SharedThreadPool::InitStatics();
// The memory reporter manager is up and running -- register our reporters.
RegisterStrongMemoryReporter(new ICUReporter());
RegisterStrongMemoryReporter(new OggReporter());
xpc::SelfHostedShmem::GetSingleton().InitMemoryReporter();
// We don't have the arguments by hand here. If logging has already been // initialized by a previous call to LogModule::Init with the arguments // passed, passing (0, nullptr) is alright here.
mozilla::LogModule::Init(0, nullptr);
GkRust_Init();
nsresult rv = nsThreadManager::get().Init(); if (NS_WARN_IF(NS_FAILED(rv))) { return rv;
}
// Set up the timer globals/timer thread.
rv = nsTimerImpl::Startup(); if (NS_WARN_IF(NS_FAILED(rv))) { return rv;
}
// Create the Component/Service Manager
nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
NS_ADDREF(nsComponentManagerImpl::gComponentManager);
rv = nsComponentManagerImpl::gComponentManager->Init(); if (NS_FAILED(rv)) {
NS_RELEASE(nsComponentManagerImpl::gComponentManager); return rv;
}
// Global cycle collector initialization. if (!nsCycleCollector_init()) { return NS_ERROR_UNEXPECTED;
}
// // NS_ShutdownXPCOM() // // The shutdown sequence for xpcom would be // // - Notify "xpcom-shutdown" for modules to release primary (root) references // - Shutdown XPCOM timers // - Notify "xpcom-shutdown-threads" for thread joins // - Shutdown the event queues // - Release the Global Service Manager // - Release all service instances held by the global service manager // - Release the Global Service Manager itself // - Release the Component Manager // - Release all factories cached by the Component Manager // - Notify module loaders to shut down // - Unload Libraries // - Release Contractid Cache held by Component Manager // - Release dll abstraction held by Component Manager // - Release the Registry held by Component Manager // - Finally, release the component manager itself //
EXPORT_XPCOM_API(nsresult)
NS_ShutdownXPCOM(nsIServiceManager* aServMgr) { return mozilla::ShutdownXPCOM(aServMgr);
}
// We want the service manager to be the subject of notifications
nsCOMPtr<nsIServiceManager> mgr;
Unused << NS_GetServiceManager(getter_AddRefs(mgr));
MOZ_DIAGNOSTIC_ASSERT(mgr != nullptr, "Service manager not present!");
mozilla::AppShutdown::AdvanceShutdownPhase(
mozilla::ShutdownPhase::XPCOMShutdown, nullptr, do_QueryInterface(mgr));
// This must happen after the shutdown of media and widgets, which // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
gfxPlatform::ShutdownLayersIPC();
mozilla::AppShutdown::AdvanceShutdownPhase(
mozilla::ShutdownPhase::XPCOMShutdownThreads); #ifdef DEBUG // Prime an assertion at ThreadEventTarget::Dispatch to avoid late // dispatches to non main-thread threads.
ThreadEventTarget::XPCOMShutdownThreadsNotificationFinished(); #endif
// Shutdown the timer thread and all timers that might still be alive
nsTimerImpl::Shutdown();
// Have an extra round of processing after the timers went away.
NS_ProcessPendingEvents(thread);
// Shutdown all remaining threads. This method does not return until // all threads created using the thread manager (with the exception of // the main thread) have exited.
nsThreadManager::get().ShutdownNonMainThreads();
RefPtr<nsObserverService> observerService;
CallGetService("@mozilla.org/observer-service;1",
(nsObserverService**)getter_AddRefs(observerService)); if (observerService) {
observerService->Shutdown();
}
#ifdef NS_FREE_PERMANENT_DATA // In leak-checking / ASAN / etc. builds, shut down the Servo thread-pool, // which will wait for all the work to be done. For other builds, we don't // really want to wait on shutdown for possibly slow tasks.
Servo_ShutdownThreadPool(); #endif
// XPCOMShutdownFinal is the default phase for ClearOnShutdown. // This AdvanceShutdownPhase will thus free most ClearOnShutdown()'ed // smart pointers. Some destructors may fire extra main thread runnables // that will be processed inside AdvanceShutdownPhase.
AppShutdown::AdvanceShutdownPhase(ShutdownPhase::XPCOMShutdownFinal);
// Shutdown the main thread, processing our very last round of events, and // then mark that we've finished main thread event processing.
nsThreadManager::get().ShutdownMainThread();
gXPCOMMainThreadEventsAreDoomed = true;
BackgroundHangMonitor().NotifyActivity();
mozilla::dom::JSExecutionManager::Shutdown();
}
// XPCOM is officially in shutdown mode NOW // Set this only after the observers have been notified as this // will cause servicemanager to become inaccessible.
mozilla::services::Shutdown();
// We may have AddRef'd for the caller of NS_InitXPCOM, so release it // here again:
NS_IF_RELEASE(aServMgr);
// Shutdown global servicemanager if (nsComponentManagerImpl::gComponentManager) {
nsComponentManagerImpl::gComponentManager->FreeServices();
}
// Remove the remaining main thread representations
nsThreadManager::get().ReleaseMainThread();
AbstractThread::ShutdownMainThread();
// Release the directory service
nsDirectoryService::gService = nullptr;
free(gGREBinPath);
gGREBinPath = nullptr;
// FIXME: This can cause harmless writes from sqlite committing // log files. We have to ignore them before we can move // the mozilla::PoisonWrite call before this point. See bug // 834945 for the details.
mozJSModuleLoader::UnloadLoaders();
// Clear the profiler's JS context before cycle collection. The profiler will // notify the JS engine that it can let go of any data it's holding on to for // profiling purposes.
PROFILER_CLEAR_JS_CONTEXT();
// There can be code trying to refer to global objects during the final cc // shutdown. This is the phase for such global objects to correctly release.
AppShutdown::AdvanceShutdownPhase(ShutdownPhase::CCPostLastCycleCollection);
// Shutdown xpcom. This will release all loaders and cause others holding // a refcount to the component manager to release it. if (nsComponentManagerImpl::gComponentManager) {
DebugOnly<nsresult> rv =
(nsComponentManagerImpl::gComponentManager)->Shutdown();
NS_ASSERTION(NS_SUCCEEDED(rv.value), "Component Manager shutdown failed.");
} else {
NS_WARNING("Component Manager was never created ...");
}
if (sInitializedJS) { // Shut down the JS engine.
JS_ShutDown();
sInitializedJS = false;
}
// Release shared memory which might be borrowed by the JS engine.
xpc::SelfHostedShmem::Shutdown();
// After all threads have been joined and the component manager has been shut // down, any remaining objects that could be holding NSS resources (should) // have been released, so we can safely shut down NSS. if (NSS_IsInitialized()) {
nsNSSComponent::DoClearSSLExternalAndInternalSessionCache(); if (NSS_Shutdown() != SECSuccess) { // If you're seeing this crash and/or warning, some NSS resources are // still in use (see bugs 1417680 and 1230312). Set the environment // variable 'MOZ_IGNORE_NSS_SHUTDOWN_LEAKS' to some value to ignore this. // Also, if leak checking is enabled, report this as a fake leak instead // of crashing. #ifdefined(DEBUG) && !defined(ANDROID) if (!getenv("MOZ_IGNORE_NSS_SHUTDOWN_LEAKS") &&
!getenv("XPCOM_MEM_BLOAT_LOG") && !getenv("XPCOM_MEM_LEAK_LOG") &&
!getenv("XPCOM_MEM_REFCNT_LOG") && !getenv("XPCOM_MEM_COMPTR_LOG")) {
MOZ_CRASH("NSS_Shutdown failed");
} else { # ifdef NS_BUILD_REFCNT_LOGGING // Create a fake leak.
NS_LogCtor((void*)0x100, "NSSShutdownFailed", 100); # endif // NS_BUILD_REFCNT_LOGGING
NS_WARNING("NSS_Shutdown failed");
} #else
NS_WARNING("NSS_Shutdown failed"); #endif// defined(DEBUG) && !defined(ANDROID)
}
}
// Finally, release the component manager last because it unloads the // libraries: if (nsComponentManagerImpl::gComponentManager) {
nsrefcnt cnt;
NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
}
nsComponentManagerImpl::gComponentManager = nullptr;
nsCategoryManager::Destroy();
nsLanguageAtomService::Shutdown();
GkRust_Shutdown();
#ifdef NS_FREE_PERMANENT_DATA // As we do shutdown Servo only in leak-checking builds, there may still // be async parse tasks going on in the Servo thread-pool in other builds. // CSS parsing heavily uses the atom table, so we can safely drop it only // if Servo has been stopped, too.
NS_ShutdownAtomTable(); #endif
NS_IF_RELEASE(gDebug);
delete sIOThread;
sIOThread = nullptr;
delete sMessageLoop;
sMessageLoop = nullptr;
mozilla::TaskController::Shutdown();
if (sCommandLineWasInitialized) {
CommandLine::Terminate();
sCommandLineWasInitialized = false;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.