diff --git a/src/derived/slot.rs b/src/derived/slot.rs index 4af7025..d2c4fe6 100644 --- a/src/derived/slot.rs +++ b/src/derived/slot.rs @@ -9,6 +9,7 @@ use crate::plumbing::GetQueryTable; use crate::plumbing::HasQueryGroup; use crate::plumbing::QueryFunction; use crate::runtime::FxIndexSet; +use crate::runtime::IsConstant; use crate::runtime::Revision; use crate::runtime::Runtime; use crate::runtime::RuntimeId; @@ -73,7 +74,7 @@ where /// If true, then this value was considered a constant when last /// verified. - is_constant: bool, + is_constant: IsConstant, /// The inputs that went into our query, if we are tracking them. inputs: MemoInputs, @@ -617,7 +618,7 @@ where /// True if this memo should still be considered constant /// (presuming it ever was). fn is_still_constant(&self, db: &DB) -> bool { - self.is_constant && { + self.is_constant.0 && { let last_changed = db.salsa_runtime().revision_when_constant_last_changed(); debug!( "is_still_constant(last_changed={:?} <= verified_at={:?}) = {:?}", diff --git a/src/input.rs b/src/input.rs index e3c7091..e4d89f7 100644 --- a/src/input.rs +++ b/src/input.rs @@ -4,6 +4,7 @@ use crate::plumbing::CycleDetected; use crate::plumbing::InputQueryStorageOps; use crate::plumbing::QueryStorageMassOps; use crate::plumbing::QueryStorageOps; +use crate::runtime::IsConstant; use crate::runtime::Revision; use crate::runtime::StampedValue; use crate::Database; @@ -58,8 +59,6 @@ where } } -struct IsConstant(bool); - impl InputStorage where Q: Query, @@ -101,7 +100,7 @@ where // into the same cell while we block on the lock.) let stamped_value = StampedValue { value, - is_constant: is_constant.0, + is_constant: is_constant, changed_at: guard.new_revision(), }; @@ -109,7 +108,7 @@ where Entry::Occupied(entry) => { let mut slot_stamped_value = entry.get().stamped_value.write(); - if slot_stamped_value.is_constant { + if slot_stamped_value.is_constant.0 { guard.mark_constants_as_changed(); } @@ -152,7 +151,7 @@ where fn is_constant(&self, _db: &DB, key: &Q::Key) -> bool { self.slot(key) - .map(|slot| slot.stamped_value.read().is_constant) + .map(|slot| slot.stamped_value.read().is_constant.0) .unwrap_or(false) } diff --git a/src/interned.rs b/src/interned.rs index 8c3914e..66514de 100644 --- a/src/interned.rs +++ b/src/interned.rs @@ -5,6 +5,7 @@ use crate::plumbing::CycleDetected; use crate::plumbing::HasQueryGroup; use crate::plumbing::QueryStorageMassOps; use crate::plumbing::QueryStorageOps; +use crate::runtime::IsConstant; use crate::runtime::Revision; use crate::Query; use crate::{Database, DiscardIf, SweepStrategy}; @@ -323,7 +324,7 @@ where let changed_at = slot.interned_at; let index = slot.index; db.salsa_runtime() - .report_query_read(slot, false, changed_at); + .report_query_read(slot, IsConstant(false), changed_at); Ok(::from_intern_id(index)) } @@ -424,7 +425,7 @@ where let value = slot.value.clone(); let interned_at = slot.interned_at; db.salsa_runtime() - .report_query_read(slot, false, interned_at); + .report_query_read(slot, IsConstant(false), interned_at); Ok(value) } diff --git a/src/runtime.rs b/src/runtime.rs index 4d10d72..b48b29e 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -355,7 +355,7 @@ where pub(crate) fn report_query_read<'hack>( &self, database_slot: Arc + 'hack>, - is_constant: bool, + is_constant: IsConstant, changed_at: Revision, ) { let dependency = Dependency::new(database_slot); @@ -537,7 +537,7 @@ struct ActiveQuery { database_key: DB::DatabaseKey, /// True if all inputs were constant (and no untracked inputs). - is_constant: bool, + is_constant: IsConstant, /// Maximum revision of all inputs observed. If we observe an /// untracked read, this will be set to the most recent revision. @@ -553,7 +553,7 @@ pub(crate) struct ComputedQueryResult { pub(crate) value: V, /// True if all inputs were constant (and no untracked inputs). - pub(crate) is_constant: bool, + pub(crate) is_constant: IsConstant, /// Maximum revision of all inputs observed. If we observe an /// untracked read, this will be set to the most recent revision. @@ -568,24 +568,29 @@ impl ActiveQuery { fn new(database_key: DB::DatabaseKey) -> Self { ActiveQuery { database_key, - is_constant: true, + is_constant: IsConstant(true), changed_at: Revision::start(), dependencies: Some(FxIndexSet::default()), } } - fn add_read(&mut self, dependency: Dependency, is_constant: bool, revision: Revision) { + fn add_read( + &mut self, + dependency: Dependency, + is_constant: IsConstant, + revision: Revision, + ) { if let Some(set) = &mut self.dependencies { set.insert(dependency); } - self.is_constant &= is_constant; + self.is_constant = self.is_constant.and(is_constant); self.changed_at = self.changed_at.max(revision); } fn add_untracked_read(&mut self, changed_at: Revision) { self.dependencies = None; - self.is_constant = false; + self.is_constant = IsConstant(false); self.changed_at = changed_at; } @@ -638,10 +643,19 @@ impl std::fmt::Debug for Revision { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) struct IsConstant(pub(crate) bool); + +impl IsConstant { + pub(crate) fn and(self, c: IsConstant) -> IsConstant { + IsConstant(self.0 & c.0) + } +} + #[derive(Clone, Debug)] pub(crate) struct StampedValue { pub(crate) value: V, - pub(crate) is_constant: bool, + pub(crate) is_constant: IsConstant, pub(crate) changed_at: Revision, } diff --git a/src/runtime/local_state.rs b/src/runtime/local_state.rs index fe769a7..67dbb7f 100644 --- a/src/runtime/local_state.rs +++ b/src/runtime/local_state.rs @@ -1,5 +1,6 @@ use crate::dependency::Dependency; use crate::runtime::ActiveQuery; +use crate::runtime::IsConstant; use crate::runtime::Revision; use crate::Database; use std::cell::Ref; @@ -60,7 +61,7 @@ impl LocalState { pub(super) fn report_query_read( &self, dependency: Dependency, - is_constant: bool, + is_constant: IsConstant, changed_at: Revision, ) { if let Some(top_query) = self.query_stack.borrow_mut().last_mut() {