diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index e55208ddb207..5f340d65d818 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -809,6 +809,16 @@ NS_InitMinimalXPCOM() 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; diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h index 4bcac8355a33..a57d188c8a9c 100644 --- a/xpcom/components/Module.h +++ b/xpcom/components/Module.h @@ -38,13 +38,20 @@ struct Module /** * This selector allows CIDEntrys to be marked so that they're only loaded - * into certain kinds of processes. + * into certain kinds of processes. Selectors can be combined. */ enum ProcessSelector { - ANY_PROCESS = 0, - MAIN_PROCESS_ONLY, - CONTENT_PROCESS_ONLY + ANY_PROCESS = 0x0, + MAIN_PROCESS_ONLY = 0x1, + CONTENT_PROCESS_ONLY = 0x2, + + /** + * By default, modules are not loaded in the GPU process, even if + * ANY_PROCESS is specified. This flag enables a module in the + * GPU process. + */ + ALLOW_IN_GPU_PROCESS = 0x4 }; /** @@ -113,6 +120,12 @@ struct Module */ LoadFuncPtr loadProc; UnloadFuncPtr unloadProc; + + /** + * Optional flags which control whether the module loads on a process-type + * basis. + */ + ProcessSelector selector; }; } // namespace mozilla diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 6ccc27758e31..25161490a2a6 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -356,46 +356,49 @@ nsComponentManagerImpl::Init() RegisterModule((*sStaticModules)[i], nullptr); } - // The overall order in which chrome.manifests are expected to be treated - // is the following: - // - greDir - // - greDir's omni.ja - // - appDir - // - appDir's omni.ja + bool loadChromeManifests = (XRE_GetProcessType() != GeckoProcessType_GPU); + if (loadChromeManifests) { + // The overall order in which chrome.manifests are expected to be treated + // is the following: + // - greDir + // - greDir's omni.ja + // - appDir + // - appDir's omni.ja - InitializeModuleLocations(); - ComponentLocation* cl = sModuleLocations->AppendElement(); - nsCOMPtr lf = CloneAndAppend(greDir, - NS_LITERAL_CSTRING("chrome.manifest")); - cl->type = NS_APP_LOCATION; - cl->location.Init(lf); - - RefPtr greOmnijar = - mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE); - if (greOmnijar) { - cl = sModuleLocations->AppendElement(); + InitializeModuleLocations(); + ComponentLocation* cl = sModuleLocations->AppendElement(); + nsCOMPtr lf = CloneAndAppend(greDir, + NS_LITERAL_CSTRING("chrome.manifest")); cl->type = NS_APP_LOCATION; - cl->location.Init(greOmnijar, "chrome.manifest"); - } - - bool equals = false; - appDir->Equals(greDir, &equals); - if (!equals) { - cl = sModuleLocations->AppendElement(); - cl->type = NS_APP_LOCATION; - lf = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest")); cl->location.Init(lf); - } - RefPtr appOmnijar = - mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); - if (appOmnijar) { - cl = sModuleLocations->AppendElement(); - cl->type = NS_APP_LOCATION; - cl->location.Init(appOmnijar, "chrome.manifest"); - } + RefPtr greOmnijar = + mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE); + if (greOmnijar) { + cl = sModuleLocations->AppendElement(); + cl->type = NS_APP_LOCATION; + cl->location.Init(greOmnijar, "chrome.manifest"); + } - RereadChromeManifests(false); + bool equals = false; + appDir->Equals(greDir, &equals); + if (!equals) { + cl = sModuleLocations->AppendElement(); + cl->type = NS_APP_LOCATION; + lf = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest")); + cl->location.Init(lf); + } + + RefPtr appOmnijar = + mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); + if (appOmnijar) { + cl = sModuleLocations->AppendElement(); + cl->type = NS_APP_LOCATION; + cl->location.Init(appOmnijar, "chrome.manifest"); + } + + RereadChromeManifests(false); + } nsCategoryManager::GetSingleton()->SuppressNotifications(false); @@ -429,12 +432,37 @@ nsComponentManagerImpl::Init() return NS_OK; } +static bool +ProcessSelectorMatches(Module::ProcessSelector aSelector) +{ + GeckoProcessType type = XRE_GetProcessType(); + if (type == GeckoProcessType_GPU) { + return !!(aSelector & Module::ALLOW_IN_GPU_PROCESS); + } + + if (aSelector & Module::MAIN_PROCESS_ONLY) { + return type == GeckoProcessType_Default; + } + if (aSelector & Module::CONTENT_PROCESS_ONLY) { + return type == GeckoProcessType_Content; + } + return true; +} + +static const int kModuleVersionWithSelector = 51; + void nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule, FileLocation* aFile) { mLock.AssertNotCurrentThreadOwns(); + if (aModule->mVersion >= kModuleVersionWithSelector && + !ProcessSelectorMatches(aModule->selector)) + { + return; + } + { // Scope the monitor so that we don't hold it while calling into the // category manager. @@ -479,24 +507,6 @@ nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule, } } -static bool -ProcessSelectorMatches(Module::ProcessSelector aSelector) -{ - if (aSelector == Module::ANY_PROCESS) { - return true; - } - - GeckoProcessType type = XRE_GetProcessType(); - switch (aSelector) { - case Module::MAIN_PROCESS_ONLY: - return type == GeckoProcessType_Default; - case Module::CONTENT_PROCESS_ONLY: - return type == GeckoProcessType_Content; - default: - MOZ_CRASH("invalid process aSelector"); - } -} - void nsComponentManagerImpl::RegisterCIDEntryLocked( const mozilla::Module::CIDEntry* aEntry,