Files
Emily McDonough 2e526174b9 Bug 2059260 Part 2 - Update xpconnect/AutoMemMap to use MemoryMappedFile r=afranchuk
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
2026-08-11 23:13:07 +00:00

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