summaryrefslogtreecommitdiff
path: root/lib/Support/MemoryBuffer.cpp
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2013-03-12 19:28:19 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2013-03-12 19:28:19 +0000
commitcc189bfb08864ef615e5dc48476b992b81f29167 (patch)
tree2a08cc1df61d0a3bf44a7e55ce075593db52c529 /lib/Support/MemoryBuffer.cpp
parentad5a5e04275a5fec94b9a4dfc9a865191088a5bf (diff)
downloadllvm-cc189bfb08864ef615e5dc48476b992b81f29167.tar.gz
llvm-cc189bfb08864ef615e5dc48476b992b81f29167.tar.bz2
llvm-cc189bfb08864ef615e5dc48476b992b81f29167.tar.xz
[Support][MemoryBuffer] Use sys::fs::mapped_file_region instead of sys::Path::MapInFilePages.
This gives us memory mapped file I/O on Windows. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176886 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/MemoryBuffer.cpp')
-rw-r--r--lib/Support/MemoryBuffer.cpp79
1 files changed, 44 insertions, 35 deletions
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 4c558b37cf..1c354be2e0 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -72,13 +72,15 @@ static void CopyStringRef(char *Memory, StringRef Data) {
Memory[Data.size()] = 0; // Null terminate string.
}
-/// GetNamedBuffer - Allocates a new MemoryBuffer with Name copied after it.
-template <typename T>
-static T *GetNamedBuffer(StringRef Buffer, StringRef Name,
- bool RequiresNullTerminator) {
- char *Mem = static_cast<char*>(operator new(sizeof(T) + Name.size() + 1));
- CopyStringRef(Mem + sizeof(T), Name);
- return new (Mem) T(Buffer, RequiresNullTerminator);
+struct NamedBufferAlloc {
+ StringRef Name;
+ NamedBufferAlloc(StringRef Name) : Name(Name) {}
+};
+
+void *operator new(size_t N, const NamedBufferAlloc &Alloc) {
+ char *Mem = static_cast<char *>(operator new(N + Alloc.Name.size() + 1));
+ CopyStringRef(Mem + N, Alloc.Name);
+ return Mem;
}
namespace {
@@ -105,8 +107,8 @@ public:
MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
StringRef BufferName,
bool RequiresNullTerminator) {
- return GetNamedBuffer<MemoryBufferMem>(InputData, BufferName,
- RequiresNullTerminator);
+ return new (NamedBufferAlloc(BufferName))
+ MemoryBufferMem(InputData, RequiresNullTerminator);
}
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
@@ -183,24 +185,38 @@ error_code MemoryBuffer::getFileOrSTDIN(const char *Filename,
//===----------------------------------------------------------------------===//
namespace {
-/// MemoryBufferMMapFile - This represents a file that was mapped in with the
-/// sys::Path::MapInFilePages method. When destroyed, it calls the
-/// sys::Path::UnMapFilePages method.
-class MemoryBufferMMapFile : public MemoryBufferMem {
-public:
- MemoryBufferMMapFile(StringRef Buffer, bool RequiresNullTerminator)
- : MemoryBufferMem(Buffer, RequiresNullTerminator) { }
+/// \brief Memorry maps a file descriptor using sys::fs::mapped_file_region.
+///
+/// This handles converting the offset into a legal offset on the platform.
+class MemoryBufferMMapFile : public MemoryBuffer {
+ sys::fs::mapped_file_region MFR;
+
+ static uint64_t getLegalMapOffset(uint64_t Offset) {
+ return Offset & ~(sys::fs::mapped_file_region::alignment() - 1);
+ }
+
+ static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) {
+ return Len + (Offset - getLegalMapOffset(Offset));
+ }
- ~MemoryBufferMMapFile() {
- static int PageSize = sys::process::get_self()->page_size();
+ const char *getStart(uint64_t Len, uint64_t Offset) {
+ return MFR.const_data() + (Offset - getLegalMapOffset(Offset));
+ }
- uintptr_t Start = reinterpret_cast<uintptr_t>(getBufferStart());
- size_t Size = getBufferSize();
- uintptr_t RealStart = Start & ~(PageSize - 1);
- size_t RealSize = Size + (Start - RealStart);
+public:
+ MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
+ uint64_t Offset, error_code EC)
+ : MFR(FD, sys::fs::mapped_file_region::readonly,
+ getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
+ if (!EC) {
+ const char *Start = getStart(Len, Offset);
+ init(Start, Start + Len, RequiresNullTerminator);
+ }
+ }
- sys::Path::UnMapFilePages(reinterpret_cast<const char*>(RealStart),
- RealSize);
+ virtual const char *getBufferIdentifier() const LLVM_OVERRIDE {
+ // The name is stored after the class itself.
+ return reinterpret_cast<const char *>(this + 1);
}
virtual BufferKind getBufferKind() const LLVM_OVERRIDE {
@@ -265,7 +281,6 @@ error_code MemoryBuffer::getFile(const char *Filename,
error_code ret = getOpenFile(FD, Filename, result, FileSize, FileSize,
0, RequiresNullTerminator);
- close(FD);
return ret;
}
@@ -344,17 +359,11 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
PageSize)) {
- off_t RealMapOffset = Offset & ~(PageSize - 1);
- off_t Delta = Offset - RealMapOffset;
- size_t RealMapSize = MapSize + Delta;
-
- if (const char *Pages = sys::Path::MapInFilePages(FD,
- RealMapSize,
- RealMapOffset)) {
- result.reset(GetNamedBuffer<MemoryBufferMMapFile>(
- StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator));
+ error_code EC;
+ result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile(
+ RequiresNullTerminator, FD, MapSize, Offset, EC));
+ if (!EC)
return error_code::success();
- }
}
MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename);