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
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
- name: Set up Miri
run: cargo +nightly miri setup
- name: Run tests under Miri
run: cargo +nightly miri test -p oscars
run: cargo +nightly miri test -p oscars --all-features

docs:
name: Documentation
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions oscars/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ allocator-api2 = { version = "0.4.0", optional = true }
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 }

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
Expand All @@ -32,3 +33,4 @@ default = ["mark_sweep"]
std = []
mark_sweep = []
gc_allocator = ["dep:allocator-api2", "mark_sweep"]
thin-vec = ["dep:thin-vec", "mark_sweep"]
18 changes: 15 additions & 3 deletions oscars/src/collectors/mark_sweep/gc_collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ mod tests {

#[test]
fn gc_alloc_vec_basic() {
let collector = &MarkSweepGarbageCollector::default();
let collector = &mut MarkSweepGarbageCollector::default();
let vec = GcAllocVec::new_in(collector);
let gc_vec = Gc::new_in(GcRefCell::new(vec), collector);

Expand All @@ -214,6 +214,9 @@ mod tests {
assert_eq!(gc_vec.borrow()[0], 1);
assert_eq!(gc_vec.borrow()[1], 2);
assert_eq!(gc_vec.borrow()[2], 3);

drop(gc_vec);
collector.collect();
}

#[test]
Expand All @@ -237,11 +240,14 @@ mod tests {

#[test]
fn gc_alloc_box_basic() {
let collector = &MarkSweepGarbageCollector::default();
let collector = &mut MarkSweepGarbageCollector::default();
let boxed = GcAllocBox::new_in(42u64, collector);
let gc_box = Gc::new_in(GcRefCell::new(boxed), collector);

assert_eq!(**gc_box.borrow(), 42);

drop(gc_box);
collector.collect();
}

#[test]
Expand All @@ -255,11 +261,14 @@ mod tests {

assert_eq!(gc_box.borrow().len(), 5);
assert_eq!(gc_box.borrow()[2], 3);

drop(gc_box);
collector.collect();
}

#[test]
fn gc_alloc_vec_with_gc_pointers() {
let collector = &MarkSweepGarbageCollector::default();
let collector = &mut MarkSweepGarbageCollector::default();
let vec = GcAllocVec::new_in(collector);
let gc_vec = Gc::new_in(GcRefCell::new(vec), collector);

Expand All @@ -278,5 +287,8 @@ mod tests {
assert_eq!(gc_vec.borrow().len(), 2);
assert_eq!(*gc_vec.borrow()[0].borrow(), 100);
assert_eq!(*gc_vec.borrow()[1].borrow(), 200);

drop(gc_vec);
collector.collect();
}
}
99 changes: 99 additions & 0 deletions oscars/src/collectors/mark_sweep/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,3 +642,102 @@ mod gc_edge_cases {
collector.collect();
}
}

#[cfg(feature = "thin-vec")]
mod thin_vec_trace {
use thin_vec::ThinVec;

use crate::collectors::mark_sweep::MarkSweepGarbageCollector;
use crate::collectors::mark_sweep::cell::GcRefCell;
use crate::collectors::mark_sweep::pointers::Gc;
use crate::{Finalize, Trace};

/// `ThinVec<Gc<T>>` keeps inner `Gc` values alive across collections.
#[test]
fn thin_vec_keeps_inner_gc_alive() {
let collector = &mut MarkSweepGarbageCollector::default()
.with_page_size(4096)
.with_heap_threshold(8_192);

let a = Gc::new_in(GcRefCell::new(1u64), collector);
let b = Gc::new_in(GcRefCell::new(2u64), collector);
let c = Gc::new_in(GcRefCell::new(3u64), collector);

let mut vec: ThinVec<Gc<GcRefCell<u64>>> = ThinVec::new();
vec.push(a.clone());
vec.push(b.clone());
vec.push(c.clone());

let container = Gc::new_in(vec, collector);

collector.collect();

assert_eq!(*a.borrow(), 1u64, "a was incorrectly swept");
assert_eq!(*b.borrow(), 2u64, "b was incorrectly swept");
assert_eq!(*c.borrow(), 3u64, "c was incorrectly swept");

drop(container);
drop(a);
drop(b);
drop(c);
collector.collect();
}

/// An empty `ThinVec` does not cause panics during tracing.
#[test]
fn thin_vec_empty_trace() {
let collector = &mut MarkSweepGarbageCollector::default()
.with_page_size(256)
.with_heap_threshold(512);

let empty: ThinVec<Gc<u64>> = ThinVec::new();
let gc = Gc::new_in(empty, collector);

collector.collect();

drop(gc);
collector.collect();
}

/// `ThinVec` can be embedded inside a derived `Trace` struct.
#[test]
fn thin_vec_in_derived_trace_struct() {
#[derive(Finalize, Trace)]
struct AstNode {
value: u64,
children: ThinVec<Gc<AstNode>>,
}

let collector = &mut MarkSweepGarbageCollector::default()
.with_page_size(4096)
.with_heap_threshold(8_192);

let leaf = Gc::new_in(
AstNode {
value: 42,
children: ThinVec::new(),
},
collector,
);

let mut root_children = ThinVec::new();
root_children.push(leaf.clone());

let root = Gc::new_in(
AstNode {
value: 0,
children: root_children,
},
collector,
);

collector.collect();

assert_eq!(root.value, 0);
assert_eq!(leaf.value, 42);

drop(root);
drop(leaf);
collector.collect();
}
}
6 changes: 1 addition & 5 deletions oscars/src/collectors/mark_sweep/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,22 +311,18 @@ unsafe impl<T: Trace, C: allocator_api2::alloc::Allocator> Trace
});
}

// TODO: Needed for boa_engine

/*
#[cfg(feature = "thin-vec")]
impl<T: Trace> Finalize for thin_vec::ThinVec<T> {}

#[cfg(feature = "thin-vec")]
// SAFETY: All the inner elements of the `Vec` are correctly marked.
// SAFETY: All the inner elements of the `ThinVec` are correctly marked.
unsafe impl<T: Trace> Trace for thin_vec::ThinVec<T> {
custom_trace!(this, mark, {
for e in this {
mark(e);
}
});
}
*/

impl<T: Trace> Finalize for Option<T> {}
// SAFETY: The inner value of the `Option` is correctly marked.
Expand Down
Loading