Skip to content

Commit 7fe054e

Browse files
authored
Remove extra page indirection in Table (#710)
By manually erasing the concrete slot types and dealing with the vtable ourselves
1 parent f1c233b commit 7fe054e

File tree

7 files changed

+228
-215
lines changed

7 files changed

+228
-215
lines changed

src/id.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::Database;
1414
/// room for niches; currently there is only one niche, so that
1515
/// `Option<Id>` is the same size as an `Id`.
1616
///
17-
/// As an end-user of `Salsa` you will not use `Id` directly,
17+
/// As an end-user of `Salsa` you will generally not use `Id` directly,
1818
/// it is wrapped in new types.
1919
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2020
pub struct Id {
@@ -31,14 +31,22 @@ impl Id {
3131
/// In general, you should not need to create salsa ids yourself,
3232
/// but it can be useful if you are using the type as a general
3333
/// purpose "identifier" internally.
34+
///
35+
/// # Safety
36+
///
37+
/// The supplied value must be less than [`Self::MAX_U32`].
38+
///
39+
/// Additionally, creating an arbitrary `Id` can lead to unsoundness if such an ID ends up being used to index
40+
/// the internal allocation tables which end up being out of bounds. Care must be taken that the
41+
/// ID is either constructed with a valid value or that it never ends up being used as keys to
42+
/// salsa computations.
3443
#[doc(hidden)]
3544
#[track_caller]
36-
pub const fn from_u32(x: u32) -> Self {
45+
pub const unsafe fn from_u32(v: u32) -> Self {
46+
debug_assert!(v < Self::MAX_U32);
3747
Id {
38-
value: match NonZeroU32::new(x + 1) {
39-
Some(v) => v,
40-
None => panic!("given value is too large to be a `salsa::Id`"),
41-
},
48+
// SAFETY: Caller obligation
49+
value: unsafe { NonZeroU32::new_unchecked(v + 1) },
4250
}
4351
}
4452

src/input.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,7 @@ impl<C: Configuration> IngredientImpl<C> {
187187
&'db self,
188188
db: &'db dyn crate::Database,
189189
) -> impl Iterator<Item = &'db Value<C>> {
190-
db.zalsa()
191-
.table()
192-
.pages
193-
.iter()
194-
.filter_map(|(_, page)| page.cast_type::<crate::table::Page<Value<C>>>())
195-
.flat_map(|page| page.slots())
190+
db.zalsa().table().slots_of::<Value<C>>()
196191
}
197192

198193
/// Peek at the field values without recording any read dependency.
@@ -318,14 +313,17 @@ impl<C> Slot for Value<C>
318313
where
319314
C: Configuration,
320315
{
316+
#[inline]
321317
unsafe fn memos(&self, _current_revision: Revision) -> &crate::table::memo::MemoTable {
322318
&self.memos
323319
}
324320

321+
#[inline]
325322
fn memos_mut(&mut self) -> &mut crate::table::memo::MemoTable {
326323
&mut self.memos
327324
}
328325

326+
#[inline]
329327
unsafe fn syncs(&self, _current_revision: Revision) -> &SyncTable {
330328
&self.syncs
331329
}

src/input/singleton.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ impl SingletonChoice for Singleton {
3434
fn index(&self) -> Option<Id> {
3535
match self.index.load(Ordering::Acquire) {
3636
0 => None,
37-
id => Some(Id::from_u32(id - 1)),
37+
// SAFETY: Our u32 is derived from an ID and thus safe to convert back.
38+
id => Some(unsafe { Id::from_u32(id - 1) }),
3839
}
3940
}
4041
}

src/interned.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,7 @@ where
364364
&'db self,
365365
db: &'db dyn crate::Database,
366366
) -> impl Iterator<Item = &'db Value<C>> {
367-
db.zalsa()
368-
.table()
369-
.pages
370-
.iter()
371-
.filter_map(|(_, page)| page.cast_type::<crate::table::Page<Value<C>>>())
372-
.flat_map(|page| page.slots())
367+
db.zalsa().table().slots_of::<Value<C>>()
373368
}
374369
}
375370

@@ -475,14 +470,17 @@ impl<C> Slot for Value<C>
475470
where
476471
C: Configuration,
477472
{
473+
#[inline]
478474
unsafe fn memos(&self, _current_revision: Revision) -> &MemoTable {
479475
&self.memos
480476
}
481477

478+
#[inline]
482479
fn memos_mut(&mut self) -> &mut MemoTable {
483480
&mut self.memos
484481
}
485482

483+
#[inline]
486484
unsafe fn syncs(&self, _current_revision: Revision) -> &crate::table::sync::SyncTable {
487485
&self.syncs
488486
}

0 commit comments

Comments
 (0)