Auto merge of #99677 - pietroalbini:pa-fix-97786-perf-regression, r=Mark-Simulacrum

Remove new allocations from `imported_source_files`

https://github.com/rust-lang/rust/pull/97786 introduced a [large performance regression](https://github.com/rust-lang/rust/pull/97786#issuecomment-1176552836). After some local investigation it turns out the allocations performed by my change were the cause of the perf regression. This PR refactors my change to remove those allocations.
This commit is contained in:
bors 2022-07-26 07:29:29 +00:00
commit 96b9bb4620

View file

@ -41,7 +41,7 @@ use std::io;
use std::iter::TrustedLen;
use std::mem;
use std::num::NonZeroUsize;
use std::path::PathBuf;
use std::path::Path;
use tracing::debug;
pub(super) use cstore_impl::provide;
@ -1474,30 +1474,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
/// Proc macro crates don't currently export spans, so this function does not have
/// to work for them.
fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
fn filter<'a>(sess: &Session, path: Option<&'a Path>) -> Option<&'a Path> {
path.filter(|_| {
// Only spend time on further checks if we have what to translate *to*.
sess.opts.real_rust_source_base_dir.is_some()
// Some tests need the translation to be always skipped.
&& sess.opts.unstable_opts.translate_remapped_path_to_local_path
})
.filter(|virtual_dir| {
// Don't translate away `/rustc/$hash` if we're still remapping to it,
// since that means we're still building `std`/`rustc` that need it,
// and we don't want the real path to leak into codegen/debuginfo.
!sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
})
}
// Translate the virtual `/rustc/$hash` prefix back to a real directory
// that should hold actual sources, where possible.
//
// NOTE: if you update this, you might need to also update bootstrap's code for generating
// the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
let virtual_rust_source_base_dir = [
option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
sess.opts.unstable_opts.simulate_remapped_rust_src_base.clone(),
]
.into_iter()
.filter(|_| {
// Only spend time on further checks if we have what to translate *to*.
sess.opts.real_rust_source_base_dir.is_some()
// Some tests need the translation to be always skipped.
&& sess.opts.unstable_opts.translate_remapped_path_to_local_path
})
.flatten()
.filter(|virtual_dir| {
// Don't translate away `/rustc/$hash` if we're still remapping to it,
// since that means we're still building `std`/`rustc` that need it,
// and we don't want the real path to leak into codegen/debuginfo.
!sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
})
.collect::<Vec<_>>();
filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)),
filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()),
];
let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
debug!(
@ -1506,7 +1506,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
name, virtual_rust_source_base_dir, sess.opts.real_rust_source_base_dir,
);
for virtual_dir in &virtual_rust_source_base_dir {
for virtual_dir in virtual_rust_source_base_dir.iter().flatten() {
if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
if let rustc_span::FileName::Real(old_name) = name {
if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =