diff options
Diffstat (limited to 'ipc/glue/GeckoChildProcessHost.cpp')
-rw-r--r-- | ipc/glue/GeckoChildProcessHost.cpp | 122 |
1 files changed, 118 insertions, 4 deletions
diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index bde3a9a389..cd03b488ed 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -13,6 +13,7 @@ #include "base/task.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/process_watcher.h" +#include "mozilla/ProcessType.h" #ifdef MOZ_WIDGET_COCOA # include <bsm/libbsm.h> # include <mach/mach_traps.h> @@ -66,6 +67,7 @@ #ifdef XP_WIN # include <stdlib.h> +# include "mozilla/WindowsVersion.h" # include "nsIWinTaskbar.h" # define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1" @@ -249,7 +251,7 @@ class BaseProcessLauncher { }; #ifdef XP_WIN -class WindowsProcessLauncher : public BaseProcessLauncher { +class WindowsProcessLauncher final : public BaseProcessLauncher { public: WindowsProcessLauncher(GeckoChildProcessHost* aHost, std::vector<std::string>&& aExtraOpts) @@ -261,8 +263,13 @@ class WindowsProcessLauncher : public BaseProcessLauncher { virtual RefPtr<ProcessHandlePromise> DoLaunch() override; virtual Result<Ok, LaunchError> DoFinishLaunch() override; + private: + void AddApplicationPrefetchArgument(); + mozilla::Maybe<CommandLine> mCmdLine; +# ifdef MOZ_SANDBOX bool mUseSandbox = false; +# endif const Buffer<IMAGE_THUNK_DATA>* mCachedNtdllThunk; }; @@ -343,7 +350,20 @@ class LinuxProcessLauncher : public PosixProcessLauncher { virtual Result<Ok, LaunchError> DoSetup() override; }; typedef LinuxProcessLauncher ProcessLauncher; -# elif +# elif defined(MOZ_WIDGET_UIKIT) +class IosProcessLauncher : public PosixProcessLauncher { + public: + IosProcessLauncher(GeckoChildProcessHost* aHost, + std::vector<std::string>&& aExtraOpts) + : PosixProcessLauncher(aHost, std::move(aExtraOpts)) {} + + protected: + virtual RefPtr<ProcessHandlePromise> DoLaunch() override { + MOZ_CRASH("IosProcessLauncher::DoLaunch not implemented"); + } +}; +typedef IosProcessLauncher ProcessLauncher; +# else # error "Unknown platform" # endif #endif // XP_UNIX @@ -1189,7 +1209,7 @@ Result<Ok, LaunchError> PosixProcessLauncher::DoSetup() { } mLaunchOptions->env_map["LD_LIBRARY_PATH"] = new_ld_lib_path.get(); -# elif XP_DARWIN +# elif XP_MACOSX // With signed production Mac builds, the dynamic linker (dyld) will // ignore dyld environment variables preventing the use of variables // such as DYLD_LIBRARY_PATH and DYLD_INSERT_LIBRARIES. @@ -1212,7 +1232,7 @@ Result<Ok, LaunchError> PosixProcessLauncher::DoSetup() { // Prevent connection attempts to diagnosticd(8) to save cycles. Log // messages can trigger these connection attempts, but access to // diagnosticd is blocked in sandboxed child processes. -# ifdef MOZ_SANDBOX +# if defined(MOZ_SANDBOX) && defined(XP_MACOSX) if (mDisableOSActivityMode) { mLaunchOptions->env_map["OS_ACTIVITY_MODE"] = "disable"; } @@ -1388,6 +1408,97 @@ Result<Ok, LaunchError> MacProcessLauncher::DoFinishLaunch() { #endif // XP_MACOSX #ifdef XP_WIN +void WindowsProcessLauncher::AddApplicationPrefetchArgument() { + // The Application Launch Prefetcher (ALPF) is an ill-documented Windows + // subsystem that's intended to speed up process launching, apparently mostly + // by assuming that a binary is going to want to load the same DLLs as it did + // the last time it launched, and getting those prepped for loading as well. + // + // For most applications, that's a good bet. For Firefox, it's less so, since + // we use the same binary with different arguments to do completely different + // things. Windows does allow applications to take up multiple slots in this + // cache, but the "which bucket does this invocation go in?" mechanism is + // highly unusual: the OS scans the command line and looks for a command-line + // switch of a particular form. + // + // (There is allegedly a way to do this without involving the command line, + // OVERRIDE_PREFETCH_PARAMETER, but it's even more poorly documented.) + + // Applications' different prefetch-cache buckets are named with numbers from + // "1" to some OS-version-determined limit, with an additional implicit "0" + // cache bucket which is used when no valid prefetch cache slot is named. + // + // (The "0" bucket's existence and behavior is not documented, but has been + // confirmed by observing the creation and enumeration of cache files in the + // C:\Windows\Prefetch folder.) + static size_t const kMaxSlotNo = IsWin1122H2OrLater() ? 16 : 8; + + // Determine the prefetch-slot number to be used for the process we're about + // to launch. + // + // This may be changed freely between Firefox versions, as a Firefox update + // will completely invalidate the prefetch cache anyway. + size_t const prefetchSlot = [&]() -> size_t { + switch (mProcessType) { + // This code path is not used when starting the main process... + case GeckoProcessType_Default: + // ...ForkServer is not used on Windows... + case GeckoProcessType_ForkServer: + // ..."End" isn't a process-type, just a limit... + case GeckoProcessType_End: + // ...and any new process-types should be considered explicitly here. + default: + MOZ_ASSERT_UNREACHABLE("Invalid process type"); + return 0; + + // We reserve 1 for the main process as started by the launcher process. + // (See LauncherProcessWin.cpp.) Otherwise, we mostly match the process- + // type enumeration. + case GeckoProcessType_Content: + return 2; + case GeckoProcessType_Socket: + return 3; // usurps IPDLUnitTest + case GeckoProcessType_GMPlugin: + return 4; + case GeckoProcessType_GPU: + return 5; + case GeckoProcessType_RemoteSandboxBroker: + return 6; // usurps VR + case GeckoProcessType_RDD: + return 7; + + case GeckoProcessType_Utility: { + // Continue the enumeration, using the SandboxingKind as a + // probably-passably-precise proxy for the process's purpose. + // + // (On Win10 and earlier, or when sandboxing is not used, this will lump + // all utility processes into slot 8.) +# ifndef MOZ_SANDBOX + size_t const val = 0; +# else + size_t const val = static_cast<size_t>(mSandbox); +# endif + return std::min(kMaxSlotNo, 8 + val); + } + + // These process types are started so rarely that we're not concerned + // about their interaction with the prefetch cache. Lump them together at + // the end (possibly alongside other process types). + case GeckoProcessType_IPDLUnitTest: + case GeckoProcessType_VR: + return kMaxSlotNo; + } + }(); + MOZ_ASSERT(prefetchSlot <= kMaxSlotNo); + + if (prefetchSlot == 0) { + // default; no explicit argument needed + return; + } + + mCmdLine->AppendLooseValue(StringPrintf(L"/prefetch:%zu", prefetchSlot)); +} + Result<Ok, LaunchError> WindowsProcessLauncher::DoSetup() { Result<Ok, LaunchError> aError = BaseProcessLauncher::DoSetup(); if (aError.isErr()) { @@ -1568,6 +1679,9 @@ Result<Ok, LaunchError> WindowsProcessLauncher::DoSetup() { // Process type mCmdLine->AppendLooseValue(UTF8ToWide(ChildProcessType())); + // Prefetch cache hint + AddApplicationPrefetchArgument(); + # ifdef MOZ_SANDBOX if (mUseSandbox) { // Mark the handles to inherit as inheritable. |