summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 18:25:25 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 18:25:25 +0000
commitfeb6e5499bc2abfda723e754f1455a286bf48695 (patch)
tree246018cdd86fe6854b217e62b45e51b4061f6a4b /base
parent13081fccbf907aef8476c94d904fc94d6c59a206 (diff)
downloadchromium_src-feb6e5499bc2abfda723e754f1455a286bf48695.zip
chromium_src-feb6e5499bc2abfda723e754f1455a286bf48695.tar.gz
chromium_src-feb6e5499bc2abfda723e754f1455a286bf48695.tar.bz2
Fixes warm-start performance on Vista and Win7 when using pre-reading optimization. Avg times go from ~500ms to ~300ms.
TEST=run chrome_frame_perftests.exe --gtest_filter=*X.PerfWarm on Vista/Win7 and XP. Note that warm starts are now faster on Vista and unchanged on XP. BUG=45510 Review URL: http://codereview.chromium.org/3058023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54934 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/file_util_win.cc73
1 files changed, 57 insertions, 16 deletions
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 4090ce4..cef0df4 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -1035,25 +1035,66 @@ bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
bool PreReadImage(const wchar_t* file_path, size_t size_to_read,
size_t step_size) {
- HMODULE dll_module = LoadLibraryExW(
- file_path,
- NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH | DONT_RESOLVE_DLL_REFERENCES);
+ if (win_util::GetWinVersion() > win_util::WINVERSION_XP) {
+ // Vista+ branch. On these OSes, the forced reads through the DLL actually
+ // slows warm starts. The solution is to sequentially read file contents
+ // with an optional cap on total amount to read.
+ ScopedHandle file(
+ CreateFile(file_path,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL));
- if (!dll_module)
- return false;
+ if (!file.IsValid())
+ return false;
+
+ // Default to 1MB sequential reads.
+ const DWORD actual_step_size = std::max(static_cast<DWORD>(step_size),
+ static_cast<DWORD>(1024*1024));
+ LPVOID buffer = ::VirtualAlloc(NULL,
+ actual_step_size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
- PEImage pe_image(dll_module);
- PIMAGE_NT_HEADERS nt_headers = pe_image.GetNTHeaders();
- size_t actual_size_to_read = size_to_read ? size_to_read :
- nt_headers->OptionalHeader.SizeOfImage;
- volatile uint8* touch = reinterpret_cast<uint8*>(dll_module);
- size_t offset = 0;
- while (offset < actual_size_to_read) {
- uint8 unused = *(touch + offset);
- offset += step_size;
+ if (buffer == NULL)
+ return false;
+
+ DWORD len;
+ size_t total_read = 0;
+ while (::ReadFile(file, buffer, actual_step_size, &len, NULL) &&
+ len > 0 &&
+ (size_to_read ? total_read < size_to_read : true)) {
+ total_read += static_cast<size_t>(len);
+ }
+ ::VirtualFree(buffer, 0, MEM_RELEASE);
+ } else {
+ // WinXP branch. Here, reading the DLL from disk doesn't do
+ // what we want so instead we pull the pages into memory by loading
+ // the DLL and touching pages at a stride.
+ HMODULE dll_module = ::LoadLibraryExW(
+ file_path,
+ NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH | DONT_RESOLVE_DLL_REFERENCES);
+
+ if (!dll_module)
+ return false;
+
+ PEImage pe_image(dll_module);
+ PIMAGE_NT_HEADERS nt_headers = pe_image.GetNTHeaders();
+ size_t actual_size_to_read = size_to_read ? size_to_read :
+ nt_headers->OptionalHeader.SizeOfImage;
+ volatile uint8* touch = reinterpret_cast<uint8*>(dll_module);
+ size_t offset = 0;
+ while (offset < actual_size_to_read) {
+ uint8 unused = *(touch + offset);
+ offset += step_size;
+ }
+ FreeLibrary(dll_module);
}
- FreeLibrary(dll_module);
+
return true;
}