1 //===--- MemoryTree.h - A special tree for components and sizes -*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MEMORYTREE_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MEMORYTREE_H
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/Allocator.h"
23 /// A tree that can be used to represent memory usage of nested components while
24 /// preserving the hierarchy.
25 /// Edges have associated names. An edge that might not be interesting to all
26 /// traversers or costly to copy (e.g. file names) can be marked as "detail".
27 /// Tree construction allows chosing between a detailed and brief mode, in brief
28 /// mode all "detail" edges are ignored and tree is constructed without any
32 /// If Alloc is nullptr, tree is in brief mode and will ignore detail edges.
33 MemoryTree(llvm::BumpPtrAllocator
*DetailAlloc
= nullptr)
34 : DetailAlloc(DetailAlloc
) {}
36 /// No copy of the \p Name.
37 /// Note that returned pointers are invalidated with subsequent calls to
39 MemoryTree
&child(llvm::StringLiteral Name
) { return createChild(Name
); }
41 MemoryTree(const MemoryTree
&) = delete;
42 MemoryTree
&operator=(const MemoryTree
&) = delete;
44 MemoryTree(MemoryTree
&&) = default;
45 MemoryTree
&operator=(MemoryTree
&&) = default;
47 /// Makes a copy of the \p Name in detailed mode, returns current node
49 /// Note that returned pointers are invalidated with subsequent calls to
51 MemoryTree
&detail(llvm::StringRef Name
) {
52 return DetailAlloc
? createChild(Name
.copy(*DetailAlloc
)) : *this;
55 /// Increases size of current node by \p Increment.
56 void addUsage(size_t Increment
) { Size
+= Increment
; }
58 /// Returns edges to direct children of this node.
59 const llvm::DenseMap
<llvm::StringRef
, MemoryTree
> &children() const;
61 /// Returns total number of bytes used by this sub-tree. Performs a traversal.
64 /// Returns total number of bytes used by this node only.
65 size_t self() const { return Size
; }
68 /// Adds a child with an edge labeled as \p Name. Multiple calls to this
69 /// function returns the same node.
70 MemoryTree
&createChild(llvm::StringRef Name
);
72 /// Allocator to use for detailed edge names.
73 llvm::BumpPtrAllocator
*DetailAlloc
= nullptr;
75 /// Bytes owned by this component specifically.
78 /// Edges from current node to its children. Keys are the labels for edges.
79 llvm::DenseMap
<llvm::StringRef
, MemoryTree
> Children
;
82 /// Records total memory usage of each node under \p Out. Labels are edges on
83 /// the path joined with ".", starting with \p RootName.
84 void record(const MemoryTree
&MT
, std::string RootName
,
85 const trace::Metric
&Out
);