[clangd] Add $/memoryUsage LSP extension

Performs a detailed profiling of clangd lsp server and conveys the
result to the client as a json object. It is of the form:
   {
     "_self": 0,
     "_total": 8,
     "child1": {
       "_self": 4,
       "_total": 4,
     }
     "child2": {
       "_self": 2,
       "_total": 4,
       "child_deep": {
         "_self": 2,
         "_total": 2,
       }
     }
   }

Differential Revision: https://reviews.llvm.org/D89277
This commit is contained in:
Kadir Cetinkaya 2020-10-13 00:10:04 +02:00
parent 0b7b446a40
commit d0f287464d
No known key found for this signature in database
GPG Key ID: E39E36B8D2057ED6
6 changed files with 133 additions and 0 deletions

View File

@ -36,8 +36,11 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
@ -617,6 +620,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
ExecuteCommandParams::CLANGD_APPLY_TWEAK}},
}},
{"typeHierarchyProvider", true},
{"memoryUsageProvider", true}, // clangd extension.
}}}};
if (Opts.Encoding)
Result["offsetEncoding"] = *Opts.Encoding;
@ -1383,6 +1387,14 @@ void ClangdLSPServer::onSemanticTokensDelta(
});
}
void ClangdLSPServer::onMemoryUsage(const NoParams &,
Callback<MemoryTree> Reply) {
llvm::BumpPtrAllocator DetailAlloc;
MemoryTree MT(&DetailAlloc);
profile(MT);
Reply(std::move(MT));
}
ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
const ThreadsafeFS &TFS,
const ClangdLSPServer::Options &Opts)
@ -1425,6 +1437,7 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink);
MsgHandler->bind("textDocument/semanticTokens/full", &ClangdLSPServer::onSemanticTokens);
MsgHandler->bind("textDocument/semanticTokens/full/delta", &ClangdLSPServer::onSemanticTokensDelta);
MsgHandler->bind("$/memoryUsage", &ClangdLSPServer::onMemoryUsage);
if (Opts.FoldingRanges)
MsgHandler->bind("textDocument/foldingRange", &ClangdLSPServer::onFoldingRange);
// clang-format on

View File

@ -24,6 +24,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/JSON.h"
#include <chrono>
#include <cstddef>
#include <memory>
namespace clang {
@ -141,6 +142,9 @@ private:
void onSemanticTokens(const SemanticTokensParams &, Callback<SemanticTokens>);
void onSemanticTokensDelta(const SemanticTokensDeltaParams &,
Callback<SemanticTokensOrDelta>);
/// This is a clangd extension. Provides a json tree representing memory usage
/// hierarchy.
void onMemoryUsage(const NoParams &, Callback<MemoryTree>);
std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);

View File

@ -1300,5 +1300,17 @@ llvm::json::Value toJSON(const FoldingRange &Range) {
return Result;
}
llvm::json::Value toJSON(const MemoryTree &MT) {
llvm::json::Object Out;
int64_t Total = MT.self();
Out["_self"] = Total;
for (const auto &Entry : MT.children()) {
auto Child = toJSON(Entry.getSecond());
Total += *Child.getAsObject()->getInteger("_total");
Out[Entry.first] = std::move(Child);
}
Out["_total"] = Total;
return Out;
}
} // namespace clangd
} // namespace clang

View File

@ -25,6 +25,7 @@
#include "URI.h"
#include "index/SymbolID.h"
#include "support/MemoryTree.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/JSON.h"
@ -1576,6 +1577,27 @@ struct FoldingRange {
};
llvm::json::Value toJSON(const FoldingRange &Range);
/// Keys starting with an underscore(_) represent leaves, e.g. _total or _self
/// for memory usage of whole subtree or only that specific node in bytes. All
/// other keys represents children. An example:
/// {
/// "_self": 0,
/// "_total": 8,
/// "child1": {
/// "_self": 4,
/// "_total": 4,
/// }
/// "child2": {
/// "_self": 2,
/// "_total": 4,
/// "child_deep": {
/// "_self": 2,
/// "_total": 2,
/// }
/// }
/// }
llvm::json::Value toJSON(const MemoryTree &MT);
} // namespace clangd
} // namespace clang

View File

@ -66,6 +66,7 @@
# CHECK-NEXT: ]
# CHECK-NEXT: },
# CHECK-NEXT: "hoverProvider": true,
# CHECK-NEXT: "memoryUsageProvider": true
# CHECK-NEXT: "referencesProvider": true,
# CHECK-NEXT: "renameProvider": true,
# CHECK-NEXT: "selectionRangeProvider": true,

View File

@ -0,0 +1,81 @@
# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
---
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void func() {}"}}}
---
{"jsonrpc":"2.0","id":1,"method":"$/memoryUsage","params":{}}
# CHECK: "id": 1,
# CHECK-NEXT: "jsonrpc": "2.0",
# CHECK-NEXT: "result": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "clangd_server": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "dynamic_index": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "main_file": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "index": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: },
# CHECK-NEXT: "symbols": {
# CHECK-NEXT: "{{.*}}main.cpp": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "references": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: },
# CHECK-NEXT: "relations": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: },
# CHECK-NEXT: "symbols": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: }
# CHECK-NEXT: },
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: }
# CHECK-NEXT: },
# CHECK-NEXT: "preamble": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "index": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: },
# CHECK-NEXT: "symbols": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: }
# CHECK-NEXT: }
# CHECK-NEXT: },
# CHECK-NEXT: "tuscheduler": {
# CHECK-NEXT: "{{.*}}main.cpp": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}},
# CHECK-NEXT: "ast": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: },
# CHECK-NEXT: "preamble": {
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: }
# CHECK-NEXT: },
# CHECK-NEXT: "_self": {{[0-9]+}},
# CHECK-NEXT: "_total": {{[0-9]+}}
# CHECK-NEXT: }
# CHECK-NEXT: }
# CHECK-NEXT: }
---
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
---
{"jsonrpc":"2.0","method":"exit"}