diff options
| author | Wesley Wiser <wwiser@gmail.com> | 2020-02-19 07:59:21 -0500 |
|---|---|---|
| committer | Wesley Wiser <wwiser@gmail.com> | 2020-02-19 18:28:37 -0500 |
| commit | 9f3bc82fe40fd38fadfd24b7968548929abc9d4c (patch) | |
| tree | b3e01662a61cb256a36713f5fed3c15068a8afea | |
| parent | ae5467826d1e677aff4662fc0481ace33761fc90 (diff) | |
| download | rust-9f3bc82fe40fd38fadfd24b7968548929abc9d4c.tar.gz rust-9f3bc82fe40fd38fadfd24b7968548929abc9d4c.zip | |
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.
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 0bcdf9ae3c1..1df389d9c8b 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<FnVal<'tcx, M::ExtraFnVal>> { 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> { |
