cgc_single_threaded/
api.rs1use crate::mem::Address;
2use smallvec::SmallVec;
3pub unsafe trait Trace: Finalizer {
4 fn mark(&self);
5 fn unmark(&self);
6 fn references(&self) -> SmallVec<[*const dyn HeapTrait; 64]>;
7}
8
9#[derive(Default)]
10pub struct Tracer {
11 stack: SmallVec<[*const dyn HeapTrait; 64]>,
12}
13impl Tracer {
14 pub fn for_each(&mut self, mut f: impl FnMut(*const dyn HeapTrait)) {
15 while let Some(item) = self.stack.pop() {
16 f(item);
17 }
18 }
20
21 pub fn trace(&mut self, item: *const dyn HeapTrait) {
22 self.stack.push(item);
23 }
24}
25
26pub trait Traceable
27where
28 Self: Finalizer,
29{
30 fn trace_with(&self, _: &mut Tracer) {}
31}
32
33unsafe impl<T: Traceable> Trace for T {
34 fn mark(&self) {
35 let mut tracer = Tracer::default();
36 self.trace_with(&mut tracer);
37 tracer.for_each(|pointer| unsafe { (*pointer).mark() });
38 }
39 fn unmark(&self) {
40 let mut tracer = Tracer::default();
41 self.trace_with(&mut tracer);
42 tracer.for_each(|pointer| unsafe { (*pointer).unmark() });
43 }
44
45 fn references(&self) -> SmallVec<[*const dyn HeapTrait; 64]> {
46 let mut tracer = Tracer::default();
47 self.trace_with(&mut tracer);
48 tracer.stack
49 }
50}
51
52pub unsafe trait HeapTrait {
53 fn mark(&self);
54 fn unmark(&self);
55 fn slot(&self) -> Address;
56 fn get_fwd(&self) -> Address;
57 fn set_fwd(&self, _: Address);
58 fn copy_to(&self, addr: Address);
59 fn addr(&self) -> Address;
60 fn inner(&self) -> *mut crate::heap::HeapInner<dyn Trace>;
61
62 fn is_marked(&self) -> bool;
63}
64
65pub trait Finalizer {
66 fn finalize(&mut self) {}
67}
68
69macro_rules! simple {
70 ($($t: ty)*) => {
71 $(
72 impl Traceable for $t {}
73 impl Finalizer for $t {}
74 )*
75 };
76}
77
78simple!(
79 i8
80 i16
81 i32
82 i64
83 i128
84 u8
85 u16
86 u32
87 u64
88 u128
89 f64
90 f32
91 bool
92 String
93 isize
94 usize
95 std::fs::File
96 std::fs::FileType
97 std::fs::Metadata
98 std::fs::OpenOptions
99 std::io::Stdin
100 std::io::Stdout
101 std::io::Stderr
102 std::io::Error
103 std::net::TcpStream
104 std::net::TcpListener
105 std::net::UdpSocket
106 std::net::Ipv4Addr
107 std::net::Ipv6Addr
108 std::net::SocketAddrV4
109 std::net::SocketAddrV6
110 std::path::Path
111 std::path::PathBuf
112 std::process::Command
113 std::process::Child
114 std::process::ChildStdout
115 std::process::ChildStdin
116 std::process::ChildStderr
117 std::process::Output
118 std::process::ExitStatus
119 std::process::Stdio
120 std::sync::Barrier
121 std::sync::Condvar
122 std::sync::Once
123 std::ffi::CStr
124 std::ffi::CString
125 &'static str
126);
127
128impl<T: Traceable> Traceable for Option<T> {
129 fn trace_with(&self, tracer: &mut Tracer) {
130 if let Some(item) = self {
131 item.trace_with(tracer);
132 }
133 }
134}
135impl<T: Traceable> Finalizer for Option<T> {
136 fn finalize(&mut self) {
137 if let Some(item) = self {
138 item.finalize();
139 }
140 }
141}
142
143impl<T: Traceable> Traceable for Vec<T> {
144 fn trace_with(&self, tracer: &mut Tracer) {
145 for item in self.iter() {
146 item.trace_with(tracer);
147 }
148 }
149}
150
151impl<T: HeapTrait + Finalizer + 'static> Traceable for T {
152 fn trace_with(&self, tracer: &mut Tracer) {
153 tracer.trace(self as *const dyn HeapTrait);
154 }
155}
156
157impl<T: Finalizer> Finalizer for Vec<T> {
158 fn finalize(&mut self) {
159 for item in self.iter_mut() {
160 item.finalize();
161 }
162 }
163}
164
165pub trait RootedTrait
166where
167 Self: HeapTrait,
168{
169 fn is_rooted(&self) -> bool;
170 fn references(&self) -> SmallVec<[*const dyn HeapTrait; 64]>;
171}
172
173pub struct Rooted<T: Trace + ?Sized> {
174 pub(crate) inner: *mut RootedInner<T>,
175}
176
177impl<T: Trace + ?Sized> Rooted<T> {
178 fn inner(&self) -> &mut RootedInner<T> {
179 unsafe { &mut *self.inner }
180 }
181 pub fn to_heap(&self) -> Handle<T> {
182 Handle {
183 inner: self.inner().inner,
184 }
185 }
186 pub fn get(&self) -> &T {
187 unsafe { &(&*self.inner().inner).value }
188 }
189 pub fn get_mut(&self) -> &mut T {
190 unsafe { &mut (&mut *self.inner().inner).value }
191 }
192}
193
194pub(crate) struct RootedInner<T: Trace + ?Sized> {
195 pub(crate) counter: u32,
196 pub(crate) inner: *mut crate::heap::HeapInner<T>,
197}
198impl<T: Trace + ?Sized> Drop for Rooted<T> {
199 fn drop(&mut self) {
200 unsafe {
201 debug_assert!(!self.inner.is_null());
202 let inner = &mut *self.inner;
203 inner.counter = inner.counter.wrapping_sub(1);
204 }
205 }
206}
207
208impl<T: Trace + ?Sized> Clone for Rooted<T> {
209 fn clone(&self) -> Self {
210 unsafe {
211 let inner = &mut *self.inner;
212 inner.counter = inner.counter + 1;
213 Rooted {
214 inner: inner as *mut _,
215 }
216 }
217 }
218}
219
220unsafe impl<T: Trace + Sized + 'static> HeapTrait for RootedInner<T> {
221 fn mark(&self) {
222 unsafe {
223 (&mut *self.inner).mark(true);
224 }
225 }
226
227 fn unmark(&self) {
228 unsafe {
229 (&mut *self.inner).mark(false);
230 }
231 }
232 fn get_fwd(&self) -> Address {
233 unsafe { (&*self.inner).fwdptr() }
234 }
235
236 fn set_fwd(&self, fwd: Address) {
237 unsafe {
238 (&mut *self.inner).set_fwdptr(fwd);
239 }
240 }
241
242 fn copy_to(&self, addr: Address) {
243 debug_assert!(addr.is_non_null() && !self.inner.is_null());
244 unsafe {
245 std::ptr::copy(
246 self.inner as *const u8,
247 addr.to_mut_ptr(),
248 std::mem::size_of_val(&*self.inner),
249 )
250 }
251 }
252 fn slot(&self) -> Address {
253 debug_assert!(!self.inner.is_null());
254 let slot = &self.inner;
255 Address::from_ptr(slot)
256 }
257 fn addr(&self) -> Address {
258 Address::from_ptr(self.inner as *const u8)
259 }
260 fn is_marked(&self) -> bool {
261 unsafe { (&*self.inner).is_marked() }
262 }
263 fn inner(&self) -> *mut crate::heap::HeapInner<dyn Trace> {
264 self.inner
265 }
266}
267
268impl<T: Trace + Sized + 'static> RootedTrait for RootedInner<T> {
269 fn is_rooted(&self) -> bool {
270 self.counter >= 1
271 }
272 fn references(&self) -> SmallVec<[*const dyn HeapTrait; 64]> {
273 unsafe { (&*self.inner).value.references() }
274 }
275}
276
277pub struct Handle<T: Trace + ?Sized> {
281 pub(crate) inner: *mut crate::heap::HeapInner<T>,
282}
283impl<T: Trace + ?Sized> From<Rooted<T>> for Handle<T> {
284 fn from(x: Rooted<T>) -> Self {
285 unsafe {
286 Self {
287 inner: (*x.inner).inner,
288 }
289 }
290 }
291}
292
293impl<T: Trace + ?Sized> From<&Rooted<T>> for Handle<T> {
294 fn from(x: &Rooted<T>) -> Self {
295 unsafe {
296 Self {
297 inner: (*x.inner).inner,
298 }
299 }
300 }
301}
302
303impl<T: Trace + ?Sized> Handle<T> {
304 pub fn get(&self) -> &T {
305 unsafe {
306 debug_assert!(!self.inner.is_null());
307 let inner = &*self.inner;
308 &inner.value
309 }
310 }
311
312 pub fn get_mut(&mut self) -> &mut T {
321 unsafe {
322 let inner = &mut *self.inner;
323 &mut inner.value
324 }
325 }
326}
327
328unsafe impl<T: Trace + Sized + 'static> HeapTrait for Handle<T> {
329 fn copy_to(&self, addr: Address) {
330 debug_assert!(addr.is_non_null() && !self.inner.is_null());
331 unsafe {
332 std::ptr::copy(
333 self.inner as *const u8,
334 addr.to_mut_ptr(),
335 std::mem::size_of_val(&*self.inner),
336 )
337 }
338 }
339 fn mark(&self) {
340 unsafe {
341 (&mut *self.inner).mark(true);
342 }
343 }
344 fn unmark(&self) {
345 unsafe {
346 (&mut *self.inner).mark(false);
347 }
348 }
349 fn get_fwd(&self) -> Address {
350 unsafe { (&*self.inner).fwdptr() }
351 }
352
353 fn set_fwd(&self, fwd: Address) {
354 unsafe {
355 (&mut *self.inner).set_fwdptr(fwd);
356 }
357 }
358 fn slot(&self) -> Address {
359 debug_assert!(!self.inner.is_null());
360 let slot = &self.inner;
361 Address::from_ptr(slot)
362 }
363 fn addr(&self) -> Address {
364 Address::from_ptr(self.inner as *const u8)
365 }
366 fn is_marked(&self) -> bool {
367 unsafe { (&*self.inner).is_marked() }
368 }
369 fn inner(&self) -> *mut crate::heap::HeapInner<dyn Trace> {
370 self.inner
371 }
372}
373impl<T: Trace> Copy for Handle<T> {}
374impl<T: Trace> Clone for Handle<T> {
375 fn clone(&self) -> Self {
376 *self
377 }
378}
379
380use std::cmp;
381
382impl<T: Trace + PartialOrd> PartialOrd for Handle<T> {
383 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
384 self.get().partial_cmp(other.get())
385 }
386}
387
388impl<T: Trace + Ord> Ord for Handle<T> {
389 fn cmp(&self, other: &Self) -> cmp::Ordering {
390 self.get().cmp(other.get())
391 }
392}
393
394impl<T: Trace + PartialEq> PartialEq for Handle<T> {
395 fn eq(&self, other: &Self) -> bool {
396 self.get().eq(other.get())
397 }
398}
399
400impl<T: Trace + Eq> Eq for Handle<T> {}
401
402use std::hash::{Hash, Hasher};
403
404impl<T: Trace + Hash> Hash for Handle<T> {
405 fn hash<H: Hasher>(&self, state: &mut H) {
406 self.get().hash(state);
407 }
408}
409
410use std::fmt;
411
412impl<T: Trace + fmt::Display> fmt::Display for Handle<T> {
413 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
414 self.get().fmt(f)
415 }
416}
417
418impl<T: Trace + fmt::Debug> fmt::Debug for Handle<T> {
419 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420 self.get().fmt(f)
421 }
422}
423
424impl<T: Trace + PartialOrd> PartialOrd for Rooted<T> {
425 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
426 self.get().partial_cmp(other.get())
427 }
428}
429
430impl<T: Trace + Ord> Ord for Rooted<T> {
431 fn cmp(&self, other: &Self) -> cmp::Ordering {
432 self.get().cmp(other.get())
433 }
434}
435
436impl<T: Trace + PartialEq> PartialEq for Rooted<T> {
437 fn eq(&self, other: &Self) -> bool {
438 self.get().eq(other.get())
439 }
440}
441
442impl<T: Trace + Eq> Eq for Rooted<T> {}
443
444impl<T: Trace + Hash> Hash for Rooted<T> {
445 fn hash<H: Hasher>(&self, state: &mut H) {
446 self.get().hash(state);
447 }
448}
449
450impl<T: Trace + fmt::Display> fmt::Display for Rooted<T> {
451 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452 self.get().fmt(f)
453 }
454}
455
456impl<T: Trace + fmt::Debug> fmt::Debug for Rooted<T> {
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 write!(f, "{:?}", self.get())
459 }
460}
461
462impl<T: Trace> Finalizer for Handle<T> {
463 fn finalize(&mut self) {}
464}
465
466impl<T: Traceable> Finalizer for Rooted<T> {
467 fn finalize(&mut self) {
468 self.get_mut().finalize();
469 }
470}
471
472use std::ops::{Deref, DerefMut};
473
474impl<T: Traceable> Deref for Rooted<T> {
475 type Target = T;
476 fn deref(&self) -> &T {
477 self.get()
478 }
479}
480
481impl<T: Traceable> DerefMut for Rooted<T> {
482 fn deref_mut(&mut self) -> &mut T {
483 self.get_mut()
484 }
485}
486
487impl<T: Traceable> Deref for Handle<T> {
488 type Target = T;
489 fn deref(&self) -> &T {
490 self.get()
491 }
492}
493
494impl<T: Traceable> DerefMut for Handle<T> {
495 fn deref_mut(&mut self) -> &mut T {
496 self.get_mut()
497 }
498}