diff options
author | fdoray <fdoray@chromium.org> | 2016-01-21 14:14:21 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-21 22:15:45 +0000 |
commit | dee064299d3b3a13d5cc35f219d87d6a8478f227 (patch) | |
tree | 13ab77a3e2de6b2dc0cc3d6734d96adae77c9aa7 | |
parent | cdb380ab20c7fbd93c198d59e21f4d4afd12b95f (diff) | |
download | chromium_src-dee064299d3b3a13d5cc35f219d87d6a8478f227.zip chromium_src-dee064299d3b3a13d5cc35f219d87d6a8478f227.tar.gz chromium_src-dee064299d3b3a13d5cc35f219d87d6a8478f227.tar.bz2 |
Store PreRead options obtained from the registry in a global variable.
Instead of reading PreRead options from the registry every time they
are needed, read them once and store them in a global variable.
This optimization isn't immediately useful as PreRead options are
currently read only once per process. However, with the upcoming
/prefetch:# experiment, the browser process will need the PreRead
options every time it launches a process.
This CL also has these benefits:
- The caller of GetPreReadOptions doesn't need to know the product
registry path. This will allow content to get the PreRead options
to decide whether it should use a /prefetch:# switch when
launching a process.
- The PreRead options are returned as a bit field instead of by
setting multiple booleans. This will facilitate the addition of
new PreRead options.
BUG=577698
Review URL: https://codereview.chromium.org/1610733002
Cr-Commit-Position: refs/heads/master@{#370805}
3 files changed, 54 insertions, 44 deletions
diff --git a/chrome/app/main_dll_loader_win.cc b/chrome/app/main_dll_loader_win.cc index a70a678..f28d301 100644 --- a/chrome/app/main_dll_loader_win.cc +++ b/chrome/app/main_dll_loader_win.cc @@ -64,35 +64,31 @@ HMODULE LoadModuleWithDirectory(const base::FilePath& module) { ::SetCurrentDirectoryW(module.DirName().value().c_str()); // Get pre-read options from the PreRead field trial. - bool trial_no_pre_read = false; - bool trial_high_priority = false; - bool trial_only_if_cold = false; - bool trial_prefetch_virtual_memory = false; - startup_metric_utils::GetPreReadOptions( - BrowserDistribution::GetDistribution()->GetRegistryPath(), - &trial_no_pre_read, &trial_high_priority, &trial_only_if_cold, - &trial_prefetch_virtual_memory); + startup_metric_utils::InitializePreReadOptions( + BrowserDistribution::GetDistribution()->GetRegistryPath()); + const startup_metric_utils::PreReadOptions pre_read_options = + startup_metric_utils::GetPreReadOptions(); // Pre-read the binary to warm the memory caches (avoids a lot of random IO). - if (!trial_no_pre_read) { + if (!pre_read_options.no_pre_read) { base::ThreadPriority previous_priority = base::ThreadPriority::NORMAL; - if (trial_high_priority) { + if (pre_read_options.high_priority) { previous_priority = base::PlatformThread::GetCurrentThreadPriority(); base::PlatformThread::SetCurrentThreadPriority( base::ThreadPriority::DISPLAY); } - if (trial_only_if_cold) { + if (pre_read_options.only_if_cold) { base::MemoryMappedFile module_memory_map; const bool map_initialize_success = module_memory_map.Initialize(module); DCHECK(map_initialize_success); if (!IsMemoryMappedFileWarm(module_memory_map)) { - if (trial_prefetch_virtual_memory) + if (pre_read_options.prefetch_virtual_memory) PreReadMemoryMappedFile(module_memory_map, module); else PreReadFile(module); } - } else if (trial_prefetch_virtual_memory) { + } else if (pre_read_options.prefetch_virtual_memory) { base::MemoryMappedFile module_memory_map; const bool map_initialize_success = module_memory_map.Initialize(module); DCHECK(map_initialize_success); @@ -101,7 +97,7 @@ HMODULE LoadModuleWithDirectory(const base::FilePath& module) { PreReadFile(module); } - if (trial_high_priority) + if (pre_read_options.high_priority) base::PlatformThread::SetCurrentThreadPriority(previous_priority); } diff --git a/components/startup_metric_utils/common/pre_read_field_trial_utils_win.cc b/components/startup_metric_utils/common/pre_read_field_trial_utils_win.cc index 6aa82a1..a75a81c 100644 --- a/components/startup_metric_utils/common/pre_read_field_trial_utils_win.cc +++ b/components/startup_metric_utils/common/pre_read_field_trial_utils_win.cc @@ -35,6 +35,10 @@ const base::char16 kPrefetchVirtualMemoryVariationName[] = // Registry key in which the PreRead field trial group is stored. const base::char16 kPreReadFieldTrialRegistryKey[] = L"\\PreReadFieldTrial"; +// Pre-read options to use for the current process. This is initialized by +// InitializePreReadOptions(). +PreReadOptions g_pre_read_options = {false, false, false, false}; + // Returns the registry path in which the PreRead group is stored. base::string16 GetPreReadRegistryPath( const base::string16& product_registry_path) { @@ -43,16 +47,8 @@ base::string16 GetPreReadRegistryPath( } // namespace -void GetPreReadOptions(const base::string16& product_registry_path, - bool* no_pre_read, - bool* high_priority, - bool* only_if_cold, - bool* prefetch_virtual_memory) { +void InitializePreReadOptions(const base::string16& product_registry_path) { DCHECK(!product_registry_path.empty()); - DCHECK(no_pre_read); - DCHECK(high_priority); - DCHECK(only_if_cold); - DCHECK(prefetch_virtual_memory); // Open the PreRead field trial's registry key. const base::string16 registry_path = @@ -61,25 +57,33 @@ void GetPreReadOptions(const base::string16& product_registry_path, KEY_QUERY_VALUE); // Set the PreRead field trial's options. - struct VariationMapping { + struct { const base::char16* name; - bool* variable; + bool* option; } const variations_mappings[] = { - {kNoPreReadVariationName, no_pre_read}, - {kHighPriorityVariationName, high_priority}, - {kOnlyIfColdVariationName, only_if_cold}, - {kPrefetchVirtualMemoryVariationName, prefetch_virtual_memory}, + {kNoPreReadVariationName, &g_pre_read_options.no_pre_read}, + {kHighPriorityVariationName, &g_pre_read_options.high_priority}, + {kOnlyIfColdVariationName, &g_pre_read_options.only_if_cold}, + {kPrefetchVirtualMemoryVariationName, + &g_pre_read_options.prefetch_virtual_memory}, }; for (const auto& mapping : variations_mappings) { // Set the option variable to true if the corresponding value is found in // the registry. Set to false otherwise (default behavior). DWORD value = 0; - *mapping.variable = key.ReadValueDW(mapping.name, &value) == ERROR_SUCCESS; - DCHECK(!*mapping.variable || value == 1); + if (key.ReadValueDW(mapping.name, &value) == ERROR_SUCCESS) { + DCHECK_EQ(1U, value); + DCHECK(!*mapping.option); + *mapping.option = true; + } } } +PreReadOptions GetPreReadOptions() { + return g_pre_read_options; +} + void UpdatePreReadOptions(const base::string16& product_registry_path) { DCHECK(!product_registry_path.empty()); diff --git a/components/startup_metric_utils/common/pre_read_field_trial_utils_win.h b/components/startup_metric_utils/common/pre_read_field_trial_utils_win.h index 612f76b..cacf4b3 100644 --- a/components/startup_metric_utils/common/pre_read_field_trial_utils_win.h +++ b/components/startup_metric_utils/common/pre_read_field_trial_utils_win.h @@ -19,19 +19,29 @@ namespace startup_metric_utils { using RegisterPreReadSyntheticFieldTrialCallback = const base::Callback<bool(const std::string&, const std::string&)>; -// Get DLL pre-reading options. |product_registry_path| is the registry path -// under which the registry key for this field trial resides. The |no_pre_read| -// option is set if DLLs should not be pre-read. The |high_priority| option is -// set if pre-reading should be done with a high thread priority. The -// |only_if_cold| option is set if only cold DLLs should be pre-read. The -// |prefetch_virtual_memory| option is set if the -// ::PrefetchVirtualMemory function should be used to pre-read DLLs, if -// available. -void GetPreReadOptions(const base::string16& product_registry_path, - bool* no_pre_read, - bool* high_priority, - bool* only_if_cold, - bool* prefetch_virtual_memory); +// The options controlled by the PreRead field trial. +struct PreReadOptions { + // No explicit DLL pre-reading. + bool no_pre_read; + + // Pre-read DLLs with a high thread priority. + bool high_priority; + + // Pre-read DLLs only when they are cold. + bool only_if_cold; + + // Pre-read DLLs using the ::PrefetchVirtualMemory function, if available. + bool prefetch_virtual_memory; +}; + +// Initializes DLL pre-reading options from the registry. +// |product_registry_path| is the registry path under which the registry key for +// this field trial resides. +void InitializePreReadOptions(const base::string16& product_registry_path); + +// Returns the bitfield of the DLL pre-reading options to use for the current +// process. InitializePreReadOptions() must have been called before this. +PreReadOptions GetPreReadOptions(); // Updates DLL pre-reading options in the registry with the latest info for the // next startup. |product_registry_path| is the registry path under which the |