Commit 2d10fab8 authored by Doug Thayer's avatar Doug Thayer
Browse files

Bug 1546498 - Split out MaybePrefetchMemory's check into two functions r=aklotz

Temporarily just sidestep the issue in bug 1546498 (crash with latest SDK
on startup in Windows 7) by just continuing to use the old method in
Windows 7. We saw no wins in telemetry for Windows 7 anyway, so we should
investigate why that is, and why we see a mysterious crash in the fallback
code, in a followup bug.

Differential Revision: https://phabricator.services.mozilla.com/D29239

--HG--
extra : moz-landing-system : lando
parent 5c6938eb
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -651,8 +651,7 @@ nsresult nsZipArchive::BuildFileList(PRFileDesc *aFd) {
      xtolong(startp + centralOffset) == CENTRALSIG) {
    // Success means optimized jar layout from bug 559961 is in effect
    uint32_t readaheadLength = xtolong(startp);
    mozilla::MaybePrefetchMemory(const_cast<uint8_t *>(startp),
                                 readaheadLength);
    mozilla::PrefetchMemory(const_cast<uint8_t *>(startp), readaheadLength);
  } else {
    for (buf = endp - ZIPEND_SIZE; buf > startp; buf--) {
      if (xtolong(buf) == ENDSIG) {
+6 −5
Original line number Diff line number Diff line
@@ -358,6 +358,10 @@ void mozilla::ReadAheadLib(mozilla::pathstr_t aFilePath) {
    return;
  }
#if defined(XP_WIN)
  if (!CanPrefetchMemory()) {
    ReadAheadFile(aFilePath);
    return;
  }
  nsAutoHandle fd(CreateFileW(aFilePath, GENERIC_READ, FILE_SHARE_READ, nullptr,
                              OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
                              nullptr));
@@ -382,11 +386,8 @@ void mozilla::ReadAheadLib(mozilla::pathstr_t aFilePath) {
      MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, (size_t)fileSize.QuadPart);
  auto guard = MakeScopeExit([=]() { UnmapViewOfFile(data); });

  if (data && !MaybePrefetchMemory((uint8_t*)data, (size_t)fileSize.QuadPart)) {
    volatile uint8_t read = 0;
    for (size_t i = 0; i < (size_t)fileSize.QuadPart; i += 4096) {
      read += ((uint8_t*)data)[i];
    }
  if (data) {
    PrefetchMemory((uint8_t*)data, (size_t)fileSize.QuadPart);
  }

#elif defined(LINUX) && !defined(ANDROID)
+32 −15
Original line number Diff line number Diff line
@@ -8,28 +8,48 @@

#if defined(XP_WIN)
#  include <windows.h>
#  include "mozilla/Maybe.h"
#else
#  include <sys/mman.h>
#endif

bool mozilla::MaybePrefetchMemory(uint8_t* aStart, size_t aNumBytes) {
  if (aNumBytes == 0) {
#if defined(XP_WIN)
typedef BOOL (*PrefetchVirtualMemoryFn)(HANDLE, ULONG_PTR, PVOID, ULONG);

mozilla::Maybe<PrefetchVirtualMemoryFn> sPrefetchVirtualMemory;

void MaybeInitPrefetchVirtualMemory() {
  if (sPrefetchVirtualMemory.isNothing()) {
    sPrefetchVirtualMemory.emplace(
        reinterpret_cast<PrefetchVirtualMemoryFn>(GetProcAddress(
            GetModuleHandleW(L"kernel32.dll"), "PrefetchVirtualMemory")));
  }
}
#endif

bool mozilla::CanPrefetchMemory() {
#if defined(XP_SOLARIS) || defined(XP_UNIX)
  return true;
#elif defined(XP_WIN)
  MaybeInitPrefetchVirtualMemory();
  return *sPrefetchVirtualMemory;
#else
  return false;
#endif
}

void mozilla::PrefetchMemory(uint8_t* aStart, size_t aNumBytes) {
  if (aNumBytes == 0) {
    return;
  }

#if defined(XP_SOLARIS)
  posix_madvise(aStart, aNumBytes, POSIX_MADV_WILLNEED);
  return true;
#elif defined(XP_UNIX)
  madvise(aStart, aNumBytes, MADV_WILLNEED);
  return true;
#elif defined(XP_WIN)
  static auto prefetchVirtualMemory =
      reinterpret_cast<BOOL(WINAPI*)(HANDLE, ULONG_PTR, PVOID, ULONG)>(
          GetProcAddress(GetModuleHandleW(L"kernel32.dll"),
                         "PrefetchVirtualMemory"));

  if (prefetchVirtualMemory) {
  MaybeInitPrefetchVirtualMemory();
  if (*sPrefetchVirtualMemory) {
    // 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
@@ -40,11 +60,8 @@ bool mozilla::MaybePrefetchMemory(uint8_t* aStart, size_t aNumBytes) {
    } entry;
    entry.VirtualAddress = aStart;
    entry.NumberOfBytes = aNumBytes;
    prefetchVirtualMemory(GetCurrentProcess(), 1, &entry, 0);
    return true;
    (*sPrefetchVirtualMemory)(GetCurrentProcess(), 1, &entry, 0);
    return;
  }
  return false;
#else
  return false;
#endif
}
+2 −1
Original line number Diff line number Diff line
@@ -12,7 +12,8 @@

namespace mozilla {

bool MaybePrefetchMemory(uint8_t* aStart, size_t aNumBytes);
bool CanPrefetchMemory();
void PrefetchMemory(uint8_t* aStart, size_t aNumBytes);

}  // namespace mozilla