10
10
11
11
//! Code to save/load the dep-graph from files.
12
12
13
- use rustc:: dep_graph:: { PreviousDepGraph , SerializedDepGraph } ;
13
+ use rustc_data_structures:: fx:: FxHashMap ;
14
+ use rustc:: dep_graph:: { PreviousDepGraph , SerializedDepGraph , WorkProduct , WorkProductId } ;
14
15
use rustc:: session:: Session ;
15
16
use rustc:: ty:: TyCtxt ;
16
17
use rustc:: ty:: maps:: OnDiskCache ;
@@ -32,73 +33,30 @@ pub fn dep_graph_tcx_init<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
32
33
33
34
tcx. allocate_metadata_dep_nodes ( ) ;
34
35
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
- }
79
36
}
80
37
38
+ type WorkProductMap = FxHashMap < WorkProductId , WorkProduct > ;
39
+
81
40
pub enum LoadResult < T > {
82
41
Ok { data : T } ,
83
42
DataOutOfDate ,
84
43
Error { message : String } ,
85
44
}
86
45
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 ) {
90
48
match self {
91
49
LoadResult :: Error { message } => {
92
50
sess. warn ( & message) ;
93
- PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
51
+ ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
94
52
} ,
95
53
LoadResult :: DataOutOfDate => {
96
54
if let Err ( err) = delete_all_session_dir_contents ( sess) {
97
55
sess. err ( & format ! ( "Failed to delete invalidated or incompatible \
98
56
incremental compilation session directory contents `{}`: {}.",
99
57
dep_graph_path( sess) . display( ) , err) ) ;
100
58
}
101
- PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
59
+ ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
102
60
}
103
61
LoadResult :: Ok { data } => data
104
62
}
@@ -125,10 +83,10 @@ fn load_data(report_incremental_info: bool, path: &Path) -> LoadResult<(Vec<u8>,
125
83
}
126
84
}
127
85
128
- fn delete_dirty_work_product ( tcx : TyCtxt ,
86
+ fn delete_dirty_work_product ( sess : & Session ,
129
87
swp : SerializedWorkProduct ) {
130
88
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 ) ;
132
90
}
133
91
134
92
/// Either a result that has already be computed or a
@@ -149,7 +107,7 @@ impl<T> MaybeAsync<T> {
149
107
150
108
/// Launch a thread and load the dependency graph in the background.
151
109
pub fn load_dep_graph ( sess : & Session ) ->
152
- MaybeAsync < LoadResult < PreviousDepGraph > >
110
+ MaybeAsync < LoadResult < ( PreviousDepGraph , WorkProductMap ) > >
153
111
{
154
112
// Since `sess` isn't `Sync`, we perform all accesses to `sess`
155
113
// before we fire the background thread.
@@ -159,7 +117,7 @@ pub fn load_dep_graph(sess: &Session) ->
159
117
if sess. opts . incremental . is_none ( ) {
160
118
// No incremental compilation.
161
119
return MaybeAsync :: Sync ( LoadResult :: Ok {
162
- data : PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) )
120
+ data : ( PreviousDepGraph :: new ( SerializedDepGraph :: new ( ) ) , FxHashMap ( ) )
163
121
} ) ;
164
122
}
165
123
@@ -169,6 +127,50 @@ pub fn load_dep_graph(sess: &Session) ->
169
127
let report_incremental_info = sess. opts . debugging_opts . incremental_info ;
170
128
let expected_hash = sess. opts . dep_tracking_hash ( ) ;
171
129
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 exit here. 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
+
172
174
MaybeAsync :: Async ( std:: thread:: spawn ( move || {
173
175
time_ext ( time_passes, None , "background load prev dep-graph" , move || {
174
176
match load_data ( report_incremental_info, & path) {
@@ -195,7 +197,7 @@ pub fn load_dep_graph(sess: &Session) ->
195
197
let dep_graph = SerializedDepGraph :: decode ( & mut decoder)
196
198
. expect ( "Error reading cached dep-graph" ) ;
197
199
198
- LoadResult :: Ok { data : PreviousDepGraph :: new ( dep_graph) }
200
+ LoadResult :: Ok { data : ( PreviousDepGraph :: new ( dep_graph) , prev_work_products ) }
199
201
}
200
202
}
201
203
} )
0 commit comments