@@ -159,7 +159,11 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
159
159
return TryGetJob :: Cycle ( Q :: handle_cycle_error ( tcx, cycle) ) ;
160
160
}
161
161
162
- let cached = tcx. try_get_cached :: < Q > ( key) . 0 . unwrap ( ) ;
162
+ let cached = tcx. try_get_cached :: < Q , _ , _ , _ > (
163
+ key,
164
+ |( value, index) | ( value. clone ( ) , index) ,
165
+ |_, _| panic ! ( "value must be in cache after waiting" ) ,
166
+ ) ;
163
167
164
168
if let Some ( prof_timer) = _query_blocked_prof_timer. take ( ) {
165
169
prof_timer. finish_with_query_invocation_id ( cached. 1 . into ( ) ) ;
@@ -374,10 +378,18 @@ impl<'tcx> TyCtxt<'tcx> {
374
378
/// which will be used if the query is not in the cache and we need
375
379
/// to compute it.
376
380
#[ inline( always) ]
377
- fn try_get_cached < Q : QueryDescription < ' tcx > > (
381
+ fn try_get_cached < Q , R , OnHit , OnMiss > (
378
382
self ,
379
- key : & Q :: Key ,
380
- ) -> ( Option < ( Q :: Value , DepNodeIndex ) > , QueryLookup < ' tcx , Q > ) {
383
+ key : Q :: Key ,
384
+ // `on_hit` can be called while holding a lock to the query cache
385
+ on_hit : OnHit ,
386
+ on_miss : OnMiss ,
387
+ ) -> R
388
+ where
389
+ Q : QueryDescription < ' tcx > + ' tcx ,
390
+ OnHit : FnOnce ( & Q :: Value , DepNodeIndex ) -> R ,
391
+ OnMiss : FnOnce ( Q :: Key , QueryLookup < ' tcx , Q > ) -> R ,
392
+ {
381
393
let cache = Q :: query_cache ( self ) ;
382
394
383
395
// We compute the key's hash once and then use it for both the
@@ -391,23 +403,17 @@ impl<'tcx> TyCtxt<'tcx> {
391
403
let mut lock_guard = cache. get_shard_by_index ( shard) . lock ( ) ;
392
404
let lock = & mut * lock_guard;
393
405
394
- let result =
395
- lock. results . raw_entry ( ) . from_key_hashed_nocheck ( key_hash, key) . map ( |( _, value) | {
396
- if unlikely ! ( self . prof. enabled( ) ) {
397
- self . prof . query_cache_hit ( value. index . into ( ) ) ;
398
- }
406
+ let result = lock. results . raw_entry ( ) . from_key_hashed_nocheck ( key_hash, & key) ;
399
407
400
- ( value. value . clone ( ) , value. index )
401
- } ) ;
402
-
403
- #[ cfg( debug_assertions) ]
404
- {
405
- if result. is_some ( ) {
406
- lock. cache_hits += 1 ;
408
+ if let Some ( ( _, value) ) = result {
409
+ if unlikely ! ( self . prof. enabled( ) ) {
410
+ self . prof . query_cache_hit ( value. index . into ( ) ) ;
407
411
}
408
- }
409
412
410
- ( result, QueryLookup { lock : lock_guard, shard } )
413
+ on_hit ( & value. value , value. index )
414
+ } else {
415
+ on_miss ( key, QueryLookup { lock : lock_guard, shard } )
416
+ }
411
417
}
412
418
413
419
#[ inline( never) ]
@@ -418,14 +424,14 @@ impl<'tcx> TyCtxt<'tcx> {
418
424
) -> Q :: Value {
419
425
debug ! ( "ty::query::get_query<{}>(key={:?}, span={:?})" , Q :: NAME , key, span) ;
420
426
421
- let ( cached , lookup ) = self . try_get_cached :: < Q > ( & key ) ;
422
-
423
- if let Some ( ( v , index ) ) = cached {
424
- self . dep_graph . read_index ( index) ;
425
- return v ;
426
- }
427
-
428
- self . try_execute_query ( span , key , lookup )
427
+ self . try_get_cached :: < Q , _ , _ , _ > (
428
+ key ,
429
+ |value , index| {
430
+ self . dep_graph . read_index ( index) ;
431
+ value . clone ( )
432
+ } ,
433
+ |key , lookup| self . try_execute_query ( span , key , lookup ) ,
434
+ )
429
435
}
430
436
431
437
#[ inline( always) ]
@@ -688,19 +694,21 @@ impl<'tcx> TyCtxt<'tcx> {
688
694
// We may be concurrently trying both execute and force a query.
689
695
// Ensure that only one of them runs the query.
690
696
691
- let ( cached, lookup) = self . try_get_cached :: < Q > ( & key) ;
692
-
693
- if cached. is_some ( ) {
694
- return ;
695
- }
696
-
697
- let job = match JobOwner :: try_start ( self , span, & key, lookup) {
698
- TryGetJob :: NotYetStarted ( job) => job,
699
- TryGetJob :: Cycle ( _) => return ,
700
- #[ cfg( parallel_compiler) ]
701
- TryGetJob :: JobCompleted ( _) => return ,
702
- } ;
703
- self . force_query_with_job :: < Q > ( key, job, dep_node) ;
697
+ self . try_get_cached :: < Q , _ , _ , _ > (
698
+ key,
699
+ |_, _| {
700
+ // Cache hit, do nothing
701
+ } ,
702
+ |key, lookup| {
703
+ let job = match JobOwner :: try_start ( self , span, & key, lookup) {
704
+ TryGetJob :: NotYetStarted ( job) => job,
705
+ TryGetJob :: Cycle ( _) => return ,
706
+ #[ cfg( parallel_compiler) ]
707
+ TryGetJob :: JobCompleted ( _) => return ,
708
+ } ;
709
+ self . force_query_with_job :: < Q > ( key, job, dep_node) ;
710
+ } ,
711
+ ) ;
704
712
}
705
713
}
706
714
0 commit comments