Add a command to compute memory usage statistics

This commit is contained in:
Jonas Schievink 2020-07-07 12:10:14 +02:00
parent 0f5d62a3f3
commit f44c4b61e1
8 changed files with 74 additions and 1 deletions

View file

@ -164,6 +164,15 @@ impl RootDatabase {
hir::db::BodyQuery.in_db(self).sweep(sweep); hir::db::BodyQuery.in_db(self).sweep(sweep);
} }
// Feature: Memory Usage
//
// Clears rust-analyzer's internal database and prints memory usage statistics.
//
// |===
// | Editor | Action Name
//
// | VS Code | **Rust Analyzer: Memory Usage (Clears Database)**
// |===
pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> {
let mut acc: Vec<(String, Bytes)> = vec![]; let mut acc: Vec<(String, Bytes)> = vec![];
let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();

View file

@ -32,7 +32,7 @@ use crate::{
cargo_target_spec::CargoTargetSpec, cargo_target_spec::CargoTargetSpec,
config::RustfmtConfig, config::RustfmtConfig,
from_json, from_proto, from_json, from_proto,
global_state::GlobalStateSnapshot, global_state::{GlobalState, GlobalStateSnapshot},
lsp_ext::{self, InlayHint, InlayHintsParams}, lsp_ext::{self, InlayHint, InlayHintsParams},
to_proto, LspError, Result, to_proto, LspError, Result,
}; };
@ -62,6 +62,17 @@ pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result
Ok(buf) Ok(buf)
} }
pub(crate) fn handle_memory_usage(state: &mut GlobalState, _: ()) -> Result<String> {
let _p = profile("handle_memory_usage");
let mem = state.analysis_host.per_query_memory_usage();
let mut out = String::new();
for (name, bytes) in mem {
format_to!(out, "{:>8} {}\n", bytes, name);
}
Ok(out)
}
pub(crate) fn handle_syntax_tree( pub(crate) fn handle_syntax_tree(
snap: GlobalStateSnapshot, snap: GlobalStateSnapshot,
params: lsp_ext::SyntaxTreeParams, params: lsp_ext::SyntaxTreeParams,

View file

@ -14,6 +14,14 @@ impl Request for AnalyzerStatus {
const METHOD: &'static str = "rust-analyzer/analyzerStatus"; const METHOD: &'static str = "rust-analyzer/analyzerStatus";
} }
pub enum MemoryUsage {}
impl Request for MemoryUsage {
type Params = ();
type Result = String;
const METHOD: &'static str = "rust-analyzer/memoryUsage";
}
pub enum ReloadWorkspace {} pub enum ReloadWorkspace {}
impl Request for ReloadWorkspace { impl Request for ReloadWorkspace {

View file

@ -341,6 +341,7 @@ impl GlobalState {
.on_sync::<lsp_ext::MatchingBrace>(|s, p| { .on_sync::<lsp_ext::MatchingBrace>(|s, p| {
handlers::handle_matching_brace(s.snapshot(), p) handlers::handle_matching_brace(s.snapshot(), p)
})? })?
.on_sync::<lsp_ext::MemoryUsage>(|s, p| handlers::handle_memory_usage(s, p))?
.on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)? .on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)?
.on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)? .on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)?
.on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)? .on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)?

View file

@ -61,6 +61,7 @@
"activationEvents": [ "activationEvents": [
"onLanguage:rust", "onLanguage:rust",
"onCommand:rust-analyzer.analyzerStatus", "onCommand:rust-analyzer.analyzerStatus",
"onCommand:rust-analyzer.memoryUsage",
"onCommand:rust-analyzer.reloadWorkspace", "onCommand:rust-analyzer.reloadWorkspace",
"workspaceContains:**/Cargo.toml" "workspaceContains:**/Cargo.toml"
], ],
@ -142,6 +143,11 @@
"title": "Status", "title": "Status",
"category": "Rust Analyzer" "category": "Rust Analyzer"
}, },
{
"command": "rust-analyzer.memoryUsage",
"title": "Memory Usage (Clears Database)",
"category": "Rust Analyzer"
},
{ {
"command": "rust-analyzer.reloadWorkspace", "command": "rust-analyzer.reloadWorkspace",
"title": "Reload workspace", "title": "Reload workspace",
@ -843,6 +849,10 @@
"command": "rust-analyzer.analyzerStatus", "command": "rust-analyzer.analyzerStatus",
"when": "inRustProject" "when": "inRustProject"
}, },
{
"command": "rust-analyzer.memoryUsage",
"when": "inRustProject"
},
{ {
"command": "rust-analyzer.reloadWorkspace", "command": "rust-analyzer.reloadWorkspace",
"when": "inRustProject" "when": "inRustProject"

View file

@ -55,6 +55,38 @@ export function analyzerStatus(ctx: Ctx): Cmd {
}; };
} }
export function memoryUsage(ctx: Ctx): Cmd {
const tdcp = new class implements vscode.TextDocumentContentProvider {
readonly uri = vscode.Uri.parse('rust-analyzer-memory://memory');
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
if (!vscode.window.activeTextEditor) return '';
return ctx.client.sendRequest(ra.memoryUsage, null).then((mem) => {
return 'Per-query memory usage:\n' + mem + '\n(note: database has been cleared)';
});
}
get onDidChange(): vscode.Event<vscode.Uri> {
return this.eventEmitter.event;
}
}();
ctx.pushCleanup(
vscode.workspace.registerTextDocumentContentProvider(
'rust-analyzer-memory',
tdcp,
),
);
return async () => {
tdcp.eventEmitter.fire(tdcp.uri);
const document = await vscode.workspace.openTextDocument(tdcp.uri);
return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true);
};
}
export function matchingBrace(ctx: Ctx): Cmd { export function matchingBrace(ctx: Ctx): Cmd {
return async () => { return async () => {
const editor = ctx.activeRustEditor; const editor = ctx.activeRustEditor;

View file

@ -5,6 +5,7 @@
import * as lc from "vscode-languageclient"; import * as lc from "vscode-languageclient";
export const analyzerStatus = new lc.RequestType<null, string, void>("rust-analyzer/analyzerStatus"); export const analyzerStatus = new lc.RequestType<null, string, void>("rust-analyzer/analyzerStatus");
export const memoryUsage = new lc.RequestType<null, string, void>("rust-analyzer/memoryUsage");
export type Status = "loading" | "ready" | "invalid" | "needsReload"; export type Status = "loading" | "ready" | "invalid" | "needsReload";
export const status = new lc.NotificationType<Status>("rust-analyzer/status"); export const status = new lc.NotificationType<Status>("rust-analyzer/status");

View file

@ -96,6 +96,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
}); });
ctx.registerCommand('analyzerStatus', commands.analyzerStatus); ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
ctx.registerCommand('memoryUsage', commands.memoryUsage);
ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace); ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace);
ctx.registerCommand('matchingBrace', commands.matchingBrace); ctx.registerCommand('matchingBrace', commands.matchingBrace);
ctx.registerCommand('joinLines', commands.joinLines); ctx.registerCommand('joinLines', commands.joinLines);