Skip to content

Commit 0ca8cbc

Browse files
committed
Evacuate Gc<T>
1 parent 2e77f8b commit 0ca8cbc

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

src/mark.rs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::gc::*;
22
use crate::{auto_traits::HasGc, trace::GcTypeInfo};
33
use smallvec::SmallVec;
44
use std::ops::Range;
5+
use std::{mem, ptr};
56

67
/// This will be sound once GAT or const Eq &str lands.
78
/// The former will allow transmuting only lifetimes.
@@ -13,19 +14,22 @@ pub unsafe trait Mark<'o, 'n, 'r: 'n, O: 'o, N: 'r> {
1314

1415
// Blanket Arena<T> impl is in src/arena.rs
1516

16-
pub struct Handlers<'e, E: FnMut(*const u8)> {
17+
/// Currently just holds Arenas
18+
pub struct Handlers {
1719
// TODO benchmark sizes
18-
translation: &'e SmallVec<[u8; 16]>,
19-
effects: &'e mut SmallVec<[E; 4]>,
20+
translation: SmallVec<[u8; 16]>,
21+
nexts: SmallVec<[*mut u8; 4]>,
22+
/// forward(old, new) -> already evacuated
23+
forward: fn(*const u8, *const u8) -> Option<*const u8>,
2024
}
2125

2226
pub unsafe trait Condemned {
2327
fn feilds(s: &Self, grey_feilds: u8, region: Range<usize>) -> u8;
24-
fn evacuate<'e, E: FnMut(*const u8), const OFFSET: u8>(
28+
fn evacuate<'e, const OFFSET: u8>(
2529
s: &Self,
2630
grey_feilds: u8,
2731
region: Range<usize>,
28-
handlers: Handlers<'e, E>,
32+
handlers: &mut Handlers,
2933
);
3034

3135
const PRE_CONDTION: bool;
@@ -42,13 +46,7 @@ unsafe impl<T> Condemned for T {
4246
}
4347
}
4448

45-
default fn evacuate<'e, E: FnMut(*const u8), const OFFSET: u8>(
46-
_: &Self,
47-
_: u8,
48-
_: Range<usize>,
49-
_: Handlers<'e, E>,
50-
) {
51-
}
49+
default fn evacuate<'e, const OFFSET: u8>(_: &Self, _: u8, _: Range<usize>, _: &mut Handlers) {}
5250

5351
default const PRE_CONDTION: bool = if T::HAS_GC {
5452
// TODO When fmt is allowed in const s/your type/type_name::<T>()
@@ -63,13 +61,33 @@ unsafe impl<'r, T> Condemned for Gc<'r, T> {
6361
0b0000_0000
6462
}
6563
const PRE_CONDTION: bool = true;
66-
fn evacuate<'e, E: FnMut(*const u8), const OFFSET: u8>(
64+
fn evacuate<'e, const OFFSET: u8>(
6765
s: &Self,
68-
grey_feilds: u8,
66+
_: u8,
6967
region: std::ops::Range<usize>,
70-
handlers: Handlers<'e, E>,
68+
handlers: &mut Handlers,
7169
) {
72-
todo!()
70+
let ptr = s.ptr as *const T;
71+
let addr = ptr as usize;
72+
if region.contains(&addr) {
73+
let i = handlers.translation[OFFSET as usize];
74+
if let Some(next) = handlers.nexts.get_mut(i as usize) {
75+
unsafe { ptr::copy_nonoverlapping(ptr, *next as *mut T, 1) }
76+
let forward = handlers.forward;
77+
if let Some(pre_evac) = forward(ptr as *const u8, *next as *const u8) {
78+
let r = s as *const Gc<T> as *mut *const T;
79+
unsafe {
80+
*r = pre_evac as *const T;
81+
}
82+
} else {
83+
let r = s as *const Gc<T> as *mut *const T;
84+
unsafe {
85+
*r = *next as *const T;
86+
}
87+
*next = (addr + mem::size_of::<T>()) as *mut u8;
88+
}
89+
}
90+
}
7391
}
7492
}
7593

@@ -83,14 +101,14 @@ unsafe impl<T> Condemned for Option<T> {
83101
}
84102
}
85103

86-
fn evacuate<'e, E: FnMut(*const u8), const OFFSET: u8>(
104+
fn evacuate<'e, const OFFSET: u8>(
87105
s: &Self,
88106
grey_feilds: u8,
89107
region: Range<usize>,
90-
handlers: Handlers<'e, E>,
108+
handlers: &mut Handlers,
91109
) {
92110
match s {
93-
Some(t) => Condemned::evacuate::<E, OFFSET>(t, grey_feilds, region, handlers),
111+
Some(t) => Condemned::evacuate::<OFFSET>(t, grey_feilds, region, handlers),
94112
None => (),
95113
}
96114
}

0 commit comments

Comments
 (0)