1
- use crate :: dep_graph:: DepKind ;
2
- use crate :: ty:: context:: TyCtxt ;
3
1
use crate :: ty:: query:: config:: QueryContext ;
4
2
use crate :: ty:: query:: plumbing:: CycleError ;
5
- use crate :: ty :: query :: Query ;
3
+ # [ cfg ( parallel_compiler ) ]
6
4
use crate :: ty:: tls;
7
5
8
6
use rustc_data_structures:: fx:: FxHashMap ;
7
+ use rustc_query_system:: dep_graph:: DepContext ;
9
8
use rustc_span:: Span ;
10
9
11
10
use std:: convert:: TryFrom ;
@@ -28,13 +27,13 @@ use {
28
27
29
28
/// Represents a span and a query key.
30
29
#[ derive( Clone , Debug ) ]
31
- pub struct QueryInfo < CTX : QueryContext > {
30
+ pub struct QueryInfo < Q > {
32
31
/// The span corresponding to the reason for which this query was required.
33
32
pub span : Span ,
34
- pub query : CTX :: Query ,
33
+ pub query : Q ,
35
34
}
36
35
37
- type QueryMap < ' tcx > = FxHashMap < QueryJobId < DepKind > , QueryJobInfo < TyCtxt < ' tcx > > > ;
36
+ type QueryMap < CTX > = FxHashMap < QueryJobId < < CTX as DepContext > :: DepKind > , QueryJobInfo < CTX > > ;
38
37
39
38
/// A value uniquely identifiying an active query job within a shard in the query cache.
40
39
#[ derive( Copy , Clone , Eq , PartialEq , Hash ) ]
@@ -53,35 +52,36 @@ pub struct QueryJobId<K> {
53
52
pub kind : K ,
54
53
}
55
54
56
- impl < K > QueryJobId < K > {
55
+ impl < K : rustc_query_system :: dep_graph :: DepKind > QueryJobId < K > {
57
56
pub fn new ( job : QueryShardJobId , shard : usize , kind : K ) -> Self {
58
57
QueryJobId { job, shard : u16:: try_from ( shard) . unwrap ( ) , kind }
59
58
}
60
- }
61
59
62
- impl QueryJobId < DepKind > {
63
- fn query < ' tcx > ( self , map : & QueryMap < ' tcx > ) -> Query < ' tcx > {
60
+ fn query < CTX : QueryContext < DepKind = K > > ( self , map : & QueryMap < CTX > ) -> CTX :: Query {
64
61
map. get ( & self ) . unwrap ( ) . info . query . clone ( )
65
62
}
66
63
67
64
#[ cfg( parallel_compiler) ]
68
- fn span ( self , map : & QueryMap < ' _ > ) -> Span {
65
+ fn span < CTX : QueryContext < DepKind = K > > ( self , map : & QueryMap < CTX > ) -> Span {
69
66
map. get ( & self ) . unwrap ( ) . job . span
70
67
}
71
68
72
69
#[ cfg( parallel_compiler) ]
73
- fn parent ( self , map : & QueryMap < ' _ > ) -> Option < QueryJobId < DepKind > > {
70
+ fn parent < CTX : QueryContext < DepKind = K > > ( self , map : & QueryMap < CTX > ) -> Option < QueryJobId < K > > {
74
71
map. get ( & self ) . unwrap ( ) . job . parent
75
72
}
76
73
77
74
#[ cfg( parallel_compiler) ]
78
- fn latch < ' a , ' tcx > ( self , map : & ' a QueryMap < ' tcx > ) -> Option < & ' a QueryLatch < TyCtxt < ' tcx > > > {
75
+ fn latch < ' a , CTX : QueryContext < DepKind = K > > (
76
+ self ,
77
+ map : & ' a QueryMap < CTX > ,
78
+ ) -> Option < & ' a QueryLatch < CTX > > {
79
79
map. get ( & self ) . unwrap ( ) . job . latch . as_ref ( )
80
80
}
81
81
}
82
82
83
83
pub struct QueryJobInfo < CTX : QueryContext > {
84
- pub info : QueryInfo < CTX > ,
84
+ pub info : QueryInfo < CTX :: Query > ,
85
85
pub job : QueryJob < CTX > ,
86
86
}
87
87
@@ -147,16 +147,12 @@ pub(super) struct QueryLatch<CTX: QueryContext> {
147
147
}
148
148
149
149
#[ cfg( not( parallel_compiler) ) ]
150
- impl < ' tcx > QueryLatch < TyCtxt < ' tcx > > {
151
- pub ( super ) fn find_cycle_in_stack (
152
- & self ,
153
- tcx : TyCtxt < ' tcx > ,
154
- span : Span ,
155
- ) -> CycleError < TyCtxt < ' tcx > > {
156
- let query_map = tcx. queries . try_collect_active_jobs ( ) . unwrap ( ) ;
150
+ impl < CTX : QueryContext > QueryLatch < CTX > {
151
+ pub ( super ) fn find_cycle_in_stack ( & self , tcx : CTX , span : Span ) -> CycleError < CTX :: Query > {
152
+ let query_map = tcx. try_collect_active_jobs ( ) . unwrap ( ) ;
157
153
158
154
// Get the current executing query (waiter) and find the waitee amongst its parents
159
- let mut current_job = tls :: with_related_context ( tcx, |icx| icx . query ) ;
155
+ let mut current_job = tcx. read_query_job ( |query| query) ;
160
156
let mut cycle = Vec :: new ( ) ;
161
157
162
158
while let Some ( job) = current_job {
@@ -192,7 +188,7 @@ struct QueryWaiter<CTX: QueryContext> {
192
188
query : Option < QueryJobId < CTX :: DepKind > > ,
193
189
condvar : Condvar ,
194
190
span : Span ,
195
- cycle : Lock < Option < CycleError < CTX > > > ,
191
+ cycle : Lock < Option < CycleError < CTX :: Query > > > ,
196
192
}
197
193
198
194
#[ cfg( parallel_compiler) ]
@@ -225,13 +221,9 @@ impl<CTX: QueryContext> QueryLatch<CTX> {
225
221
}
226
222
227
223
#[ cfg( parallel_compiler) ]
228
- impl < K , CTX > QueryLatch < CTX >
229
- where
230
- K : rustc_query_system:: dep_graph:: DepKind ,
231
- CTX : QueryContext < DepKind = K > ,
232
- {
224
+ impl < CTX : QueryContext > QueryLatch < CTX > {
233
225
/// Awaits for the query job to complete.
234
- pub ( super ) fn wait_on ( & self , tcx : CTX , span : Span ) -> Result < ( ) , CycleError < CTX > > {
226
+ pub ( super ) fn wait_on ( & self , tcx : CTX , span : Span ) -> Result < ( ) , CycleError < CTX :: Query > > {
235
227
tcx. read_query_job ( move |query| {
236
228
let waiter = Lrc :: new ( QueryWaiter {
237
229
query,
@@ -299,7 +291,7 @@ impl<CTX: QueryContext> QueryLatch<CTX> {
299
291
300
292
/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
301
293
#[ cfg( parallel_compiler) ]
302
- type Waiter = ( QueryJobId < DepKind > , usize ) ;
294
+ type Waiter < K > = ( QueryJobId < K > , usize ) ;
303
295
304
296
/// Visits all the non-resumable and resumable waiters of a query.
305
297
/// Only waiters in a query are visited.
@@ -311,13 +303,13 @@ type Waiter = (QueryJobId<DepKind>, usize);
311
303
/// required information to resume the waiter.
312
304
/// If all `visit` calls returns None, this function also returns None.
313
305
#[ cfg( parallel_compiler) ]
314
- fn visit_waiters < ' tcx , F > (
315
- query_map : & QueryMap < ' tcx > ,
316
- query : QueryJobId < DepKind > ,
306
+ fn visit_waiters < CTX : QueryContext , F > (
307
+ query_map : & QueryMap < CTX > ,
308
+ query : QueryJobId < CTX :: DepKind > ,
317
309
mut visit : F ,
318
- ) -> Option < Option < Waiter > >
310
+ ) -> Option < Option < Waiter < CTX :: DepKind > > >
319
311
where
320
- F : FnMut ( Span , QueryJobId < DepKind > ) -> Option < Option < Waiter > > ,
312
+ F : FnMut ( Span , QueryJobId < CTX :: DepKind > ) -> Option < Option < Waiter < CTX :: DepKind > > > ,
321
313
{
322
314
// Visit the parent query which is a non-resumable waiter since it's on the same stack
323
315
if let Some ( parent) = query. parent ( query_map) {
@@ -346,13 +338,13 @@ where
346
338
/// If a cycle is detected, this initial value is replaced with the span causing
347
339
/// the cycle.
348
340
#[ cfg( parallel_compiler) ]
349
- fn cycle_check < ' tcx > (
350
- query_map : & QueryMap < ' tcx > ,
351
- query : QueryJobId < DepKind > ,
341
+ fn cycle_check < CTX : QueryContext > (
342
+ query_map : & QueryMap < CTX > ,
343
+ query : QueryJobId < CTX :: DepKind > ,
352
344
span : Span ,
353
- stack : & mut Vec < ( Span , QueryJobId < DepKind > ) > ,
354
- visited : & mut FxHashSet < QueryJobId < DepKind > > ,
355
- ) -> Option < Option < Waiter > > {
345
+ stack : & mut Vec < ( Span , QueryJobId < CTX :: DepKind > ) > ,
346
+ visited : & mut FxHashSet < QueryJobId < CTX :: DepKind > > ,
347
+ ) -> Option < Option < Waiter < CTX :: DepKind > > > {
356
348
if !visited. insert ( query) {
357
349
return if let Some ( p) = stack. iter ( ) . position ( |q| q. 1 == query) {
358
350
// We detected a query cycle, fix up the initial span and return Some
@@ -387,10 +379,10 @@ fn cycle_check<'tcx>(
387
379
/// from `query` without going through any of the queries in `visited`.
388
380
/// This is achieved with a depth first search.
389
381
#[ cfg( parallel_compiler) ]
390
- fn connected_to_root < ' tcx > (
391
- query_map : & QueryMap < ' tcx > ,
392
- query : QueryJobId < DepKind > ,
393
- visited : & mut FxHashSet < QueryJobId < DepKind > > ,
382
+ fn connected_to_root < CTX : QueryContext > (
383
+ query_map : & QueryMap < CTX > ,
384
+ query : QueryJobId < CTX :: DepKind > ,
385
+ visited : & mut FxHashSet < QueryJobId < CTX :: DepKind > > ,
394
386
) -> bool {
395
387
// We already visited this or we're deliberately ignoring it
396
388
if !visited. insert ( query) {
@@ -410,12 +402,12 @@ fn connected_to_root<'tcx>(
410
402
411
403
// Deterministically pick an query from a list
412
404
#[ cfg( parallel_compiler) ]
413
- fn pick_query < ' a , ' tcx , T , F : Fn ( & T ) -> ( Span , QueryJobId < DepKind > ) > (
414
- query_map : & QueryMap < ' tcx > ,
415
- tcx : TyCtxt < ' tcx > ,
416
- queries : & ' a [ T ] ,
417
- f : F ,
418
- ) -> & ' a T {
405
+ fn pick_query < ' a , CTX , T , F > ( query_map : & QueryMap < CTX > , tcx : CTX , queries : & ' a [ T ] , f : F ) -> & ' a T
406
+ where
407
+ CTX : QueryContext ,
408
+ CTX :: Query : HashStable < CTX :: StableHashingContext > ,
409
+ F : Fn ( & T ) -> ( Span , QueryJobId < CTX :: DepKind > ) ,
410
+ {
419
411
// Deterministically pick an entry point
420
412
// FIXME: Sort this instead
421
413
let mut hcx = tcx. create_stable_hashing_context ( ) ;
@@ -440,12 +432,15 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryJobId<DepKind>)>(
440
432
/// If a cycle was not found, the starting query is removed from `jobs` and
441
433
/// the function returns false.
442
434
#[ cfg( parallel_compiler) ]
443
- fn remove_cycle < ' tcx > (
444
- query_map : & QueryMap < ' tcx > ,
445
- jobs : & mut Vec < QueryJobId < DepKind > > ,
446
- wakelist : & mut Vec < Lrc < QueryWaiter < TyCtxt < ' tcx > > > > ,
447
- tcx : TyCtxt < ' tcx > ,
448
- ) -> bool {
435
+ fn remove_cycle < CTX : QueryContext > (
436
+ query_map : & QueryMap < CTX > ,
437
+ jobs : & mut Vec < QueryJobId < CTX :: DepKind > > ,
438
+ wakelist : & mut Vec < Lrc < QueryWaiter < CTX > > > ,
439
+ tcx : CTX ,
440
+ ) -> bool
441
+ where
442
+ CTX :: Query : HashStable < CTX :: StableHashingContext > ,
443
+ {
449
444
let mut visited = FxHashSet :: default ( ) ;
450
445
let mut stack = Vec :: new ( ) ;
451
446
// Look for a cycle starting with the last query in `jobs`
@@ -497,7 +492,7 @@ fn remove_cycle<'tcx>(
497
492
}
498
493
}
499
494
} )
500
- . collect :: < Vec < ( Span , QueryJobId < DepKind > , Option < ( Span , QueryJobId < DepKind > ) > ) > > ( ) ;
495
+ . collect :: < Vec < ( Span , QueryJobId < CTX :: DepKind > , Option < ( Span , QueryJobId < CTX :: DepKind > ) > ) > > ( ) ;
501
496
502
497
// Deterministically pick an entry point
503
498
let ( _, entry_point, usage) = pick_query ( query_map, tcx, & entry_points, |e| ( e. 0 , e. 1 ) ) ;
@@ -569,15 +564,18 @@ pub unsafe fn handle_deadlock() {
569
564
/// There may be multiple cycles involved in a deadlock, so this searches
570
565
/// all active queries for cycles before finally resuming all the waiters at once.
571
566
#[ cfg( parallel_compiler) ]
572
- fn deadlock ( tcx : TyCtxt < ' _ > , registry : & rayon_core:: Registry ) {
567
+ fn deadlock < CTX : QueryContext > ( tcx : CTX , registry : & rayon_core:: Registry )
568
+ where
569
+ CTX :: Query : HashStable < CTX :: StableHashingContext > ,
570
+ {
573
571
let on_panic = OnDrop ( || {
574
572
eprintln ! ( "deadlock handler panicked, aborting process" ) ;
575
573
process:: abort ( ) ;
576
574
} ) ;
577
575
578
576
let mut wakelist = Vec :: new ( ) ;
579
- let query_map = tcx. queries . try_collect_active_jobs ( ) . unwrap ( ) ;
580
- let mut jobs: Vec < QueryJobId < DepKind > > = query_map. keys ( ) . cloned ( ) . collect ( ) ;
577
+ let query_map = tcx. try_collect_active_jobs ( ) . unwrap ( ) ;
578
+ let mut jobs: Vec < QueryJobId < CTX :: DepKind > > = query_map. keys ( ) . cloned ( ) . collect ( ) ;
581
579
582
580
let mut found_cycle = false ;
583
581
0 commit comments