]> git.lizzy.rs Git - rust.git/commitdiff
Include `countme` crate to count important data structures.
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 21 Jan 2021 16:04:50 +0000 (19:04 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 21 Jan 2021 16:30:52 +0000 (19:30 +0300)
Cargo.lock
crates/hir_def/src/item_tree.rs
crates/hir_def/src/nameres.rs
crates/ide/src/status.rs
crates/profile/Cargo.toml
crates/profile/src/hprof.rs
crates/profile/src/lib.rs
crates/rust-analyzer/src/cli/analysis_stats.rs
docs/dev/README.md

index 71223218dd2118eb17518eda9c394881de32614e..9f7a1d0192c016a49f8448fdfe9ad2358588415f 100644 (file)
@@ -273,6 +273,17 @@ version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
 
+[[package]]
+name = "countme"
+version = "2.0.0-pre.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5716604cba7c02a846ecad3f4a3fd2d2b641faccc2a24a51efb21aff0d01f35"
+dependencies = [
+ "dashmap",
+ "once_cell",
+ "rustc-hash",
+]
+
 [[package]]
 name = "crc32fast"
 version = "1.2.1"
@@ -349,6 +360,16 @@ dependencies = [
  "lazy_static",
 ]
 
+[[package]]
+name = "dashmap"
+version = "4.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
+dependencies = [
+ "cfg-if 1.0.0",
+ "num_cpus",
+]
+
 [[package]]
 name = "dissimilar"
 version = "1.0.2"
@@ -1260,6 +1281,7 @@ name = "profile"
 version = "0.0.0"
 dependencies = [
  "cfg-if 1.0.0",
+ "countme",
  "jemalloc-ctl",
  "la-arena",
  "libc",
@@ -1375,10 +1397,11 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
 
 [[package]]
 name = "rowan"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bea4527c692099becd37ec777cfd6949d0534348528d2fc84ee420d2d5fac83d"
+checksum = "24c2d78254049413f9d73495f883e7fa0b7a7d4b88468cd72a3bbbd0ad585cd1"
 dependencies = [
+ "countme",
  "hashbrown",
  "memoffset",
  "rustc-hash",
index 1226d7d8538e7057e6039c2ac3a6759a0d0fcafd..b8d7608e7cc535bbd4257dcc9fbf8a9da00e9ce7 100644 (file)
@@ -21,6 +21,7 @@
     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<Self>,
+
     top_level: SmallVec<[ModItem; 1]>,
     attrs: FxHashMap<AttrOwner, RawAttrs>,
 
@@ -116,7 +119,12 @@ pub(crate) fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<I
     }
 
     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) {
index 93931a21af886cb0c6d3f86e1dcde6d7b479f4b5..bd3ea9b8b1bf59e322198d04b53cda300d67ca4d 100644 (file)
@@ -59,6 +59,7 @@
 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 @@
 /// Contains all top-level defs from a macro-expanded crate
 #[derive(Debug, PartialEq, Eq)]
 pub struct DefMap {
+    _c: Count<Self>,
     parent: Option<Arc<DefMap>>,
     root: LocalModuleId,
     modules: Arena<ModuleData>,
@@ -215,6 +217,7 @@ fn empty(krate: CrateId, edition: Edition) -> DefMap {
         let mut modules: Arena<ModuleData> = Arena::default();
         let root = modules.alloc(ModuleData::default());
         DefMap {
+            _c: Count::new(),
             parent: None,
             krate,
             edition,
index e10d7c3a454fd67e6aa57b10d778dfd091b067c2..137c38c0d9c1dcfcc0c7841d422ac6b5385ff2d5 100644 (file)
@@ -38,6 +38,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> 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<FileId>) -> String {
             None => format_to!(buf, "does not belong to any crate"),
         }
     }
+
     buf
 }
 
index f7231c2b8eaab89606e1d4500b48ac02d5faa279..cc7da27f7e51bb301da0cb27447251cf5a4937bf 100644 (file)
@@ -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]
index 8957ea0164342778928b56fd33ef6c9549a3ce22..29d2ed51870ccfe75ef5adf7dd211161556fa74c 100644 (file)
@@ -3,6 +3,7 @@
 use std::{
     cell::RefCell,
     collections::{BTreeMap, HashSet},
+    env,
     io::{stderr, Write},
     sync::{
         atomic::{AtomicBool, Ordering},
@@ -18,7 +19,8 @@
 /// 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);
 }
 
index aa6ccc36c3f3a31305f3710c2c5be11ddd45ff62..79dba47d5e1cbda607477d1ed54915a0af4b38f1 100644 (file)
     stop_watch::{StopWatch, StopWatchSpan},
 };
 
+pub use countme;
+/// Include `_c: Count<Self>` 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<bool> = RefCell::new(false));
 
 /// Allows to check if the current code is withing some dynamic scope, can be
index fd1407e6071af41a304b804884ba82c8be49b43a..66416f709522c09bd346a611a775a34f4151792d 100644 (file)
@@ -2,6 +2,7 @@
 //! errors.
 
 use std::{
+    env,
     path::PathBuf,
     time::{SystemTime, UNIX_EPOCH},
 };
@@ -295,6 +296,10 @@ pub fn run(self, verbosity: Verbosity) -> Result<()> {
             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);
         }
index dd2bfc493d19a440efda535ced9e43f29adc8877..24197b3322741289176e0733d02625c0bf6cf94b 100644 (file)
@@ -251,6 +251,9 @@ RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more tha
 
 In particular, I have `export RA_PROFILE='*>10'` in my shell profile.
 
+We also have a "counting" profiler which counts number of instances of popular structs.
+It is enabled by `RA_COUNT=1`.
+
 To measure time for from-scratch analysis, use something like this:
 
 ```