pub(crate) unsafe fn collect(&mut self, roots: impl Iterator<Item = RawValue>) {
      unsafe fn mark_all_unreachable<T>(memories: impl Iterator<Item = GcRaw<T>>) {
         for memory in memories {
            let mem = memory.get_mem();
            mem.reachable.set(false);
         }
      }

      // unsafe fn mark_reachable_rec(value: RawValue) {
      // }

      unsafe fn sweep_unreachable<T>(memories: &mut Vec<GcRaw<T>>, allocated_bytes: &mut usize) {
         let mut i = 0;
         while i < memories.len() {
            let memory = memories[i];
            let mem = memory.get_mem();
            if !mem.reachable.get() {
               GcMem::release(memory);
               *allocated_bytes -= mem.data_size;
               #[cfg(feature = "trace-gc")]
               {
                  println!(
                     "gc | freed {} bytes, now at {}",
                     mem.data_size, *allocated_bytes
                  );
               }
               memories.swap_remove(i);
            } else {
               i += 1;
            }
         }
      }

      // NOTE: Marking all objects as unreachable beforehand is *somehow* faster than doing it
      // during the sweep phase. I believe it might have something to do with the objects being
      // loaded into the CPU cache but I'm really not sure.
      mark_all_unreachable(self.allocations.iter().copied());
      for value in roots {
         self.gray_stack.push(value);
         self.mark_all_gray_reachable();
      }
      sweep_unreachable(&mut self.allocations, &mut self.allocated_bytes);
   }
/// Marks and sweeps unused allocations.
///
/// # Safety
/// All root pointers in values yielded by the iterator must be valid.
Marks and sweeps unused allocations.
Marks and sweeps unused allocations .
pub(crate) unsafe fn collect(&mut self, roots: impl Iterator<Item = RawValue>) {
      unsafe fn mark_all_unreachable<T>(memories: impl Iterator<Item = GcRaw<T>>) {
         for memory in memories {
            let mem = memory.get_mem();
            mem.reachable.set(false);
         }
      }
      // unsafe fn mark_reachable_rec(value: RawValue) {
      // }
      unsafe fn sweep_unreachable<T>(memories: &mut Vec<GcRaw<T>>, allocated_bytes: &mut usize) {
         let mut i = 0;
         while i < memories.len() {
            let memory = memories[i];
            let mem = memory.get_mem();
            if !mem.reachable.get() {
               GcMem::release(memory);
               *allocated_bytes -= mem.data_size;
               #[cfg(feature = "trace-gc")]
               {
                  println!(
                     "gc | freed {} bytes, now at {}",
                     mem.data_size, *allocated_bytes
                  );
               }
               memories.swap_remove(i);
            } else {
               i += 1;
            }
         }
      }
      // NOTE: Marking all objects as unreachable beforehand is *somehow* faster than doing it
      // during the sweep phase. I believe it might have something to do with the objects being
      // loaded into the CPU cache but I'm really not sure.
      mark_all_unreachable(self.allocations.iter().copied());
      for value in roots {
         self.gray_stack.push(value);
         self.mark_all_gray_reachable();
      }
      sweep_unreachable(&mut self.allocations, &mut self.allocated_bytes);
   }
pub ( crate ) unsafe fn collect ( & mut self , roots : impl Iterator < Item = RawValue > ) { unsafe fn mark_all_unreachable < T > ( memories : impl Iterator < Item = GcRaw < T > > ) { for memory in memories { let mem = memory . get_mem ( ) ; mem . reachable . set ( false ) ; } } // unsafe fn mark_reachable_rec(value: RawValue) { // } unsafe fn sweep_unreachable < T > ( memories : & mut Vec < GcRaw < T > > , allocated_bytes : & mut usize ) { let mut i = 0 ; while i < memories . len ( ) { let memory = memories [ i ] ; let mem = memory . get_mem ( ) ; if ! mem . reachable . get ( ) { GcMem :: release ( memory ) ; * allocated_bytes -= mem . data_size ; # [ cfg ( feature " " ) ] { println ! ( " " mem data_size allocated_bytes ) ; } memories . swap_remove ( i ) ; } else { i += 1 ; } } } // NOTE: Marking all objects as unreachable beforehand is *somehow* faster than doing it // during the sweep phase. I believe it might have something to do with the objects being // loaded into the CPU cache but I'm really not sure. mark_all_unreachable ( self . allocations . iter ( ) . copied ( ) ) ; for value in roots { self . gray_stack . push ( value ) ; self . mark_all_gray_reachable ( ) ; } sweep_unreachable ( & mut self . allocations , & mut self . allocated_bytes ) ; }
Marks and sweeps unused allocations.
Marks and sweeps unused allocations .
&mut self
roots
impl Iterator<Item = RawValue>
safety
All root pointers in values yielded by the iterator must be valid.
All root pointers in values yielded by the iterator must be valid .