Bug 1538279 - Only readahead DLLs in parent process r=glandium
☠☠ backed out by d1b15e1a37f0 ☠ ☠
authorDoug Thayer <dothayer@mozilla.com>
Fri, 12 Apr 2019 02:17:48 +0000
changeset 469207 508ee4cf9ea283ba9f43786a5aaf47e33072cf13
parent 469206 6f2e7c819c11054ef4a1261816e7a0d5023759c5
child 469208 af07f58d18cc43677c03e801baa4f81292f314ae
push id35858
push usershindli@mozilla.com
push dateFri, 12 Apr 2019 09:34:00 +0000
treeherdermozilla-central@a632dfa60af6 [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,20 @@ 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();
+    // 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.
+    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 +275,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,38 @@ 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);
+  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 +196,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 +295,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 +341,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 +363,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;
   }