1010
1111//! Code to save/load the dep-graph from files.
1212
13- use rustc:: dep_graph:: { PreviousDepGraph , SerializedDepGraph } ;
13+ use rustc_data_structures:: fx:: FxHashMap ;
14+ use rustc:: dep_graph:: { PreviousDepGraph , SerializedDepGraph , WorkProduct , WorkProductId } ;
1415use rustc:: session:: Session ;
1516use rustc:: ty:: TyCtxt ;
1617use rustc:: ty:: maps:: OnDiskCache ;
@@ -32,73 +33,30 @@ pub fn dep_graph_tcx_init<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
3233
3334 tcx. allocate_metadata_dep_nodes ( ) ;
3435 tcx. precompute_in_scope_traits_hashes ( ) ;
35-
36- if tcx. sess . incr_comp_session_dir_opt ( ) . is_none ( ) {
37- // If we are only building with -Zquery-dep-graph but without an actual
38- // incr. comp. session directory, we exit here. Otherwise we'd fail
39- // when trying to load work products.
40- return
41- }
42-
43- let work_products_path = work_products_path ( tcx. sess ) ;
44- let load_result = load_data ( tcx. sess . opts . debugging_opts . incremental_info , & work_products_path) ;
45-
46- if let LoadResult :: Ok { data : ( work_products_data, start_pos) } = load_result {
47- // Decode the list of work_products
48- let mut work_product_decoder = Decoder :: new ( & work_products_data[ ..] , start_pos) ;
49- let work_products: Vec < SerializedWorkProduct > =
50- RustcDecodable :: decode ( & mut work_product_decoder) . unwrap_or_else ( |e| {
51- let msg = format ! ( "Error decoding `work-products` from incremental \
52- compilation session directory: {}", e) ;
53- tcx. sess . fatal ( & msg[ ..] )
54- } ) ;
55-
56- for swp in work_products {
57- let mut all_files_exist = true ;
58- for & ( _, ref file_name) in swp. work_product . saved_files . iter ( ) {
59- let path = in_incr_comp_dir_sess ( tcx. sess , file_name) ;
60- if !path. exists ( ) {
61- all_files_exist = false ;
62-
63- if tcx. sess . opts . debugging_opts . incremental_info {
64- eprintln ! ( "incremental: could not find file for work \
65- product: {}", path. display( ) ) ;
66- }
67- }
68- }
69-
70- if all_files_exist {
71- debug ! ( "reconcile_work_products: all files for {:?} exist" , swp) ;
72- tcx. dep_graph . insert_previous_work_product ( & swp. id , swp. work_product ) ;
73- } else {
74- debug ! ( "reconcile_work_products: some file for {:?} does not exist" , swp) ;
75- delete_dirty_work_product ( tcx, swp) ;
76- }
77- }
78- }
7936}
8037
38+ type WorkProductMap = FxHashMap < WorkProductId , WorkProduct > ;
39+
8140pub enum LoadResult < T > {
8241 Ok { data : T } ,
8342 DataOutOfDate ,
8443 Error { message : String } ,
8544}
8645
87-
88- impl LoadResult < PreviousDepGraph > {
89- pub fn open ( self , sess : & Session ) -> PreviousDepGraph {
46+ impl LoadResult < ( PreviousDepGraph , WorkProductMap ) > {
47+ pub fn open ( self , sess : & Session ) -> ( PreviousDepGraph , WorkProductMap ) {
9048 match self {
9149 LoadResult :: Error { message } => {
9250 sess. warn ( & message) ;
93- PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
51+ ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
9452 } ,
9553 LoadResult :: DataOutOfDate => {
9654 if let Err ( err) = delete_all_session_dir_contents ( sess) {
9755 sess. err ( & format ! ( "Failed to delete invalidated or incompatible \
9856 incremental compilation session directory contents `{}`: {}.",
9957 dep_graph_path( sess) . display( ) , err) ) ;
10058 }
101- PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
59+ ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
10260 }
10361 LoadResult :: Ok { data } => data
10462 }
@@ -125,10 +83,10 @@ fn load_data(report_incremental_info: bool, path: &Path) -> LoadResult<(Vec<u8>,
12583 }
12684}
12785
128- fn delete_dirty_work_product ( tcx : TyCtxt ,
86+ fn delete_dirty_work_product ( sess : & Session ,
12987 swp : SerializedWorkProduct ) {
13088 debug ! ( "delete_dirty_work_product({:?})" , swp) ;
131- work_product:: delete_workproduct_files ( tcx . sess , & swp. work_product ) ;
89+ work_product:: delete_workproduct_files ( sess, & swp. work_product ) ;
13290}
13391
13492/// Either a result that has already be computed or a
@@ -149,7 +107,7 @@ impl<T> MaybeAsync<T> {
149107
150108/// Launch a thread and load the dependency graph in the background.
151109pub fn load_dep_graph ( sess : & Session ) ->
152- MaybeAsync < LoadResult < PreviousDepGraph > >
110+ MaybeAsync < LoadResult < ( PreviousDepGraph , WorkProductMap ) > >
153111{
154112 // Since `sess` isn't `Sync`, we perform all accesses to `sess`
155113 // before we fire the background thread.
@@ -159,7 +117,7 @@ pub fn load_dep_graph(sess: &Session) ->
159117 if sess. opts . incremental . is_none ( ) {
160118 // No incremental compilation.
161119 return MaybeAsync :: Sync ( LoadResult :: Ok {
162- data : PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
120+ data : ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
163121 } ) ;
164122 }
165123
@@ -169,6 +127,50 @@ pub fn load_dep_graph(sess: &Session) ->
169127 let report_incremental_info = sess. opts . debugging_opts . incremental_info ;
170128 let expected_hash = sess. opts . dep_tracking_hash ( ) ;
171129
130+ let mut prev_work_products = FxHashMap ( ) ;
131+
132+ // If we are only building with -Zquery-dep-graph but without an actual
133+ // incr. comp. session directory, we skip this. Otherwise we'd fail
134+ // when trying to load work products.
135+ if sess. incr_comp_session_dir_opt ( ) . is_some ( ) {
136+ let work_products_path = work_products_path ( sess) ;
137+ let load_result = load_data ( report_incremental_info, & work_products_path) ;
138+
139+ if let LoadResult :: Ok { data : ( work_products_data, start_pos) } = load_result {
140+ // Decode the list of work_products
141+ let mut work_product_decoder = Decoder :: new ( & work_products_data[ ..] , start_pos) ;
142+ let work_products: Vec < SerializedWorkProduct > =
143+ RustcDecodable :: decode ( & mut work_product_decoder) . unwrap_or_else ( |e| {
144+ let msg = format ! ( "Error decoding `work-products` from incremental \
145+ compilation session directory: {}", e) ;
146+ sess. fatal ( & msg[ ..] )
147+ } ) ;
148+
149+ for swp in work_products {
150+ let mut all_files_exist = true ;
151+ for & ( _, ref file_name) in swp. work_product . saved_files . iter ( ) {
152+ let path = in_incr_comp_dir_sess ( sess, file_name) ;
153+ if !path. exists ( ) {
154+ all_files_exist = false ;
155+
156+ if sess. opts . debugging_opts . incremental_info {
157+ eprintln ! ( "incremental: could not find file for work \
158+ product: {}", path. display( ) ) ;
159+ }
160+ }
161+ }
162+
163+ if all_files_exist {
164+ debug ! ( "reconcile_work_products: all files for {:?} exist" , swp) ;
165+ prev_work_products. insert ( swp. id , swp. work_product ) ;
166+ } else {
167+ debug ! ( "reconcile_work_products: some file for {:?} does not exist" , swp) ;
168+ delete_dirty_work_product ( sess, swp) ;
169+ }
170+ }
171+ }
172+ }
173+
172174 MaybeAsync :: Async ( std:: thread:: spawn ( move || {
173175 time_ext ( time_passes, None , "background load prev dep-graph" , move || {
174176 match load_data ( report_incremental_info, & path) {
@@ -195,7 +197,7 @@ pub fn load_dep_graph(sess: &Session) ->
195197 let dep_graph = SerializedDepGraph :: decode ( & mut decoder)
196198 . expect ( "Error reading cached dep-graph" ) ;
197199
198- LoadResult :: Ok { data : PreviousDepGraph :: new ( dep_graph) }
200+ LoadResult :: Ok { data : ( PreviousDepGraph :: new ( dep_graph) , prev_work_products ) }
199201 }
200202 }
201203 } )
0 commit comments