Skip to content

Commit 5ed16ac

Browse files
committed
feat: implement mark_sweep_branded based on approved API redesign
1 parent ef6ff06 commit 5ed16ac

26 files changed

Lines changed: 1457 additions & 89 deletions

oscars/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ default = ["mark_sweep"]
3333
std = []
3434
mark_sweep = []
3535
mark_sweep2 = ["mark_sweep"]
36+
mark_sweep_branded = ["mark_sweep"]
3637
thin-vec = ["dep:thin-vec", "mark_sweep"]

oscars/src/collectors/common.rs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
//! Common types shared across all mark-and-sweep collector implementations.
2+
3+
use core::any::TypeId;
4+
use core::cell::{Cell, OnceCell};
5+
use core::marker::PhantomData;
6+
use core::num::{
7+
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
8+
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
9+
};
10+
use core::sync::atomic;
11+
12+
use rust_alloc::borrow::{Cow, ToOwned};
13+
use rust_alloc::boxed::Box;
14+
use rust_alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
15+
use rust_alloc::rc::Rc;
16+
use rust_alloc::string::String;
17+
use rust_alloc::vec::Vec;
18+
19+
#[cfg(feature = "std")]
20+
use std::collections::{HashMap, HashSet};
21+
22+
/// Substitute for the [`Drop`] trait for garbage collected types
23+
///
24+
/// Implement this to run cleanup logic before the GC frees an object.
25+
/// The default implementation is a no-op
26+
pub trait Finalize {
27+
/// Cleanup logic for a type
28+
fn finalize(&self) {}
29+
}
30+
31+
// primitive and standard library blanket impls
32+
33+
macro_rules! simple_finalize {
34+
($($T:ty),* $(,)?) => {
35+
$( impl Finalize for $T {} )*
36+
}
37+
}
38+
39+
simple_finalize![
40+
(),
41+
bool,
42+
isize,
43+
usize,
44+
i8,
45+
u8,
46+
i16,
47+
u16,
48+
i32,
49+
u32,
50+
i64,
51+
u64,
52+
i128,
53+
u128,
54+
f32,
55+
f64,
56+
char,
57+
TypeId,
58+
String,
59+
str,
60+
Rc<str>,
61+
NonZeroIsize,
62+
NonZeroUsize,
63+
NonZeroI8,
64+
NonZeroU8,
65+
NonZeroI16,
66+
NonZeroU16,
67+
NonZeroI32,
68+
NonZeroU32,
69+
NonZeroI64,
70+
NonZeroU64,
71+
NonZeroI128,
72+
NonZeroU128,
73+
];
74+
75+
#[cfg(target_has_atomic = "8")]
76+
simple_finalize![atomic::AtomicBool, atomic::AtomicI8, atomic::AtomicU8];
77+
78+
#[cfg(target_has_atomic = "16")]
79+
simple_finalize![atomic::AtomicI16, atomic::AtomicU16];
80+
81+
#[cfg(target_has_atomic = "32")]
82+
simple_finalize![atomic::AtomicI32, atomic::AtomicU32];
83+
84+
#[cfg(target_has_atomic = "64")]
85+
simple_finalize![atomic::AtomicI64, atomic::AtomicU64];
86+
87+
#[cfg(target_has_atomic = "ptr")]
88+
simple_finalize![atomic::AtomicIsize, atomic::AtomicUsize];
89+
90+
impl<T: ?Sized> Finalize for &'static T {}
91+
92+
impl<T: Finalize, const N: usize> Finalize for [T; N] {}
93+
94+
// Function pointer tuples, provide `Finalize` for function types.
95+
macro_rules! fn_finalize_one {
96+
($ty:ty $(,$args:ident)*) => {
97+
impl<Ret $(,$args)*> Finalize for $ty {}
98+
}
99+
}
100+
macro_rules! fn_finalize_group {
101+
() => {
102+
fn_finalize_one!(extern "Rust" fn () -> Ret);
103+
fn_finalize_one!(extern "C" fn () -> Ret);
104+
fn_finalize_one!(unsafe extern "Rust" fn () -> Ret);
105+
fn_finalize_one!(unsafe extern "C" fn () -> Ret);
106+
};
107+
($($args:ident),*) => {
108+
fn_finalize_one!(extern "Rust" fn ($($args),*) -> Ret, $($args),*);
109+
fn_finalize_one!(extern "C" fn ($($args),*) -> Ret, $($args),*);
110+
fn_finalize_one!(extern "C" fn ($($args),*, ...) -> Ret, $($args),*);
111+
fn_finalize_one!(unsafe extern "Rust" fn ($($args),*) -> Ret, $($args),*);
112+
fn_finalize_one!(unsafe extern "C" fn ($($args),*) -> Ret, $($args),*);
113+
fn_finalize_one!(unsafe extern "C" fn ($($args),*, ...) -> Ret, $($args),*);
114+
}
115+
}
116+
117+
macro_rules! tuple_finalize {
118+
() => {};
119+
($($args:ident),*) => {
120+
impl<$($args),*> Finalize for ($($args,)*) {}
121+
}
122+
}
123+
124+
macro_rules! type_arg_impls {
125+
($(($($args:ident),*);)*) => {
126+
$(
127+
fn_finalize_group!($($args),*);
128+
tuple_finalize!($($args),*);
129+
)*
130+
}
131+
}
132+
133+
type_arg_impls![
134+
();
135+
(A);
136+
(A, B);
137+
(A, B, C);
138+
(A, B, C, D);
139+
(A, B, C, D, E);
140+
(A, B, C, D, E, F);
141+
(A, B, C, D, E, F, G);
142+
(A, B, C, D, E, F, G, H);
143+
(A, B, C, D, E, F, G, H, I);
144+
(A, B, C, D, E, F, G, H, I, J);
145+
(A, B, C, D, E, F, G, H, I, J, K);
146+
(A, B, C, D, E, F, G, H, I, J, K, L);
147+
];
148+
149+
impl<T: Finalize + ?Sized> Finalize for Box<T> {}
150+
impl<T: Finalize> Finalize for Box<[T]> {}
151+
impl<T: Finalize> Finalize for Vec<T> {}
152+
153+
#[cfg(feature = "thin-vec")]
154+
impl<T: Finalize> Finalize for thin_vec::ThinVec<T> {}
155+
156+
impl<T: Finalize> Finalize for Option<T> {}
157+
impl<T: Finalize, E: Finalize> Finalize for Result<T, E> {}
158+
impl<T: Ord + Finalize> Finalize for BinaryHeap<T> {}
159+
impl<K: Finalize, V: Finalize> Finalize for BTreeMap<K, V> {}
160+
impl<T: Finalize> Finalize for BTreeSet<T> {}
161+
impl<T: Finalize> Finalize for LinkedList<T> {}
162+
impl<T: Finalize> Finalize for VecDeque<T> {}
163+
164+
use core::hash::{BuildHasher, Hash};
165+
impl<K: Eq + Hash + Finalize, V: Finalize, S: BuildHasher> Finalize
166+
for hashbrown::hash_map::HashMap<K, V, S>
167+
{
168+
}
169+
170+
#[cfg(feature = "std")]
171+
impl<K: Eq + Hash + Finalize, V: Finalize, S: BuildHasher> Finalize for HashMap<K, V, S> {}
172+
173+
#[cfg(feature = "std")]
174+
impl<T: Eq + Hash + Finalize, S: BuildHasher> Finalize for HashSet<T, S> {}
175+
176+
impl<T: Finalize> Finalize for Cell<Option<T>> {}
177+
impl<T: Finalize> Finalize for OnceCell<T> {}
178+
impl<T: ToOwned + Finalize + ?Sized> Finalize for Cow<'static, T> where T::Owned: Finalize {}
179+
180+
impl<T> Finalize for PhantomData<T> {}

0 commit comments

Comments
 (0)