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"
|
||||
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",
|
||||
|
|
|
@ -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<Self>,
|
||||
|
||||
top_level: SmallVec<[ModItem; 1]>,
|
||||
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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<Self>,
|
||||
parent: Option<Arc<DefMap>>,
|
||||
root: LocalModuleId,
|
||||
modules: Arena<ModuleData>,
|
||||
|
@ -215,6 +217,7 @@ impl DefMap {
|
|||
let mut modules: Arena<ModuleData> = Arena::default();
|
||||
let root = modules.alloc(ModuleData::default());
|
||||
DefMap {
|
||||
_c: Count::new(),
|
||||
parent: None,
|
||||
krate,
|
||||
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, "{} (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
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,13 @@ pub use crate::{
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue