Skip to content

Commit 81942f3

Browse files
committed
use Alloc not Box
to avoid uniqueness guarantees
1 parent a7b2805 commit 81942f3

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

components/salsa-2022/src/alloc.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use std::ptr::NonNull;
2+
3+
/// A box but without the uniqueness guarantees.
4+
pub struct Alloc<T> {
5+
data: NonNull<T>,
6+
}
7+
8+
impl<T> Alloc<T> {
9+
pub fn new(data: T) -> Self {
10+
let data = Box::new(data);
11+
let data = Box::into_raw(data);
12+
Alloc {
13+
data: unsafe { NonNull::new_unchecked(data) },
14+
}
15+
}
16+
}
17+
18+
impl<T> Drop for Alloc<T> {
19+
fn drop(&mut self) {
20+
let data: *mut T = self.data.as_ptr();
21+
let data: Box<T> = unsafe { Box::from_raw(data) };
22+
drop(data);
23+
}
24+
}
25+
26+
impl<T> std::ops::Deref for Alloc<T> {
27+
type Target = T;
28+
29+
fn deref(&self) -> &Self::Target {
30+
unsafe { self.data.as_ref() }
31+
}
32+
}
33+
34+
impl<T> std::ops::DerefMut for Alloc<T> {
35+
fn deref_mut(&mut self) -> &mut Self::Target {
36+
unsafe { self.data.as_mut() }
37+
}
38+
}
39+
40+
unsafe impl<T> Send for Alloc<T> where T: Send {}
41+
42+
unsafe impl<T> Sync for Alloc<T> where T: Sync {}

components/salsa-2022/src/interned.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::fmt;
33
use std::hash::Hash;
44
use std::marker::PhantomData;
55

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

4445
/// counter for the next id.
4546
counter: AtomicCell<u32>,
@@ -121,7 +122,7 @@ where
121122
let value = self
122123
.value_map
123124
.entry(next_id)
124-
.or_insert(Box::new(ValueStruct {
125+
.or_insert(Alloc::new(ValueStruct {
125126
id: next_id,
126127
fields: internal_data,
127128
}));

components/salsa-2022/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod accumulator;
2+
mod alloc;
23
pub mod cancelled;
34
pub mod cycle;
45
pub mod database;

components/salsa-2022/src/tracked_struct/struct_map.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crossbeam::queue::SegQueue;
77
use dashmap::mapref::one::RefMut;
88

99
use crate::{
10+
alloc::Alloc,
1011
hash::{FxDashMap, FxHasher},
1112
plumbing::transmute_lifetime,
1213
Id, Runtime,
@@ -18,21 +19,21 @@ pub(crate) struct StructMap<C>
1819
where
1920
C: Configuration,
2021
{
21-
map: Arc<FxDashMap<Id, Box<ValueStruct<C>>>>,
22+
map: Arc<FxDashMap<Id, Alloc<ValueStruct<C>>>>,
2223

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

3132
pub(crate) struct StructMapView<C>
3233
where
3334
C: Configuration,
3435
{
35-
map: Arc<FxDashMap<Id, Box<ValueStruct<C>>>>,
36+
map: Arc<FxDashMap<Id, Alloc<ValueStruct<C>>>>,
3637
}
3738

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

82-
let boxed_value = Box::new(value);
83+
let boxed_value = Alloc::new(value);
8384
let pointer = std::ptr::addr_of!(*boxed_value);
8485

8586
let old_value = self.map.insert(boxed_value.id, boxed_value);
@@ -165,7 +166,7 @@ where
165166
/// * If the value is not present in the map.
166167
/// * If the value has not been updated in this revision.
167168
fn get_from_map<'db>(
168-
map: &'db FxDashMap<Id, Box<ValueStruct<C>>>,
169+
map: &'db FxDashMap<Id, Alloc<ValueStruct<C>>>,
169170
runtime: &'db Runtime,
170171
id: Id,
171172
) -> &'db ValueStruct<C> {
@@ -230,7 +231,7 @@ pub(crate) struct UpdateRef<'db, C>
230231
where
231232
C: Configuration,
232233
{
233-
guard: RefMut<'db, Id, Box<ValueStruct<C>>, FxHasher>,
234+
guard: RefMut<'db, Id, Alloc<ValueStruct<C>>, FxHasher>,
234235
}
235236

236237
impl<'db, C> UpdateRef<'db, C>

0 commit comments

Comments
 (0)