From eb11fae6d08f479c0799db45860a98af528fa6e7 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 28 Jul 2018 10:51:19 +0000 Subject: Vendor import of llvm trunk r338150: https://llvm.org/svn/llvm-project/llvm/trunk@338150 --- lib/Support/MemoryBuffer.cpp | 89 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 17 deletions(-) (limited to 'lib/Support/MemoryBuffer.cpp') diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index c709fc416df6..4428c2f24e32 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -21,6 +21,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include #include #include @@ -139,15 +140,6 @@ MemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) { return nullptr; } -std::unique_ptr -MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { - auto SB = WritableMemoryBuffer::getNewUninitMemBuffer(Size, BufferName); - if (!SB) - return nullptr; - memset(SB->getBufferStart(), 0, Size); - return std::move(SB); -} - ErrorOr> MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize, bool RequiresNullTerminator) { @@ -171,7 +163,7 @@ MemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize, //===----------------------------------------------------------------------===// namespace { -/// \brief Memory maps a file descriptor using sys::fs::mapped_file_region. +/// Memory maps a file descriptor using sys::fs::mapped_file_region. /// /// This handles converting the offset into a legal offset on the platform. template @@ -193,10 +185,8 @@ class MemoryBufferMMapFile : public MB { public: MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len, uint64_t Offset, std::error_code &EC) - : MFR(FD, - MB::Writable ? sys::fs::mapped_file_region::priv - : sys::fs::mapped_file_region::readonly, - getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) { + : MFR(FD, MB::Mapmode, getLegalMapSize(Len, Offset), + getLegalMapOffset(Offset), EC) { if (!EC) { const char *Start = getStart(Len, Offset); MemoryBuffer::init(Start, Start + Len, RequiresNullTerminator); @@ -226,7 +216,7 @@ getMemoryBufferForStream(int FD, const Twine &BufferName) { // Read into Buffer until we hit EOF. do { Buffer.reserve(Buffer.size() + ChunkSize); - ReadBytes = sys::RetryAfterSignal(-1, read, FD, Buffer.end(), ChunkSize); + ReadBytes = sys::RetryAfterSignal(-1, ::read, FD, Buffer.end(), ChunkSize); if (ReadBytes == -1) return std::error_code(errno, std::generic_category()); Buffer.set_size(Buffer.size() + ReadBytes); @@ -254,7 +244,7 @@ static ErrorOr> getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile) { int FD; - std::error_code EC = sys::fs::openFileForRead(Filename, FD); + std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None); if (EC) return EC; @@ -306,6 +296,15 @@ WritableMemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName return std::unique_ptr(Ret); } +std::unique_ptr +WritableMemoryBuffer::getNewMemBuffer(size_t Size, const Twine &BufferName) { + auto SB = WritableMemoryBuffer::getNewUninitMemBuffer(Size, BufferName); + if (!SB) + return nullptr; + memset(SB->getBufferStart(), 0, Size); + return SB; +} + static bool shouldUseMmap(int FD, size_t FileSize, size_t MapSize, @@ -361,6 +360,59 @@ static bool shouldUseMmap(int FD, return true; } +static ErrorOr> +getReadWriteFile(const Twine &Filename, uint64_t FileSize, uint64_t MapSize, + uint64_t Offset) { + int FD; + std::error_code EC = sys::fs::openFileForReadWrite( + Filename, FD, sys::fs::CD_OpenExisting, sys::fs::OF_None); + + if (EC) + return EC; + + // Default is to map the full file. + if (MapSize == uint64_t(-1)) { + // If we don't know the file size, use fstat to find out. fstat on an open + // file descriptor is cheaper than stat on a random path. + if (FileSize == uint64_t(-1)) { + sys::fs::file_status Status; + std::error_code EC = sys::fs::status(FD, Status); + if (EC) + return EC; + + // If this not a file or a block device (e.g. it's a named pipe + // or character device), we can't mmap it, so error out. + sys::fs::file_type Type = Status.type(); + if (Type != sys::fs::file_type::regular_file && + Type != sys::fs::file_type::block_file) + return make_error_code(errc::invalid_argument); + + FileSize = Status.getSize(); + } + MapSize = FileSize; + } + + std::unique_ptr Result( + new (NamedBufferAlloc(Filename)) + MemoryBufferMMapFile(false, FD, MapSize, + Offset, EC)); + if (EC) + return EC; + return std::move(Result); +} + +ErrorOr> +WriteThroughMemoryBuffer::getFile(const Twine &Filename, int64_t FileSize) { + return getReadWriteFile(Filename, FileSize, FileSize, 0); +} + +/// Map a subrange of the specified file as a WritableMemoryBuffer. +ErrorOr> +WriteThroughMemoryBuffer::getFileSlice(const Twine &Filename, uint64_t MapSize, + uint64_t Offset) { + return getReadWriteFile(Filename, -1, MapSize, Offset); +} + template static ErrorOr> getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, @@ -466,7 +518,7 @@ ErrorOr> MemoryBuffer::getSTDIN() { ErrorOr> MemoryBuffer::getFileAsStream(const Twine &Filename) { int FD; - std::error_code EC = sys::fs::openFileForRead(Filename, FD); + std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None); if (EC) return EC; ErrorOr> Ret = @@ -480,3 +532,6 @@ MemoryBufferRef MemoryBuffer::getMemBufferRef() const { StringRef Identifier = getBufferIdentifier(); return MemoryBufferRef(Data, Identifier); } + +void MemoryBuffer::anchor() {} +void SmallVectorMemoryBuffer::anchor() {} -- cgit v1.2.3