33use crate :: errors;
44use rustc_data_structures:: memmap:: Mmap ;
55use rustc_data_structures:: unord:: UnordMap ;
6- use rustc_middle:: dep_graph:: { DepsType , SerializedDepGraph , WorkProductMap } ;
6+ use rustc_middle:: dep_graph:: { DepGraph , DepsType , SerializedDepGraph , WorkProductMap } ;
77use rustc_middle:: query:: on_disk_cache:: OnDiskCache ;
88use rustc_serialize:: opaque:: MemDecoder ;
99use rustc_serialize:: Decodable ;
1010use rustc_session:: config:: IncrementalStateAssertion ;
11- use rustc_session:: Session ;
11+ use rustc_session:: { Session , StableCrateId } ;
12+ use rustc_span:: { ErrorGuaranteed , Symbol } ;
1213use std:: path:: { Path , PathBuf } ;
1314
1415use super :: data:: * ;
1516use super :: file_format;
1617use super :: fs:: * ;
18+ use super :: save:: build_dep_graph;
1719use super :: work_product;
1820
1921#[ derive( Debug ) ]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
7274}
7375
7476fn load_data ( path : & Path , sess : & Session ) -> LoadResult < ( Mmap , usize ) > {
75- load_data_no_sess (
77+ match file_format :: read_file (
7678 path,
7779 sess. opts . unstable_opts . incremental_info ,
7880 sess. is_nightly_build ( ) ,
7981 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+ ) {
9083 Ok ( Some ( data_and_pos) ) => LoadResult :: Ok { data : data_and_pos } ,
9184 Ok ( None ) => {
9285 // 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) {
10295 work_product:: delete_workproduct_files ( sess, & swp. work_product ) ;
10396}
10497
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 ) > {
13399 let prof = sess. prof . clone ( ) ;
134100
135101 if sess. opts . incremental . is_none ( ) {
136102 // No incremental compilation.
137- return MaybeAsync :: Sync ( LoadResult :: Ok { data : Default :: default ( ) } ) ;
103+ return LoadResult :: Ok { data : Default :: default ( ) } ;
138104 }
139105
140106 let _timer = sess. prof . generic_activity ( "incr_comp_prepare_load_dep_graph" ) ;
141107
142108 // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
143109 // Fortunately, we just checked that this isn't the case.
144110 let path = dep_graph_path ( & sess) ;
145- let report_incremental_info = sess. opts . unstable_opts . incremental_info ;
146111 let expected_hash = sess. opts . dep_tracking_hash ( false ) ;
147112
148113 let mut prev_work_products = UnordMap :: default ( ) ;
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
180145 }
181146 }
182147
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" ) ;
188149
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) ;
196157
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 \
201162 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+ ) ;
209164 }
165+ // We can't reuse the cache, purge it.
166+ debug ! ( "load_dep_graph_new: differing commandline arg hashes" ) ;
210167
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 ;
214170 }
171+
172+ let dep_graph = SerializedDepGraph :: decode :: < DepsType > ( & mut decoder) ;
173+
174+ LoadResult :: Ok { data : ( dep_graph, prev_work_products) }
215175 }
216- } ) )
176+ }
217177}
218178
219179/// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
235195 _ => Some ( OnDiskCache :: new_empty ( sess. source_map ( ) ) ) ,
236196 }
237197}
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