summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfdoray <fdoray@chromium.org>2016-01-21 14:14:21 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-21 22:15:45 +0000
commitdee064299d3b3a13d5cc35f219d87d6a8478f227 (patch)
tree13ab77a3e2de6b2dc0cc3d6734d96adae77c9aa7
parentcdb380ab20c7fbd93c198d59e21f4d4afd12b95f (diff)
downloadchromium_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}
-rw-r--r--chrome/app/main_dll_loader_win.cc24
-rw-r--r--components/startup_metric_utils/common/pre_read_field_trial_utils_win.cc38
-rw-r--r--components/startup_metric_utils/common/pre_read_field_trial_utils_win.h36
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