diff options
author | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 18:25:25 +0000 |
---|---|---|
committer | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 18:25:25 +0000 |
commit | feb6e5499bc2abfda723e754f1455a286bf48695 (patch) | |
tree | 246018cdd86fe6854b217e62b45e51b4061f6a4b /base | |
parent | 13081fccbf907aef8476c94d904fc94d6c59a206 (diff) | |
download | chromium_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.cc | 73 |
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; } |