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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to