aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-01-21 16:04:50 +0000
committerAleksey Kladov <[email protected]>2021-01-21 16:30:52 +0000
commite5c5c0a040e0c74892ea0a36c7fd50e5410879bd (patch)
tree4da6406b6d85f884b5ee2c927b2c1126192a9159
parent235583f3fc886bb839f34c4ff5713d101939d95c (diff)
Include `countme` crate to count important data structures.
-rw-r--r--Cargo.lock27
-rw-r--r--crates/hir_def/src/item_tree.rs10
-rw-r--r--crates/hir_def/src/nameres.rs3
-rw-r--r--crates/ide/src/status.rs2
-rw-r--r--crates/profile/Cargo.toml1
-rw-r--r--crates/profile/src/hprof.rs4
-rw-r--r--crates/profile/src/lib.rs7
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs5
-rw-r--r--docs/dev/README.md3
9 files changed, 58 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 71223218d..9f7a1d019 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -274,6 +274,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
274checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" 274checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
275 275
276[[package]] 276[[package]]
277name = "countme"
278version = "2.0.0-pre.2"
279source = "registry+https://github.com/rust-lang/crates.io-index"
280checksum = "c5716604cba7c02a846ecad3f4a3fd2d2b641faccc2a24a51efb21aff0d01f35"
281dependencies = [
282 "dashmap",
283 "once_cell",
284 "rustc-hash",
285]
286
287[[package]]
277name = "crc32fast" 288name = "crc32fast"
278version = "1.2.1" 289version = "1.2.1"
279source = "registry+https://github.com/rust-lang/crates.io-index" 290source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -350,6 +361,16 @@ dependencies = [
350] 361]
351 362
352[[package]] 363[[package]]
364name = "dashmap"
365version = "4.0.2"
366source = "registry+https://github.com/rust-lang/crates.io-index"
367checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
368dependencies = [
369 "cfg-if 1.0.0",
370 "num_cpus",
371]
372
373[[package]]
353name = "dissimilar" 374name = "dissimilar"
354version = "1.0.2" 375version = "1.0.2"
355source = "registry+https://github.com/rust-lang/crates.io-index" 376source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1260,6 +1281,7 @@ name = "profile"
1260version = "0.0.0" 1281version = "0.0.0"
1261dependencies = [ 1282dependencies = [
1262 "cfg-if 1.0.0", 1283 "cfg-if 1.0.0",
1284 "countme",
1263 "jemalloc-ctl", 1285 "jemalloc-ctl",
1264 "la-arena", 1286 "la-arena",
1265 "libc", 1287 "libc",
@@ -1375,10 +1397,11 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
1375 1397
1376[[package]] 1398[[package]]
1377name = "rowan" 1399name = "rowan"
1378version = "0.12.0" 1400version = "0.12.1"
1379source = "registry+https://github.com/rust-lang/crates.io-index" 1401source = "registry+https://github.com/rust-lang/crates.io-index"
1380checksum = "bea4527c692099becd37ec777cfd6949d0534348528d2fc84ee420d2d5fac83d" 1402checksum = "24c2d78254049413f9d73495f883e7fa0b7a7d4b88468cd72a3bbbd0ad585cd1"
1381dependencies = [ 1403dependencies = [
1404 "countme",
1382 "hashbrown", 1405 "hashbrown",
1383 "memoffset", 1406 "memoffset",
1384 "rustc-hash", 1407 "rustc-hash",
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::{
21 HirFileId, InFile, 21 HirFileId, InFile,
22}; 22};
23use la_arena::{Arena, Idx, RawIdx}; 23use la_arena::{Arena, Idx, RawIdx};
24use profile::Count;
24use rustc_hash::FxHashMap; 25use rustc_hash::FxHashMap;
25use smallvec::SmallVec; 26use smallvec::SmallVec;
26use syntax::{ast, match_ast}; 27use syntax::{ast, match_ast};
@@ -67,6 +68,8 @@ impl GenericParamsId {
67/// The item tree of a source file. 68/// The item tree of a source file.
68#[derive(Debug, Eq, PartialEq)] 69#[derive(Debug, Eq, PartialEq)]
69pub struct ItemTree { 70pub struct ItemTree {
71 _c: Count<Self>,
72
70 top_level: SmallVec<[ModItem; 1]>, 73 top_level: SmallVec<[ModItem; 1]>,
71 attrs: FxHashMap<AttrOwner, RawAttrs>, 74 attrs: FxHashMap<AttrOwner, RawAttrs>,
72 75
@@ -116,7 +119,12 @@ impl ItemTree {
116 } 119 }
117 120
118 fn empty() -> Self { 121 fn empty() -> Self {
119 Self { top_level: Default::default(), attrs: Default::default(), data: Default::default() } 122 Self {
123 _c: Count::new(),
124 top_level: Default::default(),
125 attrs: Default::default(),
126 data: Default::default(),
127 }
120 } 128 }
121 129
122 fn shrink_to_fit(&mut self) { 130 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;
59use base_db::{CrateId, Edition, FileId}; 59use base_db::{CrateId, Edition, FileId};
60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; 60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
61use la_arena::Arena; 61use la_arena::Arena;
62use profile::Count;
62use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
63use stdx::format_to; 64use stdx::format_to;
64use syntax::{ast, AstNode}; 65use syntax::{ast, AstNode};
@@ -75,6 +76,7 @@ use crate::{
75/// Contains all top-level defs from a macro-expanded crate 76/// Contains all top-level defs from a macro-expanded crate
76#[derive(Debug, PartialEq, Eq)] 77#[derive(Debug, PartialEq, Eq)]
77pub struct DefMap { 78pub struct DefMap {
79 _c: Count<Self>,
78 parent: Option<Arc<DefMap>>, 80 parent: Option<Arc<DefMap>>,
79 root: LocalModuleId, 81 root: LocalModuleId,
80 modules: Arena<ModuleData>, 82 modules: Arena<ModuleData>,
@@ -215,6 +217,7 @@ impl DefMap {
215 let mut modules: Arena<ModuleData> = Arena::default(); 217 let mut modules: Arena<ModuleData> = Arena::default();
216 let root = modules.alloc(ModuleData::default()); 218 let root = modules.alloc(ModuleData::default());
217 DefMap { 219 DefMap {
220 _c: Count::new(),
218 parent: None, 221 parent: None,
219 krate, 222 krate,
220 edition, 223 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<FileId>) -> String {
38 format_to!(buf, "{}\n", syntax_tree_stats(db)); 38 format_to!(buf, "{}\n", syntax_tree_stats(db));
39 format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db)); 39 format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
40 format_to!(buf, "{} total\n", memory_usage()); 40 format_to!(buf, "{} total\n", memory_usage());
41 format_to!(buf, "\ncounts:\n{}", profile::countme::get_all());
41 42
42 if let Some(file_id) = file_id { 43 if let Some(file_id) = file_id {
43 format_to!(buf, "\nfile info:\n"); 44 format_to!(buf, "\nfile info:\n");
@@ -60,6 +61,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
60 None => format_to!(buf, "does not belong to any crate"), 61 None => format_to!(buf, "does not belong to any crate"),
61 } 62 }
62 } 63 }
64
63 buf 65 buf
64} 66}
65 67
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"
14cfg-if = "1" 14cfg-if = "1"
15libc = "0.2.73" 15libc = "0.2.73"
16la-arena = { version = "0.2.0", path = "../../lib/arena" } 16la-arena = { version = "0.2.0", path = "../../lib/arena" }
17countme = { version = "2.0.0-pre.2", features = ["enable"] }
17jemalloc-ctl = { version = "0.3.3", optional = true } 18jemalloc-ctl = { version = "0.3.3", optional = true }
18 19
19[target.'cfg(target_os = "linux")'.dependencies] 20[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;
3use std::{ 3use std::{
4 cell::RefCell, 4 cell::RefCell,
5 collections::{BTreeMap, HashSet}, 5 collections::{BTreeMap, HashSet},
6 env,
6 io::{stderr, Write}, 7 io::{stderr, Write},
7 sync::{ 8 sync::{
8 atomic::{AtomicBool, Ordering}, 9 atomic::{AtomicBool, Ordering},
@@ -18,7 +19,8 @@ use crate::tree::{Idx, Tree};
18/// env RA_PROFILE=foo|bar|baz // enabled only selected entries 19/// env RA_PROFILE=foo|bar|baz // enabled only selected entries
19/// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms 20/// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms
20pub fn init() { 21pub fn init() {
21 let spec = std::env::var("RA_PROFILE").unwrap_or_default(); 22 countme::enable(env::var("RA_COUNT").is_ok());
23 let spec = env::var("RA_PROFILE").unwrap_or_default();
22 init_from(&spec); 24 init_from(&spec);
23} 25}
24 26
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::{
15 stop_watch::{StopWatch, StopWatchSpan}, 15 stop_watch::{StopWatch, StopWatchSpan},
16}; 16};
17 17
18pub use countme;
19/// Include `_c: Count<Self>` field in important structs to count them.
20///
21/// To view the counts, run with `RA_COUNT=1`. The overhead of disabled count is
22/// almost zero.
23pub use countme::Count;
24
18thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); 25thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false));
19 26
20/// Allows to check if the current code is withing some dynamic scope, can be 27/// 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 @@
2//! errors. 2//! errors.
3 3
4use std::{ 4use std::{
5 env,
5 path::PathBuf, 6 path::PathBuf,
6 time::{SystemTime, UNIX_EPOCH}, 7 time::{SystemTime, UNIX_EPOCH},
7}; 8};
@@ -295,6 +296,10 @@ impl AnalysisStatsCmd {
295 report_metric("total memory", memory.allocated.megabytes() as u64, "MB"); 296 report_metric("total memory", memory.allocated.megabytes() as u64, "MB");
296 } 297 }
297 298
299 if env::var("RA_COUNT").is_ok() {
300 eprintln!("{}", profile::countme::get_all());
301 }
302
298 if self.memory_usage && verbosity.is_verbose() { 303 if self.memory_usage && verbosity.is_verbose() {
299 print_memory_usage(host, vfs); 304 print_memory_usage(host, vfs);
300 } 305 }
diff --git a/docs/dev/README.md b/docs/dev/README.md
index dd2bfc493..24197b332 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -251,6 +251,9 @@ RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more tha
251 251
252In particular, I have `export RA_PROFILE='*>10'` in my shell profile. 252In particular, I have `export RA_PROFILE='*>10'` in my shell profile.
253 253
254We also have a "counting" profiler which counts number of instances of popular structs.
255It is enabled by `RA_COUNT=1`.
256
254To measure time for from-scratch analysis, use something like this: 257To measure time for from-scratch analysis, use something like this:
255 258
256``` 259```