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
18 changes: 14 additions & 4 deletions oscars/src/collectors/mark_sweep_branded/ephemeron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,27 @@ pub struct Ephemeron<'id, K: Trace, V: Trace> {
}

impl<'id, K: Trace, V: Trace> Ephemeron<'id, K, V> {
pub(crate) fn new(
key_ptr: Option<PoolPointer<'static, GcBox<K>>>,
key_alloc_id: usize,
value_ptr: PoolPointer<'static, GcBox<V>>,
) -> Self {
Self {
key_ptr,
key_alloc_id,
value_ptr,
_marker: PhantomData,
}
}

/// Returns the value if the key is alive.
pub fn get_value<'gc>(&self, _cx: &MutationContext<'id, 'gc>) -> Option<Gc<'gc, V>> {
// SAFETY: `_cx` proves the collector is alive, alloc_id guards ABA
let key_alive = self
.key_ptr
.is_some_and(|p| unsafe { (*p.as_ptr().as_ptr()).0.alloc_id == self.key_alloc_id });
if key_alive {
Some(Gc {
ptr: self.value_ptr,
_marker: PhantomData,
})
Some(Gc::with_pointer(self.value_ptr))
} else {
None
}
Expand Down
10 changes: 10 additions & 0 deletions oscars/src/collectors/mark_sweep_branded/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ impl<'gc, T: Trace + ?Sized + 'gc> Clone for Gc<'gc, T> {
}
}

impl<'gc, T: Trace + ?Sized + 'gc> Gc<'gc, T> {
#[inline]
pub(crate) fn with_pointer(ptr: PoolPointer<'static, GcBox<T>>) -> Self {
Self {
ptr,
_marker: PhantomData,
}
}
}

impl<'gc, T: Trace + 'gc> Gc<'gc, T> {
/// Returns a shared reference to the value.
#[inline]
Expand Down
5 changes: 1 addition & 4 deletions oscars/src/collectors/mark_sweep_branded/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ impl Collector {

drop(pool);

Ok(Gc {
ptr: unsafe { ptr.extend_lifetime() },
_marker: PhantomData,
})
Ok(Gc::with_pointer(unsafe { ptr.extend_lifetime() }))
}

/// Runs a collection cycle
Expand Down
15 changes: 3 additions & 12 deletions oscars/src/collectors/mark_sweep_branded/mutation_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ impl<'id, 'gc> MutationContext<'id, 'gc> {
/// Downgrades a `Gc` into a weak reference
pub fn alloc_weak<T: Trace + Finalize + 'gc>(&self, gc: Gc<'gc, T>) -> WeakGc<'id, T> {
let alloc_id = unsafe { (*gc.ptr.as_ptr().as_ptr()).0.alloc_id };
WeakGc {
ptr: gc.ptr,
alloc_id,
_marker: PhantomData,
}
WeakGc::with_pointer_and_alloc_id(gc.ptr, alloc_id)
}

/// Promotes a `Gc` pointer to a `Root`
Expand All @@ -45,7 +41,7 @@ impl<'id, 'gc> MutationContext<'id, 'gc> {
gc: Gc<'gc, T>,
) -> Result<Root<'id, T>, PoolAllocError> {
let raw = self.collector.try_alloc_root_node(gc.ptr)?;
Ok(Root { raw })
Ok(Root::from_raw(raw))
}

/// Creates an ephemeron binding `key` to `value`.
Expand All @@ -66,12 +62,7 @@ impl<'id, 'gc> MutationContext<'id, 'gc> {
let erased_value: PoolPointer<'static, GcBox<()>> =
unsafe { value.ptr.to_erased().to_typed_pool_pointer::<GcBox<()>>() };
self.collector.register_ephemeron(erased_key, erased_value);
Ephemeron {
key_ptr: Some(key.ptr),
key_alloc_id,
value_ptr: value.ptr,
_marker: core::marker::PhantomData,
}
Ephemeron::new(Some(key.ptr), key_alloc_id, value.ptr)
}

/// Triggers a gc cycle.
Expand Down
11 changes: 6 additions & 5 deletions oscars/src/collectors/mark_sweep_branded/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,14 @@ pub struct Root<'id, T: Trace> {
}

impl<'id, T: Trace> Root<'id, T> {
pub(crate) fn from_raw(raw: NonNull<RootNode<'id, T>>) -> Self {
Self { raw }
}

/// Converts this root into a `Gc` pointer
pub fn get<'gc>(&self, _cx: &MutationContext<'id, 'gc>) -> Gc<'gc, T> {
Gc {
// SAFETY: `raw` is non null and valid
ptr: unsafe { self.raw.as_ref().gc_ptr },
_marker: PhantomData,
}
// SAFETY: `raw` is non null and valid
Gc::with_pointer(unsafe { self.raw.as_ref().gc_ptr })
}
}

Expand Down
16 changes: 12 additions & 4 deletions oscars/src/collectors/mark_sweep_branded/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ pub struct WeakGc<'id, T: Trace + ?Sized> {
}

impl<'id, T: Trace> WeakGc<'id, T> {
pub(crate) fn with_pointer_and_alloc_id(
ptr: PoolPointer<'static, GcBox<T>>,
alloc_id: usize,
) -> Self {
Self {
ptr,
alloc_id,
_marker: PhantomData,
}
}

/// Attempts to upgrade to a strong `Gc<'gc, T>`.
pub fn upgrade<'gc>(
&self,
Expand All @@ -29,10 +40,7 @@ impl<'id, T: Trace> WeakGc<'id, T> {
let is_valid = unsafe { (*self.ptr.as_ptr().as_ptr()).0.alloc_id == self.alloc_id };

if is_valid {
Some(Gc {
ptr: self.ptr,
_marker: PhantomData,
})
Some(Gc::with_pointer(self.ptr))
} else {
None
}
Expand Down
16 changes: 12 additions & 4 deletions oscars/src/collectors/null_collector_branded/ephemeron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@ pub struct Ephemeron<'id, K: Trace, V: Trace> {
}

impl<'id, K: Trace, V: Trace> Ephemeron<'id, K, V> {
pub(crate) fn new(
key_ptr: Option<PoolPointer<'static, GcBox<K>>>,
value_ptr: PoolPointer<'static, GcBox<V>>,
) -> Self {
Self {
key_ptr,
value_ptr,
_marker: PhantomData,
}
}

/// Returns the value if the key is alive.
pub fn get_value<'gc>(&self, _cx: &MutationContext<'id, 'gc>) -> Option<Gc<'gc, V>> {
// In the null collector, everything stays alive until context drops.
if self.key_ptr.is_some() {
Some(Gc {
ptr: self.value_ptr,
_marker: PhantomData,
})
Some(Gc::with_pointer(self.value_ptr))
} else {
None
}
Expand Down
10 changes: 10 additions & 0 deletions oscars/src/collectors/null_collector_branded/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ impl<'gc, T: Trace + ?Sized + 'gc> Clone for Gc<'gc, T> {
}
}

impl<'gc, T: Trace + ?Sized + 'gc> Gc<'gc, T> {
#[inline]
pub(crate) fn with_pointer(ptr: PoolPointer<'static, GcBox<T>>) -> Self {
Self {
ptr,
_marker: PhantomData,
}
}
}

impl<'gc, T: Trace + 'gc> Gc<'gc, T> {
/// Returns a shared reference to the value.
#[inline]
Expand Down
5 changes: 1 addition & 4 deletions oscars/src/collectors/null_collector_branded/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ impl Collector {

drop(pool);

Ok(Gc {
ptr: unsafe { ptr.extend_lifetime() },
_marker: PhantomData,
})
Ok(Gc::with_pointer(unsafe { ptr.extend_lifetime() }))
}

/// Runs a collection cycle (no-op for null collector)
Expand Down
11 changes: 2 additions & 9 deletions oscars/src/collectors/null_collector_branded/mutation_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ impl<'id, 'gc> MutationContext<'id, 'gc> {

/// Downgrades a `Gc` into weak reference
pub fn alloc_weak<T: Trace + Finalize + 'gc>(&self, gc: Gc<'gc, T>) -> WeakGc<'id, T> {
WeakGc {
ptr: gc.ptr,
_marker: PhantomData,
}
WeakGc::with_pointer(gc.ptr)
}

pub fn root<T: Trace + Finalize + 'gc>(
Expand All @@ -53,11 +50,7 @@ impl<'id, 'gc> MutationContext<'id, 'gc> {
) -> Ephemeron<'id, K, V> {
// In the null collector, ephemerons don't need to be registered
// since the collector never collects.
Ephemeron {
key_ptr: Some(key.ptr),
value_ptr: value.ptr,
_marker: core::marker::PhantomData,
}
Ephemeron::new(Some(key.ptr), value.ptr)
}

pub fn collect(&self) {
Expand Down
5 changes: 1 addition & 4 deletions oscars/src/collectors/null_collector_branded/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ impl<'id, T: Trace> Root<'id, T> {

/// Converts this root into a `Gc` pointer
pub fn get<'gc>(&self, _cx: &MutationContext<'id, 'gc>) -> Gc<'gc, T> {
Gc {
ptr: self.gc_ptr,
_marker: PhantomData,
}
Gc::with_pointer(self.gc_ptr)
}
}
12 changes: 8 additions & 4 deletions oscars/src/collectors/null_collector_branded/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ pub struct WeakGc<'id, T: Trace + ?Sized> {
}

impl<'id, T: Trace> WeakGc<'id, T> {
pub(crate) fn with_pointer(ptr: PoolPointer<'static, GcBox<T>>) -> Self {
Self {
ptr,
_marker: PhantomData,
}
}

/// Attempts to upgrade to a strong `Gc<'gc, T>`
pub fn upgrade<'gc>(
&self,
_cx: &crate::collectors::null_collector_branded::MutationContext<'id, 'gc>,
) -> Option<Gc<'gc, T>> {
// In the null collector, everything stays alive until context drops.
Some(Gc {
ptr: self.ptr,
_marker: PhantomData,
})
Some(Gc::with_pointer(self.ptr))
}
}

Expand Down