1 use rustc_data_structures::fx::FxHashSet;
5 pub trait VisitMachineValues {
6 fn visit_machine_values(&self, visit: &mut impl FnMut(&Operand<Provenance>));
9 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
10 pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
11 /// Generic GC helper to visit everything that can store a value. The `acc` offers some chance to
12 /// accumulate everything.
13 fn visit_all_machine_values<T>(
16 mut visit_operand: impl FnMut(&mut T, &Operand<Provenance>),
17 mut visit_alloc: impl FnMut(&mut T, &Allocation<Provenance, AllocExtra>),
19 let this = self.eval_context_ref();
22 this.memory.alloc_map().iter(|it| {
23 for (_id, (_kind, alloc)) in it {
24 visit_alloc(acc, alloc);
28 // And all the other machine values.
29 this.machine.visit_machine_values(&mut |op| visit_operand(acc, op));
32 fn garbage_collect_tags(&mut self) -> InterpResult<'tcx> {
33 let this = self.eval_context_mut();
34 // No reason to do anything at all if stacked borrows is off.
35 if this.machine.stacked_borrows.is_none() {
39 let mut tags = FxHashSet::default();
41 let visit_scalar = |tags: &mut FxHashSet<SbTag>, s: &Scalar<Provenance>| {
42 if let Scalar::Ptr(ptr, _) = s {
43 if let Provenance::Concrete { sb, .. } = ptr.provenance {
49 this.visit_all_machine_values(
53 Operand::Immediate(Immediate::Scalar(s)) => {
54 visit_scalar(tags, s);
56 Operand::Immediate(Immediate::ScalarPair(s1, s2)) => {
57 visit_scalar(tags, s1);
58 visit_scalar(tags, s2);
60 Operand::Immediate(Immediate::Uninit) => {}
61 Operand::Indirect(MemPlace { ptr, .. }) => {
62 if let Some(Provenance::Concrete { sb, .. }) = ptr.provenance {
69 for (_size, prov) in alloc.provenance().iter() {
70 if let Provenance::Concrete { sb, .. } = prov {
77 self.remove_unreachable_tags(tags);
82 fn remove_unreachable_tags(&mut self, tags: FxHashSet<SbTag>) {
83 let this = self.eval_context_mut();
84 this.memory.alloc_map().iter(|it| {
85 for (_id, (_kind, alloc)) in it {
92 .remove_unreachable_tags(&tags);