Bug 1538279 - Only readahead DLLs in parent process r=glandium
authorDoug Thayer <dothayer@mozilla.com>
Sat, 13 Apr 2019 18:46:13 +0000
changeset 469416 05fe1e4224558caf7483c6f9d5f1d9e0a9f5912d
parent 469415 9f73549db05e66e2af402cb6aefe53fc360365e9
child 469417 2c3837b46068b53cabeb3a1a3222f04eb8132b55
push id35865
push userapavel@mozilla.com
push dateSat, 13 Apr 2019 21:44:49 +0000
treeherdermozilla-central@2c3837b46068 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1538279
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1538279 - Only readahead DLLs in parent process r=glandium There shouldn't be any need to do this for content processes as the DLL should already be in the system file cache. Differential Revision: https://phabricator.services.mozilla.com/D26017
browser/app/nsBrowserApp.cpp
mozglue/android/APKOpen.cpp
toolkit/xre/Bootstrap.h
xpcom/glue/standalone/nsXPCOMGlue.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -207,24 +207,24 @@ static int do_main(int argc, char* argv[
 #ifdef LIBFUZZER
   if (getenv("LIBFUZZER"))
     gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
 #endif
 
   return gBootstrap->XRE_main(argc, argv, config);
 }
 
-static nsresult InitXPCOMGlue() {
+static nsresult InitXPCOMGlue(LibLoadingStrategy aLibLoadingStrategy) {
   UniqueFreePtr<char> exePath = BinaryPath::Get();
   if (!exePath) {
     Output("Couldn't find the application directory.\n");
     return NS_ERROR_FAILURE;
   }
 
-  gBootstrap = mozilla::GetBootstrap(exePath.get());
+  gBootstrap = mozilla::GetBootstrap(exePath.get(), aLibLoadingStrategy);
   if (!gBootstrap) {
     Output("Couldn't load XPCOM.\n");
     return NS_ERROR_FAILURE;
   }
 
   // This will set this thread as the main thread.
   gBootstrap->NS_LogInit();
 
@@ -250,17 +250,17 @@ int main(int argc, char* argv[], char* e
     // We need to initialize the sandbox TargetServices before InitXPCOMGlue
     // because we might need the sandbox broker to give access to some files.
     if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
       Output("Failed to initialize the sandbox target services.");
       return 255;
     }
 #  endif
 
-    nsresult rv = InitXPCOMGlue();
+    nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
     if (NS_FAILED(rv)) {
       return 255;
     }
 
     int result = content_process_main(gBootstrap.get(), argc, argv);
 
 #  if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST)
     DllBlocklist_Shutdown();
@@ -272,17 +272,17 @@ int main(int argc, char* argv[], char* e
     return result;
   }
 #endif
 
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize(gBlocklistInitFlags);
 #endif
 
-  nsresult rv = InitXPCOMGlue();
+  nsresult rv = InitXPCOMGlue(LibLoadingStrategy::ReadAhead);
   if (NS_FAILED(rv)) {
     return 255;
   }
 
   gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
   gBootstrap->XRE_EnableSameExecutableForContentProc();
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -191,17 +191,18 @@ static void* dlopenLibrary(const char* l
 }
 
 static mozglueresult loadGeckoLibs() {
   TimeStamp t0 = TimeStamp::Now();
   struct rusage usage1_thread, usage1;
   getrusage(RUSAGE_THREAD, &usage1_thread);
   getrusage(RUSAGE_SELF, &usage1);
 
-  gBootstrap = GetBootstrap(getUnpackedLibraryName("libxul.so").get());
+  gBootstrap = GetBootstrap(getUnpackedLibraryName("libxul.so").get(),
+                            LibLoadingStrategy::ReadAhead);
   if (!gBootstrap) {
     __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad",
                         "Couldn't get a handle to libxul!");
     return FAILURE;
   }
 
   TimeStamp t1 = TimeStamp::Now();
   struct rusage usage2_thread, usage2;
--- a/toolkit/xre/Bootstrap.h
+++ b/toolkit/xre/Bootstrap.h
@@ -123,31 +123,39 @@ class Bootstrap {
   virtual void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) = 0;
 #endif
 
 #ifdef MOZ_IPDL_TESTS
   virtual int XRE_RunIPDLTest(int argc, char** argv) = 0;
 #endif
 };
 
+enum class LibLoadingStrategy {
+  NoReadAhead,
+  ReadAhead,
+};
+
 /**
  * Creates and returns the singleton instnace of the bootstrap object.
  * @param `b` is an outparam. We use a parameter and not a return value
  *        because MSVC doesn't let us return a c++ class from a function with
  *        "C" linkage. On failure this will be null.
  * @note This function may only be called once and will crash if called again.
  */
 #ifdef XPCOM_GLUE
 typedef void (*GetBootstrapType)(Bootstrap::UniquePtr&);
-Bootstrap::UniquePtr GetBootstrap(const char* aXPCOMFile = nullptr);
+Bootstrap::UniquePtr GetBootstrap(
+    const char* aXPCOMFile = nullptr,
+    LibLoadingStrategy aLibLoadingStrategy = LibLoadingStrategy::NoReadAhead);
 #else
 extern "C" NS_EXPORT void NS_FROZENCALL
 XRE_GetBootstrap(Bootstrap::UniquePtr& b);
 
-inline Bootstrap::UniquePtr GetBootstrap(const char* aXPCOMFile = nullptr) {
+inline Bootstrap::UniquePtr GetBootstrap(
+    const char* aXPCOMFile = nullptr) {
   Bootstrap::UniquePtr bootstrap;
   XRE_GetBootstrap(bootstrap);
   return bootstrap;
 }
 #endif
 
 }  // namespace mozilla
 
--- a/xpcom/glue/standalone/nsXPCOMGlue.cpp
+++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp
@@ -118,35 +118,41 @@ static void AppendDependentLib(LibHandle
   }
 
   d->next = sTop;
   d->libHandle = aLibHandle;
 
   sTop = d;
 }
 
-static bool ReadDependentCB(pathstr_t aDependentLib) {
+static bool ReadDependentCB(pathstr_t aDependentLib,
+                            LibLoadingStrategy aLibLoadingStrategy) {
 #ifndef MOZ_LINKER
-  // We do this unconditionally because of data in bug 771745
-  ReadAheadLib(aDependentLib);
+  // Don't bother doing a ReadAhead if we're not in the parent process.
+  // What we need from the library should already be in the system file
+  // cache.
+  if (aLibLoadingStrategy == LibLoadingStrategy::ReadAhead) {
+    ReadAheadLib(aDependentLib);
+  }
 #endif
   LibHandleType libHandle = GetLibHandle(aDependentLib);
   if (libHandle) {
     AppendDependentLib(libHandle);
   }
 
   return libHandle;
 }
 
 #ifdef XP_WIN
-static bool ReadDependentCB(const char* aDependentLib) {
+static bool ReadDependentCB(const char* aDependentLib,
+                            LibLoadingStrategy aLibLoadingStrategy) {
   wchar_t wideDependentLib[MAX_PATH];
   MultiByteToWideChar(CP_UTF8, 0, aDependentLib, -1, wideDependentLib,
                       MAX_PATH);
-  return ReadDependentCB(wideDependentLib);
+  return ReadDependentCB(wideDependentLib, aLibLoadingStrategy);
 }
 
 inline FILE* TS_tfopen(const char* path, const wchar_t* mode) {
   wchar_t wPath[MAX_PATH];
   MultiByteToWideChar(CP_UTF8, 0, path, -1, wPath, MAX_PATH);
   return _wfopen(wPath, mode);
 }
 #else
@@ -193,19 +199,20 @@ static const char* ns_strrpbrk(const cha
       }
     }
   }
 
   return found;
 }
 #endif
 
-static nsresult XPCOMGlueLoad(const char* aXPCOMFile) {
+static nsresult XPCOMGlueLoad(const char* aXPCOMFile,
+                              LibLoadingStrategy aLibLoadingStrategy) {
 #ifdef MOZ_LINKER
-  if (!ReadDependentCB(aXPCOMFile)) {
+  if (!ReadDependentCB(aXPCOMFile, aLibLoadingStrategy)) {
     return NS_ERROR_FAILURE;
   }
 #else
   char xpcomDir[MAXPATHLEN];
 #  ifdef XP_WIN
   const char* lastSlash = ns_strrpbrk(aXPCOMFile, "/\\");
 #  elif XP_MACOSX
   // On OSX, the dependentlibs.list file lives under Contents/Resources.
@@ -291,17 +298,17 @@ static nsresult XPCOMGlueLoad(const char
       buffer[l - 1] = '\0';
     }
 
     if (l + size_t(cursor - xpcomDir) > MAXPATHLEN) {
       return NS_ERROR_FAILURE;
     }
 
     strcpy(cursor, buffer);
-    if (!ReadDependentCB(xpcomDir)) {
+    if (!ReadDependentCB(xpcomDir, aLibLoadingStrategy)) {
       XPCOMGlueUnload();
       return NS_ERROR_FAILURE;
     }
   }
 #endif
   return NS_OK;
 }
 
@@ -337,17 +344,18 @@ class GSliceInit {
 
  private:
   bool mHadGSlice;
 };
 #endif
 
 namespace mozilla {
 
-Bootstrap::UniquePtr GetBootstrap(const char* aXPCOMFile) {
+Bootstrap::UniquePtr GetBootstrap(const char* aXPCOMFile,
+                                  LibLoadingStrategy aLibLoadingStrategy) {
 #ifdef MOZ_GSLICE_INIT
   GSliceInit gSliceInit;
 #endif
 
   if (!aXPCOMFile) {
     return nullptr;
   }
 
@@ -358,17 +366,17 @@ Bootstrap::UniquePtr GetBootstrap(const 
   }
   size_t base_len = size_t(lastSlash - aXPCOMFile) + 1;
 
   UniqueFreePtr<char> file(
       reinterpret_cast<char*>(malloc(base_len + sizeof(XPCOM_DLL))));
   memcpy(file.get(), aXPCOMFile, base_len);
   memcpy(file.get() + base_len, XPCOM_DLL, sizeof(XPCOM_DLL));
 
-  if (NS_FAILED(XPCOMGlueLoad(file.get()))) {
+  if (NS_FAILED(XPCOMGlueLoad(file.get(), aLibLoadingStrategy))) {
     return nullptr;
   }
 
   GetBootstrapType func =
       (GetBootstrapType)GetSymbol(sTop->libHandle, "XRE_GetBootstrap");
   if (!func) {
     return nullptr;
   }