1
Fork 0

const alloc interning: only check for references for arrays/slices

Checking the size/alignment of an mplace may be costly, so we only do it
on the types where the walk we want to avoid could be expensive: the larger types
like arrays and slices, rather than on all aggregates being interned.
This commit is contained in:
Rémy Rakic 2022-06-13 17:35:00 +02:00
parent 18cbc19de2
commit c9772d7619

View file

@ -179,22 +179,26 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
return Ok(false); return Ok(false);
} }
// Now, check whether this alloc contains reference types (as relocations). // Now, check whether this allocation contains reference types (as relocations).
//
// FIXME(lqd): checking the size and alignment could be expensive here, only do the // Note, this check may sometimes not be cheap, so we only do it when the walk we'd like
// following for the potentially bigger aggregates like arrays and slices. // to avoid could be expensive: on the potentially larger types, arrays and slices,
// rather than on all aggregates unconditionally.
if matches!(mplace.layout.ty.kind(), ty::Array(..) | ty::Slice(..)) {
let Some((size, align)) = self.ecx.size_and_align_of_mplace(&mplace)? else { let Some((size, align)) = self.ecx.size_and_align_of_mplace(&mplace)? else {
// We do the walk if we can't determine the size of the mplace: we may be dealing // We do the walk if we can't determine the size of the mplace: we may be
// with extern types here in the future. // dealing with extern types here in the future.
return Ok(true); return Ok(true);
}; };
// If there are no refs or relocations in this allocation, we can avoid the interning // If there are no refs or relocations in this allocation, we can avoid the
// walk. // interning walk.
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? {
&& !alloc.has_relocations() { if !alloc.has_relocations() {
return Ok(false); return Ok(false);
} }
}
}
// In the general case, we do the walk. // In the general case, we do the walk.
Ok(true) Ok(true)