3
3
use crate :: errors;
4
4
use rustc_data_structures:: memmap:: Mmap ;
5
5
use rustc_data_structures:: unord:: UnordMap ;
6
- use rustc_middle:: dep_graph:: { DepsType , SerializedDepGraph , WorkProductMap } ;
6
+ use rustc_middle:: dep_graph:: { DepGraph , DepsType , SerializedDepGraph , WorkProductMap } ;
7
7
use rustc_middle:: query:: on_disk_cache:: OnDiskCache ;
8
8
use rustc_serialize:: opaque:: MemDecoder ;
9
9
use rustc_serialize:: Decodable ;
10
10
use rustc_session:: config:: IncrementalStateAssertion ;
11
- use rustc_session:: Session ;
11
+ use rustc_session:: { Session , StableCrateId } ;
12
+ use rustc_span:: { ErrorGuaranteed , Symbol } ;
12
13
use std:: path:: { Path , PathBuf } ;
13
14
14
15
use super :: data:: * ;
15
16
use super :: file_format;
16
17
use super :: fs:: * ;
18
+ use super :: save:: build_dep_graph;
17
19
use super :: work_product;
18
20
19
21
#[ derive( Debug ) ]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
72
74
}
73
75
74
76
fn load_data ( path : & Path , sess : & Session ) -> LoadResult < ( Mmap , usize ) > {
75
- load_data_no_sess (
77
+ match file_format :: read_file (
76
78
path,
77
79
sess. opts . unstable_opts . incremental_info ,
78
80
sess. is_nightly_build ( ) ,
79
81
sess. cfg_version ,
80
- )
81
- }
82
-
83
- fn load_data_no_sess (
84
- path : & Path ,
85
- report_incremental_info : bool ,
86
- is_nightly_build : bool ,
87
- cfg_version : & ' static str ,
88
- ) -> LoadResult < ( Mmap , usize ) > {
89
- match file_format:: read_file ( path, report_incremental_info, is_nightly_build, cfg_version) {
82
+ ) {
90
83
Ok ( Some ( data_and_pos) ) => LoadResult :: Ok { data : data_and_pos } ,
91
84
Ok ( None ) => {
92
85
// The file either didn't exist or was produced by an incompatible
@@ -102,47 +95,19 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
102
95
work_product:: delete_workproduct_files ( sess, & swp. work_product ) ;
103
96
}
104
97
105
- /// Either a result that has already be computed or a
106
- /// handle that will let us wait until it is computed
107
- /// by a background thread.
108
- pub enum MaybeAsync < T > {
109
- Sync ( T ) ,
110
- Async ( std:: thread:: JoinHandle < T > ) ,
111
- }
112
-
113
- impl < T > MaybeAsync < LoadResult < T > > {
114
- /// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible.
115
- pub fn open ( self ) -> LoadResult < T > {
116
- match self {
117
- MaybeAsync :: Sync ( result) => result,
118
- MaybeAsync :: Async ( handle) => {
119
- handle. join ( ) . unwrap_or_else ( |e| LoadResult :: DecodeIncrCache ( e) )
120
- }
121
- }
122
- }
123
- }
124
-
125
- /// An asynchronous type for computing the dependency graph.
126
- pub type DepGraphFuture = MaybeAsync < LoadResult < ( SerializedDepGraph , WorkProductMap ) > > ;
127
-
128
- /// Launch a thread and load the dependency graph in the background.
129
- pub fn load_dep_graph ( sess : & Session ) -> DepGraphFuture {
130
- // Since `sess` isn't `Sync`, we perform all accesses to `sess`
131
- // before we fire the background thread.
132
-
98
+ fn load_dep_graph ( sess : & Session ) -> LoadResult < ( SerializedDepGraph , WorkProductMap ) > {
133
99
let prof = sess. prof . clone ( ) ;
134
100
135
101
if sess. opts . incremental . is_none ( ) {
136
102
// No incremental compilation.
137
- return MaybeAsync :: Sync ( LoadResult :: Ok { data : Default :: default ( ) } ) ;
103
+ return LoadResult :: Ok { data : Default :: default ( ) } ;
138
104
}
139
105
140
106
let _timer = sess. prof . generic_activity ( "incr_comp_prepare_load_dep_graph" ) ;
141
107
142
108
// Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
143
109
// Fortunately, we just checked that this isn't the case.
144
110
let path = dep_graph_path ( & sess) ;
145
- let report_incremental_info = sess. opts . unstable_opts . incremental_info ;
146
111
let expected_hash = sess. opts . dep_tracking_hash ( false ) ;
147
112
148
113
let mut prev_work_products = UnordMap :: default ( ) ;
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
180
145
}
181
146
}
182
147
183
- let is_nightly_build = sess. is_nightly_build ( ) ;
184
- let cfg_version = sess. cfg_version ;
185
-
186
- MaybeAsync :: Async ( std:: thread:: spawn ( move || {
187
- let _prof_timer = prof. generic_activity ( "incr_comp_load_dep_graph" ) ;
148
+ let _prof_timer = prof. generic_activity ( "incr_comp_load_dep_graph" ) ;
188
149
189
- match load_data_no_sess ( & path, report_incremental_info , is_nightly_build , cfg_version ) {
190
- LoadResult :: DataOutOfDate => LoadResult :: DataOutOfDate ,
191
- LoadResult :: LoadDepGraph ( path, err) => LoadResult :: LoadDepGraph ( path, err) ,
192
- LoadResult :: DecodeIncrCache ( err) => LoadResult :: DecodeIncrCache ( err) ,
193
- LoadResult :: Ok { data : ( bytes, start_pos) } => {
194
- let mut decoder = MemDecoder :: new ( & bytes, start_pos) ;
195
- let prev_commandline_args_hash = u64:: decode ( & mut decoder) ;
150
+ match load_data ( & path, sess ) {
151
+ LoadResult :: DataOutOfDate => LoadResult :: DataOutOfDate ,
152
+ LoadResult :: LoadDepGraph ( path, err) => LoadResult :: LoadDepGraph ( path, err) ,
153
+ LoadResult :: DecodeIncrCache ( err) => LoadResult :: DecodeIncrCache ( err) ,
154
+ LoadResult :: Ok { data : ( bytes, start_pos) } => {
155
+ let mut decoder = MemDecoder :: new ( & bytes, start_pos) ;
156
+ let prev_commandline_args_hash = u64:: decode ( & mut decoder) ;
196
157
197
- if prev_commandline_args_hash != expected_hash {
198
- if report_incremental_info {
199
- eprintln ! (
200
- "[incremental] completely ignoring cache because of \
158
+ if prev_commandline_args_hash != expected_hash {
159
+ if sess . opts . unstable_opts . incremental_info {
160
+ eprintln ! (
161
+ "[incremental] completely ignoring cache because of \
201
162
differing commandline arguments"
202
- ) ;
203
- }
204
- // We can't reuse the cache, purge it.
205
- debug ! ( "load_dep_graph_new: differing commandline arg hashes" ) ;
206
-
207
- // No need to do any further work
208
- return LoadResult :: DataOutOfDate ;
163
+ ) ;
209
164
}
165
+ // We can't reuse the cache, purge it.
166
+ debug ! ( "load_dep_graph_new: differing commandline arg hashes" ) ;
210
167
211
- let dep_graph = SerializedDepGraph :: decode :: < DepsType > ( & mut decoder) ;
212
-
213
- LoadResult :: Ok { data : ( dep_graph, prev_work_products) }
168
+ // No need to do any further work
169
+ return LoadResult :: DataOutOfDate ;
214
170
}
171
+
172
+ let dep_graph = SerializedDepGraph :: decode :: < DepsType > ( & mut decoder) ;
173
+
174
+ LoadResult :: Ok { data : ( dep_graph, prev_work_products) }
215
175
}
216
- } ) )
176
+ }
217
177
}
218
178
219
179
/// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
235
195
_ => Some ( OnDiskCache :: new_empty ( sess. source_map ( ) ) ) ,
236
196
}
237
197
}
198
+
199
+ /// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
200
+ /// new graph to an incremental session directory.
201
+ pub fn setup_dep_graph (
202
+ sess : & Session ,
203
+ crate_name : Symbol ,
204
+ stable_crate_id : StableCrateId ,
205
+ ) -> Result < DepGraph , ErrorGuaranteed > {
206
+ // `load_dep_graph` can only be called after `prepare_session_directory`.
207
+ prepare_session_directory ( sess, crate_name, stable_crate_id) ?;
208
+
209
+ let res = sess. opts . build_dep_graph ( ) . then ( || load_dep_graph ( sess) ) ;
210
+
211
+ if sess. opts . incremental . is_some ( ) {
212
+ sess. time ( "incr_comp_garbage_collect_session_directories" , || {
213
+ if let Err ( e) = garbage_collect_session_directories ( sess) {
214
+ warn ! (
215
+ "Error while trying to garbage collect incremental \
216
+ compilation cache directory: {}",
217
+ e
218
+ ) ;
219
+ }
220
+ } ) ;
221
+ }
222
+
223
+ Ok ( res
224
+ . and_then ( |result| {
225
+ let ( prev_graph, prev_work_products) = result. open ( sess) ;
226
+ build_dep_graph ( sess, prev_graph, prev_work_products)
227
+ } )
228
+ . unwrap_or_else ( DepGraph :: new_disabled) )
229
+ }
0 commit comments