@@ -28,6 +28,7 @@ use rustc_middle::ty::codec::TyEncoder;
28
28
use rustc_middle:: ty:: fast_reject:: { self , SimplifiedType , TreatParams } ;
29
29
use rustc_middle:: ty:: query:: Providers ;
30
30
use rustc_middle:: ty:: { self , SymbolName , Ty , TyCtxt } ;
31
+ use rustc_middle:: util:: common:: to_readable_str;
31
32
use rustc_serialize:: { opaque, Decodable , Decoder , Encodable , Encoder } ;
32
33
use rustc_session:: config:: CrateType ;
33
34
use rustc_session:: cstore:: { ForeignModule , LinkagePreference , NativeLib } ;
@@ -554,78 +555,56 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
554
555
555
556
fn encode_crate_root ( & mut self ) -> LazyValue < CrateRoot > {
556
557
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( ) ) ;
600
591
601
592
// 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( ) ) ;
605
594
606
595
// 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" , || {
629
608
let mut interpret_alloc_index = Vec :: new( ) ;
630
609
let mut n = 0 ;
631
610
trace!( "beginning to encode alloc ids" ) ;
@@ -646,125 +625,90 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
646
625
n = new_n;
647
626
}
648
627
self . lazy_array( interpret_alloc_index)
649
- } ;
650
- let interpret_alloc_index_bytes = self . position ( ) - i;
628
+ } ) ;
651
629
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( ) ) ;
658
634
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) ) ;
662
636
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( ) ) ;
666
639
667
640
// Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
668
641
// 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
+ } ) ;
673
645
674
- // Encode the hygiene data,
646
+ // Encode the hygiene data.
675
647
// IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
676
648
// process of encoding other items (e.g. `optimized_mir`) may cause us to load data from
677
649
// the incremental cache. If this causes us to deserialize a `Span`, then we may load
678
650
// additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode
679
651
// 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
+ } )
740
707
} ) ;
741
- let final_bytes = self . position ( ) - i;
742
708
743
709
let total_bytes = self . position ( ) ;
744
710
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 ( ) ;
768
712
assert_eq ! ( total_bytes, computed_total_bytes) ;
769
713
770
714
if tcx. sess . meta_stats ( ) {
@@ -782,42 +726,38 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
782
726
}
783
727
assert_eq ! ( self . opaque. file( ) . stream_position( ) . unwrap( ) , pos_before_rewind) ;
784
728
729
+ stats. sort_by_key ( |& ( _, usize) | usize) ;
730
+
731
+ let prefix = "meta-stats" ;
785
732
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
- } ;
789
733
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
+ ) ;
791
753
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) ,
795
758
perc( zero_bytes)
796
759
) ;
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) ;
821
761
}
822
762
823
763
root
0 commit comments