@@ -11,6 +11,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
11
11
use parking_lot:: Mutex ;
12
12
use smallvec:: { smallvec, SmallVec } ;
13
13
use std:: collections:: hash_map:: Entry ;
14
+ use std:: fmt:: Debug ;
14
15
use std:: hash:: Hash ;
15
16
use std:: marker:: PhantomData ;
16
17
use std:: sync:: atomic:: Ordering :: Relaxed ;
@@ -208,89 +209,99 @@ impl<K: DepKind> DepGraph<K> {
208
209
/// `arg` parameter.
209
210
///
210
211
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html
211
- pub fn with_task < Ctxt : HasDepContext < DepKind = K > , A , R > (
212
+ pub fn with_task < Ctxt : HasDepContext < DepKind = K > , A : Debug , R > (
212
213
& self ,
213
214
key : DepNode < K > ,
214
215
cx : Ctxt ,
215
216
arg : A ,
216
217
task : fn ( Ctxt , A ) -> R ,
217
- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
218
+ hash_result : fn ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
218
219
) -> ( R , DepNodeIndex ) {
219
- self . with_task_impl (
220
- key,
221
- cx,
222
- arg,
223
- task,
224
- |_key| {
225
- Some ( TaskDeps {
226
- #[ cfg( debug_assertions) ]
227
- node : Some ( _key) ,
228
- reads : SmallVec :: new ( ) ,
229
- read_set : Default :: default ( ) ,
230
- phantom_data : PhantomData ,
231
- } )
232
- } ,
233
- hash_result,
234
- )
220
+ if self . is_fully_enabled ( ) {
221
+ self . with_task_impl ( key, cx, arg, task, hash_result)
222
+ } else {
223
+ // Incremental compilation is turned off. We just execute the task
224
+ // without tracking. We still provide a dep-node index that uniquely
225
+ // identifies the task so that we have a cheap way of referring to
226
+ // the query for self-profiling.
227
+ ( task ( cx, arg) , self . next_virtual_depnode_index ( ) )
228
+ }
235
229
}
236
230
237
- fn with_task_impl < Ctxt : HasDepContext < DepKind = K > , A , R > (
231
+ fn with_task_impl < Ctxt : HasDepContext < DepKind = K > , A : Debug , R > (
238
232
& self ,
239
233
key : DepNode < K > ,
240
234
cx : Ctxt ,
241
235
arg : A ,
242
236
task : fn ( Ctxt , A ) -> R ,
243
- create_task : fn ( DepNode < K > ) -> Option < TaskDeps < K > > ,
244
- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
237
+ hash_result : fn ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
245
238
) -> ( R , DepNodeIndex ) {
246
- if let Some ( ref data) = self . data {
247
- let dcx = cx. dep_context ( ) ;
248
- let task_deps = create_task ( key) . map ( Lock :: new) ;
249
- let result = K :: with_deps ( task_deps. as_ref ( ) , || task ( cx, arg) ) ;
250
- let edges = task_deps. map_or_else ( || smallvec ! [ ] , |lock| lock. into_inner ( ) . reads ) ;
251
-
252
- let mut hcx = dcx. create_stable_hashing_context ( ) ;
253
- let hashing_timer = dcx. profiler ( ) . incr_result_hashing ( ) ;
254
- let current_fingerprint = hash_result ( & mut hcx, & result) ;
255
-
256
- let print_status = cfg ! ( debug_assertions) && dcx. sess ( ) . opts . debugging_opts . dep_tasks ;
257
-
258
- // Get timer for profiling `DepNode` interning
259
- let node_intern_timer = self
260
- . node_intern_event_id
261
- . map ( |eid| dcx. profiler ( ) . generic_activity_with_event_id ( eid) ) ;
262
- // Intern the new `DepNode`.
263
- let ( dep_node_index, prev_and_color) = data. current . intern_node (
264
- dcx. profiler ( ) ,
265
- & data. previous ,
266
- key,
267
- edges,
268
- current_fingerprint,
269
- print_status,
270
- ) ;
271
- drop ( node_intern_timer) ;
239
+ // This function is only called when the graph is enabled.
240
+ let data = self . data . as_ref ( ) . unwrap ( ) ;
272
241
273
- hashing_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
242
+ // If the following assertion triggers, it can have two reasons:
243
+ // 1. Something is wrong with DepNode creation, either here or
244
+ // in `DepGraph::try_mark_green()`.
245
+ // 2. Two distinct query keys get mapped to the same `DepNode`
246
+ // (see for example #48923).
247
+ assert ! (
248
+ !self . dep_node_exists( & key) ,
249
+ "forcing query with already existing `DepNode`\n \
250
+ - query-key: {:?}\n \
251
+ - dep-node: {:?}",
252
+ arg,
253
+ key
254
+ ) ;
274
255
275
- if let Some ( ( prev_index, color) ) = prev_and_color {
276
- debug_assert ! (
277
- data. colors. get( prev_index) . is_none( ) ,
278
- "DepGraph::with_task() - Duplicate DepNodeColor \
279
- insertion for {:?}",
280
- key
281
- ) ;
256
+ let task_deps = if key. kind . is_eval_always ( ) {
257
+ None
258
+ } else {
259
+ Some ( Lock :: new ( TaskDeps {
260
+ #[ cfg( debug_assertions) ]
261
+ node : Some ( key) ,
262
+ reads : SmallVec :: new ( ) ,
263
+ read_set : Default :: default ( ) ,
264
+ phantom_data : PhantomData ,
265
+ } ) )
266
+ } ;
267
+ let result = K :: with_deps ( task_deps. as_ref ( ) , || task ( cx, arg) ) ;
268
+ let edges = task_deps. map_or_else ( || smallvec ! [ ] , |lock| lock. into_inner ( ) . reads ) ;
269
+
270
+ let dcx = cx. dep_context ( ) ;
271
+ let mut hcx = dcx. create_stable_hashing_context ( ) ;
272
+ let hashing_timer = dcx. profiler ( ) . incr_result_hashing ( ) ;
273
+ let current_fingerprint = hash_result ( & mut hcx, & result) ;
274
+
275
+ let print_status = cfg ! ( debug_assertions) && dcx. sess ( ) . opts . debugging_opts . dep_tasks ;
276
+
277
+ // Get timer for profiling `DepNode` interning
278
+ let node_intern_timer =
279
+ self . node_intern_event_id . map ( |eid| dcx. profiler ( ) . generic_activity_with_event_id ( eid) ) ;
280
+ // Intern the new `DepNode`.
281
+ let ( dep_node_index, prev_and_color) = data. current . intern_node (
282
+ dcx. profiler ( ) ,
283
+ & data. previous ,
284
+ key,
285
+ edges,
286
+ current_fingerprint,
287
+ print_status,
288
+ ) ;
289
+ drop ( node_intern_timer) ;
282
290
283
- data. colors . insert ( prev_index, color) ;
284
- }
291
+ hashing_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
285
292
286
- ( result, dep_node_index)
287
- } else {
288
- // Incremental compilation is turned off. We just execute the task
289
- // without tracking. We still provide a dep-node index that uniquely
290
- // identifies the task so that we have a cheap way of referring to
291
- // the query for self-profiling.
292
- ( task ( cx, arg) , self . next_virtual_depnode_index ( ) )
293
+ if let Some ( ( prev_index, color) ) = prev_and_color {
294
+ debug_assert ! (
295
+ data. colors. get( prev_index) . is_none( ) ,
296
+ "DepGraph::with_task() - Duplicate DepNodeColor \
297
+ insertion for {:?}",
298
+ key
299
+ ) ;
300
+
301
+ data. colors . insert ( prev_index, color) ;
293
302
}
303
+
304
+ ( result, dep_node_index)
294
305
}
295
306
296
307
/// Executes something within an "anonymous" task, that is, a task the
@@ -357,19 +368,6 @@ impl<K: DepKind> DepGraph<K> {
357
368
}
358
369
}
359
370
360
- /// Executes something within an "eval-always" task which is a task
361
- /// that runs whenever anything changes.
362
- pub fn with_eval_always_task < Ctxt : HasDepContext < DepKind = K > , A , R > (
363
- & self ,
364
- key : DepNode < K > ,
365
- cx : Ctxt ,
366
- arg : A ,
367
- task : fn ( Ctxt , A ) -> R ,
368
- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
369
- ) -> ( R , DepNodeIndex ) {
370
- self . with_task_impl ( key, cx, arg, task, |_| None , hash_result)
371
- }
372
-
373
371
#[ inline]
374
372
pub fn read_index ( & self , dep_node_index : DepNodeIndex ) {
375
373
if let Some ( ref data) = self . data {
@@ -484,22 +482,11 @@ impl<K: DepKind> DepGraph<K> {
484
482
None
485
483
}
486
484
487
- /// Try to read a node index for the node dep_node.
485
+ /// Try to mark a node index for the node dep_node.
486
+ ///
488
487
/// A node will have an index, when it's already been marked green, or when we can mark it
489
488
/// green. This function will mark the current task as a reader of the specified node, when
490
489
/// a node index can be found for that node.
491
- pub fn try_mark_green_and_read < Ctxt : QueryContext < DepKind = K > > (
492
- & self ,
493
- tcx : Ctxt ,
494
- dep_node : & DepNode < K > ,
495
- ) -> Option < ( SerializedDepNodeIndex , DepNodeIndex ) > {
496
- self . try_mark_green ( tcx, dep_node) . map ( |( prev_index, dep_node_index) | {
497
- debug_assert ! ( self . is_green( & dep_node) ) ;
498
- self . read_index ( dep_node_index) ;
499
- ( prev_index, dep_node_index)
500
- } )
501
- }
502
-
503
490
pub fn try_mark_green < Ctxt : QueryContext < DepKind = K > > (
504
491
& self ,
505
492
tcx : Ctxt ,
0 commit comments