Skip to content

Commit

Permalink
use Alloc not Box
Browse files Browse the repository at this point in the history
to avoid uniqueness guarantees
  • Loading branch information
nikomatsakis committed May 27, 2024
1 parent a7b2805 commit 81942f3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
42 changes: 42 additions & 0 deletions components/salsa-2022/src/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::ptr::NonNull;

/// A box but without the uniqueness guarantees.
pub struct Alloc<T> {
data: NonNull<T>,
}

impl<T> Alloc<T> {
pub fn new(data: T) -> Self {
let data = Box::new(data);
let data = Box::into_raw(data);
Alloc {
data: unsafe { NonNull::new_unchecked(data) },
}
}
}

impl<T> Drop for Alloc<T> {
fn drop(&mut self) {
let data: *mut T = self.data.as_ptr();
let data: Box<T> = unsafe { Box::from_raw(data) };
drop(data);
}
}

impl<T> std::ops::Deref for Alloc<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
unsafe { self.data.as_ref() }
}
}

impl<T> std::ops::DerefMut for Alloc<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.data.as_mut() }
}
}

unsafe impl<T> Send for Alloc<T> where T: Send {}

unsafe impl<T> Sync for Alloc<T> where T: Sync {}
5 changes: 3 additions & 2 deletions components/salsa-2022/src/interned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt;
use std::hash::Hash;
use std::marker::PhantomData;

use crate::alloc::Alloc;
use crate::durability::Durability;
use crate::id::{AsId, LookupId};
use crate::ingredient::{fmt_index, IngredientRequiresReset};
Expand Down Expand Up @@ -39,7 +40,7 @@ pub struct InternedIngredient<C: Configuration> {
/// Maps from an interned id to its data.
///
/// Deadlock requirement: We access `value_map` while holding lock on `key_map`, but not vice versa.
value_map: FxDashMap<Id, Box<ValueStruct<C>>>,
value_map: FxDashMap<Id, Alloc<ValueStruct<C>>>,

/// counter for the next id.
counter: AtomicCell<u32>,
Expand Down Expand Up @@ -121,7 +122,7 @@ where
let value = self
.value_map
.entry(next_id)
.or_insert(Box::new(ValueStruct {
.or_insert(Alloc::new(ValueStruct {
id: next_id,
fields: internal_data,
}));
Expand Down
1 change: 1 addition & 0 deletions components/salsa-2022/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod accumulator;
mod alloc;
pub mod cancelled;
pub mod cycle;
pub mod database;
Expand Down
13 changes: 7 additions & 6 deletions components/salsa-2022/src/tracked_struct/struct_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crossbeam::queue::SegQueue;
use dashmap::mapref::one::RefMut;

use crate::{
alloc::Alloc,
hash::{FxDashMap, FxHasher},
plumbing::transmute_lifetime,
Id, Runtime,
Expand All @@ -18,21 +19,21 @@ pub(crate) struct StructMap<C>
where
C: Configuration,
{
map: Arc<FxDashMap<Id, Box<ValueStruct<C>>>>,
map: Arc<FxDashMap<Id, Alloc<ValueStruct<C>>>>,

/// When specific entities are deleted, their data is added
/// to this vector rather than being immediately freed. This is because we may` have
/// references to that data floating about that are tied to the lifetime of some
/// `&db` reference. This queue itself is not freed until we have an `&mut db` reference,
/// guaranteeing that there are no more references to it.
deleted_entries: SegQueue<Box<ValueStruct<C>>>,
deleted_entries: SegQueue<Alloc<ValueStruct<C>>>,
}

pub(crate) struct StructMapView<C>
where
C: Configuration,
{
map: Arc<FxDashMap<Id, Box<ValueStruct<C>>>>,
map: Arc<FxDashMap<Id, Alloc<ValueStruct<C>>>>,
}

/// Return value for [`StructMap`][]'s `update` method.
Expand Down Expand Up @@ -79,7 +80,7 @@ where
pub fn insert<'db>(&'db self, runtime: &'db Runtime, value: ValueStruct<C>) -> &ValueStruct<C> {
assert_eq!(value.created_at, runtime.current_revision());

let boxed_value = Box::new(value);
let boxed_value = Alloc::new(value);
let pointer = std::ptr::addr_of!(*boxed_value);

let old_value = self.map.insert(boxed_value.id, boxed_value);
Expand Down Expand Up @@ -165,7 +166,7 @@ where
/// * If the value is not present in the map.
/// * If the value has not been updated in this revision.
fn get_from_map<'db>(
map: &'db FxDashMap<Id, Box<ValueStruct<C>>>,
map: &'db FxDashMap<Id, Alloc<ValueStruct<C>>>,
runtime: &'db Runtime,
id: Id,
) -> &'db ValueStruct<C> {
Expand Down Expand Up @@ -230,7 +231,7 @@ pub(crate) struct UpdateRef<'db, C>
where
C: Configuration,
{
guard: RefMut<'db, Id, Box<ValueStruct<C>>, FxHasher>,
guard: RefMut<'db, Id, Alloc<ValueStruct<C>>, FxHasher>,
}

impl<'db, C> UpdateRef<'db, C>
Expand Down

0 comments on commit 81942f3

Please sign in to comment.