Skip to content

Commit 1f61345

Browse files
committed
Auto merge of #17639 - Veykril:salsa-perf, r=Veykril
Some more small salsa memory improvements This does limit our lru limits to 2^16 but if you want to set them higher than that you might as well not set them at all.
2 parents 9fd6c69 + 7fcac48 commit 1f61345

File tree

10 files changed

+68
-60
lines changed

10 files changed

+68
-60
lines changed

crates/base-db/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ pub trait Upcast<T: ?Sized> {
4242
fn upcast(&self) -> &T;
4343
}
4444

45-
pub const DEFAULT_FILE_TEXT_LRU_CAP: usize = 16;
46-
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
47-
pub const DEFAULT_BORROWCK_LRU_CAP: usize = 2024;
45+
pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16;
46+
pub const DEFAULT_PARSE_LRU_CAP: u16 = 128;
47+
pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024;
4848

4949
pub trait FileLoader {
5050
/// Text of the file.

crates/ide-db/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl Default for RootDatabase {
145145
}
146146

147147
impl RootDatabase {
148-
pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
148+
pub fn new(lru_capacity: Option<u16>) -> RootDatabase {
149149
let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()) };
150150
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
151151
db.set_proc_macros_with_durability(Default::default(), Durability::HIGH);
@@ -161,7 +161,7 @@ impl RootDatabase {
161161
self.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
162162
}
163163

164-
pub fn update_base_query_lru_capacities(&mut self, lru_capacity: Option<usize>) {
164+
pub fn update_base_query_lru_capacities(&mut self, lru_capacity: Option<u16>) {
165165
let lru_capacity = lru_capacity.unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP);
166166
base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP);
167167
base_db::ParseQuery.in_db_mut(self).set_lru_capacity(lru_capacity);
@@ -170,7 +170,7 @@ impl RootDatabase {
170170
hir::db::BorrowckQuery.in_db_mut(self).set_lru_capacity(base_db::DEFAULT_BORROWCK_LRU_CAP);
171171
}
172172

173-
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, usize>) {
173+
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, u16>) {
174174
use hir::db as hir_db;
175175

176176
base_db::FileTextQuery.in_db_mut(self).set_lru_capacity(DEFAULT_FILE_TEXT_LRU_CAP);

crates/ide/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,19 @@ pub struct AnalysisHost {
161161
}
162162

163163
impl AnalysisHost {
164-
pub fn new(lru_capacity: Option<usize>) -> AnalysisHost {
164+
pub fn new(lru_capacity: Option<u16>) -> AnalysisHost {
165165
AnalysisHost { db: RootDatabase::new(lru_capacity) }
166166
}
167167

168168
pub fn with_database(db: RootDatabase) -> AnalysisHost {
169169
AnalysisHost { db }
170170
}
171171

172-
pub fn update_lru_capacity(&mut self, lru_capacity: Option<usize>) {
172+
pub fn update_lru_capacity(&mut self, lru_capacity: Option<u16>) {
173173
self.db.update_base_query_lru_capacities(lru_capacity);
174174
}
175175

176-
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, usize>) {
176+
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, u16>) {
177177
self.db.update_lru_capacities(lru_capacities);
178178
}
179179

crates/load-cargo/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ fn load_crate_graph(
377377
) -> RootDatabase {
378378
let ProjectWorkspace { toolchain, target_layout, .. } = ws;
379379

380-
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
380+
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<u16>().ok());
381381
let mut db = RootDatabase::new(lru_cap);
382382
let mut analysis_change = ChangeWithProcMacros::new();
383383

crates/rust-analyzer/src/config.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,9 @@ config_data! {
283283
linkedProjects: Vec<ManifestOrProjectJson> = vec![],
284284

285285
/// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
286-
lru_capacity: Option<usize> = None,
286+
lru_capacity: Option<u16> = None,
287287
/// Sets the LRU capacity of the specified queries.
288-
lru_query_capacities: FxHashMap<Box<str>, usize> = FxHashMap::default(),
288+
lru_query_capacities: FxHashMap<Box<str>, u16> = FxHashMap::default(),
289289

290290
/// These proc-macros will be ignored when trying to expand them.
291291
///
@@ -1743,11 +1743,11 @@ impl Config {
17431743
extra_env
17441744
}
17451745

1746-
pub fn lru_parse_query_capacity(&self) -> Option<usize> {
1746+
pub fn lru_parse_query_capacity(&self) -> Option<u16> {
17471747
self.lru_capacity().to_owned()
17481748
}
17491749

1750-
pub fn lru_query_capacities_config(&self) -> Option<&FxHashMap<Box<str>, usize>> {
1750+
pub fn lru_query_capacities_config(&self) -> Option<&FxHashMap<Box<str>, u16>> {
17511751
self.lru_query_capacities().is_empty().not().then(|| self.lru_query_capacities())
17521752
}
17531753

crates/salsa/src/derived.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ where
203203
Q: QueryFunction,
204204
MP: MemoizationPolicy<Q>,
205205
{
206-
fn set_lru_capacity(&self, new_capacity: usize) {
206+
fn set_lru_capacity(&self, new_capacity: u16) {
207207
self.lru_list.set_lru_capacity(new_capacity);
208208
}
209209
}

crates/salsa/src/interned.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ impl InternValueTrivial for String {}
121121

122122
#[derive(Debug)]
123123
struct Slot<V> {
124-
/// DatabaseKeyIndex for this slot.
125-
database_key_index: DatabaseKeyIndex,
124+
/// key index for this slot.
125+
key_index: u32,
126126

127127
/// Value that was interned.
128128
value: V,
@@ -199,13 +199,8 @@ where
199199
};
200200

201201
let create_slot = |index: InternId| {
202-
let database_key_index = DatabaseKeyIndex {
203-
group_index: self.group_index,
204-
query_index: Q::QUERY_INDEX,
205-
key_index: index.as_u32(),
206-
};
207202
Arc::new(Slot {
208-
database_key_index,
203+
key_index: index.as_u32(),
209204
value: insert(Q::Value::from_intern_id(index)),
210205
interned_at: revision_now,
211206
})
@@ -242,7 +237,11 @@ where
242237
};
243238
let changed_at = slot.interned_at;
244239
db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted(
245-
slot.database_key_index,
240+
DatabaseKeyIndex {
241+
group_index: self.group_index,
242+
query_index: Q::QUERY_INDEX,
243+
key_index: slot.key_index,
244+
},
246245
INTERN_DURABILITY,
247246
changed_at,
248247
);
@@ -294,7 +293,11 @@ where
294293
};
295294
let changed_at = slot.interned_at;
296295
db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted(
297-
slot.database_key_index,
296+
DatabaseKeyIndex {
297+
group_index: self.group_index,
298+
query_index: Q::QUERY_INDEX,
299+
key_index: slot.key_index,
300+
},
298301
INTERN_DURABILITY,
299302
changed_at,
300303
);
@@ -414,7 +417,11 @@ where
414417
let value = slot.value.clone();
415418
let interned_at = slot.interned_at;
416419
db.salsa_runtime().report_query_read_and_unwind_if_cycle_resulted(
417-
slot.database_key_index,
420+
DatabaseKeyIndex {
421+
group_index: interned_storage.group_index,
422+
query_index: Q::QUERY_INDEX,
423+
key_index: slot.key_index,
424+
},
418425
INTERN_DURABILITY,
419426
interned_at,
420427
);

crates/salsa/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ where
577577
/// cost of potential extra recalculations of evicted values.
578578
///
579579
/// If `cap` is zero, all values are preserved, this is the default.
580-
pub fn set_lru_capacity(&self, cap: usize)
580+
pub fn set_lru_capacity(&self, cap: u16)
581581
where
582582
Q::Storage: plumbing::LruQueryStorageOps,
583583
{

crates/salsa/src/lru.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use oorandom::Rand64;
22
use parking_lot::Mutex;
33
use std::fmt::Debug;
4-
use std::sync::atomic::AtomicUsize;
4+
use std::sync::atomic::AtomicU16;
55
use std::sync::atomic::Ordering;
66
use triomphe::Arc;
77

@@ -20,15 +20,15 @@ pub(crate) struct Lru<Node>
2020
where
2121
Node: LruNode,
2222
{
23-
green_zone: AtomicUsize,
23+
green_zone: AtomicU16,
2424
data: Mutex<LruData<Node>>,
2525
}
2626

2727
#[derive(Debug)]
2828
struct LruData<Node> {
29-
end_red_zone: usize,
30-
end_yellow_zone: usize,
31-
end_green_zone: usize,
29+
end_red_zone: u16,
30+
end_yellow_zone: u16,
31+
end_green_zone: u16,
3232
rng: Rand64,
3333
entries: Vec<Arc<Node>>,
3434
}
@@ -39,9 +39,9 @@ pub(crate) trait LruNode: Sized + Debug {
3939

4040
#[derive(Debug)]
4141
pub(crate) struct LruIndex {
42-
/// Index in the appropriate LRU list, or std::usize::MAX if not a
42+
/// Index in the appropriate LRU list, or std::u16::MAX if not a
4343
/// member.
44-
index: AtomicUsize,
44+
index: AtomicU16,
4545
}
4646

4747
impl<Node> Default for Lru<Node>
@@ -68,12 +68,12 @@ where
6868

6969
#[cfg_attr(not(test), allow(dead_code))]
7070
fn with_seed(seed: &str) -> Self {
71-
Lru { green_zone: AtomicUsize::new(0), data: Mutex::new(LruData::with_seed(seed)) }
71+
Lru { green_zone: AtomicU16::new(0), data: Mutex::new(LruData::with_seed(seed)) }
7272
}
7373

7474
/// Adjust the total number of nodes permitted to have a value at
7575
/// once. If `len` is zero, this disables LRU caching completely.
76-
pub(crate) fn set_lru_capacity(&self, len: usize) {
76+
pub(crate) fn set_lru_capacity(&self, len: u16) {
7777
let mut data = self.data.lock();
7878

7979
// We require each zone to have at least 1 slot. Therefore,
@@ -143,23 +143,24 @@ where
143143
LruData { end_yellow_zone: 0, end_green_zone: 0, end_red_zone: 0, entries: Vec::new(), rng }
144144
}
145145

146-
fn green_zone(&self) -> std::ops::Range<usize> {
146+
fn green_zone(&self) -> std::ops::Range<u16> {
147147
0..self.end_green_zone
148148
}
149149

150-
fn yellow_zone(&self) -> std::ops::Range<usize> {
150+
fn yellow_zone(&self) -> std::ops::Range<u16> {
151151
self.end_green_zone..self.end_yellow_zone
152152
}
153153

154-
fn red_zone(&self) -> std::ops::Range<usize> {
154+
fn red_zone(&self) -> std::ops::Range<u16> {
155155
self.end_yellow_zone..self.end_red_zone
156156
}
157157

158-
fn resize(&mut self, len_green_zone: usize, len_yellow_zone: usize, len_red_zone: usize) {
158+
fn resize(&mut self, len_green_zone: u16, len_yellow_zone: u16, len_red_zone: u16) {
159159
self.end_green_zone = len_green_zone;
160160
self.end_yellow_zone = self.end_green_zone + len_yellow_zone;
161161
self.end_red_zone = self.end_yellow_zone + len_red_zone;
162-
let entries = std::mem::replace(&mut self.entries, Vec::with_capacity(self.end_red_zone));
162+
let entries =
163+
std::mem::replace(&mut self.entries, Vec::with_capacity(self.end_red_zone as usize));
163164

164165
tracing::debug!("green_zone = {:?}", self.green_zone());
165166
tracing::debug!("yellow_zone = {:?}", self.yellow_zone());
@@ -207,7 +208,7 @@ where
207208

208209
// Easy case: we still have capacity. Push it, and then promote
209210
// it up to the appropriate zone.
210-
let len = self.entries.len();
211+
let len = self.entries.len() as u16;
211212
if len < self.end_red_zone {
212213
self.entries.push(node.clone());
213214
node.lru_index().store(len);
@@ -218,7 +219,7 @@ where
218219
// Harder case: no capacity. Create some by evicting somebody from red
219220
// zone and then promoting.
220221
let victim_index = self.pick_index(self.red_zone());
221-
let victim_node = std::mem::replace(&mut self.entries[victim_index], node.clone());
222+
let victim_node = std::mem::replace(&mut self.entries[victim_index as usize], node.clone());
222223
tracing::debug!("evicting red node {:?} from {}", victim_node, victim_index);
223224
victim_node.lru_index().clear();
224225
self.promote_red_to_green(node, victim_index);
@@ -231,7 +232,7 @@ where
231232
///
232233
/// NB: It is not required that `node.lru_index()` is up-to-date
233234
/// when entering this method.
234-
fn promote_red_to_green(&mut self, node: &Arc<Node>, red_index: usize) {
235+
fn promote_red_to_green(&mut self, node: &Arc<Node>, red_index: u16) {
235236
debug_assert!(self.red_zone().contains(&red_index));
236237

237238
// Pick a yellow at random and switch places with it.
@@ -242,12 +243,12 @@ where
242243
let yellow_index = self.pick_index(self.yellow_zone());
243244
tracing::debug!(
244245
"demoting yellow node {:?} from {} to red at {}",
245-
self.entries[yellow_index],
246+
self.entries[yellow_index as usize],
246247
yellow_index,
247248
red_index,
248249
);
249-
self.entries.swap(yellow_index, red_index);
250-
self.entries[red_index].lru_index().store(red_index);
250+
self.entries.swap(yellow_index as usize, red_index as usize);
251+
self.entries[red_index as usize].lru_index().store(red_index);
251252

252253
// Now move ourselves up into the green zone.
253254
self.promote_yellow_to_green(node, yellow_index);
@@ -259,51 +260,51 @@ where
259260
///
260261
/// NB: It is not required that `node.lru_index()` is up-to-date
261262
/// when entering this method.
262-
fn promote_yellow_to_green(&mut self, node: &Arc<Node>, yellow_index: usize) {
263+
fn promote_yellow_to_green(&mut self, node: &Arc<Node>, yellow_index: u16) {
263264
debug_assert!(self.yellow_zone().contains(&yellow_index));
264265

265266
// Pick a yellow at random and switch places with it.
266267
let green_index = self.pick_index(self.green_zone());
267268
tracing::debug!(
268269
"demoting green node {:?} from {} to yellow at {}",
269-
self.entries[green_index],
270+
self.entries[green_index as usize],
270271
green_index,
271272
yellow_index
272273
);
273-
self.entries.swap(green_index, yellow_index);
274-
self.entries[yellow_index].lru_index().store(yellow_index);
274+
self.entries.swap(green_index as usize, yellow_index as usize);
275+
self.entries[yellow_index as usize].lru_index().store(yellow_index);
275276
node.lru_index().store(green_index);
276277

277278
tracing::debug!("promoted {:?} to green index {}", node, green_index);
278279
}
279280

280-
fn pick_index(&mut self, zone: std::ops::Range<usize>) -> usize {
281-
let end_index = std::cmp::min(zone.end, self.entries.len());
282-
self.rng.rand_range(zone.start as u64..end_index as u64) as usize
281+
fn pick_index(&mut self, zone: std::ops::Range<u16>) -> u16 {
282+
let end_index = std::cmp::min(zone.end, self.entries.len() as u16);
283+
self.rng.rand_range(zone.start as u64..end_index as u64) as u16
283284
}
284285
}
285286

286287
impl Default for LruIndex {
287288
fn default() -> Self {
288-
Self { index: AtomicUsize::new(usize::MAX) }
289+
Self { index: AtomicU16::new(u16::MAX) }
289290
}
290291
}
291292

292293
impl LruIndex {
293-
fn load(&self) -> usize {
294+
fn load(&self) -> u16 {
294295
self.index.load(Ordering::Acquire) // see note on ordering below
295296
}
296297

297-
fn store(&self, value: usize) {
298+
fn store(&self, value: u16) {
298299
self.index.store(value, Ordering::Release) // see note on ordering below
299300
}
300301

301302
fn clear(&self) {
302-
self.store(usize::MAX);
303+
self.store(u16::MAX);
303304
}
304305

305306
fn is_in_lru(&self) -> bool {
306-
self.load() != usize::MAX
307+
self.load() != u16::MAX
307308
}
308309
}
309310

crates/salsa/src/plumbing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ where
228228
/// that is, storage whose value is not derived from other storage but
229229
/// is set independently.
230230
pub trait LruQueryStorageOps {
231-
fn set_lru_capacity(&self, new_capacity: usize);
231+
fn set_lru_capacity(&self, new_capacity: u16);
232232
}
233233

234234
pub trait DerivedQueryStorageOps<Q>

0 commit comments

Comments
 (0)