diff --git a/js/xpconnect/loader/AutoMemMap.cpp b/js/xpconnect/loader/AutoMemMap.cpp index ecf7a8fb536b..92bc728c243c 100644 --- a/js/xpconnect/loader/AutoMemMap.cpp +++ b/js/xpconnect/loader/AutoMemMap.cpp @@ -10,9 +10,13 @@ #include "mozilla/Unused.h" #include "nsIFile.h" +#include + namespace mozilla { namespace loader { +using namespace mozilla::ipc; + AutoMemMap::~AutoMemMap() { if (fileMap) { @@ -26,26 +30,62 @@ AutoMemMap::~AutoMemMap() } } +FileDescriptor +AutoMemMap::cloneFileDescriptor() +{ + if (fd.get()) { + auto handle = FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd.get())); + return FileDescriptor(handle); + } + return FileDescriptor(); +} + Result AutoMemMap::init(nsIFile* file, int flags, int mode, PRFileMapProtect prot) { MOZ_ASSERT(!fd); + + NS_TRY(file->OpenNSPRFileDesc(flags, mode, &fd.rwget())); + + return initInternal(prot); +} + +Result +AutoMemMap::init(const FileDescriptor& file) +{ + MOZ_ASSERT(!fd); + if (!file.IsValid()) { + return Err(NS_ERROR_INVALID_ARG); + } + + auto handle = file.ClonePlatformHandle(); + + fd = PR_ImportFile(PROsfd(handle.get())); + if (!fd) { + return Err(NS_ERROR_FAILURE); + } + Unused << handle.release(); + + return initInternal(); +} + +Result +AutoMemMap::initInternal(PRFileMapProtect prot) +{ MOZ_ASSERT(!fileMap); MOZ_ASSERT(!addr); - int64_t fileSize; - NS_TRY(file->GetFileSize(&fileSize)); + PRFileInfo64 fileInfo; + NS_TRY(PR_GetOpenFileInfo64(fd.get(), &fileInfo)); - if (fileSize > UINT32_MAX) + if (fileInfo.size > UINT32_MAX) return Err(NS_ERROR_INVALID_ARG); - NS_TRY(file->OpenNSPRFileDesc(flags, mode, &fd.rwget())); - fileMap = PR_CreateFileMap(fd, 0, prot); if (!fileMap) return Err(NS_ERROR_FAILURE); - size_ = fileSize; + size_ = fileInfo.size; addr = PR_MemMap(fileMap, 0, size_); if (!addr) return Err(NS_ERROR_FAILURE); diff --git a/js/xpconnect/loader/AutoMemMap.h b/js/xpconnect/loader/AutoMemMap.h index 91cba0595895..5257cfd7f948 100644 --- a/js/xpconnect/loader/AutoMemMap.h +++ b/js/xpconnect/loader/AutoMemMap.h @@ -10,6 +10,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/RangedPtr.h" #include "mozilla/Result.h" +#include "mozilla/ipc/FileDescriptor.h" #include "nsIMemoryReporter.h" #include @@ -19,6 +20,8 @@ class nsIFile; namespace mozilla { namespace loader { +using mozilla::ipc::FileDescriptor; + class AutoMemMap { public: @@ -30,6 +33,9 @@ class AutoMemMap init(nsIFile* file, int flags = PR_RDONLY, int mode = 0, PRFileMapProtect prot = PR_PROT_READONLY); + Result + init(const ipc::FileDescriptor& file); + bool initialized() { return addr; } uint32_t size() const { MOZ_ASSERT(fd); return size_; } @@ -50,7 +56,11 @@ class AutoMemMap size_t nonHeapSizeOfExcludingThis() { return size_; } + FileDescriptor cloneFileDescriptor(); + private: + Result initInternal(PRFileMapProtect prot = PR_PROT_READONLY); + AutoFDClose fd; PRFileMap* fileMap = nullptr;