Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions oscars/src/collectors/mark_sweep/internals/ephemeron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ impl<K: Trace, V: Trace> Ephemeron<K, V> {
None
}

pub fn upgrade(&self) -> Option<Gc<K>> {
self.key.inner_ptr().map(|ptr| {
// Increment the roots, since we are creating a new root.
ptr.as_inner_ref().inc_roots();
// Safety: This is safe because WeakGc's collection insures
// the liveliness of the underlying pointer
unsafe { Gc::from_raw(ptr) }
})
}

pub fn is_reachable(&self, color: TraceColor) -> bool {
self.key.is_reachable(color)
}
Expand Down
8 changes: 6 additions & 2 deletions oscars/src/collectors/mark_sweep/pointers/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ impl<T: Trace> Gc<T> {

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

/// Creates a `Gc` from the provided [`PoolPointer`].
Expand Down Expand Up @@ -84,8 +86,10 @@ impl<T: Trace> Gc<T> {
#[inline]
#[must_use]
pub unsafe fn cast_unchecked<U: Trace + 'static>(this: Self) -> Gc<U> {
let inner_ptr = this.inner_ptr;
core::mem::forget(this);
Gc {
inner_ptr: this.inner_ptr,
inner_ptr,
marker: PhantomData,
}
}
Expand Down
7 changes: 6 additions & 1 deletion oscars/src/collectors/mark_sweep/pointers/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// optimized in the future
use crate::{
alloc::mempool3::PoolPointer,
collectors::mark_sweep::{Collector, Trace, internals::Ephemeron},
collectors::mark_sweep::{Collector, Gc, Trace, internals::Ephemeron},
};

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

/// Returns the value of this [`WeakGc`] if the underlying value is alive.
pub fn value(&self) -> Option<&T> {
self.inner_ptr.as_inner_ref().key()
}

pub fn upgrade(&self) -> Option<Gc<T>> {
self.inner_ptr.as_inner_ref().upgrade()
}
}
10 changes: 10 additions & 0 deletions oscars/src/collectors/mark_sweep_arena2/internals/ephemeron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ impl<K: Trace, V: Trace> Ephemeron<K, V> {
pub(crate) fn invalidate(&self) {
self.active.set(false);
}

pub fn upgrade(&self) -> Option<Gc<K>> {
self.key.inner_ptr().map(|ptr| {
// Increment the root by one since we are upgrading this value.
ptr.as_inner_ref().inc_roots();
// Safety: This is safe because WeakGc's collection insures
// the liveliness of the underlying pointer
unsafe { Gc::from_raw(ptr) }
})
}
}

impl<K: Trace, V: Trace> Ephemeron<K, V> {
Expand Down
8 changes: 6 additions & 2 deletions oscars/src/collectors/mark_sweep_arena2/pointers/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ impl<T: Trace> Gc<T> {

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

/// Creates a `Gc` from the provided [`ArenaPointer`].
Expand Down Expand Up @@ -88,8 +90,10 @@ impl<T: Trace> Gc<T> {
#[inline]
#[must_use]
pub unsafe fn cast_unchecked<U: Trace + 'static>(this: Self) -> Gc<U> {
let inner_ptr = this.inner_ptr;
core::mem::forget(this);
Gc {
inner_ptr: this.inner_ptr,
inner_ptr,
marker: PhantomData,
}
}
Expand Down
6 changes: 5 additions & 1 deletion oscars/src/collectors/mark_sweep_arena2/pointers/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// optimized in the future
use crate::{
alloc::arena2::ArenaPointer,
collectors::mark_sweep_arena2::{Trace, internals::Ephemeron},
collectors::mark_sweep_arena2::{Gc, Trace, internals::Ephemeron},
};

#[repr(transparent)]
Expand Down Expand Up @@ -33,4 +33,8 @@ impl<T: Trace> WeakGc<T> {
pub fn value(&self) -> Option<&T> {
self.inner_ptr.as_inner_ref().key()
}

pub fn upgrade(&self) -> Option<Gc<T>> {
self.inner_ptr.as_inner_ref().upgrade()
}
}