kadircet created this revision.
Herald added subscribers: cfe-commits, usaxena95, arphaman.
Herald added a project: clang.
kadircet requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.
Depends on D88415 <https://reviews.llvm.org/D88415>
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D88417
Files:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/unittests/ClangdTests.cpp
Index: clang-tools-extra/clangd/unittests/ClangdTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ClangdTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdTests.cpp
@@ -48,6 +48,7 @@
namespace {
using ::testing::AllOf;
+using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::Gt;
@@ -61,6 +62,16 @@
Location{URIForFile::canonicalize(File, testRoot()), Range};
}
+MATCHER_P(WithName, Name, "") {
+ if (arg.Name == Name)
+ return true;
+ if (auto *Stream = result_listener->stream()) {
+ llvm::raw_os_ostream OS(*Stream);
+ OS << arg.Name;
+ }
+ return false;
+}
+
bool diagsContainErrors(const std::vector<Diag> &Diagnostics) {
for (auto D : Diagnostics) {
if (D.Severity == DiagnosticsEngine::Error ||
@@ -1236,6 +1247,35 @@
EXPECT_FALSE(DiagConsumer.HadDiagsInLastCallback);
}
+TEST(ClangdServer, MemoryUsageTest) {
+ MockFS FS;
+ MockCompilationDatabase CDB;
+ ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
+
+ struct Component {
+ std::string Name;
+ bool Size;
+ };
+ std::vector<Component> SeenComponents;
+ auto CB = [&SeenComponents](size_t Size, llvm::StringRef CompName) {
+ Component C;
+ C.Name = CompName.str();
+ C.Size = Size;
+ llvm::errs() << "Got: " << CompName << '\n';
+ SeenComponents.emplace_back(std::move(C));
+ };
+
+ Server.getMemoryUsage().traverseTree(false, CB, "clangd_server");
+ EXPECT_THAT(SeenComponents, Contains(WithName("clangd_server")));
+
+ auto FooCpp = testPath("foo.cpp");
+ Server.addDocument(FooCpp, "");
+ ASSERT_TRUE(Server.blockUntilIdleForTest());
+ Server.getMemoryUsage().traverseTree(false, CB, "clangd_server");
+ EXPECT_THAT(SeenComponents,
+ Contains(WithName(
+ "clangd_server.dynamic_index.preamble_symbols.foo.cpp")));
+}
} // namespace
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -25,6 +25,7 @@
#include "refactor/Tweak.h"
#include "support/Cancellation.h"
#include "support/Function.h"
+#include "support/MemoryTree.h"
#include "support/ThreadsafeFS.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Core/Replacement.h"
@@ -337,6 +338,9 @@
LLVM_NODISCARD bool
blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
+ /// Builds a nested representation of memory used by components.
+ MemoryTree getMemoryUsage() const;
+
private:
void formatCode(PathRef File, llvm::StringRef Code,
ArrayRef<tooling::Range> Ranges,
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -833,5 +833,14 @@
BackgroundIdx->blockUntilIdleForTest(TimeoutSeconds));
}
+MemoryTree ClangdServer::getMemoryUsage() const {
+ MemoryTree MT;
+ if (DynamicIdx)
+ MT.addChild("dynamic_index", DynamicIdx->getMemoryUsage());
+ if (BackgroundIdx)
+ MT.addChild("background_index", BackgroundIdx->getMemoryUsage());
+ MT.addChild("tuscheduler", WorkScheduler.getMemoryUsage());
+ return MT;
+}
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -170,14 +170,22 @@
log("<-- {0}", Method);
if (Method == "exit")
return false;
- if (!Server.Server)
+ if (!Server.Server) {
elog("Notification {0} before initialization", Method);
- else if (Method == "$/cancelRequest")
+ return true;
+ }
+ if (Method == "$/cancelRequest")
onCancel(std::move(Params));
else if (auto Handler = Notifications.lookup(Method))
Handler(std::move(Params));
else
log("unhandled notification {0}", Method);
+
+ // Record memory usage after each memory usage. This currently takes <1ms,
+ // so it is safe to do frequently.
+ trace::Span Tracer("RecordMemoryUsage");
+ Server.Server->getMemoryUsage().traverseTree(true, trace::recordMemoryUsage,
+ "clangd_server");
return true;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits