From e5c5c0a040e0c74892ea0a36c7fd50e5410879bd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Jan 2021 19:04:50 +0300 Subject: Include `countme` crate to count important data structures. --- crates/hir_def/src/item_tree.rs | 10 +++++++++- crates/hir_def/src/nameres.rs | 3 +++ crates/ide/src/status.rs | 2 ++ crates/profile/Cargo.toml | 1 + crates/profile/src/hprof.rs | 4 +++- crates/profile/src/lib.rs | 7 +++++++ crates/rust-analyzer/src/cli/analysis_stats.rs | 5 +++++ 7 files changed, 30 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 1226d7d85..b8d7608e7 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -21,6 +21,7 @@ use hir_expand::{ HirFileId, InFile, }; use la_arena::{Arena, Idx, RawIdx}; +use profile::Count; use rustc_hash::FxHashMap; use smallvec::SmallVec; use syntax::{ast, match_ast}; @@ -67,6 +68,8 @@ impl GenericParamsId { /// The item tree of a source file. #[derive(Debug, Eq, PartialEq)] pub struct ItemTree { + _c: Count, + top_level: SmallVec<[ModItem; 1]>, attrs: FxHashMap, @@ -116,7 +119,12 @@ impl ItemTree { } fn empty() -> Self { - Self { top_level: Default::default(), attrs: Default::default(), data: Default::default() } + Self { + _c: Count::new(), + top_level: Default::default(), + attrs: Default::default(), + data: Default::default(), + } } fn shrink_to_fit(&mut self) { diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 93931a21a..bd3ea9b8b 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -59,6 +59,7 @@ use std::sync::Arc; use base_db::{CrateId, Edition, FileId}; use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; use la_arena::Arena; +use profile::Count; use rustc_hash::FxHashMap; use stdx::format_to; use syntax::{ast, AstNode}; @@ -75,6 +76,7 @@ use crate::{ /// Contains all top-level defs from a macro-expanded crate #[derive(Debug, PartialEq, Eq)] pub struct DefMap { + _c: Count, parent: Option>, root: LocalModuleId, modules: Arena, @@ -215,6 +217,7 @@ impl DefMap { let mut modules: Arena = Arena::default(); let root = modules.alloc(ModuleData::default()); DefMap { + _c: Count::new(), parent: None, krate, edition, diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index e10d7c3a4..137c38c0d 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs @@ -38,6 +38,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { format_to!(buf, "{}\n", syntax_tree_stats(db)); format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db)); format_to!(buf, "{} total\n", memory_usage()); + format_to!(buf, "\ncounts:\n{}", profile::countme::get_all()); if let Some(file_id) = file_id { format_to!(buf, "\nfile info:\n"); @@ -60,6 +61,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { None => format_to!(buf, "does not belong to any crate"), } } + buf } diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index f7231c2b8..cc7da27f7 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml @@ -14,6 +14,7 @@ once_cell = "1.3.1" cfg-if = "1" libc = "0.2.73" la-arena = { version = "0.2.0", path = "../../lib/arena" } +countme = { version = "2.0.0-pre.2", features = ["enable"] } jemalloc-ctl = { version = "0.3.3", optional = true } [target.'cfg(target_os = "linux")'.dependencies] diff --git a/crates/profile/src/hprof.rs b/crates/profile/src/hprof.rs index 8957ea016..29d2ed518 100644 --- a/crates/profile/src/hprof.rs +++ b/crates/profile/src/hprof.rs @@ -3,6 +3,7 @@ use once_cell::sync::Lazy; use std::{ cell::RefCell, collections::{BTreeMap, HashSet}, + env, io::{stderr, Write}, sync::{ atomic::{AtomicBool, Ordering}, @@ -18,7 +19,8 @@ use crate::tree::{Idx, Tree}; /// env RA_PROFILE=foo|bar|baz // enabled only selected entries /// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms pub fn init() { - let spec = std::env::var("RA_PROFILE").unwrap_or_default(); + countme::enable(env::var("RA_COUNT").is_ok()); + let spec = env::var("RA_PROFILE").unwrap_or_default(); init_from(&spec); } diff --git a/crates/profile/src/lib.rs b/crates/profile/src/lib.rs index aa6ccc36c..79dba47d5 100644 --- a/crates/profile/src/lib.rs +++ b/crates/profile/src/lib.rs @@ -15,6 +15,13 @@ pub use crate::{ stop_watch::{StopWatch, StopWatchSpan}, }; +pub use countme; +/// Include `_c: Count` field in important structs to count them. +/// +/// To view the counts, run with `RA_COUNT=1`. The overhead of disabled count is +/// almost zero. +pub use countme::Count; + thread_local!(static IN_SCOPE: RefCell = RefCell::new(false)); /// Allows to check if the current code is withing some dynamic scope, can be diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index fd1407e60..66416f709 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -2,6 +2,7 @@ //! errors. use std::{ + env, path::PathBuf, time::{SystemTime, UNIX_EPOCH}, }; @@ -295,6 +296,10 @@ impl AnalysisStatsCmd { report_metric("total memory", memory.allocated.megabytes() as u64, "MB"); } + if env::var("RA_COUNT").is_ok() { + eprintln!("{}", profile::countme::get_all()); + } + if self.memory_usage && verbosity.is_verbose() { print_memory_usage(host, vfs); } -- cgit v1.2.3