[clang-tools-extra] c9d2876 - [clangd] Add a metric for tracking memory usage

Kadir Cetinkaya via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 06:27:20 PDT 2020


Author: Kadir Cetinkaya
Date: 2020-10-12T15:25:29+02:00
New Revision: c9d2876da95c5a15c85de8473a0cb5fb44eb3289

URL: https://github.com/llvm/llvm-project/commit/c9d2876da95c5a15c85de8473a0cb5fb44eb3289
DIFF: https://github.com/llvm/llvm-project/commit/c9d2876da95c5a15c85de8473a0cb5fb44eb3289.diff

LOG: [clangd] Add a metric for tracking memory usage

Differential Revision: https://reviews.llvm.org/D88413

Added: 
    

Modified: 
    clang-tools-extra/clangd/support/MemoryTree.cpp
    clang-tools-extra/clangd/support/MemoryTree.h
    clang-tools-extra/clangd/unittests/support/MemoryTreeTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/support/MemoryTree.cpp b/clang-tools-extra/clangd/support/MemoryTree.cpp
index d7acf7b3d8c0..a495778b9e5b 100644
--- a/clang-tools-extra/clangd/support/MemoryTree.cpp
+++ b/clang-tools-extra/clangd/support/MemoryTree.cpp
@@ -1,4 +1,5 @@
 #include "support/MemoryTree.h"
+#include "Trace.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include <cstddef>
@@ -6,6 +7,25 @@
 namespace clang {
 namespace clangd {
 
+namespace {
+
+size_t traverseTree(const MemoryTree &MT, std::string &ComponentName,
+                    const trace::Metric &Out) {
+  size_t OriginalLen = ComponentName.size();
+  if (!ComponentName.empty())
+    ComponentName += '.';
+  size_t Total = MT.self();
+  for (const auto &Entry : MT.children()) {
+    ComponentName += Entry.first;
+    Total += traverseTree(Entry.getSecond(), ComponentName, Out);
+    ComponentName.resize(OriginalLen + 1);
+  }
+  ComponentName.resize(OriginalLen);
+  Out.record(Total, ComponentName);
+  return Total;
+}
+} // namespace
+
 MemoryTree &MemoryTree::createChild(llvm::StringRef Name) {
   auto &Child = Children.try_emplace(Name, DetailAlloc).first->getSecond();
   return Child;
@@ -22,5 +42,10 @@ size_t MemoryTree::total() const {
     Total += Entry.getSecond().total();
   return Total;
 }
+
+void record(const MemoryTree &MT, std::string RootName,
+            const trace::Metric &Out) {
+  traverseTree(MT, RootName, Out);
+}
 } // namespace clangd
 } // namespace clang

diff  --git a/clang-tools-extra/clangd/support/MemoryTree.h b/clang-tools-extra/clangd/support/MemoryTree.h
index 9cb7be5e04fd..903cd64ebb7c 100644
--- a/clang-tools-extra/clangd/support/MemoryTree.h
+++ b/clang-tools-extra/clangd/support/MemoryTree.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MEMORYTREE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MEMORYTREE_H_
 
+#include "Trace.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -80,6 +81,11 @@ struct MemoryTree {
   llvm::DenseMap<llvm::StringRef, MemoryTree> Children;
 };
 
+/// Records total memory usage of each node under \p Out. Labels are edges on
+/// the path joined with ".", starting with \p RootName.
+void record(const MemoryTree &MT, std::string RootName,
+            const trace::Metric &Out);
+
 } // namespace clangd
 } // namespace clang
 

diff  --git a/clang-tools-extra/clangd/unittests/support/MemoryTreeTests.cpp b/clang-tools-extra/clangd/unittests/support/MemoryTreeTests.cpp
index 72095f04fc68..7d3d29a9e1dd 100644
--- a/clang-tools-extra/clangd/unittests/support/MemoryTreeTests.cpp
+++ b/clang-tools-extra/clangd/unittests/support/MemoryTreeTests.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "support/MemoryTree.h"
+#include "support/TestTracer.h"
+#include "support/Trace.h"
 #include "llvm/Support/Allocator.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -16,6 +18,7 @@ namespace clang {
 namespace clangd {
 namespace {
 using testing::Contains;
+using testing::ElementsAre;
 using testing::IsEmpty;
 using testing::UnorderedElementsAre;
 
@@ -73,6 +76,46 @@ TEST(MemoryTree, DetailedNodesWithDetails) {
     EXPECT_THAT(Detail.children(), Contains(WithNameAndSize("leaf", 1)));
   }
 }
+
+TEST(MemoryTree, Record) {
+  trace::TestTracer Tracer;
+  static constexpr llvm::StringLiteral MetricName = "memory_usage";
+  static constexpr trace::Metric OutMetric(MetricName, trace::Metric::Value,
+                                           "component_name");
+  auto AddNodes = [](MemoryTree Root) {
+    Root.child("leaf").addUsage(1);
+
+    {
+      auto &Detail = Root.detail("detail");
+      Detail.addUsage(1);
+      Detail.child("leaf").addUsage(1);
+      auto &Child = Detail.child("child");
+      Child.addUsage(1);
+      Child.child("leaf").addUsage(1);
+    }
+
+    {
+      auto &Child = Root.child("child");
+      Child.addUsage(1);
+      Child.child("leaf").addUsage(1);
+    }
+    return Root;
+  };
+
+  llvm::BumpPtrAllocator Alloc;
+  record(AddNodes(MemoryTree(&Alloc)), "root", OutMetric);
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root"), ElementsAre(7));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.leaf"), ElementsAre(1));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail"), ElementsAre(4));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.leaf"),
+              ElementsAre(1));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child"),
+              ElementsAre(2));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child.leaf"),
+              ElementsAre(1));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child"), ElementsAre(2));
+  EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child.leaf"), ElementsAre(1));
+}
 } // namespace
 } // namespace clangd
 } // namespace clang


        


More information about the cfe-commits mailing list