diff options
author | Aleksey Kladov <[email protected]> | 2021-01-21 16:04:50 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-01-21 16:30:52 +0000 |
commit | e5c5c0a040e0c74892ea0a36c7fd50e5410879bd (patch) | |
tree | 4da6406b6d85f884b5ee2c927b2c1126192a9159 | |
parent | 235583f3fc886bb839f34c4ff5713d101939d95c (diff) |
Include `countme` crate to count important data structures.
-rw-r--r-- | Cargo.lock | 27 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/status.rs | 2 | ||||
-rw-r--r-- | crates/profile/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/profile/src/hprof.rs | 4 | ||||
-rw-r--r-- | crates/profile/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_stats.rs | 5 | ||||
-rw-r--r-- | docs/dev/README.md | 3 |
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" | |||
274 | checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" | 274 | checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" |
275 | 275 | ||
276 | [[package]] | 276 | [[package]] |
277 | name = "countme" | ||
278 | version = "2.0.0-pre.2" | ||
279 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
280 | checksum = "c5716604cba7c02a846ecad3f4a3fd2d2b641faccc2a24a51efb21aff0d01f35" | ||
281 | dependencies = [ | ||
282 | "dashmap", | ||
283 | "once_cell", | ||
284 | "rustc-hash", | ||
285 | ] | ||
286 | |||
287 | [[package]] | ||
277 | name = "crc32fast" | 288 | name = "crc32fast" |
278 | version = "1.2.1" | 289 | version = "1.2.1" |
279 | source = "registry+https://github.com/rust-lang/crates.io-index" | 290 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -350,6 +361,16 @@ dependencies = [ | |||
350 | ] | 361 | ] |
351 | 362 | ||
352 | [[package]] | 363 | [[package]] |
364 | name = "dashmap" | ||
365 | version = "4.0.2" | ||
366 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
367 | checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" | ||
368 | dependencies = [ | ||
369 | "cfg-if 1.0.0", | ||
370 | "num_cpus", | ||
371 | ] | ||
372 | |||
373 | [[package]] | ||
353 | name = "dissimilar" | 374 | name = "dissimilar" |
354 | version = "1.0.2" | 375 | version = "1.0.2" |
355 | source = "registry+https://github.com/rust-lang/crates.io-index" | 376 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1260,6 +1281,7 @@ name = "profile" | |||
1260 | version = "0.0.0" | 1281 | version = "0.0.0" |
1261 | dependencies = [ | 1282 | dependencies = [ |
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]] |
1377 | name = "rowan" | 1399 | name = "rowan" |
1378 | version = "0.12.0" | 1400 | version = "0.12.1" |
1379 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1380 | checksum = "bea4527c692099becd37ec777cfd6949d0534348528d2fc84ee420d2d5fac83d" | 1402 | checksum = "24c2d78254049413f9d73495f883e7fa0b7a7d4b88468cd72a3bbbd0ad585cd1" |
1381 | dependencies = [ | 1403 | dependencies = [ |
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 | }; |
23 | use la_arena::{Arena, Idx, RawIdx}; | 23 | use la_arena::{Arena, Idx, RawIdx}; |
24 | use profile::Count; | ||
24 | use rustc_hash::FxHashMap; | 25 | use rustc_hash::FxHashMap; |
25 | use smallvec::SmallVec; | 26 | use smallvec::SmallVec; |
26 | use syntax::{ast, match_ast}; | 27 | use 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)] |
69 | pub struct ItemTree { | 70 | pub 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; | |||
59 | use base_db::{CrateId, Edition, FileId}; | 59 | use base_db::{CrateId, Edition, FileId}; |
60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; | 60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; |
61 | use la_arena::Arena; | 61 | use la_arena::Arena; |
62 | use profile::Count; | ||
62 | use rustc_hash::FxHashMap; | 63 | use rustc_hash::FxHashMap; |
63 | use stdx::format_to; | 64 | use stdx::format_to; |
64 | use syntax::{ast, AstNode}; | 65 | use 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)] |
77 | pub struct DefMap { | 78 | pub 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" | |||
14 | cfg-if = "1" | 14 | cfg-if = "1" |
15 | libc = "0.2.73" | 15 | libc = "0.2.73" |
16 | la-arena = { version = "0.2.0", path = "../../lib/arena" } | 16 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
17 | countme = { version = "2.0.0-pre.2", features = ["enable"] } | ||
17 | jemalloc-ctl = { version = "0.3.3", optional = true } | 18 | jemalloc-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; | |||
3 | use std::{ | 3 | use 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 |
20 | pub fn init() { | 21 | pub 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 | ||
18 | pub 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. | ||
23 | pub use countme::Count; | ||
24 | |||
18 | thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); | 25 | thread_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 | ||
4 | use std::{ | 4 | use 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 | ||
252 | In particular, I have `export RA_PROFILE='*>10'` in my shell profile. | 252 | In particular, I have `export RA_PROFILE='*>10'` in my shell profile. |
253 | 253 | ||
254 | We also have a "counting" profiler which counts number of instances of popular structs. | ||
255 | It is enabled by `RA_COUNT=1`. | ||
256 | |||
254 | To measure time for from-scratch analysis, use something like this: | 257 | To measure time for from-scratch analysis, use something like this: |
255 | 258 | ||
256 | ``` | 259 | ``` |