There are a number of features this class provided that MemoryMappedFile can't support, but which nothing actually uses (writeable files, requesting a region size, etc) which can just be removed. This class also introduced a source of const-incorrectness, as it was possible to map a file as read-only but then get a RangedPtr to mutable data (a const pointer to mutable data is not a pointer to const data...). However, the only places this was used was for memory prefetch, which should never write to the underlying memory. Since the files were always read-only mapped, we can safely say we would already be getting protection faults if it did. So we can make the prefetch take a const pointer, and then AutoMemMap can always hold on to read-only data. This preserves the existing limit of AutoMemMap only supporting files up to 4 GB in size, even on 64-bit systems. Differential Revision: https://phabricator.services.mozilla.com/D316644
75 lines
1.7 KiB
C++
75 lines
1.7 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "AutoMemMap.h"
|
|
|
|
#include "mozilla/ipc/FileDescriptor.h"
|
|
#include "mozilla/Try.h"
|
|
|
|
#include <private/pprio.h>
|
|
|
|
#include "nsIFile.h"
|
|
#include "ScriptPreloader-inl.h"
|
|
|
|
namespace mozilla {
|
|
namespace loader {
|
|
|
|
using namespace mozilla::ipc;
|
|
|
|
FileDescriptor AutoMemMap::cloneFileDescriptor() const {
|
|
if (mFD.get()) {
|
|
auto handle =
|
|
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD.get()));
|
|
return FileDescriptor(handle);
|
|
}
|
|
return FileDescriptor();
|
|
}
|
|
|
|
FileDescriptor AutoMemMap::cloneHandle() const { return cloneFileDescriptor(); }
|
|
|
|
Result<Ok, nsresult> AutoMemMap::init(nsIFile* file) {
|
|
MOZ_ASSERT(!mFD);
|
|
|
|
MOZ_TRY(file->OpenNSPRFileDesc(PR_RDONLY, 0, getter_Transfers(mFD)));
|
|
|
|
mFile = MemoryMappedFile::Open(mFD.get(), UINT32_MAX);
|
|
if (!mFile.IsValid()) {
|
|
return Err(NS_ERROR_FAILURE);
|
|
}
|
|
return Ok();
|
|
}
|
|
|
|
Result<Ok, nsresult> AutoMemMap::init(const FileDescriptor& file) {
|
|
MOZ_ASSERT(!mFD);
|
|
if (!file.IsValid()) {
|
|
return Err(NS_ERROR_INVALID_ARG);
|
|
}
|
|
|
|
auto handle = file.ClonePlatformHandle();
|
|
|
|
mFD.reset(PR_ImportFile(PROsfd(handle.get())));
|
|
if (!mFD) {
|
|
return Err(NS_ERROR_FAILURE);
|
|
}
|
|
(void)handle.release();
|
|
|
|
mFile = MemoryMappedFile::Open(mFD.get(), UINT32_MAX);
|
|
if (!mFile.IsValid()) {
|
|
return Err(NS_ERROR_FAILURE);
|
|
}
|
|
return Ok();
|
|
}
|
|
|
|
void AutoMemMap::reset() {
|
|
if (mPersistent) {
|
|
mFile.Leak();
|
|
} else {
|
|
mFile.Unmap();
|
|
}
|
|
mFD = nullptr;
|
|
}
|
|
|
|
} // namespace loader
|
|
} // namespace mozilla
|