Skip to content

Commit bee9998

Browse files
authored
Merge pull request #19565 from davidbarsky/davidbarsky/add-prime-caches-subcommand
internal: add `prime-caches` subcommand
2 parents 1bf840b + 71c4a0d commit bee9998

File tree

6 files changed

+108
-13
lines changed

6 files changed

+108
-13
lines changed

crates/rust-analyzer/src/bin/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ fn actual_main() -> anyhow::Result<ExitCode> {
8888
flags::RustAnalyzerCmd::Scip(cmd) => cmd.run()?,
8989
flags::RustAnalyzerCmd::RunTests(cmd) => cmd.run()?,
9090
flags::RustAnalyzerCmd::RustcTests(cmd) => cmd.run()?,
91+
flags::RustAnalyzerCmd::PrimeCaches(cmd) => cmd.run()?,
9192
}
9293
Ok(ExitCode::SUCCESS)
9394
}

crates/rust-analyzer/src/cli.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod flags;
88
mod highlight;
99
mod lsif;
1010
mod parse;
11+
mod prime_caches;
1112
mod run_tests;
1213
mod rustc_tests;
1314
mod scip;

crates/rust-analyzer/src/cli/analysis_stats.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ impl flags::AnalysisStats {
437437
let mut bar = match verbosity {
438438
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
439439
_ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
440-
_ => ProgressReport::new(file_ids.len() as u64),
440+
_ => ProgressReport::new(file_ids.len()),
441441
};
442442

443443
file_ids.sort();
@@ -646,7 +646,7 @@ impl flags::AnalysisStats {
646646
let mut bar = match verbosity {
647647
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
648648
_ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
649-
_ => ProgressReport::new(bodies.len() as u64),
649+
_ => ProgressReport::new(bodies.len()),
650650
};
651651
let mut sw = self.stop_watch();
652652
let mut all = 0;
@@ -692,7 +692,7 @@ impl flags::AnalysisStats {
692692
let mut bar = match verbosity {
693693
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
694694
_ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
695-
_ => ProgressReport::new(bodies.len() as u64),
695+
_ => ProgressReport::new(bodies.len()),
696696
};
697697

698698
if self.parallel {
@@ -1023,7 +1023,7 @@ impl flags::AnalysisStats {
10231023
let mut bar = match verbosity {
10241024
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
10251025
_ if self.output.is_some() => ProgressReport::hidden(),
1026-
_ => ProgressReport::new(bodies.len() as u64),
1026+
_ => ProgressReport::new(bodies.len()),
10271027
};
10281028

10291029
let mut sw = self.stop_watch();

crates/rust-analyzer/src/cli/flags.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ xflags::xflags! {
5353

5454
/// Batch typecheck project and print summary statistics
5555
cmd analysis-stats {
56-
/// Directory with Cargo.toml.
56+
/// Directory with Cargo.toml or rust-project.json.
5757
required path: PathBuf
5858

5959
optional --output format: OutputFormat
@@ -74,7 +74,7 @@ xflags::xflags! {
7474

7575
/// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
7676
optional --disable-build-scripts
77-
/// Don't use expand proc macros.
77+
/// Don't expand proc macros.
7878
optional --disable-proc-macros
7979
/// Run the proc-macro-srv binary at the specified path.
8080
optional --proc-macro-srv path: PathBuf
@@ -101,7 +101,7 @@ xflags::xflags! {
101101

102102
/// Run unit tests of the project using mir interpreter
103103
cmd run-tests {
104-
/// Directory with Cargo.toml.
104+
/// Directory with Cargo.toml or rust-project.json.
105105
required path: PathBuf
106106
}
107107

@@ -115,30 +115,45 @@ xflags::xflags! {
115115
}
116116

117117
cmd diagnostics {
118-
/// Directory with Cargo.toml.
118+
/// Directory with Cargo.toml or rust-project.json.
119119
required path: PathBuf
120120

121121
/// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
122122
optional --disable-build-scripts
123-
/// Don't use expand proc macros.
123+
/// Don't expand proc macros.
124124
optional --disable-proc-macros
125125
/// Run the proc-macro-srv binary at the specified path.
126126
optional --proc-macro-srv path: PathBuf
127127
}
128128

129129
/// Report unresolved references
130130
cmd unresolved-references {
131-
/// Directory with Cargo.toml.
131+
/// Directory with Cargo.toml or rust-project.json.
132132
required path: PathBuf
133133

134134
/// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
135135
optional --disable-build-scripts
136-
/// Don't use expand proc macros.
136+
/// Don't expand proc macros.
137137
optional --disable-proc-macros
138138
/// Run the proc-macro-srv binary at the specified path.
139139
optional --proc-macro-srv path: PathBuf
140140
}
141141

142+
/// Prime caches, as rust-analyzer does typically at startup in interactive sessions.
143+
cmd prime-caches {
144+
/// Directory with Cargo.toml or rust-project.json.
145+
required path: PathBuf
146+
147+
/// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
148+
optional --disable-build-scripts
149+
/// Don't expand proc macros.
150+
optional --disable-proc-macros
151+
/// Run the proc-macro-srv binary at the specified path.
152+
optional --proc-macro-srv path: PathBuf
153+
/// Run cache priming in parallel.
154+
optional --parallel
155+
}
156+
142157
cmd ssr {
143158
/// A structured search replace rule (`$a.foo($b) ==>> bar($a, $b)`)
144159
repeated rule: SsrRule
@@ -197,6 +212,7 @@ pub enum RustAnalyzerCmd {
197212
RustcTests(RustcTests),
198213
Diagnostics(Diagnostics),
199214
UnresolvedReferences(UnresolvedReferences),
215+
PrimeCaches(PrimeCaches),
200216
Ssr(Ssr),
201217
Search(Search),
202218
Lsif(Lsif),
@@ -276,6 +292,16 @@ pub struct UnresolvedReferences {
276292
pub proc_macro_srv: Option<PathBuf>,
277293
}
278294

295+
#[derive(Debug)]
296+
pub struct PrimeCaches {
297+
pub path: PathBuf,
298+
299+
pub disable_build_scripts: bool,
300+
pub disable_proc_macros: bool,
301+
pub proc_macro_srv: Option<PathBuf>,
302+
pub parallel: bool,
303+
}
304+
279305
#[derive(Debug)]
280306
pub struct Ssr {
281307
pub rule: Vec<SsrRule>,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//! Load the project and run cache priming.
2+
//!
3+
//! Unlike `analysis-stats`, this command is intended to be used for
4+
//! benchmarking rust-analyzer's default startup configuration. It *does not*
5+
//! attempt to simulate the full IDE experience through the lifetime of the
6+
//! an editing session.
7+
8+
use load_cargo::{LoadCargoConfig, ProcMacroServerChoice, load_workspace};
9+
use profile::StopWatch;
10+
use project_model::{ProjectManifest, ProjectWorkspace};
11+
use vfs::AbsPathBuf;
12+
13+
use crate::cli::flags;
14+
15+
impl flags::PrimeCaches {
16+
pub fn run(self) -> anyhow::Result<()> {
17+
let root =
18+
vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize();
19+
let config = crate::config::Config::new(
20+
root.clone(),
21+
lsp_types::ClientCapabilities::default(),
22+
vec![],
23+
None,
24+
);
25+
let mut stop_watch = StopWatch::start();
26+
27+
let cargo_config = config.cargo(None);
28+
let with_proc_macro_server = if let Some(p) = &self.proc_macro_srv {
29+
let path = vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(p));
30+
ProcMacroServerChoice::Explicit(path)
31+
} else {
32+
ProcMacroServerChoice::Sysroot
33+
};
34+
let load_cargo_config = LoadCargoConfig {
35+
load_out_dirs_from_check: !self.disable_build_scripts,
36+
with_proc_macro_server,
37+
// while this command is nominally focused on cache priming,
38+
// we want to ensure that this command, not `load_workspace_at`,
39+
// is responsible for that work.
40+
prefill_caches: false,
41+
};
42+
43+
let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root));
44+
let root = ProjectManifest::discover_single(&root)?;
45+
let workspace = ProjectWorkspace::load(root, &cargo_config, &|_| {})?;
46+
47+
let (db, _, _) = load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?;
48+
let elapsed = stop_watch.elapsed();
49+
eprintln!(
50+
"Load time: {:?}ms, memory allocated: {}MB",
51+
elapsed.time.as_millis(),
52+
elapsed.memory.allocated.megabytes() as u64
53+
);
54+
55+
let threads = if self.parallel { num_cpus::get() } else { 1 };
56+
ide_db::prime_caches::parallel_prime_caches(&db, threads, &|_| ());
57+
58+
let elapsed = stop_watch.elapsed();
59+
eprintln!(
60+
"Cache priming time: {:?}ms, total memory allocated: {}MB",
61+
elapsed.time.as_millis(),
62+
elapsed.memory.allocated.megabytes() as u64
63+
);
64+
65+
Ok(())
66+
}
67+
}

crates/rust-analyzer/src/cli/progress_report.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ pub(crate) struct ProgressReport<'a> {
99
text: String,
1010
hidden: bool,
1111

12-
len: u64,
12+
len: usize,
1313
pos: u64,
1414
msg: Option<Box<dyn Fn() -> String + 'a>>,
1515
}
1616

1717
impl<'a> ProgressReport<'a> {
18-
pub(crate) fn new(len: u64) -> ProgressReport<'a> {
18+
pub(crate) fn new(len: usize) -> ProgressReport<'a> {
1919
ProgressReport { curr: 0.0, text: String::new(), hidden: false, len, pos: 0, msg: None }
2020
}
2121

0 commit comments

Comments
 (0)