diff options
Diffstat (limited to 'llvm/lib/Support/MemoryBuffer.cpp')
-rw-r--r-- | llvm/lib/Support/MemoryBuffer.cpp | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp index 9872dfa78b26..6bb046e9b3db 100644 --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -109,7 +110,8 @@ public: template <typename MB> static ErrorOr<std::unique_ptr<MB>> getFileAux(const Twine &Filename, uint64_t MapSize, uint64_t Offset, - bool IsText, bool RequiresNullTerminator, bool IsVolatile); + bool IsText, bool RequiresNullTerminator, bool IsVolatile, + Optional<Align> Alignment); std::unique_ptr<MemoryBuffer> MemoryBuffer::getMemBuffer(StringRef InputData, StringRef BufferName, @@ -144,21 +146,24 @@ MemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) { ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getFileOrSTDIN(const Twine &Filename, bool IsText, - bool RequiresNullTerminator) { + bool RequiresNullTerminator, + Optional<Align> Alignment) { SmallString<256> NameBuf; StringRef NameRef = Filename.toStringRef(NameBuf); if (NameRef == "-") return getSTDIN(); return getFile(Filename, IsText, RequiresNullTerminator, - /*IsVolatile=*/false); + /*IsVolatile=*/false, Alignment); } ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize, - uint64_t Offset, bool IsVolatile) { + uint64_t Offset, bool IsVolatile, + Optional<Align> Alignment) { return getFileAux<MemoryBuffer>(FilePath, MapSize, Offset, /*IsText=*/false, - /*RequiresNullTerminator=*/false, IsVolatile); + /*RequiresNullTerminator=*/false, IsVolatile, + Alignment); } //===----------------------------------------------------------------------===// @@ -237,58 +242,67 @@ getMemoryBufferForStream(sys::fs::file_t FD, const Twine &BufferName) { ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getFile(const Twine &Filename, bool IsText, - bool RequiresNullTerminator, bool IsVolatile) { + bool RequiresNullTerminator, bool IsVolatile, + Optional<Align> Alignment) { return getFileAux<MemoryBuffer>(Filename, /*MapSize=*/-1, /*Offset=*/0, - IsText, RequiresNullTerminator, IsVolatile); + IsText, RequiresNullTerminator, IsVolatile, + Alignment); } template <typename MB> static ErrorOr<std::unique_ptr<MB>> getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, - bool IsVolatile); + bool IsVolatile, Optional<Align> Alignment); template <typename MB> static ErrorOr<std::unique_ptr<MB>> getFileAux(const Twine &Filename, uint64_t MapSize, uint64_t Offset, - bool IsText, bool RequiresNullTerminator, bool IsVolatile) { + bool IsText, bool RequiresNullTerminator, bool IsVolatile, + Optional<Align> Alignment) { Expected<sys::fs::file_t> FDOrErr = sys::fs::openNativeFileForRead( Filename, IsText ? sys::fs::OF_TextWithCRLF : sys::fs::OF_None); if (!FDOrErr) return errorToErrorCode(FDOrErr.takeError()); sys::fs::file_t FD = *FDOrErr; auto Ret = getOpenFileImpl<MB>(FD, Filename, /*FileSize=*/-1, MapSize, Offset, - RequiresNullTerminator, IsVolatile); + RequiresNullTerminator, IsVolatile, Alignment); sys::fs::closeFile(FD); return Ret; } ErrorOr<std::unique_ptr<WritableMemoryBuffer>> -WritableMemoryBuffer::getFile(const Twine &Filename, bool IsVolatile) { +WritableMemoryBuffer::getFile(const Twine &Filename, bool IsVolatile, + Optional<Align> Alignment) { return getFileAux<WritableMemoryBuffer>( Filename, /*MapSize=*/-1, /*Offset=*/0, /*IsText=*/false, - /*RequiresNullTerminator=*/false, IsVolatile); + /*RequiresNullTerminator=*/false, IsVolatile, Alignment); } ErrorOr<std::unique_ptr<WritableMemoryBuffer>> WritableMemoryBuffer::getFileSlice(const Twine &Filename, uint64_t MapSize, - uint64_t Offset, bool IsVolatile) { + uint64_t Offset, bool IsVolatile, + Optional<Align> Alignment) { return getFileAux<WritableMemoryBuffer>( Filename, MapSize, Offset, /*IsText=*/false, - /*RequiresNullTerminator=*/false, IsVolatile); + /*RequiresNullTerminator=*/false, IsVolatile, Alignment); } std::unique_ptr<WritableMemoryBuffer> -WritableMemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName) { +WritableMemoryBuffer::getNewUninitMemBuffer(size_t Size, + const Twine &BufferName, + Optional<Align> Alignment) { using MemBuffer = MemoryBufferMem<WritableMemoryBuffer>; + + // Use 16-byte alignment if no alignment is specified. + Align BufAlign = Alignment.value_or(Align(16)); + // Allocate space for the MemoryBuffer, the data and the name. It is important // that MemoryBuffer and data are aligned so PointerIntPair works with them. - // TODO: Is 16-byte alignment enough? We copy small object files with large - // alignment expectations into this buffer. SmallString<256> NameBuf; StringRef NameRef = BufferName.toStringRef(NameBuf); - size_t AlignedStringLen = alignTo(sizeof(MemBuffer) + NameRef.size() + 1, 16); - size_t RealLen = AlignedStringLen + Size + 1; + size_t StringLen = sizeof(MemBuffer) + NameRef.size() + 1; + size_t RealLen = StringLen + Size + 1 + BufAlign.value(); if (RealLen <= Size) // Check for rollover. return nullptr; char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); @@ -299,7 +313,7 @@ WritableMemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName CopyStringRef(Mem + sizeof(MemBuffer), NameRef); // The buffer begins after the name and must be aligned. - char *Buf = Mem + AlignedStringLen; + char *Buf = (char *)alignAddr(Mem + StringLen, BufAlign); Buf[Size] = 0; // Null terminate buffer. auto *Ret = new (Mem) MemBuffer(StringRef(Buf, Size), true); @@ -427,7 +441,7 @@ template <typename MB> static ErrorOr<std::unique_ptr<MB>> getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, - bool IsVolatile) { + bool IsVolatile, Optional<Align> Alignment) { static int PageSize = sys::Process::getPageSizeEstimate(); // Default is to map the full file. @@ -469,7 +483,8 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, return EC; #endif - auto Buf = WritableMemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); + auto Buf = + WritableMemoryBuffer::getNewUninitMemBuffer(MapSize, Filename, Alignment); if (!Buf) { // Failed to create a buffer. The only way it can fail is if // new(std::nothrow) returns 0. @@ -495,18 +510,21 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, } ErrorOr<std::unique_ptr<MemoryBuffer>> -MemoryBuffer::getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, - bool RequiresNullTerminator, bool IsVolatile) { +MemoryBuffer::getOpenFile(sys::fs::file_t FD, const Twine &Filename, + uint64_t FileSize, bool RequiresNullTerminator, + bool IsVolatile, Optional<Align> Alignment) { return getOpenFileImpl<MemoryBuffer>(FD, Filename, FileSize, FileSize, 0, - RequiresNullTerminator, IsVolatile); + RequiresNullTerminator, IsVolatile, + Alignment); } ErrorOr<std::unique_ptr<MemoryBuffer>> -MemoryBuffer::getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize, - int64_t Offset, bool IsVolatile) { +MemoryBuffer::getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, + uint64_t MapSize, int64_t Offset, + bool IsVolatile, Optional<Align> Alignment) { assert(MapSize != uint64_t(-1)); return getOpenFileImpl<MemoryBuffer>(FD, Filename, -1, MapSize, Offset, false, - IsVolatile); + IsVolatile, Alignment); } ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() { |