From 7d63e4303e1764cd133c77b430a2fccf7ee86c78 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 13 Jul 2023 10:43:31 +0200 Subject: [PATCH 1/3] perf: don't deinit protected fn args --- compiler/rustc_const_eval/src/interpret/machine.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index e101785b6e242..4748c502ddca3 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -421,13 +421,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Called on places used for in-place function argument and return value handling. /// /// These places need to be protected to make sure the program cannot tell whether the - /// argument/return value was actually copied or passed in-place.. + /// argument/return value was actually copied or passed in-place. fn protect_in_place_function_argument( ecx: &mut InterpCx<'mir, 'tcx, Self>, place: &PlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { // Without an aliasing model, all we can do is put `Uninit` into the place. - ecx.write_uninit(place) + // This can only be violated with custom MIR though so we avoid the perf hit. + if ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks { + ecx.write_uninit(place)?; + } + Ok(()) } /// Called immediately before a new stack frame gets pushed. From 0ee0889f2c6fbdbf0d63d221c2a2312f55c13956 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 13 Jul 2023 10:43:52 +0200 Subject: [PATCH 2/3] interpret: avoid some clone() in argument handling --- .../rustc_const_eval/src/interpret/terminator.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 97d7a68e190b9..9e1a87ce3620f 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -40,13 +40,13 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> { impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. - pub fn copy_fn_arg( + pub fn copy_fn_arg<'a>( &self, - arg: &FnArg<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { + arg: &'a FnArg<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, Cow<'a, OpTy<'tcx, M::Provenance>>> { match arg { - FnArg::Copy(op) => Ok(op.clone()), - FnArg::InPlace(place) => self.place_to_op(&place), + FnArg::Copy(op) => Ok(Cow::Borrowed(op)), + FnArg::InPlace(place) => Ok(Cow::Owned(self.place_to_op(&place)?)), } } @@ -56,7 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, args: &[FnArg<'tcx, M::Provenance>], ) -> InterpResult<'tcx, Vec>> { - args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect() + args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg).map(|x| x.into_owned())).collect() } pub fn fn_arg_field( @@ -637,7 +637,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // An `InPlace` does nothing here, we keep the original receiver intact. We can't // really pass the argument in-place anyway, and we are constructing a new // `Immediate` receiver. - let mut receiver = self.copy_fn_arg(&args[0])?; + let mut receiver = self.copy_fn_arg(&args[0])?.into_owned(); let receiver_place = loop { match receiver.layout.ty.kind() { ty::Ref(..) | ty::RawPtr(..) => { From 9834a419e985ea198a5af1d306197eda1fe5aa64 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 18 Jul 2023 18:46:51 +0200 Subject: [PATCH 3/3] TEMP: try to reproduce earlier perf results --- compiler/rustc_const_eval/src/interpret/machine.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 4748c502ddca3..60fd8995b4602 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -423,14 +423,14 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// These places need to be protected to make sure the program cannot tell whether the /// argument/return value was actually copied or passed in-place. fn protect_in_place_function_argument( - ecx: &mut InterpCx<'mir, 'tcx, Self>, - place: &PlaceTy<'tcx, Self::Provenance>, + _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _place: &PlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { // Without an aliasing model, all we can do is put `Uninit` into the place. // This can only be violated with custom MIR though so we avoid the perf hit. - if ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks { - ecx.write_uninit(place)?; - } + //if ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks { + // ecx.write_uninit(place)?; + //} Ok(()) }