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 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -164,6 +165,14 @@ return llvm::Optional>(std::move(V)); } + size_t getUsedBytes() { + size_t TotalBytes = 0; + std::lock_guard Lock(Mut); + for (const auto &Elem : LRU) + TotalBytes += Elem.second->getUsedBytes(); + return TotalBytes; + } + private: using KVPair = std::pair>; @@ -1286,6 +1295,20 @@ FD->Contents = Inputs.Contents; } FD->Worker->update(std::move(Inputs), WantDiags); + + // Update memory usage metrics. Note that these are just estimates. + size_t ASTCacheBytes = IdleASTs->getUsedBytes(); + trace::recordMemoryUsage(ASTCacheBytes, "ast_cache"); + + size_t PreambleBytes = 0; + // Otherwise preambles are stored on disk and we only keep filename in memory. + if (Opts.StorePreamblesInMemory) { + for (const auto &Elem : fileStats()) + PreambleBytes += Elem.second.UsedBytes; + // fileStats results include ast cache sizes too, subtract them. + PreambleBytes -= ASTCacheBytes; + } + trace::recordMemoryUsage(PreambleBytes, "preambles"); return NewFile; } diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp --- a/clang-tools-extra/clangd/index/FileIndex.cpp +++ b/clang-tools-extra/clangd/index/FileIndex.cpp @@ -23,6 +23,7 @@ #include "index/dex/Dex.h" #include "support/Logger.h" #include "support/Path.h" +#include "support/Trace.h" #include "clang/AST/ASTContext.h" #include "clang/Index/IndexingAction.h" #include "clang/Index/IndexingOptions.h" @@ -399,6 +400,7 @@ auto NewIndex = PreambleSymbols.buildIndex(UseDex ? IndexType::Heavy : IndexType::Light, DuplicateHandling::PickOne, &IndexVersion); + trace::recordMemoryUsage(NewIndex->estimateMemoryUsage(), "preamble_index"); { std::lock_guard Lock(UpdateIndexMu); if (IndexVersion <= PreambleIndexVersion) { @@ -424,6 +426,7 @@ size_t IndexVersion = 0; auto NewIndex = MainFileSymbols.buildIndex( IndexType::Light, DuplicateHandling::Merge, &IndexVersion); + trace::recordMemoryUsage(NewIndex->estimateMemoryUsage(), "main_file_index"); { std::lock_guard Lock(UpdateIndexMu); if (IndexVersion <= MainIndexVersion) { diff --git a/clang-tools-extra/clangd/support/Trace.h b/clang-tools-extra/clangd/support/Trace.h --- a/clang-tools-extra/clangd/support/Trace.h +++ b/clang-tools-extra/clangd/support/Trace.h @@ -68,6 +68,10 @@ const llvm::StringLiteral LabelName; }; +/// Convenient helper for collecting memory usage metrics from across multiple +/// components. Results are recorded under a metric named "memory_usage". +void recordMemoryUsage(double Value, llvm::StringRef ComponentName); + /// A consumer of trace events and measurements. The events are produced by /// Spans and trace::log, the measurements are produced by Metrics::record. /// Implementations of this interface must be thread-safe. diff --git a/clang-tools-extra/clangd/support/Trace.cpp b/clang-tools-extra/clangd/support/Trace.cpp --- a/clang-tools-extra/clangd/support/Trace.cpp +++ b/clang-tools-extra/clangd/support/Trace.cpp @@ -326,6 +326,13 @@ Context EventTracer::beginSpan(llvm::StringRef Name, llvm::json::Object *Args) { return Context::current().clone(); } + +void recordMemoryUsage(double Value, llvm::StringRef ComponentName) { + static constexpr Metric MemoryUsage("memory_usage", Metric::Value, + "component_name"); + + MemoryUsage.record(Value, ComponentName); +} } // namespace trace } // namespace clangd } // namespace clang