diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -1279,6 +1279,7 @@ } void unmapImpl(); + void dontNeedImpl(); std::error_code init(sys::fs::file_t FD, uint64_t Offset, mapmode Mode); @@ -1308,6 +1309,7 @@ unmapImpl(); copyFrom(mapped_file_region()); } + void dontNeed() { dontNeedImpl(); } size_t size() const; char *data() const; diff --git a/llvm/include/llvm/Support/MemoryBuffer.h b/llvm/include/llvm/Support/MemoryBuffer.h --- a/llvm/include/llvm/Support/MemoryBuffer.h +++ b/llvm/include/llvm/Support/MemoryBuffer.h @@ -74,6 +74,12 @@ /// from. virtual StringRef getBufferIdentifier() const { return "Unknown buffer"; } + /// For MemoryBuffer_MMap, mark the buffer as unused for an unspecified amount + /// of time and the kernel can free resources associated with it. Further + /// access is supported but may be expensive. This calls + /// madvise(MADV_DONTNEED) on Linux. + virtual void dontNeedIfMmap() {} + /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer /// if successful, otherwise returning null. /// diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp --- a/llvm/lib/Support/MemoryBuffer.cpp +++ b/llvm/lib/Support/MemoryBuffer.cpp @@ -220,6 +220,8 @@ MemoryBuffer::BufferKind getBufferKind() const override { return MemoryBuffer::MemoryBuffer_MMap; } + + void dontNeedIfMmap() override { MFR.dontNeed(); } }; } // namespace diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -870,6 +870,12 @@ ::munmap(Mapping, Size); } +void mapped_file_region::dontNeedImpl() { + assert(Mode == mapped_file_region::readonly); + if (Mapping) + ::madvise(Mapping, Size, MADV_DONTNEED); +} + int mapped_file_region::alignment() { return Process::getPageSizeEstimate(); } diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -959,6 +959,8 @@ } } +void mapped_file_region::dontNeedImpl() {} + int mapped_file_region::alignment() { SYSTEM_INFO SysInfo; ::GetSystemInfo(&SysInfo);