aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_ide_api/src/db.rs11
-rw-r--r--crates/ra_ide_api/src/imp.rs48
-rw-r--r--crates/ra_ide_api/src/lib.rs4
-rw-r--r--crates/ra_ide_api/src/status.rs18
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs3
-rw-r--r--crates/ra_lsp_server/src/server_world.rs6
7 files changed, 73 insertions, 19 deletions
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 2d39b77ed..e479b38a0 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -5,8 +5,8 @@ version = "0.1.0"
5authors = ["Aleksey Kladov <[email protected]>"] 5authors = ["Aleksey Kladov <[email protected]>"]
6 6
7[dependencies] 7[dependencies]
8salsa = { path = "/home/matklad/projects/salsa" }
8relative-path = "0.4.0" 9relative-path = "0.4.0"
9salsa = "0.10.0-alpha5"
10rustc-hash = "1.0" 10rustc-hash = "1.0"
11parking_lot = "0.7.0" 11parking_lot = "0.7.0"
12 12
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index 3da93ec35..6850811d7 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -1,4 +1,7 @@
1use std::sync::Arc; 1use std::{
2 sync::Arc,
3 time,
4};
2 5
3use ra_db::{ 6use ra_db::{
4 CheckCanceled, FileId, Canceled, SourceDatabase, 7 CheckCanceled, FileId, Canceled, SourceDatabase,
@@ -17,6 +20,8 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};
17pub(crate) struct RootDatabase { 20pub(crate) struct RootDatabase {
18 runtime: salsa::Runtime<RootDatabase>, 21 runtime: salsa::Runtime<RootDatabase>,
19 interner: Arc<hir::HirInterner>, 22 interner: Arc<hir::HirInterner>,
23 pub(crate) last_gc: time::Instant,
24 pub(crate) last_gc_check: time::Instant,
20} 25}
21 26
22impl salsa::Database for RootDatabase { 27impl salsa::Database for RootDatabase {
@@ -33,6 +38,8 @@ impl Default for RootDatabase {
33 let mut db = RootDatabase { 38 let mut db = RootDatabase {
34 runtime: salsa::Runtime::default(), 39 runtime: salsa::Runtime::default(),
35 interner: Default::default(), 40 interner: Default::default(),
41 last_gc: time::Instant::now(),
42 last_gc_check: time::Instant::now(),
36 }; 43 };
37 db.set_crate_graph(Default::default()); 44 db.set_crate_graph(Default::default());
38 db.set_local_roots(Default::default()); 45 db.set_local_roots(Default::default());
@@ -46,6 +53,8 @@ impl salsa::ParallelDatabase for RootDatabase {
46 salsa::Snapshot::new(RootDatabase { 53 salsa::Snapshot::new(RootDatabase {
47 runtime: self.runtime.snapshot(self), 54 runtime: self.runtime.snapshot(self),
48 interner: Arc::clone(&self.interner), 55 interner: Arc::clone(&self.interner),
56 last_gc: self.last_gc.clone(),
57 last_gc_check: self.last_gc_check.clone(),
49 }) 58 })
50 } 59 }
51} 60}
diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs
index 399433a01..0dd3e8cb0 100644
--- a/crates/ra_ide_api/src/imp.rs
+++ b/crates/ra_ide_api/src/imp.rs
@@ -1,4 +1,7 @@
1use std::sync::Arc; 1use std::{
2 sync::Arc,
3 time,
4};
2 5
3use hir::{ 6use hir::{
4 self, Problem, source_binder 7 self, Problem, source_binder
@@ -19,12 +22,14 @@ use crate::{
19 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, 22 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit,
20 Query, RootChange, SourceChange, SourceFileEdit, 23 Query, RootChange, SourceChange, SourceFileEdit,
21 symbol_index::{FileSymbol, SymbolsDatabase}, 24 symbol_index::{FileSymbol, SymbolsDatabase},
25 status::syntax_tree_stats
22}; 26};
23 27
28const GC_COOLDOWN: time::Duration = time::Duration::from_millis(100);
29
24impl db::RootDatabase { 30impl db::RootDatabase {
25 pub(crate) fn apply_change(&mut self, change: AnalysisChange) { 31 pub(crate) fn apply_change(&mut self, change: AnalysisChange) {
26 log::info!("apply_change {:?}", change); 32 log::info!("apply_change {:?}", change);
27 // self.gc_syntax_trees();
28 if !change.new_roots.is_empty() { 33 if !change.new_roots.is_empty() {
29 let mut local_roots = Vec::clone(&self.local_roots()); 34 let mut local_roots = Vec::clone(&self.local_roots());
30 for (root_id, is_local) in change.new_roots { 35 for (root_id, is_local) in change.new_roots {
@@ -72,18 +77,41 @@ impl db::RootDatabase {
72 self.set_source_root(root_id, Arc::new(source_root)); 77 self.set_source_root(root_id, Arc::new(source_root));
73 } 78 }
74 79
80 pub(crate) fn maybe_collect_garbage(&mut self) {
81 if self.last_gc_check.elapsed() > GC_COOLDOWN {
82 self.last_gc_check = time::Instant::now();
83 let retained_trees = syntax_tree_stats(self).retained;
84 if retained_trees > 100 {
85 log::info!(
86 "automatic garbadge collection, {} retained trees",
87 retained_trees
88 );
89 self.collect_garbage();
90 }
91 }
92 }
93
75 /// Ideally, we should call this function from time to time to collect heavy 94 /// Ideally, we should call this function from time to time to collect heavy
76 /// syntax trees. However, if we actually do that, everything is recomputed 95 /// syntax trees. However, if we actually do that, everything is recomputed
77 /// for some reason. Needs investigation. 96 /// for some reason. Needs investigation.
78 pub(crate) fn collect_garbage(&mut self) { 97 pub(crate) fn collect_garbage(&mut self) {
79 self.query(ra_db::ParseQuery) 98 self.last_gc = time::Instant::now();
80 .sweep(SweepStrategy::default().discard_values()); 99
81 self.query(hir::db::HirParseQuery) 100 let sweep = SweepStrategy::default()
82 .sweep(SweepStrategy::default().discard_values()); 101 .discard_values()
83 self.query(hir::db::FileItemsQuery) 102 .discard_all_revisions();
84 .sweep(SweepStrategy::default().discard_values()); 103
85 self.query(hir::db::FileItemQuery) 104 self.query(ra_db::ParseQuery).sweep(sweep.clone());
86 .sweep(SweepStrategy::default().discard_values()); 105
106 self.query(hir::db::HirParseQuery).sweep(sweep.clone());
107 self.query(hir::db::FileItemsQuery).sweep(sweep.clone());
108 self.query(hir::db::FileItemQuery).sweep(sweep.clone());
109
110 self.query(hir::db::LowerModuleQuery).sweep(sweep.clone());
111 self.query(hir::db::LowerModuleSourceMapQuery)
112 .sweep(sweep.clone());
113 self.query(hir::db::BodySyntaxMappingQuery)
114 .sweep(sweep.clone());
87 } 115 }
88} 116}
89 117
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 43c8bea71..a7caac02d 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -286,6 +286,10 @@ impl AnalysisHost {
286 self.db.apply_change(change) 286 self.db.apply_change(change)
287 } 287 }
288 288
289 pub fn maybe_collect_garbage(&mut self) {
290 self.db.maybe_collect_garbage();
291 }
292
289 pub fn collect_garbage(&mut self) { 293 pub fn collect_garbage(&mut self) {
290 self.db.collect_garbage(); 294 self.db.collect_garbage();
291 } 295 }
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs
index e11eed223..0dde30ae0 100644
--- a/crates/ra_ide_api/src/status.rs
+++ b/crates/ra_ide_api/src/status.rs
@@ -15,9 +15,13 @@ use crate::{
15 symbol_index::{SymbolIndex, LibrarySymbolsQuery}, 15 symbol_index::{SymbolIndex, LibrarySymbolsQuery},
16}; 16};
17 17
18pub(crate) fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
19 db.query(ParseQuery).entries::<SyntaxTreeStats>()
20}
21
18pub(crate) fn status(db: &RootDatabase) -> String { 22pub(crate) fn status(db: &RootDatabase) -> String {
19 let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); 23 let files_stats = db.query(FileTextQuery).entries::<FilesStats>();
20 let syntax_tree_stats = db.query(ParseQuery).entries::<SyntaxTreeStats>(); 24 let syntax_tree_stats = syntax_tree_stats(db);
21 let symbols_stats = db 25 let symbols_stats = db
22 .query(LibrarySymbolsQuery) 26 .query(LibrarySymbolsQuery)
23 .entries::<LibrarySymbolsStats>(); 27 .entries::<LibrarySymbolsStats>();
@@ -26,8 +30,12 @@ pub(crate) fn status(db: &RootDatabase) -> String {
26 interner.len() 30 interner.len()
27 }; 31 };
28 format!( 32 format!(
29 "{}\n{}\n{}\nn_defs {}\n", 33 "{}\n{}\n{}\nn_defs {}\nGC {:?} seconds ago",
30 files_stats, symbols_stats, syntax_tree_stats, n_defs 34 files_stats,
35 symbols_stats,
36 syntax_tree_stats,
37 n_defs,
38 db.last_gc.elapsed().as_secs(),
31 ) 39 )
32} 40}
33 41
@@ -58,9 +66,9 @@ impl FromIterator<TableEntry<FileId, Arc<String>>> for FilesStats {
58} 66}
59 67
60#[derive(Default)] 68#[derive(Default)]
61struct SyntaxTreeStats { 69pub(crate) struct SyntaxTreeStats {
62 total: usize, 70 total: usize,
63 retained: usize, 71 pub(crate) retained: usize,
64 retained_size: Bytes, 72 retained_size: Bytes,
65} 73}
66 74
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index ddd20a41f..e430ac6de 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -172,6 +172,7 @@ fn main_loop_inner(
172 172
173 let (libdata_sender, libdata_receiver) = unbounded(); 173 let (libdata_sender, libdata_receiver) = unbounded();
174 loop { 174 loop {
175 state.maybe_collect_garbage();
175 log::trace!("selecting"); 176 log::trace!("selecting");
176 let event = select! { 177 let event = select! {
177 recv(msg_receiver) -> msg => match msg { 178 recv(msg_receiver) -> msg => match msg {
@@ -207,7 +208,7 @@ fn main_loop_inner(
207 }; 208 };
208 match req.cast::<req::CollectGarbage>() { 209 match req.cast::<req::CollectGarbage>() {
209 Ok((id, ())) => { 210 Ok((id, ())) => {
210 state.collect_garbadge(); 211 state.collect_garbage();
211 let resp = RawResponse::ok::<req::CollectGarbage>(id, &()); 212 let resp = RawResponse::ok::<req::CollectGarbage>(id, &());
212 msg_sender.send(RawMessage::Response(resp)).unwrap() 213 msg_sender.send(RawMessage::Response(resp)).unwrap()
213 } 214 }
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index bf04f1125..c2167c5d8 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -232,7 +232,11 @@ impl ServerWorldState {
232 } 232 }
233 } 233 }
234 234
235 pub fn collect_garbadge(&mut self) { 235 pub fn maybe_collect_garbage(&mut self) {
236 self.analysis_host.maybe_collect_garbage()
237 }
238
239 pub fn collect_garbage(&mut self) {
236 self.analysis_host.collect_garbage() 240 self.analysis_host.collect_garbage()
237 } 241 }
238} 242}