| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/app_launch_prefetch/app_launch_prefetch.h" |
| |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "base/notreached.h" |
| #include "base/win/windows_version.h" |
| |
| namespace { |
| |
| BASE_FEATURE(kExpandedPrefetchRange, |
| "ExpandedPrefetchRange", |
| base::FEATURE_ENABLED_BY_DEFAULT); |
| |
| // /prefetch:# arguments to use when launching various process types. It has |
| // been observed that when file reads are consistent for 3 process launches with |
| // the same /prefetch:# argument, the Windows prefetcher starts issuing reads in |
| // batch at process launch. Because reads depend on the process type, the |
| // prefetcher wouldn't be able to observe consistent reads if no /prefetch:# |
| // arguments were used. Note that the browser process has no /prefetch:# |
| // argument; as such all other processes must have one in order to avoid |
| // polluting its profile. |
| |
| // On Windows versions before Win11 21H2 the value must always be in [1, 8]; |
| // otherwise it is treated as 0 by the Windows prefetcher and will interfere |
| // with the main process launch. |
| |
| constexpr base::CommandLine::StringViewType kPrefetchArgument1 = L"/prefetch:1"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument2 = L"/prefetch:2"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument3 = L"/prefetch:3"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument4 = L"/prefetch:4"; |
| |
| // /prefetch:5, /prefetch:6 and /prefetch:7 are reserved for content embedders |
| // and are not to be used by content itself, with caveats: we violate this |
| // rule with kBrowserBackground using bucket 5, while the 7th bucket is used by |
| // the crashpad fallback handler. |
| constexpr base::CommandLine::StringViewType kPrefetchArgument5 = L"/prefetch:5"; |
| // constexpr base::CommandLine::StringViewType kPrefetchArgument6 = |
| // "/prefetch:6"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument7 = L"/prefetch:7"; |
| |
| // Catch all for Windows versions before Win 11 21H2. |
| constexpr base::CommandLine::StringViewType kPrefetchArgument8 = L"/prefetch:8"; |
| |
| // On Windows 11 21H2 and later the prefetch range was expanded to be [1,16] |
| |
| constexpr base::CommandLine::StringViewType kPrefetchArgument9 = L"/prefetch:9"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument10 = |
| L"/prefetch:10"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument11 = |
| L"/prefetch:11"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument12 = |
| L"/prefetch:12"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument13 = |
| L"/prefetch:13"; |
| constexpr base::CommandLine::StringViewType kPrefetchArgument14 = |
| L"/prefetch:14"; |
| // constexpr base::CommandLine::StringViewType kPrefetchArgument15 = |
| // "/prefetch:15"; |
| |
| // Catch all for Windows versions Win 11 21H2 and later. |
| constexpr base::CommandLine::StringViewType kPrefetchArgument16 = |
| L"/prefetch:16"; |
| |
| } // namespace |
| |
| namespace app_launch_prefetch { |
| |
| base::CommandLine::StringViewType GetPrefetchSwitch(SubprocessType type) { |
| using enum SubprocessType; |
| if (base::win::GetVersion() >= base::win::Version::WIN11 && |
| base::FeatureList::GetInstance() && |
| base::FeatureList::IsEnabled(kExpandedPrefetchRange)) { |
| // These are the prefetch arguments used on Windows versions |
| // for Win11 and later. There are fewer processes using the same |
| // values and this should lead to better App Launch PreFetch (ALPF) |
| // behavior. |
| |
| // kPrefetchArgument8 and kPrefetchArgument15 are currently unused. |
| switch (type) { |
| case kBrowser: |
| NOTREACHED(); |
| case kRenderer: |
| return kPrefetchArgument1; |
| case kGPU: |
| return kPrefetchArgument2; |
| case kPpapi: |
| return kPrefetchArgument3; |
| case kCrashpad: |
| return kPrefetchArgument4; |
| case kBrowserBackground: |
| return kPrefetchArgument5; |
| case kCrashpadFallback: |
| return kPrefetchArgument7; |
| case kExtension: |
| return kPrefetchArgument9; |
| case kGPUInfo: |
| return kPrefetchArgument10; |
| case kUtilityNetworkService: |
| return kPrefetchArgument11; |
| case kUtilityAudio: |
| return kPrefetchArgument12; |
| case kUtilityStorage: |
| return kPrefetchArgument13; |
| case kUtilityOther: |
| return kPrefetchArgument14; |
| case kCatchAll: |
| return kPrefetchArgument16; |
| } |
| } else { |
| // These are the prefetch arguments used on Windows versions |
| // before Win11 21H2. There are multiple processes using the same values |
| // and this leads to less than optimal App Launch PreFetch (ALPF) behavior. |
| |
| // /prefetch:5, /prefetch:6 and /prefetch:7 are reserved for content |
| // embedders and are not to be used by content itself, with caveats: we |
| // violate this rule with kBrowserBackground using bucket 5, while the 7th |
| // bucket is used by the crashpad fallback handler. |
| switch (type) { |
| case kBrowser: |
| NOTREACHED(); |
| case kRenderer: |
| return kPrefetchArgument1; |
| case kGPU: |
| return kPrefetchArgument2; |
| case kExtension: |
| return kPrefetchArgument2; |
| case kPpapi: |
| return kPrefetchArgument3; |
| case kUtilityNetworkService: |
| return kPrefetchArgument3; |
| case kCrashpad: |
| return kPrefetchArgument4; |
| case kBrowserBackground: |
| return kPrefetchArgument5; |
| case kCrashpadFallback: |
| return kPrefetchArgument7; |
| case kCatchAll: |
| return kPrefetchArgument8; |
| case kGPUInfo: |
| return kPrefetchArgument8; |
| case kUtilityAudio: |
| return kPrefetchArgument8; |
| case kUtilityStorage: |
| return kPrefetchArgument8; |
| case kUtilityOther: |
| return kPrefetchArgument8; |
| } |
| } |
| } |
| |
| } // namespace app_launch_prefetch |