-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathc510ffc0b0b5f0b459e4dded17f4e1cc553dd7a7.diff
67 lines (62 loc) · 2.87 KB
/
c510ffc0b0b5f0b459e4dded17f4e1cc553dd7a7.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc
index 3b73661e6c7fb..0236dd3658ca7 100644
--- a/base/files/file_util_win.cc
+++ b/base/files/file_util_win.cc
@@ -1152,19 +1152,45 @@ bool SetNonBlocking(int fd) {
return false;
}
+namespace {
+
+// ::PrefetchVirtualMemory() is only available on Windows 8 and above. Chrome
+// supports Windows 7, so we need to check for the function's presence
+// dynamically.
+using PrefetchVirtualMemoryPtr = decltype(&::PrefetchVirtualMemory);
+
+// Returns null if ::PrefetchVirtualMemory() is not available.
+PrefetchVirtualMemoryPtr GetPrefetchVirtualMemoryPtr() {
+ HMODULE kernel32_dll = ::GetModuleHandleA("kernel32.dll");
+ return reinterpret_cast<PrefetchVirtualMemoryPtr>(
+ GetProcAddress(kernel32_dll, "PrefetchVirtualMemory"));
+}
+
+} // namespace
+
bool PreReadFile(const FilePath& file_path,
bool is_executable,
bool sequential,
int64_t max_bytes) {
DCHECK_GE(max_bytes, 0);
+ // 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
+ // Image/executable pages for all pages of code executed.
+ static PrefetchVirtualMemoryPtr prefetch_virtual_memory =
+ GetPrefetchVirtualMemoryPtr();
+
+ if (prefetch_virtual_memory == nullptr)
+ return PreReadFileSlow(file_path, max_bytes);
+
if (max_bytes == 0) {
- // ::PrefetchVirtualMemory() fails when asked to read zero bytes.
+ // PrefetchVirtualMemory() fails when asked to read zero bytes.
// base::MemoryMappedFile::Initialize() fails on an empty file.
return true;
}
- // ::PrefetchVirtualMemory() fails if the file is opened with write access.
+ // PrefetchVirtualMemory() fails if the file is opened with write access.
MemoryMappedFile::Access access = is_executable
? MemoryMappedFile::READ_CODE_IMAGE
: MemoryMappedFile::READ_ONLY;
@@ -1176,11 +1202,7 @@ bool PreReadFile(const FilePath& file_path,
std::min(base::saturated_cast<::SIZE_T>(max_bytes),
base::saturated_cast<::SIZE_T>(mapped_file.length()));
::_WIN32_MEMORY_RANGE_ENTRY address_range = {mapped_file.data(), length};
- // 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
- // Image/executable pages for all pages of code executed.
- if (!::PrefetchVirtualMemory(::GetCurrentProcess(),
+ if (!prefetch_virtual_memory(::GetCurrentProcess(),
/*NumberOfEntries=*/1, &address_range,
/*Flags=*/0)) {
return PreReadFileSlow(file_path, max_bytes);