diff options
author | Michael Spencer <bigcheesegs@gmail.com> | 2020-04-08 20:29:39 -0700 |
---|---|---|
committer | Michael Spencer <bigcheesegs@gmail.com> | 2020-04-15 14:17:51 -0700 |
commit | 92e8af0ecbe7eb36bc03a211afa9151c81b7b531 (patch) | |
tree | 4a288257c6eba1e531040c77d7c51874abd6234d /clang/lib/Basic/FileManager.cpp | |
parent | 1eac2c55d861dfc6d88308ad97c242cbd60e5da1 (diff) | |
download | llvm-92e8af0ecbe7eb36bc03a211afa9151c81b7b531.zip llvm-92e8af0ecbe7eb36bc03a211afa9151c81b7b531.tar.gz llvm-92e8af0ecbe7eb36bc03a211afa9151c81b7b531.tar.bz2 |
[Clang] Expose RequiresNullTerminator in FileManager.
This is needed to fix the reason
0a2be46cfdb698fe (Modules: Invalidate out-of-date PCMs as they're
discovered) and 5b44a4b07fc1d ([modules] Do not cache invalid state for
modules that we attempted to load.) were reverted.
These patches changed Clang to use `isVolatile` when loading modules.
This had the side effect of not using mmap when loading modules, and
thus greatly increased memory usage.
The reason it wasn't using mmap is because `MemoryBuffer` plays some
games with file size when you request null termination, and it has to
disable these when `isVolatile` is set as the size may change by the
time it's mmapped. Clang by default passes
`RequiresNullTerminator = true`, and `shouldUseMmap` ignored if
`RequiresNullTerminator` was even requested.
This patch adds `RequiresNullTerminator` to the `FileManager` interface
so Clang can use it when loading modules, and changes `shouldUseMmap` to
only take volatility into account if `RequiresNullTerminator` is true.
This is fine as both `mmap` and a `read` loop are vulnerable to
modifying the file while reading, but are immune to the rename Clang
does when replacing a module file.
Differential Revision: https://reviews.llvm.org/D77772
Diffstat (limited to 'clang/lib/Basic/FileManager.cpp')
-rw-r--r-- | clang/lib/Basic/FileManager.cpp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index ac8af8f..e92e9d5 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -458,7 +458,8 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) { } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile) { +FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, + bool RequiresNullTerminator) { uint64_t FileSize = Entry->getSize(); // If there's a high enough chance that the file have changed since we // got its size, force a stat before opening it. @@ -468,28 +469,29 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile) { StringRef Filename = Entry->getName(); // If the file is already open, use the open file descriptor. if (Entry->File) { - auto Result = - Entry->File->getBuffer(Filename, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + auto Result = Entry->File->getBuffer(Filename, FileSize, + RequiresNullTerminator, isVolatile); Entry->closeFile(); return Result; } // Otherwise, open the file. - return getBufferForFileImpl(Filename, FileSize, isVolatile); + return getBufferForFileImpl(Filename, FileSize, isVolatile, + RequiresNullTerminator); } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileManager::getBufferForFileImpl(StringRef Filename, int64_t FileSize, - bool isVolatile) { + bool isVolatile, + bool RequiresNullTerminator) { if (FileSystemOpts.WorkingDir.empty()) - return FS->getBufferForFile(Filename, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + return FS->getBufferForFile(Filename, FileSize, RequiresNullTerminator, + isVolatile); SmallString<128> FilePath(Filename); FixupRelativePath(FilePath); - return FS->getBufferForFile(FilePath, FileSize, - /*RequiresNullTerminator=*/true, isVolatile); + return FS->getBufferForFile(FilePath, FileSize, RequiresNullTerminator, + isVolatile); } /// getStatValue - Get the 'stat' information for the specified path, |