Prefetch commonly used database files that are hard faulted on during
startup BUG: 992003 Change-Id: Idac6ddfc0870fbe8f7a2bc7211b87b0ee5bb9c1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1741782 Commit-Queue: Joe Laughlin <joel@microsoft.com> Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Victor Costan <pwnall@chromium.org> Reviewed-by: Alex Ilin <alexilin@chromium.org> Reviewed-by: Greg Thompson <grt@chromium.org> Cr-Commit-Position: refs/heads/master@{#690760}
This commit is contained in:
@ -1061,6 +1061,8 @@ jumbo_component("base") {
|
||||
"win/event_trace_controller.h",
|
||||
"win/event_trace_provider.cc",
|
||||
"win/event_trace_provider.h",
|
||||
"win/file_pre_reader.cc",
|
||||
"win/file_pre_reader.h",
|
||||
"win/hstring_compare.cc",
|
||||
"win/hstring_compare.h",
|
||||
"win/hstring_reference.cc",
|
||||
|
@ -2,16 +2,20 @@
|
||||
// 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 "base/win/file_pre_reader.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <memoryapi.h> // NOLINT(build/include_order)
|
||||
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/memory_mapped_file.h"
|
||||
|
||||
void PreReadFile(const base::FilePath& file_path) {
|
||||
namespace base {
|
||||
namespace win {
|
||||
|
||||
void PreReadFile(const FilePath& file_path, bool is_executable) {
|
||||
// On Win8 and higher use ::PrefetchVirtualMemory(). This is better than
|
||||
// a simple data file read, more from a RAM perspective than CPU. This is
|
||||
// because reading the file as data results in double mapping to
|
||||
@ -31,8 +35,8 @@ void PreReadFile(const base::FilePath& file_path) {
|
||||
|
||||
constexpr DWORD kStepSize = 1024 * 1024;
|
||||
|
||||
base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
|
||||
base::File::FLAG_SEQUENTIAL_SCAN);
|
||||
File file(file_path,
|
||||
File::FLAG_OPEN | File::FLAG_READ | File::FLAG_SEQUENTIAL_SCAN);
|
||||
if (!file.IsValid())
|
||||
return;
|
||||
|
||||
@ -51,9 +55,12 @@ void PreReadFile(const base::FilePath& file_path) {
|
||||
// loadlibrary the file while we are doing the mapping and prefetching or
|
||||
// the process will get a private copy of the DLL via COW.
|
||||
|
||||
base::MemoryMappedFile mapped_file;
|
||||
if (mapped_file.Initialize(file_path,
|
||||
base::MemoryMappedFile::READ_CODE_IMAGE)) {
|
||||
MemoryMappedFile mapped_file;
|
||||
MemoryMappedFile::Access access = is_executable
|
||||
? MemoryMappedFile::READ_CODE_IMAGE
|
||||
: MemoryMappedFile::READ_ONLY;
|
||||
|
||||
if (mapped_file.Initialize(file_path, access)) {
|
||||
_WIN32_MEMORY_RANGE_ENTRY address_range = {mapped_file.data(),
|
||||
mapped_file.length()};
|
||||
|
||||
@ -64,3 +71,6 @@ void PreReadFile(const base::FilePath& file_path) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace win
|
||||
} // namespace base
|
28
base/win/file_pre_reader.h
Normal file
28
base/win/file_pre_reader.h
Normal file
@ -0,0 +1,28 @@
|
||||
// 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.
|
||||
|
||||
#include "base/base_export.h"
|
||||
|
||||
#ifndef BASE_WIN_FILE_PRE_READER_H_
|
||||
#define BASE_WIN_FILE_PRE_READER_H_
|
||||
|
||||
namespace base {
|
||||
|
||||
class FilePath;
|
||||
|
||||
namespace win {
|
||||
|
||||
// Pre-reads |file_path| to avoid touching the disk when the file is actually
|
||||
// used. |is_executable| specifies whether the file is to be prefetched as
|
||||
// executable code or as data. Windows treats the file backed pages in RAM
|
||||
// differently and specifying the wrong one results in two copies in RAM.
|
||||
BASE_EXPORT void PreReadFile(const FilePath& file_path, bool is_executable);
|
||||
|
||||
} // namespace win
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_WIN_FILE_PRE_READER_H_
|
@ -195,7 +195,6 @@ if (!is_android && !is_mac) {
|
||||
":chrome_dll",
|
||||
":chrome_exe_version",
|
||||
":copy_first_run",
|
||||
":file_pre_reader",
|
||||
":visual_elements_resources",
|
||||
"//base",
|
||||
"//chrome/app/version_assembly:chrome_exe_manifest",
|
||||
@ -1493,16 +1492,6 @@ if (is_win) {
|
||||
]
|
||||
output = "$target_gen_dir/other_version.rc"
|
||||
}
|
||||
|
||||
source_set("file_pre_reader") {
|
||||
sources = [
|
||||
"app/file_pre_reader_win.cc",
|
||||
"app/file_pre_reader_win.h",
|
||||
]
|
||||
deps = [
|
||||
"//base",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
copy("visual_elements_resources") {
|
||||
|
@ -1,19 +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 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;
|
||||
}
|
||||
|
||||
// Pre-reads |file_path| to avoid touching the disk when the file is actually
|
||||
// used.
|
||||
void PreReadFile(const base::FilePath& file_path);
|
||||
|
||||
#endif // CHROME_APP_FILE_PRE_READER_WIN_H_
|
@ -27,12 +27,12 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "base/win/file_pre_reader.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
#include "base/win/shlwapi.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "chrome/app/chrome_watcher_client_win.h"
|
||||
#include "chrome/app/chrome_watcher_command_line_win.h"
|
||||
#include "chrome/app/file_pre_reader_win.h"
|
||||
#include "chrome/browser/active_use_util.h"
|
||||
#include "chrome/chrome_watcher/chrome_watcher_main_api.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
@ -57,7 +57,7 @@ typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)();
|
||||
// reference to the loaded module on success, or null on error.
|
||||
HMODULE LoadModuleWithDirectory(const base::FilePath& module) {
|
||||
::SetCurrentDirectoryW(module.DirName().value().c_str());
|
||||
PreReadFile(module);
|
||||
base::win::PreReadFile(module, true);
|
||||
return ::LoadLibraryExW(module.value().c_str(), nullptr,
|
||||
LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
}
|
||||
|
@ -3759,7 +3759,6 @@ jumbo_split_static_library("browser") {
|
||||
]
|
||||
deps += [
|
||||
":chrome_process_finder",
|
||||
"//chrome:file_pre_reader",
|
||||
"//chrome/browser/safe_browsing/chrome_cleaner",
|
||||
"//chrome/browser/safe_browsing/chrome_cleaner:public",
|
||||
"//chrome/browser/win/conflicts:module_info",
|
||||
|
@ -103,6 +103,7 @@ void PredictorDatabaseInternal::Initialize() {
|
||||
}
|
||||
|
||||
bool success = db_->Open(db_path_);
|
||||
db_->Preload();
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
@ -1047,6 +1047,7 @@ sql::InitStatus ThumbnailDatabase::OpenDatabase(sql::Database* db,
|
||||
|
||||
if (!db->Open(db_name))
|
||||
return sql::INIT_FAILURE;
|
||||
db->Preload();
|
||||
|
||||
return sql::INIT_OK;
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ bool SQLitePersistentStoreBackendBase::InitializeDatabase() {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
db_->Preload();
|
||||
|
||||
if (!MigrateDatabaseSchema() || !CreateDatabaseSchema()) {
|
||||
DLOG(ERROR) << "Unable to update or initialize " << histogram_tag_
|
||||
|
@ -36,6 +36,10 @@
|
||||
#include "sql/vfs_wrapper.h"
|
||||
#include "third_party/sqlite/sqlite3.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/file_pre_reader.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Spin for up to a second waiting for the lock to clear when setting
|
||||
@ -355,6 +359,9 @@ void Database::Preload() {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
base::win::PreReadFile(DbPath(), false);
|
||||
#else
|
||||
// The constructor and set_page_size() ensure that page_size_ is never zero.
|
||||
const int page_size = page_size_;
|
||||
DCHECK(page_size);
|
||||
@ -383,6 +390,7 @@ void Database::Preload() {
|
||||
if (rc != SQLITE_OK)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// SQLite keeps unused pages associated with a database in a cache. It asks
|
||||
|
Reference in New Issue
Block a user