diff --git a/Cargo.lock b/Cargo.lock index 579daecf18..2c1c7099e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1058,7 +1058,7 @@ dependencies = [ "ra_syntax 0.1.0", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "salsa 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", ] @@ -1478,11 +1478,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "salsa" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2125,7 +2126,7 @@ dependencies = [ "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum salsa 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2208fabe493ad352dc4f544c482b39e9b9a2c1719d9aa4a0f5e828a61210956" +"checksum salsa 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2891cd628406e8a0ca714b827511de1bff76f796e3382cc72a3de732ccad5aea" "checksum salsa-macros 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7f1e25ca2b995bdf032946174929d62156ffd57abd7ff88dc6f9bdeb5ac0c59" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index a445dcb4d4..c59821f446 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -7,7 +7,7 @@ use std::collections::HashSet; use rustc_hash::FxHashMap; use ra_db::{ - CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, + CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa::{self, Database}, }; use ra_hir::db; use ra_project_model::ProjectWorkspace; @@ -43,6 +43,12 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { impl BatchDatabase { pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { let mut db = BatchDatabase { runtime: salsa::Runtime::default() }; + let lru_cap = std::env::var("RA_LRU_CAP") + .ok() + .and_then(|it| it.parse::().ok()) + .unwrap_or(ra_db::DEFAULT_LRU_CAP); + db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_cap); + db.query_mut(ra_hir::db::ParseMacroQuery).set_lru_capacity(lru_cap); db.set_crate_graph(Arc::new(crate_graph)); // wait until Vfs has loaded all roots diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index 827855b2fb..f73dd739a4 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" authors = ["rust-analyzer developers"] [dependencies] -salsa = "0.12.1" +salsa = "0.12.3" relative-path = "0.4.0" rustc-hash = "1.0" diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 7c49c585bc..f08616100d 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -65,6 +65,8 @@ pub struct FileRange { pub range: TextRange, } +pub const DEFAULT_LRU_CAP: usize = 128; + /// Database which stores all significant input facts: source code and project /// model. Everything else in rust-analyzer is derived from these queries. #[salsa::query_group(SourceDatabaseStorage)] diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 247dc0feed..ce03a0f952 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs @@ -225,7 +225,6 @@ impl RootDatabase { let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); self.query(ra_db::ParseQuery).sweep(sweep); - self.query(hir::db::ParseMacroQuery).sweep(sweep); self.query(hir::db::MacroDefQuery).sweep(sweep); self.query(hir::db::MacroArgQuery).sweep(sweep); diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index d1a452ecb5..b3f395502e 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs @@ -5,7 +5,7 @@ use std::{ use ra_db::{ CheckCanceled, FileId, Canceled, SourceDatabase, - salsa, + salsa::{self, Database}, }; use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; @@ -41,6 +41,12 @@ impl salsa::Database for RootDatabase { impl Default for RootDatabase { fn default() -> RootDatabase { + RootDatabase::new(None) + } +} + +impl RootDatabase { + pub fn new(lru_capacity: Option) -> RootDatabase { let mut db = RootDatabase { runtime: salsa::Runtime::default(), last_gc: time::Instant::now(), @@ -49,6 +55,9 @@ impl Default for RootDatabase { db.set_crate_graph(Default::default()); db.set_local_roots(Default::default()); db.set_library_roots(Default::default()); + let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP); + db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity); + db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity); db } } diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index dbebf50a62..8741e736f5 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -242,12 +242,21 @@ pub struct CallInfo { } /// `AnalysisHost` stores the current state of the world. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct AnalysisHost { db: db::RootDatabase, } +impl Default for AnalysisHost { + fn default() -> AnalysisHost { + AnalysisHost::new(None) + } +} + impl AnalysisHost { + pub fn new(lru_capcity: Option) -> AnalysisHost { + AnalysisHost { db: db::RootDatabase::new(lru_capcity) } + } /// Returns a snapshot of the current state, which you can query for /// semantic information. pub fn analysis(&self) -> Analysis { diff --git a/crates/ra_lsp_server/src/init.rs b/crates/ra_lsp_server/src/init.rs index 1b77e03125..b894b449d7 100644 --- a/crates/ra_lsp_server/src/init.rs +++ b/crates/ra_lsp_server/src/init.rs @@ -17,11 +17,17 @@ pub struct InitializationOptions { /// Defaults to `true` #[serde(deserialize_with = "nullable_bool_true")] pub show_workspace_loaded: bool, + + pub lru_capacity: Option, } impl Default for InitializationOptions { fn default() -> InitializationOptions { - InitializationOptions { publish_decorations: false, show_workspace_loaded: true } + InitializationOptions { + publish_decorations: false, + show_workspace_loaded: true, + lru_capacity: None, + } } } @@ -54,8 +60,10 @@ mod test { assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); assert_eq!( default, - serde_json::from_str(r#"{"publishDecorations":null, "showWorkspaceLoaded":null}"#) - .unwrap() + serde_json::from_str( + r#"{"publishDecorations":null, "showWorkspaceLoaded":null, "lruCapacity":null}"# + ) + .unwrap() ); } } diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 090fb9b1b0..0790ea472e 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -73,7 +73,7 @@ pub fn main_loop( loaded_workspaces }; - let mut state = WorldState::new(ws_roots, workspaces); + let mut state = WorldState::new(ws_roots, workspaces, options.lru_capacity); let pool = ThreadPool::new(THREADPOOL_SIZE); let (task_sender, task_receiver) = unbounded::(); diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index cd8df4fdba..f9ce570ca3 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -46,7 +46,11 @@ pub struct WorldSnapshot { } impl WorldState { - pub fn new(folder_roots: Vec, workspaces: Vec) -> WorldState { + pub fn new( + folder_roots: Vec, + workspaces: Vec, + lru_capacity: Option, + ) -> WorldState { let mut change = AnalysisChange::new(); let mut roots = Vec::new(); @@ -74,7 +78,7 @@ impl WorldState { } change.set_crate_graph(crate_graph); - let mut analysis_host = AnalysisHost::default(); + let mut analysis_host = AnalysisHost::new(lru_capacity); analysis_host.apply_change(change); WorldState { roots_to_scan, diff --git a/editors/code/package.json b/editors/code/package.json index 05c8083949..c2ed8d1268 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -232,6 +232,11 @@ ], "default": "off", "description": "Trace output of cargo-watch" + }, + "rust-analyzer.lruCapacity": { + "type": "number", + "default": null, + "description": "Number of syntax trees rust-analyzer keeps in memory" } } }, diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 8d73a6b340..3024546d25 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -19,6 +19,7 @@ export class Config { public enableEnhancedTyping = true; public raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; public showWorkspaceLoadedNotification = true; + public lruCapacity: null | number = null; public cargoWatchOptions: CargoWatchOptions = { enableOnStartup: 'ask', trace: 'off', @@ -109,5 +110,8 @@ export class Config { '' ); } + if (config.has('lruCapacity')) { + this.lruCapacity = config.get('lruCapacity') as number; + } } } diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index 81c2b3fff2..7029142fdc 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts @@ -35,7 +35,8 @@ export class Server { initializationOptions: { publishDecorations: true, showWorkspaceLoaded: - Server.config.showWorkspaceLoadedNotification + Server.config.showWorkspaceLoadedNotification, + lruCapacity: Server.config.lruCapacity }, traceOutputChannel };