From c9772d76198ec04c9e610ce5d95bb9453021aa1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 13 Jun 2022 17:35:00 +0200 Subject: [PATCH] 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. --- .../rustc_const_eval/src/interpret/intern.rs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index b243f07edff6..2655568090c8 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -179,21 +179,25 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory return Ok(false); } - // Now, check whether this alloc contains reference types (as relocations). + // Now, check whether this allocation contains reference types (as relocations). + // + // Note, this check may sometimes not be cheap, so we only do it when the walk we'd like + // 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 { + // We do the walk if we can't determine the size of the mplace: we may be + // dealing with extern types here in the future. + return Ok(true); + }; - // FIXME(lqd): checking the size and alignment could be expensive here, only do the - // following for the potentially bigger aggregates like arrays and slices. - 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 - // with extern types here in the future. - return Ok(true); - }; - - // If there are no refs or relocations in this allocation, we can avoid the interning - // walk. - if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? - && !alloc.has_relocations() { - return Ok(false); + // If there are no refs or relocations in this allocation, we can avoid the + // interning walk. + if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? { + if !alloc.has_relocations() { + return Ok(false); + } + } } // In the general case, we do the walk.