Bug 810151: readahead for ordered jar files r=taras
☠☠ backed out by acec25f67366 ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Wed, 06 Mar 2013 11:58:29 -0700
changeset 124001 7f6c38239328
parent 124000 0e67704d6b18
child 124002 66f39088f57e
push id24177
push useraklotz@mozilla.com
push dateWed, 06 Mar 2013 19:49:51 +0000
treeherdermozilla-inbound@7f6c38239328 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs810151
milestone22.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 810151: readahead for ordered jar files r=taras
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -25,16 +25,17 @@
 #include <windows.h>
 #endif
 
 // For placement new used for arena allocations of zip file list
 #include NEW_H
 #define ZIP_ARENABLOCKSIZE (1*1024)
 
 #ifdef XP_UNIX
+    #include <sys/mman.h>
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <limits.h>
     #include <unistd.h>
 #elif defined(XP_WIN) || defined(XP_OS2)
     #include <io.h>
 #endif
 
@@ -151,29 +152,36 @@ nsresult gZlibInit(z_stream *zs)
   if (zerr != Z_OK) return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 nsZipHandle::nsZipHandle()
   : mFileData(nullptr)
   , mLen(0)
+#if defined(XP_WIN)
+  , mFd(nullptr)
+#endif
   , mMap(nullptr)
   , mRefCnt(0)
 {
   MOZ_COUNT_CTOR(nsZipHandle);
 }
 
 NS_IMPL_THREADSAFE_ADDREF(nsZipHandle)
 NS_IMPL_THREADSAFE_RELEASE(nsZipHandle)
 
 nsresult nsZipHandle::Init(nsIFile *file, nsZipHandle **ret)
 {
   mozilla::AutoFDClose fd;
-  nsresult rv = file->OpenNSPRFileDesc(PR_RDONLY, 0000, &fd.rwget());
+  int32_t flags = PR_RDONLY;
+#if defined(XP_WIN)
+  flags |= nsIFile::OS_READAHEAD;
+#endif
+  nsresult rv = file->OpenNSPRFileDesc(flags, 0000, &fd.rwget());
   if (NS_FAILED(rv))
     return rv;
 
   int64_t size = PR_Available64(fd);
   if (size >= INT32_MAX)
     return NS_ERROR_FILE_TOO_BIG;
 
   PRFileMap *map = PR_CreateFileMap(fd, size, PR_PROT_READONLY);
@@ -189,16 +197,19 @@ nsresult nsZipHandle::Init(nsIFile *file
 
   nsRefPtr<nsZipHandle> handle = new nsZipHandle();
   if (!handle) {
     PR_MemUnmap(buf, (uint32_t) size);
     PR_CloseFileMap(map);
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
+#if defined(XP_WIN)
+  handle->mFd = fd.forget();
+#endif
   handle->mMap = map;
   handle->mFile.Init(file);
   handle->mLen = (uint32_t) size;
   handle->mFileData = buf;
   *ret = handle.forget().get();
   return NS_OK;
 }
 
@@ -226,16 +237,21 @@ nsresult nsZipHandle::Init(nsZipArchive 
 
 int64_t nsZipHandle::SizeOfMapping()
 {
     return mLen;
 }
 
 nsZipHandle::~nsZipHandle()
 {
+#if defined(XP_WIN)
+  if (mFd) {
+    PR_Close(mFd);
+  }
+#endif
   if (mMap) {
     PR_MemUnmap((void *)mFileData, mLen);
     PR_CloseFileMap(mMap);
   }
   mFileData = nullptr;
   mMap = nullptr;
   mBuf = nullptr;
   MOZ_COUNT_DTOR(nsZipHandle);
@@ -564,16 +580,25 @@ nsresult nsZipArchive::BuildFileList()
   // Get archive size using end pos
   const uint8_t* buf;
   const uint8_t* startp = mFd->mFileData;
   const uint8_t* endp = startp + mFd->mLen;
 MOZ_WIN_MEM_TRY_BEGIN
   uint32_t centralOffset = 4;
   if (mFd->mLen > ZIPCENTRAL_SIZE && xtolong(startp + centralOffset) == CENTRALSIG) {
     // Success means optimized jar layout from bug 559961 is in effect
+    uint32_t readaheadLength = xtolong(startp);
+    if (readaheadLength) {
+#if defined(XP_UNIX)
+      madvise(const_cast<uint8_t*>(startp), readaheadLength, MADV_WILLNEED);
+#elif defined(XP_WIN)
+      HANDLE hFile = (HANDLE) PR_FileDesc2NativeHandle(mFd->mFd);
+      mozilla::ReadAhead(hFile, 0, readaheadLength);
+#endif
+    }
   } else {
     for (buf = endp - ZIPEND_SIZE; buf > startp; buf--)
       {
         if (xtolong(buf) == ENDSIG) {
           centralOffset = xtolong(((ZipEnd *)buf)->offset_central_dir);
           break;
         }
       }
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -387,16 +387,19 @@ protected:
   const uint8_t * mFileData; /* pointer to mmaped file */
   uint32_t        mLen;      /* length of file and memory mapped area */
   mozilla::FileLocation mFile; /* source file if any, for logging */
 
 private:
   nsZipHandle();
   ~nsZipHandle();
 
+#if defined(XP_WIN)
+  PRFileDesc *                      mFd;     /* nspr file descriptor */
+#endif
   PRFileMap *                       mMap;    /* nspr datastructure for mmap */
   nsAutoPtr<nsZipItemPtr<uint8_t> > mBuf;
   nsrefcnt                          mRefCnt; /* ref count */
 };
 
 nsresult gZlibInit(z_stream *zs);
 
 #endif /* nsZipArchive_h_ */