Skip to content

Commit a050cf5

Browse files
authored
Implement upgrade method plus fix issue with previous PRs (#66)
1 parent ba096fa commit a050cf5

6 files changed

Lines changed: 43 additions & 6 deletions

File tree

oscars/src/collectors/mark_sweep/internals/ephemeron.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ impl<K: Trace, V: Trace> Ephemeron<K, V> {
4747
None
4848
}
4949

50+
pub fn upgrade(&self) -> Option<Gc<K>> {
51+
self.key.inner_ptr().map(|ptr| {
52+
// Increment the roots, since we are creating a new root.
53+
ptr.as_inner_ref().inc_roots();
54+
// Safety: This is safe because WeakGc's collection insures
55+
// the liveliness of the underlying pointer
56+
unsafe { Gc::from_raw(ptr) }
57+
})
58+
}
59+
5060
pub fn is_reachable(&self, color: TraceColor) -> bool {
5161
self.key.is_reachable(color)
5262
}

oscars/src/collectors/mark_sweep/pointers/gc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ impl<T: Trace> Gc<T> {
3737

3838
/// Converts a `Gc` into a raw [`PoolPointer`].
3939
pub fn into_raw(this: Self) -> PoolPointer<'static, GcBox<T>> {
40-
this.inner_ptr()
40+
let ptr = this.inner_ptr();
41+
core::mem::forget(this);
42+
ptr
4143
}
4244

4345
/// Creates a `Gc` from the provided [`PoolPointer`].
@@ -84,8 +86,10 @@ impl<T: Trace> Gc<T> {
8486
#[inline]
8587
#[must_use]
8688
pub unsafe fn cast_unchecked<U: Trace + 'static>(this: Self) -> Gc<U> {
89+
let inner_ptr = this.inner_ptr;
90+
core::mem::forget(this);
8791
Gc {
88-
inner_ptr: this.inner_ptr,
92+
inner_ptr,
8993
marker: PhantomData,
9094
}
9195
}

oscars/src/collectors/mark_sweep/pointers/weak.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// optimized in the future
44
use crate::{
55
alloc::mempool3::PoolPointer,
6-
collectors::mark_sweep::{Collector, Trace, internals::Ephemeron},
6+
collectors::mark_sweep::{Collector, Gc, Trace, internals::Ephemeron},
77
};
88

99
#[repr(transparent)]
@@ -26,7 +26,12 @@ impl<T: Trace> WeakGc<T> {
2626
Self { inner_ptr }
2727
}
2828

29+
/// Returns the value of this [`WeakGc`] if the underlying value is alive.
2930
pub fn value(&self) -> Option<&T> {
3031
self.inner_ptr.as_inner_ref().key()
3132
}
33+
34+
pub fn upgrade(&self) -> Option<Gc<T>> {
35+
self.inner_ptr.as_inner_ref().upgrade()
36+
}
3237
}

oscars/src/collectors/mark_sweep_arena2/internals/ephemeron.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ impl<K: Trace, V: Trace> Ephemeron<K, V> {
5050
pub(crate) fn invalidate(&self) {
5151
self.active.set(false);
5252
}
53+
54+
pub fn upgrade(&self) -> Option<Gc<K>> {
55+
self.key.inner_ptr().map(|ptr| {
56+
// Increment the root by one since we are upgrading this value.
57+
ptr.as_inner_ref().inc_roots();
58+
// Safety: This is safe because WeakGc's collection insures
59+
// the liveliness of the underlying pointer
60+
unsafe { Gc::from_raw(ptr) }
61+
})
62+
}
5363
}
5464

5565
impl<K: Trace, V: Trace> Ephemeron<K, V> {

oscars/src/collectors/mark_sweep_arena2/pointers/gc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ impl<T: Trace> Gc<T> {
4040

4141
/// Converts a `Gc` into a raw [`ArenaPointer`].
4242
pub fn into_raw(this: Self) -> ArenaPointer<'static, GcBox<T>> {
43-
this.inner_ptr()
43+
let ptr = this.inner_ptr();
44+
core::mem::forget(this);
45+
ptr
4446
}
4547

4648
/// Creates a `Gc` from the provided [`ArenaPointer`].
@@ -88,8 +90,10 @@ impl<T: Trace> Gc<T> {
8890
#[inline]
8991
#[must_use]
9092
pub unsafe fn cast_unchecked<U: Trace + 'static>(this: Self) -> Gc<U> {
93+
let inner_ptr = this.inner_ptr;
94+
core::mem::forget(this);
9195
Gc {
92-
inner_ptr: this.inner_ptr,
96+
inner_ptr,
9397
marker: PhantomData,
9498
}
9599
}

oscars/src/collectors/mark_sweep_arena2/pointers/weak.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// optimized in the future
44
use crate::{
55
alloc::arena2::ArenaPointer,
6-
collectors::mark_sweep_arena2::{Trace, internals::Ephemeron},
6+
collectors::mark_sweep_arena2::{Gc, Trace, internals::Ephemeron},
77
};
88

99
#[repr(transparent)]
@@ -33,4 +33,8 @@ impl<T: Trace> WeakGc<T> {
3333
pub fn value(&self) -> Option<&T> {
3434
self.inner_ptr.as_inner_ref().key()
3535
}
36+
37+
pub fn upgrade(&self) -> Option<Gc<T>> {
38+
self.inner_ptr.as_inner_ref().upgrade()
39+
}
3640
}

0 commit comments

Comments
 (0)