Skip to content

Commit c9772d7

Browse files
committed
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.
1 parent 18cbc19 commit c9772d7

File tree

1 file changed

+18
-14
lines changed
  • compiler/rustc_const_eval/src/interpret

1 file changed

+18
-14
lines changed

compiler/rustc_const_eval/src/interpret/intern.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -179,21 +179,25 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
179179
return Ok(false);
180180
}
181181

182-
// Now, check whether this alloc contains reference types (as relocations).
183-
184-
// FIXME(lqd): checking the size and alignment could be expensive here, only do the
185-
// following for the potentially bigger aggregates like arrays and slices.
186-
let Some((size, align)) = self.ecx.size_and_align_of_mplace(&mplace)? else {
187-
// We do the walk if we can't determine the size of the mplace: we may be dealing
188-
// with extern types here in the future.
189-
return Ok(true);
190-
};
182+
// Now, check whether this allocation contains reference types (as relocations).
183+
//
184+
// Note, this check may sometimes not be cheap, so we only do it when the walk we'd like
185+
// to avoid could be expensive: on the potentially larger types, arrays and slices,
186+
// rather than on all aggregates unconditionally.
187+
if matches!(mplace.layout.ty.kind(), ty::Array(..) | ty::Slice(..)) {
188+
let Some((size, align)) = self.ecx.size_and_align_of_mplace(&mplace)? else {
189+
// We do the walk if we can't determine the size of the mplace: we may be
190+
// dealing with extern types here in the future.
191+
return Ok(true);
192+
};
191193

192-
// If there are no refs or relocations in this allocation, we can avoid the interning
193-
// walk.
194-
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)?
195-
&& !alloc.has_relocations() {
196-
return Ok(false);
194+
// If there are no refs or relocations in this allocation, we can avoid the
195+
// interning walk.
196+
if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? {
197+
if !alloc.has_relocations() {
198+
return Ok(false);
199+
}
200+
}
197201
}
198202

199203
// In the general case, we do the walk.

0 commit comments

Comments
 (0)