File: app_launch_prefetch.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (174 lines) | stat: -rw-r--r-- 6,521 bytes parent folder | download | duplicates (6)
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