Skip to content
Open
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
128 changes: 115 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions oscars/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ hashbrown = "0.16.1"
oscars_derive = { path = "../oscars_derive", version = "0.1.0" }
rustc-hash = "2.1.1"
thin-vec = { version = "0.2", optional = true }
# Optional Trace/Finalize impls for external types.
# Uses remote git dependency for standalone compilation.
# Override locally via `[patch]` in workspace root.
boa_string = { git = "https://github.com/boa-dev/boa.git", branch = "main", optional = true }
icu_locale_core = { version = "2.2.0", default-features = false, optional = true }
either = { version = "1.16.0", optional = true }
arrayvec = { version = "0.7.6", optional = true }

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
Expand Down Expand Up @@ -39,3 +46,7 @@ mark_sweep_branded = ["mark_sweep"]
null_collector = ["mark_sweep"]
null_collector_branded = ["mark_sweep"]
thin-vec = ["dep:thin-vec", "mark_sweep"]
boa_string = ["dep:boa_string", "mark_sweep"]
icu = ["dep:icu_locale_core", "mark_sweep"]
either = ["dep:either", "mark_sweep"]
arrayvec = ["dep:arrayvec", "mark_sweep"]
3 changes: 3 additions & 0 deletions oscars/src/alloc/arena2/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl<T: ?Sized> ArenaHeapItem<T> {
///
/// This avoids creating a `&mut self` reference, which can lead to stacked borrows
/// if shared references to the heap item exist
#[allow(dead_code)]
pub(crate) fn as_value_ptr(ptr: NonNull<Self>) -> *mut T {
// SAFETY: `&raw mut` computes the field address without creating a reference
unsafe { &raw mut (*ptr.as_ptr()).value }
Expand Down Expand Up @@ -147,6 +148,7 @@ impl<'arena> ErasedArenaPointer<'arena> {
/// SAFETY:
///
/// safe because the gc collector owns the arena and keeps it alive
#[allow(dead_code)]
pub(crate) unsafe fn extend_lifetime(self) -> ErasedArenaPointer<'static> {
ErasedArenaPointer(self.0, PhantomData)
}
Expand Down Expand Up @@ -202,6 +204,7 @@ impl<'arena, T> ArenaPointer<'arena, T> {
/// SAFETY:
///
/// safe because the gc collector owns the arena and keeps it alive
#[allow(dead_code)]
pub(crate) unsafe fn extend_lifetime(self) -> ArenaPointer<'static, T> {
// SAFETY: upheld by caller
ArenaPointer(unsafe { self.0.extend_lifetime() }, PhantomData)
Expand Down
2 changes: 1 addition & 1 deletion oscars/src/alloc/mempool3/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'pool, T: ?Sized> PoolPointer<'pool, T> {
}
}

impl<'pool, T> PoolPointer<'pool, T> {
impl<'pool, T: ?Sized> PoolPointer<'pool, T> {
pub(crate) unsafe fn from_raw(raw: NonNull<PoolItem<T>>) -> Self {
Self(raw, PhantomData)
}
Expand Down
1 change: 1 addition & 0 deletions oscars/src/collectors/mark_sweep/internals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod gc_header;
mod vtable;

pub(crate) use ephemeron::Ephemeron;
#[allow(unused_imports)]
pub(crate) use gc_header::{GcHeader, HeaderColor};
pub(crate) use vtable::{DropFn, FinalizeFn, TraceFn, VTable, vtable_of};

Expand Down
8 changes: 8 additions & 0 deletions oscars/src/collectors/mark_sweep/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ pub unsafe trait Trace: Finalize {
/// - An incorrect implementation may cause undefined behavior
unsafe fn trace(&self, color: TraceColor);

/// Unroots handles located in the GC heap.
///
/// # Safety
///
/// Must only be called by the garbage collector.
#[inline]
unsafe fn trace_non_roots(&self) {}

fn run_finalizer(&self);
}

Expand Down
5 changes: 2 additions & 3 deletions oscars/src/collectors/mark_sweep_branded/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,9 @@ impl<T: Trace> DerefMut for GcRefMut<'_, T> {
impl<T: Trace> Finalize for GcRefCell<T> {}

unsafe impl<T: Trace> Trace for GcRefCell<T> {
#[inline]
unsafe fn trace(&self, tracer: &mut Tracer) {
let val = unsafe { &*self.inner.as_ptr() };
unsafe {
val.trace(tracer);
}
unsafe { val.trace(tracer) };
}
}
2 changes: 1 addition & 1 deletion oscars/src/collectors/mark_sweep_branded/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'gc, T: Trace + 'gc> Deref for Gc<'gc, T> {
}
}

impl<T: Trace> Finalize for Gc<'_, T> {}
impl<T: Trace + ?Sized> Finalize for Gc<'_, T> {}
unsafe impl<T: Trace> Trace for Gc<'_, T> {
unsafe fn trace(&self, tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {
tracer.mark(self);
Expand Down
1 change: 1 addition & 0 deletions oscars/src/collectors/mark_sweep_branded/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct JsObject {
value: i32,
}

// SAFETY: JsObject contains no Gc pointers; tracing is a no-op.
unsafe impl crate::collectors::mark_sweep_branded::Trace for JsObject {
unsafe fn trace(&self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {}
}
Expand Down
1 change: 1 addition & 0 deletions oscars/src/collectors/mark_sweep_branded/tests/uaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use core::cell::Cell;

struct DetectDrop<'a>(&'a Cell<bool>);

// SAFETY: DetectDrop contains no Gc pointers; tracing is a no-op.
unsafe impl<'a> Trace for DetectDrop<'a> {
unsafe fn trace(&self, _tracer: &mut crate::collectors::mark_sweep_branded::trace::Tracer) {}
}
Expand Down
Loading