@@ -28,6 +28,7 @@ use rustc_middle::ty::codec::TyEncoder;
2828use rustc_middle:: ty:: fast_reject:: { self , SimplifiedType , TreatParams } ;
2929use rustc_middle:: ty:: query:: Providers ;
3030use rustc_middle:: ty:: { self , SymbolName , Ty , TyCtxt } ;
31+ use rustc_middle:: util:: common:: to_readable_str;
3132use rustc_serialize:: { opaque, Decodable , Decoder , Encodable , Encoder } ;
3233use rustc_session:: config:: CrateType ;
3334use rustc_session:: cstore:: { ForeignModule , LinkagePreference , NativeLib } ;
@@ -554,78 +555,56 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
554555
555556 fn encode_crate_root ( & mut self ) -> LazyValue < CrateRoot > {
556557 let tcx = self . tcx ;
557- let mut i = 0 ;
558- let preamble_bytes = self . position ( ) - i;
559-
560- // Encode the crate deps
561- i = self . position ( ) ;
562- let crate_deps = self . encode_crate_deps ( ) ;
563- let dylib_dependency_formats = self . encode_dylib_dependency_formats ( ) ;
564- let dep_bytes = self . position ( ) - i;
565-
566- // Encode the lib features.
567- i = self . position ( ) ;
568- let lib_features = self . encode_lib_features ( ) ;
569- let lib_feature_bytes = self . position ( ) - i;
570-
571- // Encode the stability implications.
572- i = self . position ( ) ;
573- let stability_implications = self . encode_stability_implications ( ) ;
574- let stability_implications_bytes = self . position ( ) - i;
575-
576- // Encode the language items.
577- i = self . position ( ) ;
578- let lang_items = self . encode_lang_items ( ) ;
579- let lang_items_missing = self . encode_lang_items_missing ( ) ;
580- let lang_item_bytes = self . position ( ) - i;
581-
582- // Encode the diagnostic items.
583- i = self . position ( ) ;
584- let diagnostic_items = self . encode_diagnostic_items ( ) ;
585- let diagnostic_item_bytes = self . position ( ) - i;
586-
587- // Encode the native libraries used
588- i = self . position ( ) ;
589- let native_libraries = self . encode_native_libraries ( ) ;
590- let native_lib_bytes = self . position ( ) - i;
591-
592- i = self . position ( ) ;
593- let foreign_modules = self . encode_foreign_modules ( ) ;
594- let foreign_modules_bytes = self . position ( ) - i;
595-
596- // Encode DefPathTable
597- i = self . position ( ) ;
598- self . encode_def_path_table ( ) ;
599- let def_path_table_bytes = self . position ( ) - i;
558+ let mut stats: Vec < ( & ' static str , usize ) > = Vec :: with_capacity ( 32 ) ;
559+
560+ macro_rules! stat {
561+ ( $label: literal, $f: expr) => { {
562+ let orig_pos = self . position( ) ;
563+ let res = $f( ) ;
564+ stats. push( ( $label, self . position( ) - orig_pos) ) ;
565+ res
566+ } } ;
567+ }
568+
569+ // We have already encoded some things. Get their combined size from the current position.
570+ stats. push ( ( "preamble" , self . position ( ) ) ) ;
571+
572+ let ( crate_deps, dylib_dependency_formats) =
573+ stat ! ( "dep" , || ( self . encode_crate_deps( ) , self . encode_dylib_dependency_formats( ) ) ) ;
574+
575+ let lib_features = stat ! ( "lib-features" , || self . encode_lib_features( ) ) ;
576+
577+ let stability_implications =
578+ stat ! ( "stability-implications" , || self . encode_stability_implications( ) ) ;
579+
580+ let ( lang_items, lang_items_missing) = stat ! ( "lang-items" , || {
581+ ( self . encode_lang_items( ) , self . encode_lang_items_missing( ) )
582+ } ) ;
583+
584+ let diagnostic_items = stat ! ( "diagnostic-items" , || self . encode_diagnostic_items( ) ) ;
585+
586+ let native_libraries = stat ! ( "native-libs" , || self . encode_native_libraries( ) ) ;
587+
588+ let foreign_modules = stat ! ( "foreign-modules" , || self . encode_foreign_modules( ) ) ;
589+
590+ _ = stat ! ( "def-path-table" , || self . encode_def_path_table( ) ) ;
600591
601592 // Encode the def IDs of traits, for rustdoc and diagnostics.
602- i = self . position ( ) ;
603- let traits = self . encode_traits ( ) ;
604- let traits_bytes = self . position ( ) - i;
593+ let traits = stat ! ( "traits" , || self . encode_traits( ) ) ;
605594
606595 // Encode the def IDs of impls, for coherence checking.
607- i = self . position ( ) ;
608- let impls = self . encode_impls ( ) ;
609- let impls_bytes = self . position ( ) - i;
610-
611- i = self . position ( ) ;
612- let incoherent_impls = self . encode_incoherent_impls ( ) ;
613- let incoherent_impls_bytes = self . position ( ) - i;
614-
615- // Encode MIR.
616- i = self . position ( ) ;
617- self . encode_mir ( ) ;
618- let mir_bytes = self . position ( ) - i;
619-
620- // Encode the items.
621- i = self . position ( ) ;
622- self . encode_def_ids ( ) ;
623- self . encode_info_for_items ( ) ;
624- let item_bytes = self . position ( ) - i;
625-
626- // Encode the allocation index
627- i = self . position ( ) ;
628- let interpret_alloc_index = {
596+ let impls = stat ! ( "impls" , || self . encode_impls( ) ) ;
597+
598+ let incoherent_impls = stat ! ( "incoherent-impls" , || self . encode_incoherent_impls( ) ) ;
599+
600+ _ = stat ! ( "mir" , || self . encode_mir( ) ) ;
601+
602+ _ = stat ! ( "items" , || {
603+ self . encode_def_ids( ) ;
604+ self . encode_info_for_items( ) ;
605+ } ) ;
606+
607+ let interpret_alloc_index = stat ! ( "interpret-alloc-index" , || {
629608 let mut interpret_alloc_index = Vec :: new( ) ;
630609 let mut n = 0 ;
631610 trace!( "beginning to encode alloc ids" ) ;
@@ -646,125 +625,90 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
646625 n = new_n;
647626 }
648627 self . lazy_array( interpret_alloc_index)
649- } ;
650- let interpret_alloc_index_bytes = self . position ( ) - i;
628+ } ) ;
651629
652- // Encode the proc macro data. This affects 'tables',
653- // so we need to do this before we encode the tables.
654- // This overwrites def_keys, so it must happen after encode_def_path_table.
655- i = self . position ( ) ;
656- let proc_macro_data = self . encode_proc_macros ( ) ;
657- let proc_macro_data_bytes = self . position ( ) - i;
630+ // Encode the proc macro data. This affects `tables`, so we need to do this before we
631+ // encode the tables. This overwrites def_keys, so it must happen after
632+ // encode_def_path_table.
633+ let proc_macro_data = stat ! ( "proc-macro-data" , || self . encode_proc_macros( ) ) ;
658634
659- i = self . position ( ) ;
660- let tables = self . tables . encode ( & mut self . opaque ) ;
661- let tables_bytes = self . position ( ) - i;
635+ let tables = stat ! ( "tables" , || self . tables. encode( & mut self . opaque) ) ;
662636
663- i = self . position ( ) ;
664- let debugger_visualizers = self . encode_debugger_visualizers ( ) ;
665- let debugger_visualizers_bytes = self . position ( ) - i;
637+ let debugger_visualizers =
638+ stat ! ( "debugger-visualizers" , || self . encode_debugger_visualizers( ) ) ;
666639
667640 // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
668641 // this as late as possible to give the prefetching as much time as possible to complete.
669- i = self . position ( ) ;
670- let exported_symbols = tcx. exported_symbols ( LOCAL_CRATE ) ;
671- let exported_symbols = self . encode_exported_symbols ( & exported_symbols) ;
672- let exported_symbols_bytes = self . position ( ) - i;
642+ let exported_symbols = stat ! ( "exported-symbols" , || {
643+ self . encode_exported_symbols( & tcx. exported_symbols( LOCAL_CRATE ) )
644+ } ) ;
673645
674- // Encode the hygiene data,
646+ // Encode the hygiene data.
675647 // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
676648 // process of encoding other items (e.g. `optimized_mir`) may cause us to load data from
677649 // the incremental cache. If this causes us to deserialize a `Span`, then we may load
678650 // additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode
679651 // the hygiene data last to ensure that we encode any `SyntaxContext`s that might be used.
680- i = self . position ( ) ;
681- let ( syntax_contexts, expn_data, expn_hashes) = self . encode_hygiene ( ) ;
682- let hygiene_bytes = self . position ( ) - i;
683-
684- i = self . position ( ) ;
685- let def_path_hash_map = self . encode_def_path_hash_map ( ) ;
686- let def_path_hash_map_bytes = self . position ( ) - i;
687-
688- // Encode source_map. This needs to be done last,
689- // since encoding `Span`s tells us which `SourceFiles` we actually
690- // need to encode.
691- i = self . position ( ) ;
692- let source_map = self . encode_source_map ( ) ;
693- let source_map_bytes = self . position ( ) - i;
694-
695- i = self . position ( ) ;
696- let attrs = tcx. hir ( ) . krate_attrs ( ) ;
697- let has_default_lib_allocator = tcx. sess . contains_name ( & attrs, sym:: default_lib_allocator) ;
698- let root = self . lazy ( CrateRoot {
699- name : tcx. crate_name ( LOCAL_CRATE ) ,
700- extra_filename : tcx. sess . opts . cg . extra_filename . clone ( ) ,
701- triple : tcx. sess . opts . target_triple . clone ( ) ,
702- hash : tcx. crate_hash ( LOCAL_CRATE ) ,
703- stable_crate_id : tcx. def_path_hash ( LOCAL_CRATE . as_def_id ( ) ) . stable_crate_id ( ) ,
704- required_panic_strategy : tcx. required_panic_strategy ( LOCAL_CRATE ) ,
705- panic_in_drop_strategy : tcx. sess . opts . unstable_opts . panic_in_drop ,
706- edition : tcx. sess . edition ( ) ,
707- has_global_allocator : tcx. has_global_allocator ( LOCAL_CRATE ) ,
708- has_panic_handler : tcx. has_panic_handler ( LOCAL_CRATE ) ,
709- has_default_lib_allocator,
710- proc_macro_data,
711- debugger_visualizers,
712- compiler_builtins : tcx. sess . contains_name ( & attrs, sym:: compiler_builtins) ,
713- needs_allocator : tcx. sess . contains_name ( & attrs, sym:: needs_allocator) ,
714- needs_panic_runtime : tcx. sess . contains_name ( & attrs, sym:: needs_panic_runtime) ,
715- no_builtins : tcx. sess . contains_name ( & attrs, sym:: no_builtins) ,
716- panic_runtime : tcx. sess . contains_name ( & attrs, sym:: panic_runtime) ,
717- profiler_runtime : tcx. sess . contains_name ( & attrs, sym:: profiler_runtime) ,
718- symbol_mangling_version : tcx. sess . opts . get_symbol_mangling_version ( ) ,
719-
720- crate_deps,
721- dylib_dependency_formats,
722- lib_features,
723- stability_implications,
724- lang_items,
725- diagnostic_items,
726- lang_items_missing,
727- native_libraries,
728- foreign_modules,
729- source_map,
730- traits,
731- impls,
732- incoherent_impls,
733- exported_symbols,
734- interpret_alloc_index,
735- tables,
736- syntax_contexts,
737- expn_data,
738- expn_hashes,
739- def_path_hash_map,
652+ let ( syntax_contexts, expn_data, expn_hashes) = stat ! ( "hygiene" , || self . encode_hygiene( ) ) ;
653+
654+ let def_path_hash_map = stat ! ( "def-path-hash-map" , || self . encode_def_path_hash_map( ) ) ;
655+
656+ // Encode source_map. This needs to be done last, because encoding `Span`s tells us which
657+ // `SourceFiles` we actually need to encode.
658+ let source_map = stat ! ( "source-map" , || self . encode_source_map( ) ) ;
659+
660+ let root = stat ! ( "final" , || {
661+ let attrs = tcx. hir( ) . krate_attrs( ) ;
662+ self . lazy( CrateRoot {
663+ name: tcx. crate_name( LOCAL_CRATE ) ,
664+ extra_filename: tcx. sess. opts. cg. extra_filename. clone( ) ,
665+ triple: tcx. sess. opts. target_triple. clone( ) ,
666+ hash: tcx. crate_hash( LOCAL_CRATE ) ,
667+ stable_crate_id: tcx. def_path_hash( LOCAL_CRATE . as_def_id( ) ) . stable_crate_id( ) ,
668+ required_panic_strategy: tcx. required_panic_strategy( LOCAL_CRATE ) ,
669+ panic_in_drop_strategy: tcx. sess. opts. unstable_opts. panic_in_drop,
670+ edition: tcx. sess. edition( ) ,
671+ has_global_allocator: tcx. has_global_allocator( LOCAL_CRATE ) ,
672+ has_panic_handler: tcx. has_panic_handler( LOCAL_CRATE ) ,
673+ has_default_lib_allocator: tcx
674+ . sess
675+ . contains_name( & attrs, sym:: default_lib_allocator) ,
676+ proc_macro_data,
677+ debugger_visualizers,
678+ compiler_builtins: tcx. sess. contains_name( & attrs, sym:: compiler_builtins) ,
679+ needs_allocator: tcx. sess. contains_name( & attrs, sym:: needs_allocator) ,
680+ needs_panic_runtime: tcx. sess. contains_name( & attrs, sym:: needs_panic_runtime) ,
681+ no_builtins: tcx. sess. contains_name( & attrs, sym:: no_builtins) ,
682+ panic_runtime: tcx. sess. contains_name( & attrs, sym:: panic_runtime) ,
683+ profiler_runtime: tcx. sess. contains_name( & attrs, sym:: profiler_runtime) ,
684+ symbol_mangling_version: tcx. sess. opts. get_symbol_mangling_version( ) ,
685+
686+ crate_deps,
687+ dylib_dependency_formats,
688+ lib_features,
689+ stability_implications,
690+ lang_items,
691+ diagnostic_items,
692+ lang_items_missing,
693+ native_libraries,
694+ foreign_modules,
695+ source_map,
696+ traits,
697+ impls,
698+ incoherent_impls,
699+ exported_symbols,
700+ interpret_alloc_index,
701+ tables,
702+ syntax_contexts,
703+ expn_data,
704+ expn_hashes,
705+ def_path_hash_map,
706+ } )
740707 } ) ;
741- let final_bytes = self . position ( ) - i;
742708
743709 let total_bytes = self . position ( ) ;
744710
745- let computed_total_bytes = preamble_bytes
746- + dep_bytes
747- + lib_feature_bytes
748- + stability_implications_bytes
749- + lang_item_bytes
750- + diagnostic_item_bytes
751- + native_lib_bytes
752- + foreign_modules_bytes
753- + def_path_table_bytes
754- + traits_bytes
755- + impls_bytes
756- + incoherent_impls_bytes
757- + mir_bytes
758- + item_bytes
759- + interpret_alloc_index_bytes
760- + proc_macro_data_bytes
761- + tables_bytes
762- + debugger_visualizers_bytes
763- + exported_symbols_bytes
764- + hygiene_bytes
765- + def_path_hash_map_bytes
766- + source_map_bytes
767- + final_bytes;
711+ let computed_total_bytes: usize = stats. iter ( ) . map ( |( _, size) | size) . sum ( ) ;
768712 assert_eq ! ( total_bytes, computed_total_bytes) ;
769713
770714 if tcx. sess . meta_stats ( ) {
@@ -782,42 +726,38 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
782726 }
783727 assert_eq ! ( self . opaque. file( ) . stream_position( ) . unwrap( ) , pos_before_rewind) ;
784728
729+ stats. sort_by_key ( |& ( _, usize) | usize) ;
730+
731+ let prefix = "meta-stats" ;
785732 let perc = |bytes| ( bytes * 100 ) as f64 / total_bytes as f64 ;
786- let p = |label, bytes| {
787- eprintln ! ( "{:>21}: {:>8} bytes ({:4.1}%)" , label, bytes, perc( bytes) ) ;
788- } ;
789733
790- eprintln ! ( "" ) ;
734+ eprintln ! ( "{} METADATA STATS" , prefix) ;
735+ eprintln ! ( "{} {:<23}{:>10}" , prefix, "Section" , "Size" ) ;
736+ eprintln ! (
737+ "{} ----------------------------------------------------------------" ,
738+ prefix
739+ ) ;
740+ for ( label, size) in stats {
741+ eprintln ! (
742+ "{} {:<23}{:>10} ({:4.1}%)" ,
743+ prefix,
744+ label,
745+ to_readable_str( size) ,
746+ perc( size)
747+ ) ;
748+ }
749+ eprintln ! (
750+ "{} ----------------------------------------------------------------" ,
751+ prefix
752+ ) ;
791753 eprintln ! (
792- "{} metadata bytes, of which {} bytes ({:.1}%) are zero" ,
793- total_bytes,
794- zero_bytes,
754+ "{} {:<23}{:>10} (of which {:.1}% are zero bytes)" ,
755+ prefix,
756+ "Total" ,
757+ to_readable_str( total_bytes) ,
795758 perc( zero_bytes)
796759 ) ;
797- p ( "preamble" , preamble_bytes) ;
798- p ( "dep" , dep_bytes) ;
799- p ( "lib feature" , lib_feature_bytes) ;
800- p ( "stability_implications" , stability_implications_bytes) ;
801- p ( "lang item" , lang_item_bytes) ;
802- p ( "diagnostic item" , diagnostic_item_bytes) ;
803- p ( "native lib" , native_lib_bytes) ;
804- p ( "foreign modules" , foreign_modules_bytes) ;
805- p ( "def-path table" , def_path_table_bytes) ;
806- p ( "traits" , traits_bytes) ;
807- p ( "impls" , impls_bytes) ;
808- p ( "incoherent_impls" , incoherent_impls_bytes) ;
809- p ( "mir" , mir_bytes) ;
810- p ( "item" , item_bytes) ;
811- p ( "interpret_alloc_index" , interpret_alloc_index_bytes) ;
812- p ( "proc-macro-data" , proc_macro_data_bytes) ;
813- p ( "tables" , tables_bytes) ;
814- p ( "debugger visualizers" , debugger_visualizers_bytes) ;
815- p ( "exported symbols" , exported_symbols_bytes) ;
816- p ( "hygiene" , hygiene_bytes) ;
817- p ( "def-path hashes" , def_path_hash_map_bytes) ;
818- p ( "source_map" , source_map_bytes) ;
819- p ( "final" , final_bytes) ;
820- eprintln ! ( "" ) ;
760+ eprintln ! ( "{}" , prefix) ;
821761 }
822762
823763 root
0 commit comments