diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -14,6 +14,7 @@ #include "GlobalCompilationDatabase.h" #include "index/CanonicalIncludes.h" #include "support/Function.h" +#include "support/MemoryTree.h" #include "support/Path.h" #include "support/Threading.h" #include "llvm/ADT/Optional.h" @@ -207,7 +208,8 @@ ~TUScheduler(); struct FileStats { - std::size_t UsedBytes = 0; + std::size_t UsedBytesAST = 0; + std::size_t UsedBytesPreamble = 0; unsigned PreambleBuilds = 0; unsigned ASTBuilds = 0; }; @@ -311,6 +313,8 @@ // FIXME: move to ClangdServer via createProcessingContext. static llvm::Optional getFileBeingProcessedInContext(); + MemoryTree getMemoryUsage() const; + private: const GlobalCompilationDatabase &CDB; Options Opts; diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -56,6 +56,7 @@ #include "support/Cancellation.h" #include "support/Context.h" #include "support/Logger.h" +#include "support/MemoryTree.h" #include "support/Path.h" #include "support/Threading.h" #include "support/Trace.h" @@ -164,6 +165,19 @@ return llvm::Optional>(std::move(V)); } + MemoryTree getMemoryUsage() const { + MemoryTree MT; + std::lock_guard Lock(Mut); + for (const auto &Elem : LRU) { + auto &SM = Elem.second->getSourceManager(); + MT.addChild( + // FIXME: Store the filename directly in the cache or ParsedAST. + SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName(), + Elem.second->getUsedBytes()); + } + return MT; + } + private: using KVPair = std::pair>; @@ -171,7 +185,7 @@ return llvm::find_if(LRU, [K](const KVPair &P) { return P.first == K; }); } - std::mutex Mut; + mutable std::mutex Mut; unsigned MaxRetainedASTs; /// Items sorted in LRU order, i.e. first item is the most recently accessed /// one. @@ -932,9 +946,9 @@ // Note that we don't report the size of ASTs currently used for processing // the in-flight requests. We used this information for debugging purposes // only, so this should be fine. - Result.UsedBytes = IdleASTs.getUsedBytes(this); + Result.UsedBytesAST = IdleASTs.getUsedBytes(this); if (auto Preamble = getPossiblyStalePreamble()) - Result.UsedBytes += Preamble->Preamble.getSize(); + Result.UsedBytesPreamble = Preamble->Preamble.getSize(); return Result; } @@ -1429,5 +1443,17 @@ return P; } +MemoryTree TUScheduler::getMemoryUsage() const { + MemoryTree MT; + MT.addChild("ast_cahe", IdleASTs->getMemoryUsage(), true); + // Otherwise preambles are stored on disk and we only keep filename in memory. + if (Opts.StorePreamblesInMemory) { + MemoryTree Preambles; + for (const auto &Elem : fileStats()) + Preambles.addChild(Elem.first(), Elem.second.UsedBytesPreamble); + MT.addChild("preambles", std::move(Preambles), true); + } + return MT; +} } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -565,7 +565,9 @@ } MATCHER_P4(Stats, Name, UsesMemory, PreambleBuilds, ASTBuilds, "") { - return arg.first() == Name && (arg.second.UsedBytes != 0) == UsesMemory && + return arg.first() == Name && + (arg.second.UsedBytesAST + arg.second.UsedBytesPreamble != 0) == + UsesMemory && std::tie(arg.second.PreambleBuilds, ASTBuilds) == std::tie(PreambleBuilds, ASTBuilds); }