@@ -2,6 +2,7 @@ use super::gc::*;
2
2
use crate :: { auto_traits:: HasGc , trace:: GcTypeInfo } ;
3
3
use smallvec:: SmallVec ;
4
4
use std:: ops:: Range ;
5
+ use std:: { mem, ptr} ;
5
6
6
7
/// This will be sound once GAT or const Eq &str lands.
7
8
/// The former will allow transmuting only lifetimes.
@@ -13,19 +14,22 @@ pub unsafe trait Mark<'o, 'n, 'r: 'n, O: 'o, N: 'r> {
13
14
14
15
// Blanket Arena<T> impl is in src/arena.rs
15
16
16
- pub struct Handlers < ' e , E : FnMut ( * const u8 ) > {
17
+ /// Currently just holds Arenas
18
+ pub struct Handlers {
17
19
// 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 > ,
20
24
}
21
25
22
26
pub unsafe trait Condemned {
23
27
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 > (
25
29
s : & Self ,
26
30
grey_feilds : u8 ,
27
31
region : Range < usize > ,
28
- handlers : Handlers < ' e , E > ,
32
+ handlers : & mut Handlers ,
29
33
) ;
30
34
31
35
const PRE_CONDTION : bool ;
@@ -42,13 +46,7 @@ unsafe impl<T> Condemned for T {
42
46
}
43
47
}
44
48
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 ) { }
52
50
53
51
default const PRE_CONDTION : bool = if T :: HAS_GC {
54
52
// 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> {
63
61
0b0000_0000
64
62
}
65
63
const PRE_CONDTION : bool = true ;
66
- fn evacuate < ' e , E : FnMut ( * const u8 ) , const OFFSET : u8 > (
64
+ fn evacuate < ' e , const OFFSET : u8 > (
67
65
s : & Self ,
68
- grey_feilds : u8 ,
66
+ _ : u8 ,
69
67
region : std:: ops:: Range < usize > ,
70
- handlers : Handlers < ' e , E > ,
68
+ handlers : & mut Handlers ,
71
69
) {
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
+ }
73
91
}
74
92
}
75
93
@@ -83,14 +101,14 @@ unsafe impl<T> Condemned for Option<T> {
83
101
}
84
102
}
85
103
86
- fn evacuate < ' e , E : FnMut ( * const u8 ) , const OFFSET : u8 > (
104
+ fn evacuate < ' e , const OFFSET : u8 > (
87
105
s : & Self ,
88
106
grey_feilds : u8 ,
89
107
region : Range < usize > ,
90
- handlers : Handlers < ' e , E > ,
108
+ handlers : & mut Handlers ,
91
109
) {
92
110
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) ,
94
112
None => ( ) ,
95
113
}
96
114
}
0 commit comments