Reland "windows startup: OVERRIDE_PREFETCH_PARAMETER on singleton"
This has been fixed by replacing DumpWithoutCrashing with a UMA
histogram.
Fixed: 381384992, 380088804
Bug: 325307453
Original change's description:
> Revert "windows startup: OVERRIDE_PREFETCH_PARAMETER on acquiring singleton"
>
> This reverts commit 5693c9daaeb9ad34a00575195caf7f8a16342c35.
>
> Reason for revert: Broken GPU tests. 381384992
>
> See three candidate CLs for fixes here:
> - crrev.com/c/6055287
> - crrev.com/c/6055311
> - crrev.com/c/6056175
>
> Original change's description:
> > windows startup: OVERRIDE_PREFETCH_PARAMETER on acquiring singleton
> >
> > With this change, run a field trial to determine the impact of
> > OVERRIDE_PREFETCH_PARAMETER on the acquiry of the singleton.
> >
> > This should effectively solve the case where short-lived browser
> > processes are polluting the App Launch Prefetch history. Local tracing
> > leads us to believe that recent versions of Windows implicitly support
> > this but we decided to experiment with this newly discovered API
> > nonetheless to verify how this fares in the wild.
> >
> > Bug: 325307453, 380088804
> > Change-Id: I515d983c6f558e4e896aadf4796b48487236f5b8
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5939457
> > Reviewed-by: Etienne Bergeron <[email protected]>
> > Reviewed-by: Gabriel Charette <[email protected]>
> > Reviewed-by: Greg Thompson <[email protected]>
> > Commit-Queue: Sean Maher <[email protected]>
> > Cr-Commit-Position: refs/heads/main@{#1389076}
>
> Bug: 325307453, 380088804
> Change-Id: I36945c81352bf4eae35d982c17db40bae0e8b2e5
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6055288
> Owners-Override: Kenichi Ishibashi <[email protected]>
> Bot-Commit: Rubber Stamper <[email protected]>
> Reviewed-by: Kenichi Ishibashi <[email protected]>
> Commit-Queue: Sean Maher <[email protected]>
> Cr-Commit-Position: refs/heads/main@{#1389655}
Bug: 325307453, 380088804
Change-Id: I4d14ad4b59c34ba747d01f6d4c66a3018284673a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6059052
Reviewed-by: Greg Thompson <[email protected]>
Reviewed-by: Sean Maher <[email protected]>
Reviewed-by: Etienne Bergeron <[email protected]>
Commit-Queue: Sean Maher <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1391721}
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index f39778a..9018092 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -957,6 +957,11 @@
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_WIN)
+ ChromeProcessSingleton::GetInstance()
+ ->ChromeProcessSingleton::InitializeFeatures();
+#endif
+
CommonEarlyInitialization(invoked_in);
// Initializes the resource bundle and determines the locale.
diff --git a/chrome/browser/chrome_process_singleton.cc b/chrome/browser/chrome_process_singleton.cc
index 89f5198..166dd73 100644
--- a/chrome/browser/chrome_process_singleton.cc
+++ b/chrome/browser/chrome_process_singleton.cc
@@ -6,6 +6,16 @@
#include <utility>
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_WIN)
+#include <windows.h>
+
+#include "base/metrics/histogram_functions.h"
+#include "chrome/common/chrome_features.h"
+#include "components/app_launch_prefetch/app_launch_prefetch.h"
+#endif
+
namespace {
ChromeProcessSingleton* g_chrome_process_singleton_ = nullptr;
@@ -49,6 +59,50 @@
startup_lock_.Unlock();
}
+#if BUILDFLAG(IS_WIN)
+void ChromeProcessSingleton::InitializeFeatures() {
+ // On Windows, App Launch Prefetch (ALPF) will monitor the disk accesses done
+ // by processes launched, and load the resources used into memory before the
+ // process needs them, if possible. Different Chrome process types use
+ // different resources, and this is signaled to ALPF via the command line:
+ // passing "/prefetch:N" on the command line with different numbers causes
+ // ALPF to treat two launches placed in different buckets as separarate
+ // applications for its purposes.
+ //
+ // Short lived browser processes occur on notification and rendezvous, both
+ // cases where nearly nothing will be used from disk, and which are not
+ // launched with `/prefetch`, and are thus considered "browser" processes
+ // according to ALPF. This may be polluting the ALPF cache.
+ //
+ // The `::ProcessOverrideSubsequentPrefetchParameter` process information
+ // attribute will change the behavior of ALPF to explicitly consider
+ // subsequent launches while this singleton process is running (rendezvous,
+ // toast) of Chrome which do not specify a prefetch bucket as if they had
+ // specified the `kCatchAll` bucket.
+ //
+ // It is expected that this will overall improve the behavior of ALPF on
+ // Windows, which should decrease startup time for ordinary browser processes.
+ if (is_singleton_instance_ &&
+ (wcsstr(::GetCommandLineW(), L"/prefetch:") == nullptr) &&
+ base::FeatureList::IsEnabled(features::kOverridePrefetchOnSingleton)) {
+ OVERRIDE_PREFETCH_PARAMETER prefetch_parameter = {};
+ prefetch_parameter.Value = app_launch_prefetch::GetPrefetchBucket(
+ app_launch_prefetch::SubprocessType::kCatchAll);
+ // This is not fatal because it is an optimization and has no bearing on the
+ // functionality of the browser. See crbug.com/380088804 for details. It has
+ // been seen that occasionally (in CQ), this call fails with
+ // ERROR_INTERNAL_ERROR.
+ base::UmaHistogramSparse(
+ "Startup.PrefetchOverrideErrorCode",
+ ::SetProcessInformation(::GetCurrentProcess(),
+ ::ProcessOverrideSubsequentPrefetchParameter,
+ &prefetch_parameter, sizeof(prefetch_parameter))
+ ? ERROR_SUCCESS
+ : ::GetLastError());
+ }
+}
+#endif
+
// static
void ChromeProcessSingleton::CreateInstance(
const base::FilePath& user_data_dir) {
diff --git a/chrome/browser/chrome_process_singleton.h b/chrome/browser/chrome_process_singleton.h
index 7567e5b9..dc79446 100644
--- a/chrome/browser/chrome_process_singleton.h
+++ b/chrome/browser/chrome_process_singleton.h
@@ -48,6 +48,12 @@
bool IsSingletonInstanceForTesting() const { return is_singleton_instance_; }
+#if BUILDFLAG(IS_WIN)
+ // Must only be called both after initialization of FeatureList and
+ // NotifyOtherProcessOrCreate().
+ void InitializeFeatures();
+#endif
+
// Create the chrome process singleton instance for the current process.
static void CreateInstance(const base::FilePath& user_data_dir);
// Delete the chrome process singleton instance.
diff --git a/chrome/browser/chrome_process_singleton_win_unittest.cc b/chrome/browser/chrome_process_singleton_win_unittest.cc
index 0708e48..016fa9db 100644
--- a/chrome/browser/chrome_process_singleton_win_unittest.cc
+++ b/chrome/browser/chrome_process_singleton_win_unittest.cc
@@ -4,13 +4,20 @@
#include "chrome/browser/chrome_process_singleton.h"
+#include <windows.h>
+
+#include <processthreadsapi.h>
+
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
+#include "chrome/common/chrome_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -90,3 +97,21 @@
EXPECT_TRUE(ps1.IsSingletonInstanceForTesting());
EXPECT_FALSE(ps2.IsSingletonInstanceForTesting());
}
+
+TEST(ChromeProcessSingletonTest, OverridePrefetch) {
+ base::test::ScopedFeatureList scoped_feature(
+ features::kOverridePrefetchOnSingleton);
+ base::ScopedTempDir profile_dir;
+ ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
+ ChromeProcessSingleton ps(profile_dir.GetPath());
+ base::HistogramTester tester;
+
+ ProcessSingleton::NotifyResult result = ps.NotifyOtherProcessOrCreate();
+ ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
+
+ ps.ChromeProcessSingleton::InitializeFeatures();
+
+ auto buckets = tester.GetAllSamples("Startup.PrefetchOverrideErrorCode");
+ EXPECT_EQ(1UL, buckets.size());
+ EXPECT_EQ(1, buckets[0].count);
+}
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index d8db5c5..520f168b 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -890,6 +890,14 @@
base::FEATURE_ENABLED_BY_DEFAULT);
#endif
+#if BUILDFLAG(IS_WIN)
+// Changes behavior of App Launch Prefetch to ignore chrome browser launches
+// after acquiry of the singleton.
+BASE_FEATURE(kOverridePrefetchOnSingleton,
+ "OverridePrefetchOnSingleton",
+ base::FEATURE_DISABLED_BY_DEFAULT);
+#endif
+
// Enables or disables the page content opt-in and setting.
BASE_FEATURE(kPageContentOptIn,
"PageContentOptIn",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 94e62e3..e0ae9c9 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -528,6 +528,11 @@
COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kOomIntervention);
#endif
+#if BUILDFLAG(IS_WIN)
+COMPONENT_EXPORT(CHROME_FEATURES)
+BASE_DECLARE_FEATURE(kOverridePrefetchOnSingleton);
+#endif
+
COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kPageContentOptIn);
#if BUILDFLAG(IS_CHROMEOS_ASH)