Author: Kadir Cetinkaya Date: 2020-10-19T12:30:25+02:00 New Revision: d0f287464d8a2b6940cc968850b7a013c665981a
URL: https://github.com/llvm/llvm-project/commit/d0f287464d8a2b6940cc968850b7a013c665981a DIFF: https://github.com/llvm/llvm-project/commit/d0f287464d8a2b6940cc968850b7a013c665981a.diff LOG: [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 Added: clang-tools-extra/clangd/test/memory_tree.test Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/initialize-params.test Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index d46147ac89cd..99c2465a579c 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -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 diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 7054c48652c5..9fb23a07f6c5 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -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 @@ class ClangdLSPServer : private ClangdServer::Callbacks { 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); diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index f41cea28fea3..0b89c622e6f8 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -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 diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 6f395ffb21c5..165a4a89e1cd 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -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 diff --git a/clang-tools-extra/clangd/test/initialize-params.test b/clang-tools-extra/clangd/test/initialize-params.test index 4125c27e4e35..8f4d0653bb78 100644 --- a/clang-tools-extra/clangd/test/initialize-params.test +++ b/clang-tools-extra/clangd/test/initialize-params.test @@ -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, diff --git a/clang-tools-extra/clangd/test/memory_tree.test b/clang-tools-extra/clangd/test/memory_tree.test new file mode 100644 index 000000000000..41efdfb49e7a --- /dev/null +++ b/clang-tools-extra/clangd/test/memory_tree.test @@ -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"} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits