10#include "llvm/Support/MemoryBuffer.h"
11#include "llvm/Support/SmallVectorMemoryBuffer.h"
12#include "llvm/Support/Threading.h"
16using namespace tooling;
17using namespace dependencies;
19llvm::ErrorOr<DependencyScanningWorkerFilesystem::TentativeEntry>
20DependencyScanningWorkerFilesystem::readFile(StringRef
Filename) {
22 auto MaybeFile = getUnderlyingFS().openFileForRead(
Filename);
24 return MaybeFile.getError();
25 auto File = std::move(*MaybeFile);
27 auto MaybeStat =
File->status();
29 return MaybeStat.getError();
30 auto Stat = std::move(*MaybeStat);
32 auto MaybeBuffer =
File->getBuffer(Stat.getName());
34 return MaybeBuffer.getError();
35 auto Buffer = std::move(*MaybeBuffer);
38 if (Stat.getSize() != Buffer->getBufferSize())
39 Stat = llvm::vfs::Status::copyWithNewSize(Stat, Buffer->getBufferSize());
41 return TentativeEntry(Stat, std::move(Buffer));
46 auto &Entry = Ref.Entry;
48 if (Entry.isError() || Entry.isDirectory())
52 assert(Contents &&
"contents not initialized");
58 std::lock_guard<std::mutex> GuardLock(Contents->
ValueLock);
72 Contents->
DepDirectives.store(
new std::optional<DependencyDirectivesTy>());
81 new std::optional<DependencyDirectivesTy>(std::move(Directives)));
93 std::max(2u, llvm::hardware_concurrency().compute_thread_count() / 4);
94 CacheShards = std::make_unique<CacheShard[]>(NumShards);
100 assert(llvm::sys::path::is_absolute_gnu(
Filename));
106 llvm::sys::fs::UniqueID UID)
const {
107 auto Hash = llvm::hash_combine(UID.getDevice(), UID.getFile());
108 return CacheShards[Hash % NumShards];
114 assert(llvm::sys::path::is_absolute_gnu(
Filename));
115 std::lock_guard<std::mutex> LockGuard(
CacheLock);
122 llvm::sys::fs::UniqueID UID)
const {
123 std::lock_guard<std::mutex> LockGuard(CacheLock);
124 auto It = EntriesByUID.find(UID);
125 return It == EntriesByUID.end() ? nullptr : It->getSecond();
131 llvm::ErrorOr<llvm::vfs::Status> Stat) {
132 std::lock_guard<std::mutex> LockGuard(CacheLock);
133 auto [It, Inserted] = CacheByFilename.insert({
Filename, {
nullptr,
nullptr}});
138 assert((Inserted ||
CachedRealPath) &&
"existing file with empty pair");
147 llvm::sys::fs::UniqueID UID, llvm::vfs::Status Stat,
148 std::unique_ptr<llvm::MemoryBuffer> Contents) {
149 std::lock_guard<std::mutex> LockGuard(CacheLock);
150 auto [It, Inserted] = EntriesByUID.insert({UID,
nullptr});
151 auto &CachedEntry = It->getSecond();
155 StoredContents =
new (ContentsStorage.Allocate())
157 CachedEntry =
new (EntryStorage.Allocate())
167 std::lock_guard<std::mutex> LockGuard(CacheLock);
168 auto [It, Inserted] = CacheByFilename.insert({
Filename, {&Entry,
nullptr}});
170 if (!Inserted || !CachedEntry)
171 CachedEntry = &Entry;
178 assert(llvm::sys::path::is_absolute_gnu(
Filename));
179 std::lock_guard<std::mutex> LockGuard(CacheLock);
180 auto It = CacheByFilename.find(
Filename);
181 return It == CacheByFilename.end() ? nullptr : It->getValue().second;
186 llvm::ErrorOr<llvm::StringRef> RealPath) {
187 std::lock_guard<std::mutex> LockGuard(CacheLock);