| 163 | } |
| 164 | |
| 165 | pub fn interpret(&mut self) -> Result<ReturnValue, VmError> { |
| 166 | loop { |
| 167 | const FUEL_PER_GC: i32 = 1024 * 10; |
| 168 | let mut fuel = Fuel::new(FUEL_PER_GC); |
| 169 | // periodically exit the arena in order to collect garbage concurrently with running the VM. |
| 170 | let result = self.arena.mutate_root(|_, state| state.step(&mut fuel)); |
| 171 | |
| 172 | const COLLECTOR_GRANULARITY: f64 = 10240.0; |
| 173 | if self.arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY { |
| 174 | // Do garbage collection. |
| 175 | #[cfg(feature = "debug")] |
| 176 | println!("Collecting..."); |
| 177 | if self.arena.collection_phase() == CollectionPhase::Sweeping { |
| 178 | self.arena.collect_debt(); |
| 179 | } else { |
| 180 | // Immediately transition to `CollectionPhase::Sweeping`. |
| 181 | self.arena.mark_all().unwrap().start_sweeping(); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | match result { |
| 186 | Ok(result) => { |
| 187 | if let Some(value) = result { |
| 188 | return Ok(value); |
| 189 | } |
| 190 | } |
| 191 | Err(err) => return Err(err), |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | #[derive(Copy, Clone)] |