Auto merge of #65240 - michaelwoerister:sp-review-3, r=Mark-Simulacrum
self-profiling: Add events for metadata loading (plus a small dep-tracking optimization) This PR - adds self-profiling events related to loading things from crate metadata - makes the compiler cache the `DepNodeIndex` of upstream crates, so that they don't have to be looked up over and over. The commits are best reviewed in isolation. Self-profiling tracking issue: https://github.com/rust-lang/rust/issues/58967 r? @Mark-Simulacrum cc @wesleywiser
This commit is contained in:
commit
d28a9c38fe
6 changed files with 55 additions and 24 deletions
|
@ -30,7 +30,7 @@ rustc_index::newtype_index! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DepNodeIndex {
|
impl DepNodeIndex {
|
||||||
const INVALID: DepNodeIndex = DepNodeIndex::MAX;
|
pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
|
use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
|
||||||
use crate::locator::{self, CratePaths};
|
use crate::locator::{self, CratePaths};
|
||||||
use crate::schema::{CrateRoot, CrateDep};
|
use crate::schema::{CrateRoot, CrateDep};
|
||||||
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
|
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
|
||||||
|
|
||||||
use rustc::hir::def_id::CrateNum;
|
use rustc::hir::def_id::CrateNum;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
|
use rustc::dep_graph::DepNodeIndex;
|
||||||
use rustc::middle::cstore::DepKind;
|
use rustc::middle::cstore::DepKind;
|
||||||
use rustc::mir::interpret::AllocDecodingState;
|
use rustc::mir::interpret::AllocDecodingState;
|
||||||
use rustc::session::{Session, CrateDisambiguator};
|
use rustc::session::{Session, CrateDisambiguator};
|
||||||
|
@ -196,6 +197,9 @@ impl<'a> CrateLoader<'a> {
|
||||||
dep_kind: DepKind,
|
dep_kind: DepKind,
|
||||||
name: Symbol
|
name: Symbol
|
||||||
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
||||||
|
let _prof_timer =
|
||||||
|
self.sess.prof.generic_activity("metadata_register_crate");
|
||||||
|
|
||||||
let crate_root = lib.metadata.get_root();
|
let crate_root = lib.metadata.get_root();
|
||||||
self.verify_no_symbol_conflicts(span, &crate_root);
|
self.verify_no_symbol_conflicts(span, &crate_root);
|
||||||
|
|
||||||
|
@ -271,7 +275,8 @@ impl<'a> CrateLoader<'a> {
|
||||||
},
|
},
|
||||||
private_dep,
|
private_dep,
|
||||||
span,
|
span,
|
||||||
raw_proc_macros
|
raw_proc_macros,
|
||||||
|
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmeta = Lrc::new(cmeta);
|
let cmeta = Lrc::new(cmeta);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// crates and libraries
|
// crates and libraries
|
||||||
|
|
||||||
use crate::schema;
|
use crate::schema;
|
||||||
|
use rustc::dep_graph::DepNodeIndex;
|
||||||
use rustc::hir::def_id::{CrateNum, DefIndex};
|
use rustc::hir::def_id::{CrateNum, DefIndex};
|
||||||
use rustc::hir::map::definitions::DefPathTable;
|
use rustc::hir::map::definitions::DefPathTable;
|
||||||
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
|
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
|
||||||
|
@ -9,7 +10,7 @@ use rustc::mir::interpret::AllocDecodingState;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc::util::nodemap::{FxHashMap, NodeMap};
|
use rustc::util::nodemap::{FxHashMap, NodeMap};
|
||||||
|
|
||||||
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
|
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ext::base::SyntaxExtension;
|
use syntax::ext::base::SyntaxExtension;
|
||||||
use syntax_pos;
|
use syntax_pos;
|
||||||
|
@ -83,6 +84,13 @@ pub struct CrateMetadata {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
||||||
pub raw_proc_macros: Option<&'static [ProcMacro]>,
|
pub raw_proc_macros: Option<&'static [ProcMacro]>,
|
||||||
|
|
||||||
|
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
|
||||||
|
/// It is initialized on the first access in `get_crate_dep_node_index()`.
|
||||||
|
/// Do not access the value directly, as it might not have been initialized
|
||||||
|
/// yet.
|
||||||
|
/// The field must always be initialized to `DepNodeIndex::INVALID`.
|
||||||
|
pub(super) dep_node_index: AtomicCell<DepNodeIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CStore {
|
pub struct CStore {
|
||||||
|
|
|
@ -48,23 +48,22 @@ macro_rules! provide {
|
||||||
$tcx: TyCtxt<$lt>,
|
$tcx: TyCtxt<$lt>,
|
||||||
def_id_arg: T,
|
def_id_arg: T,
|
||||||
) -> <ty::queries::$name<$lt> as QueryConfig<$lt>>::Value {
|
) -> <ty::queries::$name<$lt> as QueryConfig<$lt>>::Value {
|
||||||
|
let _prof_timer =
|
||||||
|
$tcx.prof.generic_activity("metadata_decode_entry");
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
let ($def_id, $other) = def_id_arg.into_args();
|
let ($def_id, $other) = def_id_arg.into_args();
|
||||||
assert!(!$def_id.is_local());
|
assert!(!$def_id.is_local());
|
||||||
|
|
||||||
let def_path_hash = $tcx.def_path_hash(DefId {
|
|
||||||
krate: $def_id.krate,
|
|
||||||
index: CRATE_DEF_INDEX
|
|
||||||
});
|
|
||||||
let dep_node = def_path_hash
|
|
||||||
.to_dep_node(rustc::dep_graph::DepKind::CrateMetadata);
|
|
||||||
// The DepNodeIndex of the DepNode::CrateMetadata should be
|
|
||||||
// cached somewhere, so that we can use read_index().
|
|
||||||
$tcx.dep_graph.read(dep_node);
|
|
||||||
|
|
||||||
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
|
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
|
||||||
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
|
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
|
||||||
.expect("CrateStore created data is not a CrateMetadata");
|
.expect("CrateStore created data is not a CrateMetadata");
|
||||||
|
|
||||||
|
if $tcx.dep_graph.is_fully_enabled() {
|
||||||
|
let crate_dep_node_index = $cdata.get_crate_dep_node_index($tcx);
|
||||||
|
$tcx.dep_graph.read_index(crate_dep_node_index);
|
||||||
|
}
|
||||||
|
|
||||||
$compute
|
$compute
|
||||||
})*
|
})*
|
||||||
|
|
||||||
|
@ -449,6 +448,8 @@ impl cstore::CStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
|
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
|
||||||
|
let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
|
||||||
|
|
||||||
let data = self.get_crate_data(id.krate);
|
let data = self.get_crate_data(id.krate);
|
||||||
if data.is_proc_macro_crate() {
|
if data.is_proc_macro_crate() {
|
||||||
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
|
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
|
||||||
|
@ -526,20 +527,10 @@ impl CrateStore for cstore::CStore {
|
||||||
/// parent `DefId` as well as some idea of what kind of data the
|
/// parent `DefId` as well as some idea of what kind of data the
|
||||||
/// `DefId` refers to.
|
/// `DefId` refers to.
|
||||||
fn def_key(&self, def: DefId) -> DefKey {
|
fn def_key(&self, def: DefId) -> DefKey {
|
||||||
// Note: loading the def-key (or def-path) for a def-id is not
|
|
||||||
// a *read* of its metadata. This is because the def-id is
|
|
||||||
// really just an interned shorthand for a def-path, which is the
|
|
||||||
// canonical name for an item.
|
|
||||||
//
|
|
||||||
// self.dep_graph.read(DepNode::MetaData(def));
|
|
||||||
self.get_crate_data(def.krate).def_key(def.index)
|
self.get_crate_data(def.krate).def_key(def.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_path(&self, def: DefId) -> DefPath {
|
fn def_path(&self, def: DefId) -> DefPath {
|
||||||
// See `Note` above in `def_key()` for why this read is
|
|
||||||
// commented out:
|
|
||||||
//
|
|
||||||
// self.dep_graph.read(DepNode::MetaData(def));
|
|
||||||
self.get_crate_data(def.krate).def_path(def.index)
|
self.get_crate_data(def.krate).def_path(def.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc::dep_graph::{DepNodeIndex, DepKind};
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
use rustc::mir::{self, interpret};
|
use rustc::mir::{self, interpret};
|
||||||
use rustc::mir::interpret::AllocDecodingSession;
|
use rustc::mir::interpret::AllocDecodingSession;
|
||||||
|
@ -1365,6 +1366,30 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
|
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
|
||||||
self.source_map_import_info.borrow()
|
self.source_map_import_info.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the `DepNodeIndex` corresponding this crate. The result of this
|
||||||
|
/// method is cached in the `dep_node_index` field.
|
||||||
|
pub(super) fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
|
||||||
|
let mut dep_node_index = self.dep_node_index.load();
|
||||||
|
|
||||||
|
if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
|
||||||
|
// We have not cached the DepNodeIndex for this upstream crate yet,
|
||||||
|
// so use the dep-graph to find it out and cache it.
|
||||||
|
// Note that multiple threads can enter this block concurrently.
|
||||||
|
// That is fine because the DepNodeIndex remains constant
|
||||||
|
// throughout the whole compilation session, and multiple stores
|
||||||
|
// would always write the same value.
|
||||||
|
|
||||||
|
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX);
|
||||||
|
let dep_node = def_path_hash.to_dep_node(DepKind::CrateMetadata);
|
||||||
|
|
||||||
|
dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
|
||||||
|
assert!(dep_node_index != DepNodeIndex::INVALID);
|
||||||
|
self.dep_node_index.store(dep_node_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
dep_node_index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cannot be implemented on 'ProcMacro', as libproc_macro
|
// Cannot be implemented on 'ProcMacro', as libproc_macro
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||||
|
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
||||||
#![recursion_limit="256"]
|
#![recursion_limit="256"]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue