diff options
author | Francois Doray <fdoray@chromium.org> | 2016-02-23 19:08:42 -0500 |
---|---|---|
committer | Francois Doray <fdoray@chromium.org> | 2016-02-24 00:11:37 +0000 |
commit | 2f8a24b93c4b3c1bb133bfa26a8ed6100bc85061 (patch) | |
tree | 4a67501f283984b66a4e8a5c8e7d826eec261b8f | |
parent | 7c2861286c40e3cdca7ce260a5bba1ee7ecb349d (diff) | |
download | chromium_src-2f8a24b93c4b3c1bb133bfa26a8ed6100bc85061.zip chromium_src-2f8a24b93c4b3c1bb133bfa26a8ed6100bc85061.tar.gz chromium_src-2f8a24b93c4b3c1bb133bfa26a8ed6100bc85061.tar.bz2 |
[Merge M49] Remove XP-specific code from file_pre_reader_win.cc.
BUG=547794
Review URL: https://codereview.chromium.org/1659113002
Cr-Commit-Position: refs/heads/master@{#373352}
(cherry picked from commit bb4fe7af38b6a9cee46b095e18810295d18e6523)
TBR=gab@chromium.org
Review URL: https://codereview.chromium.org/1730883002 .
Cr-Commit-Position: refs/branch-heads/2623@{#489}
Cr-Branched-From: 92d77538a86529ca35f9220bd3cd512cbea1f086-refs/heads/master@{#369907}
-rw-r--r-- | chrome/app/file_pre_reader_win.cc | 95 | ||||
-rw-r--r-- | chrome/app/file_pre_reader_win.h | 3 |
2 files changed, 11 insertions, 87 deletions
diff --git a/chrome/app/file_pre_reader_win.cc b/chrome/app/file_pre_reader_win.cc index 7d57244..bfade83 100644 --- a/chrome/app/file_pre_reader_win.cc +++ b/chrome/app/file_pre_reader_win.cc @@ -5,101 +5,28 @@ #include "chrome/app/file_pre_reader_win.h" #include <windows.h> -#include <stdint.h> #include "base/files/file.h" #include "base/files/memory_mapped_file.h" -#include "base/logging.h" -#include "base/scoped_native_library.h" #include "base/threading/thread_restrictions.h" -#include "base/win/pe_image.h" -#include "base/win/windows_version.h" - -namespace { - -// A helper function to touch all pages in the range -// [base_addr, base_addr + length). -void TouchPagesInRange(const void* base_addr, uint32_t length) { - DCHECK(base_addr); - DCHECK_GT(length, static_cast<uint32_t>(0)); - - // Get the system info so we know the page size. Also, make sure we use a - // non-zero value for the page size; GetSystemInfo() is hookable/patchable, - // and you never know what shenanigans someone could get up to. - SYSTEM_INFO system_info = {}; - ::GetSystemInfo(&system_info); - if (system_info.dwPageSize == 0) - system_info.dwPageSize = 4096; - - // We don't want to read outside the byte range (which could trigger an - // access violation), so let's figure out the exact locations of the first - // and final bytes we want to read. - volatile uint8_t const* touch_ptr = - reinterpret_cast<uint8_t const*>(base_addr); - volatile uint8_t const* final_touch_ptr = touch_ptr + length - 1; - - // Read the memory in the range [touch_ptr, final_touch_ptr] with a stride - // of the system page size, to ensure that it's been paged in. - uint8_t dummy; - for (; touch_ptr < final_touch_ptr; touch_ptr += system_info.dwPageSize) - dummy = *touch_ptr; - dummy = *final_touch_ptr; -} - -} // namespace void PreReadFile(const base::FilePath& file_path) { base::ThreadRestrictions::AssertIOAllowed(); - if (base::win::GetVersion() > base::win::VERSION_XP) { - // Vista+ branch. On these OSes, the forced reads through the file actually - // slows warm starts. The solution is to sequentially read file contents. - base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_SEQUENTIAL_SCAN); - if (!file.IsValid()) - return; - - const DWORD kStepSize = 1024 * 1024; - char* buffer = reinterpret_cast<char*>( - ::VirtualAlloc(nullptr, kStepSize, MEM_COMMIT, PAGE_READWRITE)); - if (!buffer) - return; - - while (file.ReadAtCurrentPos(buffer, kStepSize) > 0) {} - - ::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 and touch pages at a stride. We use - // the system's page size as the stride, to make sure each page in the range - // is touched. - - // Don't show an error popup when |file_path| is not a valid PE file. - UINT previous_error_mode = ::SetErrorMode(SEM_FAILCRITICALERRORS); - ::SetErrorMode(previous_error_mode | SEM_FAILCRITICALERRORS); - - base::ScopedNativeLibrary dll_module(::LoadLibraryExW( - file_path.value().c_str(), NULL, - LOAD_WITH_ALTERED_SEARCH_PATH | DONT_RESOLVE_DLL_REFERENCES)); - - ::SetErrorMode(previous_error_mode); - - // Pre-reading non-PE files is not supported on XP. - if (!dll_module.is_valid()) - return; + base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_SEQUENTIAL_SCAN); + if (!file.IsValid()) + return; - base::win::PEImage pe_image(dll_module.get()); - if (!pe_image.VerifyMagic()) - return; + const DWORD kStepSize = 1024 * 1024; + char* buffer = reinterpret_cast<char*>( + ::VirtualAlloc(nullptr, kStepSize, MEM_COMMIT, PAGE_READWRITE)); + if (!buffer) + return; - // We don't want to read past the end of the module (which could trigger - // an access violation), so make sure to check the image size. - PIMAGE_NT_HEADERS nt_headers = pe_image.GetNTHeaders(); - const uint32_t dll_module_length = nt_headers->OptionalHeader.SizeOfImage; + while (file.ReadAtCurrentPos(buffer, kStepSize) > 0) {} - // Page in the module. - TouchPagesInRange(dll_module.get(), dll_module_length); - } + ::VirtualFree(buffer, 0, MEM_RELEASE); } void PreReadMemoryMappedFile(const base::MemoryMappedFile& memory_mapped_file, diff --git a/chrome/app/file_pre_reader_win.h b/chrome/app/file_pre_reader_win.h index da88ba4..85912b8 100644 --- a/chrome/app/file_pre_reader_win.h +++ b/chrome/app/file_pre_reader_win.h @@ -14,9 +14,6 @@ class MemoryMappedFile; } // Reads |file_path| to avoid touching the disk when the file is actually used. -// The function checks the Windows version to determine which pre-reading -// mechanism to use. On Vista+, chunks of 1 MB are read into a buffer. On XP, -// pre-reading non-PE files is not supported. void PreReadFile(const base::FilePath& file_path); // Reads |memory_mapped_file| to avoid touching the disk when the mapped file is |