Skip to content

Commit 39866f8

Browse files
committed
remove a fastpath that does not seem to actually help
1 parent 6851060 commit 39866f8

File tree

1 file changed

+31
-46
lines changed

1 file changed

+31
-46
lines changed

src/stacked_borrows/mod.rs

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,10 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
10211021
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
10221022
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
10231023
let this = self.eval_context_mut();
1024+
let retag_fields = this.machine.stacked_borrows.as_mut().unwrap().get_mut().retag_fields;
1025+
let mut visitor = RetagVisitor { ecx: this, kind, retag_fields };
1026+
return visitor.visit_value(place);
1027+
10241028
// Determine mutability and whether to add a protector.
10251029
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
10261030
// making it useless.
@@ -1043,46 +1047,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
10431047
}
10441048
}
10451049

1046-
// For some types we can do the work without starting up the visitor infrastructure.
1047-
if let Some((ref_kind, protector)) = qualify(place.layout.ty, kind) {
1048-
let val = this.read_immediate(&this.place_to_op(place)?)?;
1049-
let val = this.retag_reference(&val, ref_kind, protector)?;
1050-
this.write_immediate(*val, place)?;
1051-
return Ok(());
1052-
}
1053-
1054-
// If we don't want to recurse, we are already done.
1055-
// EXCEPT if this is a `Box`, then we have to recurse because allocators.
1056-
// (Yes this means we technically also recursively retag the allocator itself even if field
1057-
// retagging is not enabled. *shrug*)
1058-
if !this.machine.stacked_borrows.as_mut().unwrap().get_mut().retag_fields
1059-
&& !place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box())
1060-
{
1061-
return Ok(());
1062-
}
1063-
1064-
// Skip some types that have no further structure we might care about.
1065-
if matches!(
1066-
place.layout.ty.kind(),
1067-
ty::RawPtr(..)
1068-
| ty::Ref(..)
1069-
| ty::Int(..)
1070-
| ty::Uint(..)
1071-
| ty::Float(..)
1072-
| ty::Bool
1073-
| ty::Char
1074-
) {
1075-
return Ok(());
1076-
}
1077-
1078-
// Now go visit this thing.
1079-
let mut visitor = RetagVisitor { ecx: this, kind };
1080-
return visitor.visit_value(place);
1081-
10821050
// The actual visitor.
10831051
struct RetagVisitor<'ecx, 'mir, 'tcx> {
10841052
ecx: &'ecx mut MiriEvalContext<'mir, 'tcx>,
10851053
kind: RetagKind,
1054+
retag_fields: bool,
1055+
}
1056+
impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> {
1057+
#[inline(always)] // yes this helps in our benchmarks
1058+
fn retag_place(
1059+
&mut self,
1060+
place: &PlaceTy<'tcx, Tag>,
1061+
ref_kind: RefKind,
1062+
protector: bool,
1063+
) -> InterpResult<'tcx> {
1064+
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
1065+
let val = self.ecx.retag_reference(&val, ref_kind, protector)?;
1066+
self.ecx.write_immediate(*val, place)?;
1067+
Ok(())
1068+
}
10861069
}
10871070
impl<'ecx, 'mir, 'tcx> MutValueVisitor<'mir, 'tcx, Evaluator<'mir, 'tcx>>
10881071
for RetagVisitor<'ecx, 'mir, 'tcx>
@@ -1097,26 +1080,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
10971080
fn visit_box(&mut self, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
10981081
// Boxes do not get a protector: protectors reflect that references outlive the call
10991082
// they were passed in to; that's just not the case for boxes.
1100-
let (ref_kind, protector) = (RefKind::Unique { two_phase: false }, false);
1101-
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
1102-
let val = self.ecx.retag_reference(&val, ref_kind, protector)?;
1103-
self.ecx.write_immediate(*val, place)?;
1104-
Ok(())
1083+
self.retag_place(
1084+
place,
1085+
RefKind::Unique { two_phase: false },
1086+
/*protector*/ false,
1087+
)
11051088
}
11061089

11071090
fn visit_value(&mut self, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
11081091
if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
1109-
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
1110-
let val = self.ecx.retag_reference(&val, ref_kind, protector)?;
1111-
self.ecx.write_immediate(*val, place)?;
1092+
self.retag_place(place, ref_kind, protector)?;
11121093
} else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
11131094
// Wide raw pointers *do* have fields and their types are strange.
11141095
// vtables have a type like `&[*const (); 3]` or so!
11151096
// Do *not* recurse into them.
11161097
// (No need to worry about wide references, those always "qualify". And Boxes
11171098
// are handles specially by the visitor anyway.)
1118-
} else {
1119-
// Recurse deeper.
1099+
} else if self.retag_fields
1100+
|| place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box())
1101+
{
1102+
// Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`.
1103+
// (Yes this means we technically also recursively retag the allocator itself
1104+
// even if field retagging is not enabled. *shrug*)
11201105
self.walk_value(place)?;
11211106
}
11221107
Ok(())

0 commit comments

Comments
 (0)