diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 703cb14ae23174..104001afde54b4 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn @@ -123,7 +123,7 @@ if (!is_android) { deps += [ ":chrome_dll", ":chrome_exe_version", - ":image_pre_reader", + ":file_pre_reader", # 'chrome_nacl_win64" TODO(GYP) bug 512869 # '../win8/delegate_execute/delegate_execute.gyp:*', TODO(GYP) bug 512867 @@ -517,10 +517,10 @@ if (is_win) { output = "$target_gen_dir/other_version.rc" } - source_set("image_pre_reader") { + source_set("file_pre_reader") { sources = [ - "app/image_pre_reader_win.cc", - "app/image_pre_reader_win.h", + "app/file_pre_reader_win.cc", + "app/file_pre_reader_win.h", ] deps = [ "//base", diff --git a/chrome/app/file_pre_reader_win.cc b/chrome/app/file_pre_reader_win.cc new file mode 100644 index 00000000000000..fb8febb1e201da --- /dev/null +++ b/chrome/app/file_pre_reader_win.cc @@ -0,0 +1,104 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/app/file_pre_reader_win.h" + +#include +#include + +#include "base/files/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(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(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 + +bool PreReadFile(const base::FilePath& file_path, int step_size) { + DCHECK_GT(step_size, 0); + 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 false; + + char* buffer = reinterpret_cast(::VirtualAlloc( + nullptr, static_cast(step_size), MEM_COMMIT, PAGE_READWRITE)); + if (!buffer) + return false; + + while (file.ReadAtCurrentPos(buffer, step_size) > 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, ignoring the passed in |step_size|, + // 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 false; + + base::win::PEImage pe_image(dll_module.get()); + if (!pe_image.VerifyMagic()) + return false; + + // 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; + + // Page in the module. + TouchPagesInRange(dll_module.get(), dll_module_length); + } + + return true; +} diff --git a/chrome/app/file_pre_reader_win.h b/chrome/app/file_pre_reader_win.h new file mode 100644 index 00000000000000..bf7008b46b126f --- /dev/null +++ b/chrome/app/file_pre_reader_win.h @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file defines a function to pre-read a file in order to avoid touching +// the disk when it is subsequently used. + +#ifndef CHROME_APP_FILE_PRE_READER_WIN_H_ +#define CHROME_APP_FILE_PRE_READER_WIN_H_ + +namespace base { +class FilePath; +} + +// 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 |step_size| bytes are read into a +// buffer. The bigger |step_size| is, the faster the file is pre-read (up to +// about 4MB according to local tests), but also the more memory is allocated +// for the buffer. On XP, pre-reading non-PE files is not supported. +bool PreReadFile(const base::FilePath& file_path, int step_size); + +#endif // CHROME_APP_FILE_PRE_READER_WIN_H_ diff --git a/chrome/app/image_pre_reader_win.cc b/chrome/app/image_pre_reader_win.cc deleted file mode 100644 index 9998a036905a03..00000000000000 --- a/chrome/app/image_pre_reader_win.cc +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/app/image_pre_reader_win.h" - -#include -#include -#include -#include - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/threading/thread_restrictions.h" -#include "base/win/pe_image.h" -#include "base/win/scoped_handle.h" -#include "base/win/windows_version.h" - -namespace { - -// The minimum buffer size to allocate when reading the PE file headers. -// -// The PE file headers usually fit into a single 1KB page, and a PE file must -// at least contain the initial page with the headers. That said, as long as -// we expect at least sizeof(IMAGE_DOS_HEADER) bytes, we're ok. -const size_t kMinHeaderBufferSize = 0x400; - -// A handy symbolic constant. -const size_t kOneHundredPercent = 100; - -static_assert(kMinHeaderBufferSize >= sizeof(IMAGE_DOS_HEADER), - "kMinHeaderBufferSize must be at least as big as the dos header"); - -// This struct provides a deallocation functor for use with scoped_ptr -// allocated with ::VirtualAlloc(). -struct VirtualFreeDeleter { - void operator() (void* ptr) { - ::VirtualFree(ptr, 0, MEM_RELEASE); - } -}; - -// A wrapper for the Win32 ::SetFilePointer() function with some error checking. -bool SetFilePointer(HANDLE file_handle, size_t position) { - return position <= static_cast(std::numeric_limits::max()) && - ::SetFilePointer(file_handle, - static_cast(position), - NULL, - FILE_BEGIN) != INVALID_SET_FILE_POINTER; -} - -// A helper function to read the next |bytes_to_read| bytes from the file -// given by |file_handle| into |buffer|. -bool ReadNextBytes(HANDLE file_handle, void* buffer, size_t bytes_to_read) { - DCHECK(file_handle != INVALID_HANDLE_VALUE); - DCHECK(buffer != NULL); - DCHECK(bytes_to_read > 0); - - DWORD bytes_read = 0; - return bytes_to_read <= std::numeric_limits::max() && - ::ReadFile(file_handle, - buffer, - static_cast(bytes_to_read), - &bytes_read, - NULL) && - bytes_read == bytes_to_read; -} - -// A helper function to extend the |current_buffer| of bytes such that it -// contains |desired_length| bytes read from the file given by |file_handle|. -// -// It is assumed that |file_handle| has been used to sequentially populate -// |current_buffer| thus far and is already positioned at the appropriate -// read location. -bool ReadMissingBytes(HANDLE file_handle, - std::vector* current_buffer, - size_t desired_length) { - DCHECK(file_handle != INVALID_HANDLE_VALUE); - DCHECK(current_buffer != NULL); - - size_t current_length = current_buffer->size(); - if (current_length >= desired_length) - return true; - - size_t bytes_to_read = desired_length - current_length; - current_buffer->resize(desired_length); - return ReadNextBytes(file_handle, - &(current_buffer->at(current_length)), - bytes_to_read); -} - -// Return a |percentage| of the number of initialized bytes in the given -// |section|. -// -// This returns a percentage of the lesser of the size of the raw data in -// the section and the virtual size of the section. -// -// Note that sections can have their tails implicitly initialized to zero -// (i.e., their virtual size is larger than the raw size) and that raw data -// is padded to the PE page size if the entire section is initialized (i.e., -// their raw data size will be larger than the virtual size). -// -// Any data after the initialized portion of the section will be soft-faulted -// in (very quickly) as needed, so we don't need to include it in the returned -// length. -size_t GetPercentageOfSectionLength(const IMAGE_SECTION_HEADER* section, - size_t percentage) { - DCHECK(section != NULL); - DCHECK_GT(percentage, 0u); - DCHECK_LE(percentage, kOneHundredPercent); - - size_t initialized_length = std::min(section->SizeOfRawData, - section->Misc.VirtualSize); - - if (initialized_length == 0) - return 0; - - size_t length = (initialized_length * percentage) / kOneHundredPercent; - - return std::max(length, 1); -} - -// Helper function to read through a |percentage| of the given |section| -// of the file denoted by |file_handle|. The |temp_buffer| is (re)used as -// a transient storage area as the section is read in chunks of -// |temp_buffer_size| bytes. -bool ReadThroughSection(HANDLE file_handle, - const IMAGE_SECTION_HEADER* section, - size_t percentage, - void* temp_buffer, - size_t temp_buffer_size) { - DCHECK(file_handle != INVALID_HANDLE_VALUE); - DCHECK(section != NULL); - DCHECK_LE(percentage, kOneHundredPercent); - DCHECK(temp_buffer != NULL); - DCHECK(temp_buffer_size > 0); - - size_t bytes_to_read = GetPercentageOfSectionLength(section, percentage); - if (bytes_to_read == 0) - return true; - - if (!SetFilePointer(file_handle, section->PointerToRawData)) - return false; - - // Read all chunks except the last one. - while (bytes_to_read > temp_buffer_size) { - if (!ReadNextBytes(file_handle, temp_buffer, temp_buffer_size)) - return false; - bytes_to_read -= temp_buffer_size; - } - - // Read the last (possibly partial) chunk and return. - DCHECK(bytes_to_read > 0); - DCHECK(bytes_to_read <= temp_buffer_size); - return ReadNextBytes(file_handle, temp_buffer, bytes_to_read); -} - -// A helper function to touch all pages in the range -// [base_addr, base_addr + length). -void TouchPagesInRange(void* base_addr, size_t length) { - DCHECK(base_addr != NULL); - DCHECK(length > 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* touch_ptr = reinterpret_cast(base_addr); - volatile uint8* 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 dummy; - while (touch_ptr < final_touch_ptr) { - dummy = *touch_ptr; - touch_ptr += system_info.dwPageSize; - } - dummy = *final_touch_ptr; -} - -} // namespace - -bool ImagePreReader::PartialPreReadImageOnDisk(const wchar_t* file_path, - size_t percentage, - size_t max_chunk_size) { - // TODO(rogerm): change this to have the number of bytes pre-read per - // section be driven by a static table within the PE file (defaulting to - // full read if it's not there?) that's initialized by the optimization - // toolchain. - DCHECK(file_path != NULL); - - if (percentage == 0) - return true; - - if (percentage > kOneHundredPercent) - percentage = kOneHundredPercent; - - // Validate/setup max_chunk_size, imposing a 1MB minimum on the chunk size. - const size_t kMinChunkSize = 1024 * 1024; - max_chunk_size = std::max(max_chunk_size, kMinChunkSize); - - // Open the file. - base::win::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 (!file.IsValid()) - return false; - - // Allocate a resizable buffer for the headers. We initially reserve as much - // space as we typically see as the header size for chrome.dll and other - // PE images. - std::vector headers; - headers.reserve(kMinHeaderBufferSize); - - // Read, hopefully, all of the headers. - if (!ReadMissingBytes(file.Get(), &headers, kMinHeaderBufferSize)) - return false; - - // The DOS header starts at offset 0 and allows us to get the offset of the - // NT headers. Let's ensure we've read enough to capture the NT headers. - size_t nt_headers_start = - reinterpret_cast(&headers[0])->e_lfanew; - size_t nt_headers_end = nt_headers_start + sizeof(IMAGE_NT_HEADERS); - if (!ReadMissingBytes(file.Get(), &headers, nt_headers_end)) - return false; - - // Now that we've got the NT headers we can get the total header size, - // including all of the section headers. Let's ensure we've read enough - // to capture all of the header data. - size_t size_of_headers = reinterpret_cast( - &headers[nt_headers_start])->OptionalHeader.SizeOfHeaders; - if (!ReadMissingBytes(file.Get(), &headers, size_of_headers)) - return false; - - // Now we have all of the headers. This is enough to let us use the PEImage - // wrapper to query the structure of the image. - base::win::PEImage pe_image(reinterpret_cast(&headers[0])); - CHECK(pe_image.VerifyMagic()); - - // Allocate a buffer to hold the pre-read bytes. - scoped_ptr buffer( - static_cast( - ::VirtualAlloc(NULL, max_chunk_size, MEM_COMMIT, PAGE_READWRITE))); - if (buffer.get() == NULL) - return false; - - // Iterate over each section, reading in a percentage of each. - const IMAGE_SECTION_HEADER* section = NULL; - for (UINT i = 0; (section = pe_image.GetSectionHeader(i)) != NULL; ++i) { - CHECK_LE(reinterpret_cast(section + 1), - &headers[0] + headers.size()); - if (!ReadThroughSection(file.Get(), section, percentage, buffer.get(), - max_chunk_size)) { - return false; - } - } - - // We're done. - return true; -} - -bool ImagePreReader::PartialPreReadImageInMemory(const wchar_t* file_path, - size_t percentage) { - // TODO(rogerm): change this to have the number of bytes pre-read per - // section be driven by a static table within the PE file (defaulting to - // full read if it's not there?) that's initialized by the optimization - // toolchain. - DCHECK(file_path != NULL); - - if (percentage == 0) - return true; - - if (percentage > kOneHundredPercent) - percentage = kOneHundredPercent; - - HMODULE dll_module = ::LoadLibraryExW( - file_path, - NULL, - LOAD_WITH_ALTERED_SEARCH_PATH | DONT_RESOLVE_DLL_REFERENCES); - - if (!dll_module) - return false; - - base::win::PEImage pe_image(dll_module); - CHECK(pe_image.VerifyMagic()); - - // Iterate over each section, stepping through a percentage of each to page - // it in off the disk. - const IMAGE_SECTION_HEADER* section = NULL; - for (UINT i = 0; (section = pe_image.GetSectionHeader(i)) != NULL; ++i) { - // Get the extent we want to touch. - size_t length = GetPercentageOfSectionLength(section, percentage); - if (length == 0) - continue; - uint8* start = - static_cast(pe_image.RVAToAddr(section->VirtualAddress)); - - // Verify that the extent we're going to touch falls inside the section - // we expect it to (and by implication, inside the pe_image). - CHECK_EQ(section, - pe_image.GetImageSectionFromAddr(start)); - CHECK_EQ(section, - pe_image.GetImageSectionFromAddr(start + length - 1)); - - // Page in the section range. - TouchPagesInRange(start, length); - } - - FreeLibrary(dll_module); - - return true; -} - -bool ImagePreReader::PreReadImage(const wchar_t* file_path, - size_t size_to_read, - size_t step_size) { - base::ThreadRestrictions::AssertIOAllowed(); - if (base::win::GetVersion() > base::win::VERSION_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. - base::win::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 (!file.IsValid()) - return false; - - // Default to 1MB sequential reads. - const DWORD actual_step_size = std::max(static_cast(step_size), - static_cast(1024*1024)); - LPVOID buffer = ::VirtualAlloc(NULL, - actual_step_size, - MEM_COMMIT, - PAGE_READWRITE); - - if (buffer == NULL) - return false; - - DWORD len; - size_t total_read = 0; - while (::ReadFile(file.Get(), buffer, actual_step_size, &len, NULL) && - len > 0 && - (size_to_read ? total_read < size_to_read : true)) { - total_read += static_cast(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. We use the system's page - // size as the stride, ignoring the passed in step_size, to make sure - // each page in the range is touched. - HMODULE dll_module = ::LoadLibraryExW( - file_path, - NULL, - LOAD_WITH_ALTERED_SEARCH_PATH | DONT_RESOLVE_DLL_REFERENCES); - - if (!dll_module) - return false; - - base::win::PEImage pe_image(dll_module); - CHECK(pe_image.VerifyMagic()); - - // 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(); - size_t dll_module_length = std::min( - size_to_read ? size_to_read : ~0, - static_cast(nt_headers->OptionalHeader.SizeOfImage)); - - // Page in then release the module. - TouchPagesInRange(dll_module, dll_module_length); - FreeLibrary(dll_module); - } - - return true; -} - -bool ImagePreReader::PartialPreReadImage(const wchar_t* file_path, - size_t percentage, - size_t max_chunk_size) { - base::ThreadRestrictions::AssertIOAllowed(); - - if (percentage >= kOneHundredPercent) { - // If we're reading the whole image, we don't need to parse headers and - // navigate sections, the basic PreReadImage() can be used to just step - // blindly through the entire file / address-space. - return PreReadImage(file_path, 0, max_chunk_size); - } - - if (base::win::GetVersion() > base::win::VERSION_XP) { - // Vista+ branch. On these OSes, we warm up the Image by reading its - // file off the disk. - return PartialPreReadImageOnDisk(file_path, percentage, max_chunk_size); - } - - // WinXP branch. For XP, reading the image from disk doesn't do what we want - // so instead we pull the pages into memory by loading the DLL and touching - // initialized pages at a stride. - return PartialPreReadImageInMemory(file_path, percentage); -} diff --git a/chrome/app/image_pre_reader_win.h b/chrome/app/image_pre_reader_win.h deleted file mode 100644 index e32e019049c802..00000000000000 --- a/chrome/app/image_pre_reader_win.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file defines utility functions to pre-read a PE Image in order to -// avoid hard page faults when the image is subsequently loaded into memory -// for execution. - -#ifndef CHROME_APP_IMAGE_PRE_READER_WIN_H_ -#define CHROME_APP_IMAGE_PRE_READER_WIN_H_ - -#include "base/basictypes.h" - -// This class defines static helper functions to pre-read a PE Image in order -// to avoid hard page faults when the image is subsequently loaded into memory -// for execution. -class ImagePreReader { - public: - // Reads the file passed in as a PE Image and touches pages to avoid - // subsequent hard page faults during LoadLibrary. The size to be pre-read - // is passed in. If it is 0 then the whole file is paged in. The step size - // which indicates the number of bytes to skip after every page touched is - // also passed in. - // - // This function checks the Windows version to determine which pre-reading - // mechanism to use. - static bool PreReadImage(const wchar_t* file_path, - size_t size_to_read, - size_t step_size); - - // Loads the file passed in as PE Image and touches a percentage of the - // pages in each of the image's sections to avoid subsequent hard page - // faults during LoadLibrary. - // - // This function checks the Windows version to determine which pre-reading - // mechanism to use. - // - // The percentage of the file to be read is an integral value between 0 and - // 100, inclusive. If it is 0 then this is a NOP, if it is 100 (or greater) - // then the whole file is paged in sequentially via PreReadImage. Otherwise, - // for each section, in order, the given percentage of the blocks in that - // section are paged in, starting at the beginning of each section. For - // example: if percentage is 30 and there is a .text section and a .data - // section, then the first 30% of .text will be paged and the first 30% of - // .data will be paged in. - // - // The max_chunk_size indicates the number of bytes to read off the disk in - // each step (for Vista and greater, where this is the way the pages are - // warmed). - // - // This function is intended to be used in the context of a PE image with - // an optimized layout, such that the blocks in each section are arranged - // with the data and code most needed for startup moved to the front. - // See also: http://code.google.com/p/chromium/issues/detail?id=98508 - static bool PartialPreReadImage(const wchar_t* file_path, - size_t percentage, - size_t max_chunk_size); - - // Helper function used by PartialPreReadImage on Windows versions (Vista+) - // where reading through the file on disk serves to warm up the page cache. - // Exported for unit-testing purposes. - static bool PartialPreReadImageOnDisk(const wchar_t* file_path, - size_t percentage, - size_t max_chunk_size); - - // Helper function used by PartialPreReadImage on Windows versions (XP) where - // cheaply loading the image then stepping through its address space serves - // to warm up the page cache. Exported for unit-testing purposes. - static bool PartialPreReadImageInMemory(const wchar_t* file_path, - size_t percentage); -}; // namespace internal - -#endif // CHROME_APP_IMAGE_PRE_READER_WIN_H_ diff --git a/chrome/app/main_dll_loader_win.cc b/chrome/app/main_dll_loader_win.cc index 4f831ff6bb5a9d..ba14dba3bcc3cd 100644 --- a/chrome/app/main_dll_loader_win.cc +++ b/chrome/app/main_dll_loader_win.cc @@ -26,7 +26,7 @@ #include "chrome/app/chrome_crash_reporter_client.h" #include "chrome/app/chrome_watcher_client_win.h" #include "chrome/app/chrome_watcher_command_line_win.h" -#include "chrome/app/image_pre_reader_win.h" +#include "chrome/app/file_pre_reader_win.h" #include "chrome/app/kasko_client.h" #include "chrome/chrome_watcher/chrome_watcher_main_api.h" #include "chrome/common/chrome_constants.h" @@ -63,9 +63,7 @@ HMODULE LoadModuleWithDirectory(const base::FilePath& module, bool pre_read) { // We pre-read the binary to warm the memory caches (fewer hard faults to // page parts of the binary in). const size_t kStepSize = 1024 * 1024; - size_t percent = 100; - ImagePreReader::PartialPreReadImage(module.value().c_str(), percent, - kStepSize); + PreReadFile(module, kStepSize); } return ::LoadLibraryExW(module.value().c_str(), nullptr, diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 352a01b06adf16..a107569b0bbfb3 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -410,7 +410,7 @@ 'chrome_process_finder', 'chrome_version_resources', 'installer_util', - 'image_pre_reader', + 'file_pre_reader', '../base/base.gyp:base', '../crypto/crypto.gyp:crypto', '../breakpad/breakpad.gyp:breakpad_handler', @@ -509,11 +509,11 @@ ['OS=="win"', { 'targets': [ { - 'target_name': 'image_pre_reader', + 'target_name': 'file_pre_reader', 'type': 'static_library', 'sources': [ - 'app/image_pre_reader_win.cc', - 'app/image_pre_reader_win.h', + 'app/file_pre_reader_win.cc', + 'app/file_pre_reader_win.h', ], 'dependencies': [ '../base/base.gyp:base',