Skip to content

Commit a86db59

Browse files
Enable Garbage Collection for Interned Values (#602)
* remove table-wide dependencies * add plumbing to reuse interned slots * record durabilities on interned values * appease clippy * remove immortal interned value logic * pass correct revision when tracking interned reads * force new revision when resetting interned values * avoid unnecessary calls to `Database::zalsa` * add log events for value internment * Only log event kind because thread id can differ between runs/computers * cargo fmt --------- Co-authored-by: Micha Reiser <[email protected]>
1 parent 1d1523b commit a86db59

27 files changed

+435
-305
lines changed

book/src/plumbing/jars_and_ingredients.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,6 @@ It combines an [`IngredientIndex`] with a `key_index`, which is a `salsa::Id`:
146146
{{#include ../../../src/key.rs:DatabaseKeyIndex}}
147147
```
148148

149-
A `DependencyIndex` is similar, but the `key_index` is optional.
150-
This is used when we sometimes wish to refer to the ingredient as a whole, and not any specific value within the ingredient.
151-
152149
These kinds of indices are used to store connetions between ingredients.
153150
For example, each memoized value has to track its inputs.
154151
Those inputs are stored as dependency indices.

src/accumulator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
138138
) {
139139
}
140140

141-
fn fmt_index(&self, index: Option<crate::Id>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
141+
fn fmt_index(&self, index: crate::Id, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
142142
fmt_index(A::DEBUG_NAME, index, fmt)
143143
}
144144

src/active_query.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use std::ops::Not;
22

33
use super::zalsa_local::{QueryEdges, QueryOrigin, QueryRevisions};
44
use crate::accumulator::accumulated_map::AtomicInputAccumulatedValues;
5-
use crate::key::OutputDependencyIndex;
65
use crate::tracked_struct::{DisambiguatorMap, IdentityHash, IdentityMap};
76
use crate::zalsa_local::QueryEdge;
87
use crate::{
98
accumulator::accumulated_map::{AccumulatedMap, InputAccumulatedValues},
109
cycle::CycleHeads,
1110
durability::Durability,
1211
hash::FxIndexSet,
13-
key::{DatabaseKeyIndex, InputDependencyIndex},
12+
key::DatabaseKeyIndex,
1413
tracked_struct::Disambiguator,
1514
Revision,
1615
};
@@ -81,7 +80,7 @@ impl ActiveQuery {
8180

8281
pub(super) fn add_read(
8382
&mut self,
84-
input: InputDependencyIndex,
83+
input: DatabaseKeyIndex,
8584
durability: Durability,
8685
revision: Revision,
8786
accumulated: InputAccumulatedValues,
@@ -96,7 +95,7 @@ impl ActiveQuery {
9695

9796
pub(super) fn add_read_simple(
9897
&mut self,
99-
input: InputDependencyIndex,
98+
input: DatabaseKeyIndex,
10099
durability: Durability,
101100
revision: Revision,
102101
) {
@@ -118,12 +117,12 @@ impl ActiveQuery {
118117
}
119118

120119
/// Adds a key to our list of outputs.
121-
pub(super) fn add_output(&mut self, key: OutputDependencyIndex) {
120+
pub(super) fn add_output(&mut self, key: DatabaseKeyIndex) {
122121
self.input_outputs.insert(QueryEdge::Output(key));
123122
}
124123

125124
/// True if the given key was output by this query.
126-
pub(super) fn is_output(&self, key: OutputDependencyIndex) -> bool {
125+
pub(super) fn is_output(&self, key: DatabaseKeyIndex) -> bool {
127126
self.input_outputs.contains(&QueryEdge::Output(key))
128127
}
129128

src/database.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub trait Database: Send + AsDynDatabase + Any + ZalsaDatabase {
5656
/// which are the fine-grained components we use to track data. This is intended
5757
/// for debugging and the contents of the returned string are not semver-guaranteed.
5858
///
59-
/// Ingredient indices can be extracted from [`DependencyIndex`](`crate::DependencyIndex`) values.
59+
/// Ingredient indices can be extracted from [`DatabaseKeyIndex`](`crate::DatabaseKeyIndex`) values.
6060
fn ingredient_debug_name(&self, ingredient_index: IngredientIndex) -> Cow<'_, str> {
6161
Cow::Borrowed(
6262
self.zalsa()

src/durability.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ enum DurabilityVal {
3535
High = 2,
3636
}
3737

38+
impl From<u8> for DurabilityVal {
39+
fn from(value: u8) -> Self {
40+
match value {
41+
0 => DurabilityVal::Low,
42+
1 => DurabilityVal::Medium,
43+
2 => DurabilityVal::High,
44+
_ => panic!("invalid durability"),
45+
}
46+
}
47+
}
48+
3849
impl Durability {
3950
/// Low durability: things that change frequently.
4051
///
@@ -68,6 +79,14 @@ impl Durability {
6879
pub(crate) fn index(self) -> usize {
6980
self.0 as usize
7081
}
82+
83+
pub(crate) fn as_u8(self) -> u8 {
84+
self.0 as u8
85+
}
86+
87+
pub(crate) fn from_u8(value: u8) -> Self {
88+
Self(DurabilityVal::from(value))
89+
}
7190
}
7291

7392
impl Default for Durability {

src/event.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use std::thread::ThreadId;
22

3-
use crate::{
4-
key::DatabaseKeyIndex,
5-
key::{InputDependencyIndex, OutputDependencyIndex},
6-
};
3+
use crate::{key::DatabaseKeyIndex, Id, Revision};
74

85
/// The `Event` struct identifies various notable things that can
96
/// occur during salsa execution. Instances of this struct are given
@@ -76,7 +73,7 @@ pub enum EventKind {
7673
execute_key: DatabaseKeyIndex,
7774

7875
/// Key for the query that is no longer output
79-
output_key: OutputDependencyIndex,
76+
output_key: DatabaseKeyIndex,
8077
},
8178

8279
/// Tracked structs or memoized data were discarded (freed).
@@ -91,6 +88,24 @@ pub enum EventKind {
9188
executor_key: DatabaseKeyIndex,
9289

9390
/// Accumulator that was accumulated into
94-
accumulator: InputDependencyIndex,
91+
accumulator: DatabaseKeyIndex,
92+
},
93+
94+
/// Indicates that a value was newly interned.
95+
DidInternValue {
96+
// The ID of the interned value.
97+
id: Id,
98+
99+
// The revision the value was interned in.
100+
revision: Revision,
101+
},
102+
103+
/// Indicates that a previously interned value was read in a new revision.
104+
DidReinternValue {
105+
// The ID of the interned value.
106+
id: Id,
107+
108+
// The revision the value was interned in.
109+
revision: Revision,
95110
},
96111
}

src/function.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,8 @@ where
160160
}
161161
}
162162

163-
pub fn database_key_index(&self, k: Id) -> DatabaseKeyIndex {
164-
DatabaseKeyIndex {
165-
ingredient_index: self.index,
166-
key_index: k,
167-
}
163+
pub fn database_key_index(&self, key: Id) -> DatabaseKeyIndex {
164+
DatabaseKeyIndex::new(self.index, key)
168165
}
169166

170167
pub fn set_capacity(&mut self, capacity: usize) {
@@ -302,7 +299,7 @@ where
302299
std::mem::take(&mut self.deleted_entries);
303300
}
304301

305-
fn fmt_index(&self, index: Option<crate::Id>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
302+
fn fmt_index(&self, index: crate::Id, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
306303
fmt_index(C::DEBUG_NAME, index, fmt)
307304
}
308305

src/function/accumulated.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ where
5454
continue;
5555
}
5656

57-
let ingredient = zalsa.lookup_ingredient(k.ingredient_index);
57+
let ingredient = zalsa.lookup_ingredient(k.ingredient_index());
5858
// Extend `output` with any values accumulated by `k`.
59-
let (accumulated_map, input) = ingredient.accumulated(db, k.key_index);
59+
let (accumulated_map, input) = ingredient.accumulated(db, k.key_index());
6060
if let Some(accumulated_map) = accumulated_map {
6161
accumulated_map.extend_with_accumulated(accumulator.index(), &mut output);
6262
}
@@ -71,7 +71,7 @@ where
7171
// output vector, we want to push in execution order, so reverse order to
7272
// ensure the first child that was executed will be the first child popped
7373
// from the stack.
74-
let Some(origin) = ingredient.origin(db, k.key_index) else {
74+
let Some(origin) = ingredient.origin(db, k.key_index()) else {
7575
continue;
7676
};
7777

src/function/diff_outputs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{memo::Memo, Configuration, IngredientImpl};
22
use crate::{
3-
hash::FxHashSet, key::OutputDependencyIndex, zalsa::Zalsa, zalsa_local::QueryRevisions,
4-
AsDynDatabase as _, Database, DatabaseKeyIndex, Event, EventKind,
3+
hash::FxHashSet, zalsa::Zalsa, zalsa_local::QueryRevisions, AsDynDatabase as _, Database,
4+
DatabaseKeyIndex, Event, EventKind,
55
};
66

77
impl<C> IngredientImpl<C>
@@ -38,7 +38,7 @@ where
3838
// Remove the outputs that are no longer present in the current revision
3939
// to prevent that the next revision is seeded with a id mapping that no longer exists.
4040
revisions.tracked_struct_ids.retain(|&k, &mut value| {
41-
!old_outputs.contains(&OutputDependencyIndex::new(k.ingredient_index(), value))
41+
!old_outputs.contains(&DatabaseKeyIndex::new(k.ingredient_index(), value))
4242
});
4343
}
4444

@@ -51,7 +51,7 @@ where
5151
zalsa: &Zalsa,
5252
db: &C::DbView,
5353
key: DatabaseKeyIndex,
54-
output: OutputDependencyIndex,
54+
output: DatabaseKeyIndex,
5555
provisional: bool,
5656
) {
5757
db.salsa_event(&|| {

src/function/execute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ where
2929
let (zalsa, zalsa_local) = db.zalsas();
3030
let revision_now = zalsa.current_revision();
3131
let database_key_index = active_query.database_key_index;
32-
let id = database_key_index.key_index;
32+
let id = database_key_index.key_index();
3333

3434
tracing::info!("{:?}: executing query", database_key_index);
3535

0 commit comments

Comments
 (0)