mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Include countme
crate to count important data structures.
This commit is contained in:
parent
235583f3fc
commit
e5c5c0a040
9 changed files with 58 additions and 4 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -273,6 +273,17 @@ version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
|
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]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -349,6 +360,16 @@ dependencies = [
|
||||||
"lazy_static",
|
"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]]
|
[[package]]
|
||||||
name = "dissimilar"
|
name = "dissimilar"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -1260,6 +1281,7 @@ name = "profile"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
|
"countme",
|
||||||
"jemalloc-ctl",
|
"jemalloc-ctl",
|
||||||
"la-arena",
|
"la-arena",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1375,10 +1397,11 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rowan"
|
name = "rowan"
|
||||||
version = "0.12.0"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bea4527c692099becd37ec777cfd6949d0534348528d2fc84ee420d2d5fac83d"
|
checksum = "24c2d78254049413f9d73495f883e7fa0b7a7d4b88468cd72a3bbbd0ad585cd1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"countme",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
|
|
@ -21,6 +21,7 @@ use hir_expand::{
|
||||||
HirFileId, InFile,
|
HirFileId, InFile,
|
||||||
};
|
};
|
||||||
use la_arena::{Arena, Idx, RawIdx};
|
use la_arena::{Arena, Idx, RawIdx};
|
||||||
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use syntax::{ast, match_ast};
|
use syntax::{ast, match_ast};
|
||||||
|
@ -67,6 +68,8 @@ impl GenericParamsId {
|
||||||
/// The item tree of a source file.
|
/// The item tree of a source file.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct ItemTree {
|
pub struct ItemTree {
|
||||||
|
_c: Count<Self>,
|
||||||
|
|
||||||
top_level: SmallVec<[ModItem; 1]>,
|
top_level: SmallVec<[ModItem; 1]>,
|
||||||
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
||||||
|
|
||||||
|
@ -116,7 +119,12 @@ impl ItemTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty() -> Self {
|
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) {
|
fn shrink_to_fit(&mut self) {
|
||||||
|
|
|
@ -59,6 +59,7 @@ use std::sync::Arc;
|
||||||
use base_db::{CrateId, Edition, FileId};
|
use base_db::{CrateId, Edition, FileId};
|
||||||
use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
|
use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
@ -75,6 +76,7 @@ use crate::{
|
||||||
/// Contains all top-level defs from a macro-expanded crate
|
/// Contains all top-level defs from a macro-expanded crate
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct DefMap {
|
pub struct DefMap {
|
||||||
|
_c: Count<Self>,
|
||||||
parent: Option<Arc<DefMap>>,
|
parent: Option<Arc<DefMap>>,
|
||||||
root: LocalModuleId,
|
root: LocalModuleId,
|
||||||
modules: Arena<ModuleData>,
|
modules: Arena<ModuleData>,
|
||||||
|
@ -215,6 +217,7 @@ impl DefMap {
|
||||||
let mut modules: Arena<ModuleData> = Arena::default();
|
let mut modules: Arena<ModuleData> = Arena::default();
|
||||||
let root = modules.alloc(ModuleData::default());
|
let root = modules.alloc(ModuleData::default());
|
||||||
DefMap {
|
DefMap {
|
||||||
|
_c: Count::new(),
|
||||||
parent: None,
|
parent: None,
|
||||||
krate,
|
krate,
|
||||||
edition,
|
edition,
|
||||||
|
|
|
@ -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, "{}\n", syntax_tree_stats(db));
|
||||||
format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
|
format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
|
||||||
format_to!(buf, "{} total\n", memory_usage());
|
format_to!(buf, "{} total\n", memory_usage());
|
||||||
|
format_to!(buf, "\ncounts:\n{}", profile::countme::get_all());
|
||||||
|
|
||||||
if let Some(file_id) = file_id {
|
if let Some(file_id) = file_id {
|
||||||
format_to!(buf, "\nfile info:\n");
|
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"),
|
None => format_to!(buf, "does not belong to any crate"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ once_cell = "1.3.1"
|
||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
libc = "0.2.73"
|
libc = "0.2.73"
|
||||||
la-arena = { version = "0.2.0", path = "../../lib/arena" }
|
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 }
|
jemalloc-ctl = { version = "0.3.3", optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
|
|
@ -3,6 +3,7 @@ use once_cell::sync::Lazy;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
collections::{BTreeMap, HashSet},
|
collections::{BTreeMap, HashSet},
|
||||||
|
env,
|
||||||
io::{stderr, Write},
|
io::{stderr, Write},
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
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=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
|
/// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms
|
||||||
pub fn init() {
|
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);
|
init_from(&spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,13 @@ pub use crate::{
|
||||||
stop_watch::{StopWatch, StopWatchSpan},
|
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));
|
thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false));
|
||||||
|
|
||||||
/// Allows to check if the current code is withing some dynamic scope, can be
|
/// Allows to check if the current code is withing some dynamic scope, can be
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//! errors.
|
//! errors.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
env,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
|
@ -295,6 +296,10 @@ impl AnalysisStatsCmd {
|
||||||
report_metric("total memory", memory.allocated.megabytes() as u64, "MB");
|
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() {
|
if self.memory_usage && verbosity.is_verbose() {
|
||||||
print_memory_usage(host, vfs);
|
print_memory_usage(host, vfs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
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:
|
To measure time for from-scratch analysis, use something like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in a new issue