Skip to content

Commit 330535e

Browse files
committed
avoid key_of call
1 parent df25aed commit 330535e

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed

src/core/arena.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ impl<T> Memory<T> {
5555
self.entries.borrow().len()
5656
}
5757

58-
// Returns a pointer to the inserted entry.
58+
// Returns a key and a pointer to the inserted entry.
5959
//
6060
// SAFETY: The returned pointer is guaranteed to be valid until the entry
6161
// is removed or the Memory is dropped.
62-
fn insert(&self, e: T) -> Result<*const T, InsertError<T>> {
62+
fn insert(&self, e: T) -> Result<(usize, *const T), InsertError<T>> {
6363
let mut entries = self.entries.borrow_mut();
6464

6565
// Out of capacity. By preventing inserts beyond the capacity, we
@@ -77,19 +77,11 @@ impl<T> Memory<T> {
7777
// therefore we can return a pointer to the element and guarantee
7878
// its validity until the element is removed.
7979

80-
Ok(entry as *const T)
80+
Ok((key, entry as *const T))
8181
}
8282

83-
// The specified pointer must be one returned by the insert method
84-
unsafe fn remove(&self, e: *const T) {
85-
let mut entries = self.entries.borrow_mut();
86-
87-
// SAFETY: We trust `e` is valid
88-
let e: &T = unsafe { &*e };
89-
90-
let key = entries.key_of(e);
91-
92-
entries.remove(key);
83+
fn remove(&self, key: usize) {
84+
self.entries.borrow_mut().remove(key);
9385
}
9486

9587
// Returns a pointer to an entry if it exists.
@@ -311,6 +303,7 @@ fn unlikely_abort() {
311303
pub struct RcInner<T> {
312304
refs: Cell<usize>,
313305
memory: std::rc::Rc<RcMemory<T>>,
306+
key: Cell<usize>,
314307
value: T,
315308
}
316309

@@ -357,10 +350,11 @@ pub struct Rc<T> {
357350
impl<T> Rc<T> {
358351
#[allow(clippy::result_unit_err)]
359352
pub fn new(v: T, memory: &std::rc::Rc<RcMemory<T>>) -> Result<Self, InsertError<T>> {
360-
let ptr = memory
353+
let (key, ptr) = memory
361354
.insert(RcInner {
362355
refs: Cell::new(1),
363356
memory: std::rc::Rc::clone(memory),
357+
key: Cell::new(0),
364358
value: v,
365359
})
366360
.map_err(|e| InsertError(e.0.value))?;
@@ -369,6 +363,9 @@ impl<T> Rc<T> {
369363
// despite casting it to *mut in order to construct NonNull
370364
let ptr = unsafe { NonNull::new_unchecked(ptr as *mut RcInner<T>) };
371365

366+
// SAFETY: ptr is convertible to a reference
367+
unsafe { ptr.as_ref().key.set(key) };
368+
372369
Ok(Self {
373370
ptr,
374371
phantom: PhantomData,
@@ -409,9 +406,9 @@ impl<T> Rc<T> {
409406
// before removing the entry.
410407

411408
let memory = std::rc::Rc::clone(&self.inner().memory);
409+
let key = self.inner().key.get();
412410

413-
// SAFETY: While this Rc is alive, `ptr` is always valid
414-
unsafe { memory.remove(self.ptr.as_ptr()) };
411+
memory.remove(key);
415412
}
416413
}
417414

0 commit comments

Comments
 (0)