@@ -266,7 +266,7 @@ struct GcHeap {
266
266
config : Arc < GcConfig > ,
267
267
threshold : AtomicUsize ,
268
268
allocator : SimpleAlloc ,
269
- // TODO : This needs to be traced!!
269
+ // NOTE : This is only public so it can be traced
270
270
cached_empty_vec : Cell < Option < * mut GcVecHeader > >
271
271
}
272
272
impl GcHeap {
@@ -768,19 +768,41 @@ impl RawSimpleCollector {
768
768
& self , contexts : & [ * mut RawContext < Self > ]
769
769
) {
770
770
debug_assert ! ( self . manager. is_collecting( ) ) ;
771
- let roots: Vec < * mut dyn DynTrace > = contexts. iter ( )
772
- . flat_map ( |ctx| {
773
- ( * * ctx) . assume_valid_shadow_stack ( )
774
- . reverse_iter ( ) . map ( NonNull :: as_ptr)
775
- } )
776
- . chain ( std:: iter:: once ( & self . handle_list
771
+ let roots = {
772
+ let mut roots: Vec < * mut dyn DynTrace > = Vec :: new ( ) ;
773
+ for ctx in contexts. iter ( ) {
774
+ roots. extend ( ( * * ctx) . assume_valid_shadow_stack ( )
775
+ . reverse_iter ( ) . map ( NonNull :: as_ptr) ) ;
776
+ }
777
+ roots. push ( & self . handle_list
777
778
// Cast to wrapper type
778
779
as * const GcHandleList < Self > as * const GcHandleListWrapper
779
780
// Make into virtual pointer
780
781
as * const dyn DynTrace
781
782
as * mut dyn DynTrace
782
- ) )
783
- . collect ( ) ;
783
+ ) ;
784
+ #[ repr( transparent) ]
785
+ struct CachedEmptyVec ( GcVecHeader ) ;
786
+ unsafe impl DynTrace for CachedEmptyVec {
787
+ fn trace ( & mut self , visitor : & mut MarkVisitor ) {
788
+ let cached_vec_header = self as * mut Self as * mut GcVecHeader ;
789
+ unsafe {
790
+ let target_repr = ( cached_vec_header as * mut u8 )
791
+ . add ( GcVecHeader :: LAYOUT . value_offset ( EMPTY_VEC_ALIGNMENT ) )
792
+ . cast :: < SimpleVecRepr < ( ) > > ( ) ;
793
+ let mut target_gc = * ( & target_repr
794
+ as * const * mut SimpleVecRepr < ( ) >
795
+ as * const Gc < SimpleVecRepr < DynamicObj > > ) ;
796
+ // TODO: Assert not moving?
797
+ let Ok ( ( ) ) = visitor. visit_vec :: < ( ) , _ > ( & mut target_gc) ;
798
+ }
799
+ }
800
+ }
801
+ if let Some ( cached_vec_header) = self . heap . cached_empty_vec . get ( ) {
802
+ roots. push ( cached_vec_header as * mut CachedEmptyVec as * mut dyn DynTrace )
803
+ }
804
+ roots
805
+ } ;
784
806
let num_roots = roots. len ( ) ;
785
807
let mut task = CollectionTask {
786
808
config : & * self . config ,
0 commit comments