[llvm] 890e8c8 - [Support] Add MemoryBuffer::dontNeedIfMmap

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 30 10:42:32 PST 2021


Author: Fangrui Song
Date: 2021-12-30T10:42:28-08:00
New Revision: 890e8c8f7e9e448a870224068d6b4181d96a293d

URL: https://github.com/llvm/llvm-project/commit/890e8c8f7e9e448a870224068d6b4181d96a293d
DIFF: https://github.com/llvm/llvm-project/commit/890e8c8f7e9e448a870224068d6b4181d96a293d.diff

LOG: [Support] Add MemoryBuffer::dontNeedIfMmap

On *NIX systems, this API calls madvise(MADV_DONTNEED) on read-only file mappings.
It should not be used on a writable buffer.
The API is used to implement ld.lld LTO memory saving trick (D116367).

Note: on read-only file mappings, Linux's MADV_DONTNEED semantics match POSIX
POSIX_MADV_DONTNEED and BSD systems' MADV_DONTNEED.

On Windows, VirtualAllocEx MEM_COMMIT/MEM_RESET have similar semantics
but are unfortunately not drop-in replacements. dontNeedIfMmap is currently a no-op.

Reviewed By: aganea

Differential Revision: https://reviews.llvm.org/D116366

Added: 
    

Modified: 
    llvm/include/llvm/Support/FileSystem.h
    llvm/include/llvm/Support/MemoryBuffer.h
    llvm/lib/Support/MemoryBuffer.cpp
    llvm/lib/Support/Unix/Path.inc
    llvm/lib/Support/Windows/Path.inc

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h
index 1a049533b82b1..dabd384b400b4 100644
--- a/llvm/include/llvm/Support/FileSystem.h
+++ b/llvm/include/llvm/Support/FileSystem.h
@@ -1279,6 +1279,7 @@ class mapped_file_region {
   }
 
   void unmapImpl();
+  void dontNeedImpl();
 
   std::error_code init(sys::fs::file_t FD, uint64_t Offset, mapmode Mode);
 
@@ -1308,6 +1309,7 @@ class mapped_file_region {
     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
index c9ceeedbf3dc5..6385805eba1d7 100644
--- a/llvm/include/llvm/Support/MemoryBuffer.h
+++ b/llvm/include/llvm/Support/MemoryBuffer.h
@@ -74,6 +74,13 @@ class MemoryBuffer {
   /// from.
   virtual StringRef getBufferIdentifier() const { return "Unknown buffer"; }
 
+  /// For read-only MemoryBuffer_MMap, mark the buffer as unused in the near
+  /// future and the kernel can free resources associated with it. Further
+  /// access is supported but may be expensive. This calls
+  /// madvise(MADV_DONTNEED) on read-only file mappings on *NIX systems. This
+  /// function should not be called on a writable buffer.
+  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
index d3fa3c6f065de..345b0d4aede5d 100644
--- a/llvm/lib/Support/MemoryBuffer.cpp
+++ b/llvm/lib/Support/MemoryBuffer.cpp
@@ -220,6 +220,8 @@ class MemoryBufferMMapFile : public MB {
   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
index c0712e0a06812..a18650aadb6e9 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -870,6 +870,12 @@ void mapped_file_region::unmapImpl() {
     ::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
index b15e71a9ce2a2..175a96a8ba6c9 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -959,6 +959,8 @@ void mapped_file_region::unmapImpl() {
   }
 }
 
+void mapped_file_region::dontNeedImpl() {}
+
 int mapped_file_region::alignment() {
   SYSTEM_INFO SysInfo;
   ::GetSystemInfo(&SysInfo);


        


More information about the llvm-commits mailing list