Enable nsComponentManager in the GPU process. (bug 1294350 part 4, r=nfroyd)
authorDavid Anderson <danderson@mozilla.com>
Mon, 22 Aug 2016 22:57:36 -0700
changeset 336510 52e0e8f44ca3b4e0122a39a08f37596e30e262af
parent 336509 249d8c1dd89204a4d80b569bbb303316cebacffa
child 336511 793e8dee47eaa5aaafd8e6065e06cd6b986acde3
push id10033
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:50:26 +0000
treeherdermozilla-aurora@5dddbefdf759 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd
bugs1294350
milestone51.0a1
Enable nsComponentManager in the GPU process. (bug 1294350 part 4, r=nfroyd)
xpcom/build/XPCOMInit.cpp
xpcom/components/Module.h
xpcom/components/nsComponentManager.cpp
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -804,16 +804,26 @@ NS_InitMinimalXPCOM()
   }
 
   // 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;
   }
 
   return NS_OK;
 }
 
--- a/xpcom/components/Module.h
+++ b/xpcom/components/Module.h
@@ -33,23 +33,30 @@ struct Module
                                          const nsIID& aIID,
                                          void** aResult);
 
   typedef nsresult (*LoadFuncPtr)();
   typedef void (*UnloadFuncPtr)();
 
   /**
    * 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
   };
 
   /**
    * The constructor callback is an implementation detail of the default binary
    * loader and may be null.
    */
   struct CIDEntry
   {
@@ -108,16 +115,22 @@ struct Module
 
   /**
    * Optional Function which are called when this module is loaded and
    * at shutdown. These are not C++ constructor/destructors to avoid
    * calling them too early in startup or too late in shutdown.
    */
   LoadFuncPtr loadProc;
   UnloadFuncPtr unloadProc;
+
+  /**
+   * Optional flags which control whether the module loads on a process-type
+   * basis.
+   */
+  ProcessSelector selector;
 };
 
 } // namespace mozilla
 
 #if defined(MOZILLA_INTERNAL_API)
 #  define NSMODULE_NAME(_name) _name##_NSModule
 #  if defined(_MSC_VER)
 #    pragma section(".kPStaticModules$M", read)
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -351,57 +351,60 @@ nsComponentManagerImpl::Init()
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 
   RegisterModule(&kXPCOMModule, nullptr);
 
   for (uint32_t i = 0; i < sStaticModules->Length(); ++i) {
     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<nsIFile> lf = CloneAndAppend(greDir,
-                                        NS_LITERAL_CSTRING("chrome.manifest"));
-  cl->type = NS_APP_LOCATION;
-  cl->location.Init(lf);
-
-  RefPtr<nsZipArchive> greOmnijar =
-    mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
-  if (greOmnijar) {
-    cl = sModuleLocations->AppendElement();
+    InitializeModuleLocations();
+    ComponentLocation* cl = sModuleLocations->AppendElement();
+    nsCOMPtr<nsIFile> lf = CloneAndAppend(greDir,
+                                          NS_LITERAL_CSTRING("chrome.manifest"));
     cl->type = NS_APP_LOCATION;
-    cl->location.Init(greOmnijar, "chrome.manifest");
-  }
+    cl->location.Init(lf);
+
+    RefPtr<nsZipArchive> greOmnijar =
+      mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
+    if (greOmnijar) {
+      cl = sModuleLocations->AppendElement();
+      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);
+    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<nsZipArchive> 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);
   }
 
-  RefPtr<nsZipArchive> 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);
 
   RegisterWeakMemoryReporter(this);
 
   // NB: The logging preference watcher needs to be registered late enough in
   // startup that it's okay to use the preference system, but also as soon as
   // possible so that log modules enabled via preferences are turned on as
   // early as possible.
@@ -424,22 +427,47 @@ nsComponentManagerImpl::Init()
   MOZ_LOG(nsComponentManagerLog, LogLevel::Debug,
          ("nsComponentManager: Initialized."));
 
   mStatus = NORMAL;
 
   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.
     MutexLock lock(mLock);
 
     KnownModule* m;
     if (aFile) {
       nsCString uri;
@@ -474,34 +502,16 @@ nsComponentManagerImpl::RegisterModule(c
     const mozilla::Module::CategoryEntry* entry;
     for (entry = aModule->mCategoryEntries; entry->category; ++entry)
       nsCategoryManager::GetSingleton()->AddCategoryEntry(entry->category,
                                                           entry->entry,
                                                           entry->value);
   }
 }
 
-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,
     KnownModule* aModule)
 {
   mLock.AssertCurrentThreadOwns();
 
   if (!ProcessSelectorMatches(aEntry->processSelector)) {