1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// 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 <tuple>
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/notreached.h"
#include "base/win/windows_version.h"
namespace app_launch_prefetch {
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 std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument1 = {L"/prefetch:1", 1};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument2 = {L"/prefetch:2", 2};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument3 = {L"/prefetch:3", 3};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument4 = {L"/prefetch:4", 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 std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument5 = {L"/prefetch:5", 5};
// constexpr base::CommandLine::StringViewType kPrefetchArgument6 =
// "/prefetch:6";
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument7 = {L"/prefetch:7", 7};
// Catch all for Windows versions before Win 11 21H2.
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument8 = {L"/prefetch:8", 8};
// On Windows 11 21H2 and later the prefetch range was expanded to be [1,16]
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument9 = {L"/prefetch:9", 9};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument10 = {L"/prefetch:10", 10};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument11 = {L"/prefetch:11", 11};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument12 = {L"/prefetch:12", 12};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument13 = {L"/prefetch:13", 13};
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument14 = {L"/prefetch:14", 14};
// constexpr base::CommandLine::StringViewType kPrefetchArgument15 =
// "/prefetch:15";
// Catch all for Windows versions Win 11 21H2 and later.
constexpr std::tuple<base::CommandLine::StringViewType, int>
kPrefetchArgument16 = {L"/prefetch:16", 16};
const std::tuple<base::CommandLine::StringViewType, int>& GetPrefetchInfo(
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 kGPUInfo:
return kPrefetchArgument8;
case kUtilityAudio:
return kPrefetchArgument8;
case kUtilityStorage:
return kPrefetchArgument8;
case kUtilityOther:
return kPrefetchArgument8;
case kCatchAll:
return kPrefetchArgument8;
}
}
}
} // namespace
base::CommandLine::StringViewType GetPrefetchSwitch(SubprocessType type) {
return std::get<0>(GetPrefetchInfo(type));
}
uint32_t GetPrefetchBucket(SubprocessType type) {
return std::get<1>(GetPrefetchInfo(type));
}
} // namespace app_launch_prefetch
|