Bug 1529558 - Use PrefetchVirtualMemory in nsZipArchive::BuildFileList when supported. r=aklotz
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 26 Feb 2019 00:14:20 +0000
changeset 518905 a716ff1b62ab72a859f1a016c6635919502d4abe
parent 518904 825dfac611b25553f36ee0da6d7e5b043087b7e3
child 518906 57f2a3550fafe52aeb94187337789cf354fd5e06
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1529558, 810151
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1529558 - Use PrefetchVirtualMemory in nsZipArchive::BuildFileList when supported. r=aklotz instead of ReadAhead, which does active reading on Windows. The PrefetchVirtualMemory is a system call that is new to Windows 8. Back when the readahead code for jar was added, in bug 810151, Windows 8 was still fresh out of the oven. 6 years later, we can do a runtime check and use the PrefetchVirtualMemory function. One downside is that the IOInterposer doesn't know about it (but it doesn't know about madvise on other platforms anyways). Differential Revision: https://phabricator.services.mozilla.com/D20807
modules/libjar/nsZipArchive.cpp
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -605,17 +605,35 @@ nsresult nsZipArchive::BuildFileList(PRF
     uint32_t readaheadLength = xtolong(startp);
     if (readaheadLength) {
 #if defined(XP_SOLARIS)
       posix_madvise(const_cast<uint8_t *>(startp), readaheadLength,
                     POSIX_MADV_WILLNEED);
 #elif defined(XP_UNIX)
       madvise(const_cast<uint8_t *>(startp), readaheadLength, MADV_WILLNEED);
 #elif defined(XP_WIN)
-      if (aFd) {
+      static auto prefetchVirtualMemory =
+          reinterpret_cast<BOOL (*)(HANDLE, ULONG_PTR, PVOID, ULONG)>(
+              GetProcAddress(GetModuleHandle(L"kernel32.dll"),
+                               "PrefetchVirtualMemory"));
+      if (prefetchVirtualMemory) {
+        // Normally, we'd use WIN32_MEMORY_RANGE_ENTRY, but that requires
+        // a different _WIN32_WINNT value before including windows.h, but
+        // that causes complications with unified sources. It's a simple
+        // enough struct anyways.
+        struct {
+          PVOID VirtualAddress;
+          SIZE_T NumberOfBytes;
+        } entry;
+        entry.VirtualAddress = const_cast<uint8_t *>(startp);
+        entry.NumberOfBytes = readaheadLength;
+        prefetchVirtualMemory(GetCurrentProcess(), 1, &entry, 0);
+        readaheadLength = 0;
+      }
+      if (readaheadLength && aFd) {
         HANDLE hFile = (HANDLE)PR_FileDesc2NativeHandle(aFd);
         mozilla::ReadAhead(hFile, 0, readaheadLength);
       }
 #endif
     }
   } else {
     for (buf = endp - ZIPEND_SIZE; buf > startp; buf--) {
       if (xtolong(buf) == ENDSIG) {