From 9f3bc82fe40fd38fadfd24b7968548929abc9d4c Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 19 Feb 2020 07:59:21 -0500 Subject: [PATCH] Check `RUSTC_CTFE_BACKTRACE` much less by generating fewer errors Before this change, `get_size_and_align()` calls `get_fn_alloc()` *a lot* in CTFE heavy code. This previously returned an `Error` which would check if `RUSTC_CTFE_BACKTRACE` was set on construction. Doing this turned out to be a performance hotspot as @nnethercote discovered in #68792. This is an alternate take on that PR which resolves the performance issue by generating *many* fewer errors. Previously, `ctfe-stress-4` would generate over 5,000,000 errors each of which would check for the presence of the environment variable. With these changes, that number is reduced to 30. --- src/librustc_mir/interpret/memory.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 0bcdf9ae3c1f2..1df389d9c8bee 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -560,7 +560,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // # Function pointers // (both global from `alloc_map` and local from `extra_fn_ptr_map`) - if let Ok(_) = self.get_fn_alloc(id) { + if let Some(_) = self.get_fn_alloc(id) { return if let AllocCheck::Dereferenceable = liveness { // The caller requested no function pointers. throw_unsup!(DerefFunctionPointer) @@ -602,14 +602,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } } - fn get_fn_alloc(&self, id: AllocId) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { + fn get_fn_alloc(&self, id: AllocId) -> Option> { trace!("reading fn ptr: {}", id); if let Some(extra) = self.extra_fn_ptr_map.get(&id) { - Ok(FnVal::Other(*extra)) + Some(FnVal::Other(*extra)) } else { match self.tcx.alloc_map.lock().get(id) { - Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => throw_unsup!(ExecuteMemory), + Some(GlobalAlloc::Function(instance)) => Some(FnVal::Instance(instance)), + _ => None, } } } @@ -622,7 +622,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if ptr.offset.bytes() != 0 { throw_unsup!(InvalidFunctionPointer) } - self.get_fn_alloc(ptr.alloc_id) + self.get_fn_alloc(ptr.alloc_id).ok_or_else(|| err_unsup!(ExecuteMemory).into()) } pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {