Auto merge of #15020 - Veykril:perf2, r=Veykril

Count query entries in memory usage command
This commit is contained in:
bors 2023-06-09 23:50:34 +00:00
commit 5f8a6f67b9
7 changed files with 64 additions and 26 deletions

View file

@ -1028,13 +1028,13 @@ fn attr_macro_as_call_id(
def: MacroDefId, def: MacroDefId,
) -> MacroCallId { ) -> MacroCallId {
let arg = match macro_attr.input.as_deref() { let arg = match macro_attr.input.as_deref() {
Some(AttrInput::TokenTree(tt, map)) => ( Some(AttrInput::TokenTree(tt)) => (
{ {
let mut tt = tt.clone(); let mut tt = tt.0.clone();
tt.delimiter = tt::Delimiter::UNSPECIFIED; tt.delimiter = tt::Delimiter::UNSPECIFIED;
tt tt
}, },
map.clone(), tt.1.clone(),
), ),
_ => (tt::Subtree::empty(), Default::default()), _ => (tt::Subtree::empty(), Default::default()),
}; };

View file

@ -192,14 +192,14 @@ pub enum AttrInput {
/// `#[attr = "string"]` /// `#[attr = "string"]`
Literal(SmolStr), Literal(SmolStr),
/// `#[attr(subtree)]` /// `#[attr(subtree)]`
TokenTree(tt::Subtree, mbe::TokenMap), TokenTree(Box<(tt::Subtree, mbe::TokenMap)>),
} }
impl fmt::Display for AttrInput { impl fmt::Display for AttrInput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
AttrInput::Literal(lit) => write!(f, " = \"{}\"", lit.escape_debug()), AttrInput::Literal(lit) => write!(f, " = \"{}\"", lit.escape_debug()),
AttrInput::TokenTree(subtree, _) => subtree.fmt(f), AttrInput::TokenTree(tt) => tt.0.fmt(f),
} }
} }
} }
@ -220,7 +220,7 @@ impl Attr {
Some(Interned::new(AttrInput::Literal(value))) Some(Interned::new(AttrInput::Literal(value)))
} else if let Some(tt) = ast.token_tree() { } else if let Some(tt) = ast.token_tree() {
let (tree, map) = syntax_node_to_token_tree(tt.syntax()); let (tree, map) = syntax_node_to_token_tree(tt.syntax());
Some(Interned::new(AttrInput::TokenTree(tree, map))) Some(Interned::new(AttrInput::TokenTree(Box::new((tree, map)))))
} else { } else {
None None
}; };
@ -256,7 +256,7 @@ impl Attr {
/// #[path(ident)] /// #[path(ident)]
pub fn single_ident_value(&self) -> Option<&tt::Ident> { pub fn single_ident_value(&self) -> Option<&tt::Ident> {
match self.input.as_deref()? { match self.input.as_deref()? {
AttrInput::TokenTree(subtree, _) => match &*subtree.token_trees { AttrInput::TokenTree(tt) => match &*tt.0.token_trees {
[tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] => Some(ident), [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] => Some(ident),
_ => None, _ => None,
}, },
@ -267,7 +267,7 @@ impl Attr {
/// #[path TokenTree] /// #[path TokenTree]
pub fn token_tree_value(&self) -> Option<&Subtree> { pub fn token_tree_value(&self) -> Option<&Subtree> {
match self.input.as_deref()? { match self.input.as_deref()? {
AttrInput::TokenTree(subtree, _) => Some(subtree), AttrInput::TokenTree(tt) => Some(&tt.0),
_ => None, _ => None,
} }
} }

View file

@ -553,7 +553,17 @@ fn render_const_scalar(
render_const_scalar(f, bytes, memory_map, t) render_const_scalar(f, bytes, memory_map, t)
} }
_ => { _ => {
let addr = usize::from_le_bytes(b.try_into().unwrap()); let addr = usize::from_le_bytes(match b.try_into() {
Ok(b) => b,
Err(_) => {
never!(
"tried rendering ty {:?} in const ref with incorrect byte count {}",
t,
b.len()
);
return f.write_str("<layout-error>");
}
});
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else { let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
return f.write_str("<layout-error>"); return f.write_str("<layout-error>");
}; };

View file

@ -1,7 +1,10 @@
//! Applies changes to the IDE state transactionally. //! Applies changes to the IDE state transactionally.
use base_db::{ use base_db::{
salsa::{Database, Durability}, salsa::{
debug::{DebugQueryTable, TableEntry},
Database, Durability, Query, QueryTable,
},
Change, SourceRootId, Change, SourceRootId,
}; };
use profile::{memory_usage, Bytes}; use profile::{memory_usage, Bytes};
@ -47,16 +50,37 @@ impl RootDatabase {
// | VS Code | **rust-analyzer: Memory Usage (Clears Database)** // | VS Code | **rust-analyzer: Memory Usage (Clears Database)**
// |=== // |===
// image::https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif[] // image::https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif[]
pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes, usize)> {
let mut acc: Vec<(String, Bytes)> = vec![]; let mut acc: Vec<(String, Bytes, usize)> = vec![];
fn collect_query_count<'q, Q>(table: &QueryTable<'q, Q>) -> usize
where
QueryTable<'q, Q>: DebugQueryTable,
Q: Query,
<Q as Query>::Storage: 'q,
{
struct EntryCounter(usize);
impl<K, V> FromIterator<TableEntry<K, V>> for EntryCounter {
fn from_iter<T>(iter: T) -> EntryCounter
where
T: IntoIterator<Item = TableEntry<K, V>>,
{
EntryCounter(iter.into_iter().count())
}
}
table.entries::<EntryCounter>().0
}
macro_rules! purge_each_query { macro_rules! purge_each_query {
($($q:path)*) => {$( ($($q:path)*) => {$(
let before = memory_usage().allocated; let before = memory_usage().allocated;
$q.in_db(self).purge(); let table = $q.in_db(self);
let count = collect_query_count(&table);
table.purge();
let after = memory_usage().allocated; let after = memory_usage().allocated;
let q: $q = Default::default(); let q: $q = Default::default();
let name = format!("{:?}", q); let name = format!("{:?}", q);
acc.push((name, before - after)); acc.push((name, before - after, count));
)*} )*}
} }
purge_each_query![ purge_each_query![

View file

@ -181,7 +181,7 @@ impl AnalysisHost {
} }
/// NB: this clears the database /// NB: this clears the database
pub fn per_query_memory_usage(&mut self) -> Vec<(String, profile::Bytes)> { pub fn per_query_memory_usage(&mut self) -> Vec<(String, profile::Bytes, usize)> {
self.db.per_query_memory_usage() self.db.per_query_memory_usage()
} }
pub fn request_cancellation(&mut self) { pub fn request_cancellation(&mut self) {

View file

@ -50,21 +50,24 @@ fn report_metric(metric: &str, value: u64, unit: &str) {
} }
fn print_memory_usage(mut host: AnalysisHost, vfs: Vfs) { fn print_memory_usage(mut host: AnalysisHost, vfs: Vfs) {
let mut mem = host.per_query_memory_usage(); let mem = host.per_query_memory_usage();
let before = profile::memory_usage(); let before = profile::memory_usage();
drop(vfs); drop(vfs);
let vfs = before.allocated - profile::memory_usage().allocated; let vfs = before.allocated - profile::memory_usage().allocated;
mem.push(("VFS".into(), vfs));
let before = profile::memory_usage(); let before = profile::memory_usage();
drop(host); drop(host);
mem.push(("Unaccounted".into(), before.allocated - profile::memory_usage().allocated)); let unaccounted = before.allocated - profile::memory_usage().allocated;
let remaining = profile::memory_usage().allocated;
mem.push(("Remaining".into(), profile::memory_usage().allocated)); for (name, bytes, entries) in mem {
for (name, bytes) in mem {
// NOTE: Not a debug print, so avoid going through the `eprintln` defined above. // NOTE: Not a debug print, so avoid going through the `eprintln` defined above.
eprintln!("{bytes:>8} {name}"); eprintln!("{bytes:>8} {entries:>6} {name}");
} }
eprintln!("{vfs:>8} VFS");
eprintln!("{unaccounted:>8} Unaccounted");
eprintln!("{remaining:>8} Remaining");
} }

View file

@ -115,13 +115,14 @@ pub(crate) fn handle_analyzer_status(
pub(crate) fn handle_memory_usage(state: &mut GlobalState, _: ()) -> Result<String> { pub(crate) fn handle_memory_usage(state: &mut GlobalState, _: ()) -> Result<String> {
let _p = profile::span("handle_memory_usage"); let _p = profile::span("handle_memory_usage");
let mut mem = state.analysis_host.per_query_memory_usage(); let mem = state.analysis_host.per_query_memory_usage();
mem.push(("Remaining".into(), profile::memory_usage().allocated));
let mut out = String::new(); let mut out = String::new();
for (name, bytes) in mem { for (name, bytes, entries) in mem {
format_to!(out, "{:>8} {}\n", bytes, name); format_to!(out, "{:>8} {:>6} {}\n", bytes, entries, name);
} }
format_to!(out, "{:>8} Remaining\n", profile::memory_usage().allocated);
Ok(out) Ok(out)
} }