Rollup merge of #102041 - nnethercote:improve-meta-stats, r=bjorn3
Improve `-Zmeta-stats` some more A follow-up to #97384. r? ```@bjorn3```
This commit is contained in:
commit
4b7c596b3a
@ -28,6 +28,7 @@
|
|||||||
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
|
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
|
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
|
||||||
|
use rustc_middle::util::common::to_readable_str;
|
||||||
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
|
||||||
use rustc_session::config::CrateType;
|
use rustc_session::config::CrateType;
|
||||||
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
|
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
|
||||||
@ -261,10 +262,10 @@ fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
|
|||||||
// This allows us to avoid loading the dependencies of proc-macro crates: all of
|
// This allows us to avoid loading the dependencies of proc-macro crates: all of
|
||||||
// the information we need to decode `Span`s is stored in the proc-macro crate.
|
// the information we need to decode `Span`s is stored in the proc-macro crate.
|
||||||
let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
|
let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
|
||||||
// To simplify deserialization, we 'rebase' this span onto the crate it originally came from
|
// To simplify deserialization, we 'rebase' this span onto the crate it originally came
|
||||||
// (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
|
// from (the crate that 'owns' the file it references. These rebased 'lo' and 'hi'
|
||||||
// are relative to the source map information for the 'foreign' crate whose CrateNum
|
// values are relative to the source map information for the 'foreign' crate whose
|
||||||
// we write into the metadata. This allows `imported_source_files` to binary
|
// CrateNum we write into the metadata. This allows `imported_source_files` to binary
|
||||||
// search through the 'foreign' crate's source map information, using the
|
// search through the 'foreign' crate's source map information, using the
|
||||||
// deserialized 'lo' and 'hi' values directly.
|
// deserialized 'lo' and 'hi' values directly.
|
||||||
//
|
//
|
||||||
@ -554,78 +555,56 @@ fn encode_source_map(&mut self) -> LazyTable<u32, LazyValue<rustc_span::SourceFi
|
|||||||
|
|
||||||
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
|
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut i = 0;
|
let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32);
|
||||||
let preamble_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the crate deps
|
macro_rules! stat {
|
||||||
i = self.position();
|
($label:literal, $f:expr) => {{
|
||||||
let crate_deps = self.encode_crate_deps();
|
let orig_pos = self.position();
|
||||||
let dylib_dependency_formats = self.encode_dylib_dependency_formats();
|
let res = $f();
|
||||||
let dep_bytes = self.position() - i;
|
stats.push(($label, self.position() - orig_pos));
|
||||||
|
res
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
// Encode the lib features.
|
// We have already encoded some things. Get their combined size from the current position.
|
||||||
i = self.position();
|
stats.push(("preamble", self.position()));
|
||||||
let lib_features = self.encode_lib_features();
|
|
||||||
let lib_feature_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the stability implications.
|
let (crate_deps, dylib_dependency_formats) =
|
||||||
i = self.position();
|
stat!("dep", || (self.encode_crate_deps(), self.encode_dylib_dependency_formats()));
|
||||||
let stability_implications = self.encode_stability_implications();
|
|
||||||
let stability_implications_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the language items.
|
let lib_features = stat!("lib-features", || self.encode_lib_features());
|
||||||
i = self.position();
|
|
||||||
let lang_items = self.encode_lang_items();
|
|
||||||
let lang_items_missing = self.encode_lang_items_missing();
|
|
||||||
let lang_item_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the diagnostic items.
|
let stability_implications =
|
||||||
i = self.position();
|
stat!("stability-implications", || self.encode_stability_implications());
|
||||||
let diagnostic_items = self.encode_diagnostic_items();
|
|
||||||
let diagnostic_item_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the native libraries used
|
let (lang_items, lang_items_missing) = stat!("lang-items", || {
|
||||||
i = self.position();
|
(self.encode_lang_items(), self.encode_lang_items_missing())
|
||||||
let native_libraries = self.encode_native_libraries();
|
});
|
||||||
let native_lib_bytes = self.position() - i;
|
|
||||||
|
|
||||||
i = self.position();
|
let diagnostic_items = stat!("diagnostic-items", || self.encode_diagnostic_items());
|
||||||
let foreign_modules = self.encode_foreign_modules();
|
|
||||||
let foreign_modules_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode DefPathTable
|
let native_libraries = stat!("native-libs", || self.encode_native_libraries());
|
||||||
i = self.position();
|
|
||||||
self.encode_def_path_table();
|
let foreign_modules = stat!("foreign-modules", || self.encode_foreign_modules());
|
||||||
let def_path_table_bytes = self.position() - i;
|
|
||||||
|
_ = stat!("def-path-table", || self.encode_def_path_table());
|
||||||
|
|
||||||
// Encode the def IDs of traits, for rustdoc and diagnostics.
|
// Encode the def IDs of traits, for rustdoc and diagnostics.
|
||||||
i = self.position();
|
let traits = stat!("traits", || self.encode_traits());
|
||||||
let traits = self.encode_traits();
|
|
||||||
let traits_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the def IDs of impls, for coherence checking.
|
// Encode the def IDs of impls, for coherence checking.
|
||||||
i = self.position();
|
let impls = stat!("impls", || self.encode_impls());
|
||||||
let impls = self.encode_impls();
|
|
||||||
let impls_bytes = self.position() - i;
|
|
||||||
|
|
||||||
i = self.position();
|
let incoherent_impls = stat!("incoherent-impls", || self.encode_incoherent_impls());
|
||||||
let incoherent_impls = self.encode_incoherent_impls();
|
|
||||||
let incoherent_impls_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode MIR.
|
_ = stat!("mir", || self.encode_mir());
|
||||||
i = self.position();
|
|
||||||
self.encode_mir();
|
|
||||||
let mir_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the items.
|
_ = stat!("items", || {
|
||||||
i = self.position();
|
self.encode_def_ids();
|
||||||
self.encode_def_ids();
|
self.encode_info_for_items();
|
||||||
self.encode_info_for_items();
|
});
|
||||||
let item_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the allocation index
|
let interpret_alloc_index = stat!("interpret-alloc-index", || {
|
||||||
i = self.position();
|
|
||||||
let interpret_alloc_index = {
|
|
||||||
let mut interpret_alloc_index = Vec::new();
|
let mut interpret_alloc_index = Vec::new();
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
trace!("beginning to encode alloc ids");
|
trace!("beginning to encode alloc ids");
|
||||||
@ -646,126 +625,90 @@ fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
|
|||||||
n = new_n;
|
n = new_n;
|
||||||
}
|
}
|
||||||
self.lazy_array(interpret_alloc_index)
|
self.lazy_array(interpret_alloc_index)
|
||||||
};
|
});
|
||||||
let interpret_alloc_index_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode the proc macro data. This affects 'tables',
|
// Encode the proc macro data. This affects `tables`, so we need to do this before we
|
||||||
// so we need to do this before we encode the tables.
|
// encode the tables. This overwrites def_keys, so it must happen after
|
||||||
// This overwrites def_keys, so it must happen after encode_def_path_table.
|
// encode_def_path_table.
|
||||||
i = self.position();
|
let proc_macro_data = stat!("proc-macro-data", || self.encode_proc_macros());
|
||||||
let proc_macro_data = self.encode_proc_macros();
|
|
||||||
let proc_macro_data_bytes = self.position() - i;
|
|
||||||
|
|
||||||
i = self.position();
|
let tables = stat!("tables", || self.tables.encode(&mut self.opaque));
|
||||||
let tables = self.tables.encode(&mut self.opaque);
|
|
||||||
let tables_bytes = self.position() - i;
|
|
||||||
|
|
||||||
i = self.position();
|
let debugger_visualizers =
|
||||||
let debugger_visualizers = self.encode_debugger_visualizers();
|
stat!("debugger-visualizers", || self.encode_debugger_visualizers());
|
||||||
let debugger_visualizers_bytes = self.position() - i;
|
|
||||||
|
|
||||||
// Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
|
// Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
|
||||||
// this as late as possible to give the prefetching as much time as possible to complete.
|
// this as late as possible to give the prefetching as much time as possible to complete.
|
||||||
i = self.position();
|
let exported_symbols = stat!("exported-symbols", || {
|
||||||
let exported_symbols = tcx.exported_symbols(LOCAL_CRATE);
|
self.encode_exported_symbols(&tcx.exported_symbols(LOCAL_CRATE))
|
||||||
let exported_symbols = self.encode_exported_symbols(&exported_symbols);
|
});
|
||||||
let exported_symbols_bytes = self.position() - i;
|
|
||||||
|
// Encode the hygiene data.
|
||||||
// Encode the hygiene data,
|
// IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
|
||||||
// IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The process
|
// process of encoding other items (e.g. `optimized_mir`) may cause us to load data from
|
||||||
// of encoding other items (e.g. `optimized_mir`) may cause us to load
|
// the incremental cache. If this causes us to deserialize a `Span`, then we may load
|
||||||
// data from the incremental cache. If this causes us to deserialize a `Span`,
|
// additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode
|
||||||
// then we may load additional `SyntaxContext`s into the global `HygieneData`.
|
// the hygiene data last to ensure that we encode any `SyntaxContext`s that might be used.
|
||||||
// Therefore, we need to encode the hygiene data last to ensure that we encode
|
let (syntax_contexts, expn_data, expn_hashes) = stat!("hygiene", || self.encode_hygiene());
|
||||||
// any `SyntaxContext`s that might be used.
|
|
||||||
i = self.position();
|
let def_path_hash_map = stat!("def-path-hash-map", || self.encode_def_path_hash_map());
|
||||||
let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene();
|
|
||||||
let hygiene_bytes = self.position() - i;
|
// Encode source_map. This needs to be done last, because encoding `Span`s tells us which
|
||||||
|
// `SourceFiles` we actually need to encode.
|
||||||
i = self.position();
|
let source_map = stat!("source-map", || self.encode_source_map());
|
||||||
let def_path_hash_map = self.encode_def_path_hash_map();
|
|
||||||
let def_path_hash_map_bytes = self.position() - i;
|
let root = stat!("final", || {
|
||||||
|
let attrs = tcx.hir().krate_attrs();
|
||||||
// Encode source_map. This needs to be done last,
|
self.lazy(CrateRoot {
|
||||||
// since encoding `Span`s tells us which `SourceFiles` we actually
|
name: tcx.crate_name(LOCAL_CRATE),
|
||||||
// need to encode.
|
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
|
||||||
i = self.position();
|
triple: tcx.sess.opts.target_triple.clone(),
|
||||||
let source_map = self.encode_source_map();
|
hash: tcx.crate_hash(LOCAL_CRATE),
|
||||||
let source_map_bytes = self.position() - i;
|
stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
|
||||||
|
required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE),
|
||||||
i = self.position();
|
panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
|
||||||
let attrs = tcx.hir().krate_attrs();
|
edition: tcx.sess.edition(),
|
||||||
let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
|
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
|
||||||
let root = self.lazy(CrateRoot {
|
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
|
||||||
name: tcx.crate_name(LOCAL_CRATE),
|
has_default_lib_allocator: tcx
|
||||||
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
|
.sess
|
||||||
triple: tcx.sess.opts.target_triple.clone(),
|
.contains_name(&attrs, sym::default_lib_allocator),
|
||||||
hash: tcx.crate_hash(LOCAL_CRATE),
|
proc_macro_data,
|
||||||
stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
|
debugger_visualizers,
|
||||||
required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE),
|
compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
|
||||||
panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
|
needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
|
||||||
edition: tcx.sess.edition(),
|
needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
|
||||||
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
|
no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
|
||||||
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
|
panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
|
||||||
has_default_lib_allocator,
|
profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
|
||||||
proc_macro_data,
|
symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
|
||||||
debugger_visualizers,
|
|
||||||
compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
|
crate_deps,
|
||||||
needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
|
dylib_dependency_formats,
|
||||||
needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
|
lib_features,
|
||||||
no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
|
stability_implications,
|
||||||
panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
|
lang_items,
|
||||||
profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
|
diagnostic_items,
|
||||||
symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
|
lang_items_missing,
|
||||||
|
native_libraries,
|
||||||
crate_deps,
|
foreign_modules,
|
||||||
dylib_dependency_formats,
|
source_map,
|
||||||
lib_features,
|
traits,
|
||||||
stability_implications,
|
impls,
|
||||||
lang_items,
|
incoherent_impls,
|
||||||
diagnostic_items,
|
exported_symbols,
|
||||||
lang_items_missing,
|
interpret_alloc_index,
|
||||||
native_libraries,
|
tables,
|
||||||
foreign_modules,
|
syntax_contexts,
|
||||||
source_map,
|
expn_data,
|
||||||
traits,
|
expn_hashes,
|
||||||
impls,
|
def_path_hash_map,
|
||||||
incoherent_impls,
|
})
|
||||||
exported_symbols,
|
|
||||||
interpret_alloc_index,
|
|
||||||
tables,
|
|
||||||
syntax_contexts,
|
|
||||||
expn_data,
|
|
||||||
expn_hashes,
|
|
||||||
def_path_hash_map,
|
|
||||||
});
|
});
|
||||||
let final_bytes = self.position() - i;
|
|
||||||
|
|
||||||
let total_bytes = self.position();
|
let total_bytes = self.position();
|
||||||
|
|
||||||
let computed_total_bytes = preamble_bytes
|
let computed_total_bytes: usize = stats.iter().map(|(_, size)| size).sum();
|
||||||
+ dep_bytes
|
|
||||||
+ lib_feature_bytes
|
|
||||||
+ stability_implications_bytes
|
|
||||||
+ lang_item_bytes
|
|
||||||
+ diagnostic_item_bytes
|
|
||||||
+ native_lib_bytes
|
|
||||||
+ foreign_modules_bytes
|
|
||||||
+ def_path_table_bytes
|
|
||||||
+ traits_bytes
|
|
||||||
+ impls_bytes
|
|
||||||
+ incoherent_impls_bytes
|
|
||||||
+ mir_bytes
|
|
||||||
+ item_bytes
|
|
||||||
+ interpret_alloc_index_bytes
|
|
||||||
+ proc_macro_data_bytes
|
|
||||||
+ tables_bytes
|
|
||||||
+ debugger_visualizers_bytes
|
|
||||||
+ exported_symbols_bytes
|
|
||||||
+ hygiene_bytes
|
|
||||||
+ def_path_hash_map_bytes
|
|
||||||
+ source_map_bytes
|
|
||||||
+ final_bytes;
|
|
||||||
assert_eq!(total_bytes, computed_total_bytes);
|
assert_eq!(total_bytes, computed_total_bytes);
|
||||||
|
|
||||||
if tcx.sess.meta_stats() {
|
if tcx.sess.meta_stats() {
|
||||||
@ -783,42 +726,38 @@ fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
|
|||||||
}
|
}
|
||||||
assert_eq!(self.opaque.file().stream_position().unwrap(), pos_before_rewind);
|
assert_eq!(self.opaque.file().stream_position().unwrap(), pos_before_rewind);
|
||||||
|
|
||||||
let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
|
stats.sort_by_key(|&(_, usize)| usize);
|
||||||
let p = |label, bytes| {
|
|
||||||
eprintln!("{:>21}: {:>8} bytes ({:4.1}%)", label, bytes, perc(bytes));
|
|
||||||
};
|
|
||||||
|
|
||||||
eprintln!("");
|
let prefix = "meta-stats";
|
||||||
|
let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
|
||||||
|
|
||||||
|
eprintln!("{} METADATA STATS", prefix);
|
||||||
|
eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size");
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{} metadata bytes, of which {} bytes ({:.1}%) are zero",
|
"{} ----------------------------------------------------------------",
|
||||||
total_bytes,
|
prefix
|
||||||
zero_bytes,
|
);
|
||||||
|
for (label, size) in stats {
|
||||||
|
eprintln!(
|
||||||
|
"{} {:<23}{:>10} ({:4.1}%)",
|
||||||
|
prefix,
|
||||||
|
label,
|
||||||
|
to_readable_str(size),
|
||||||
|
perc(size)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
eprintln!(
|
||||||
|
"{} ----------------------------------------------------------------",
|
||||||
|
prefix
|
||||||
|
);
|
||||||
|
eprintln!(
|
||||||
|
"{} {:<23}{:>10} (of which {:.1}% are zero bytes)",
|
||||||
|
prefix,
|
||||||
|
"Total",
|
||||||
|
to_readable_str(total_bytes),
|
||||||
perc(zero_bytes)
|
perc(zero_bytes)
|
||||||
);
|
);
|
||||||
p("preamble", preamble_bytes);
|
eprintln!("{}", prefix);
|
||||||
p("dep", dep_bytes);
|
|
||||||
p("lib feature", lib_feature_bytes);
|
|
||||||
p("stability_implications", stability_implications_bytes);
|
|
||||||
p("lang item", lang_item_bytes);
|
|
||||||
p("diagnostic item", diagnostic_item_bytes);
|
|
||||||
p("native lib", native_lib_bytes);
|
|
||||||
p("foreign modules", foreign_modules_bytes);
|
|
||||||
p("def-path table", def_path_table_bytes);
|
|
||||||
p("traits", traits_bytes);
|
|
||||||
p("impls", impls_bytes);
|
|
||||||
p("incoherent_impls", incoherent_impls_bytes);
|
|
||||||
p("mir", mir_bytes);
|
|
||||||
p("item", item_bytes);
|
|
||||||
p("interpret_alloc_index", interpret_alloc_index_bytes);
|
|
||||||
p("proc-macro-data", proc_macro_data_bytes);
|
|
||||||
p("tables", tables_bytes);
|
|
||||||
p("debugger visualizers", debugger_visualizers_bytes);
|
|
||||||
p("exported symbols", exported_symbols_bytes);
|
|
||||||
p("hygiene", hygiene_bytes);
|
|
||||||
p("def-path hashes", def_path_hash_map_bytes);
|
|
||||||
p("source_map", source_map_bytes);
|
|
||||||
p("final", final_bytes);
|
|
||||||
eprintln!("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
root
|
root
|
||||||
|
Loading…
Reference in New Issue
Block a user