@@ -159,7 +159,11 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
159159 return TryGetJob :: Cycle ( Q :: handle_cycle_error ( tcx, cycle) ) ;
160160 }
161161
162- let cached = tcx. try_get_cached :: < Q > ( key) . 0 . unwrap ( ) ;
162+ let cached = tcx. try_get_cached :: < Q , _ , _ , _ > (
163+ ( * key) . clone ( ) ,
164+ |value, index| ( value. clone ( ) , index) ,
165+ |_, _| panic ! ( "value must be in cache after waiting" ) ,
166+ ) ;
163167
164168 if let Some ( prof_timer) = _query_blocked_prof_timer. take ( ) {
165169 prof_timer. finish_with_query_invocation_id ( cached. 1 . into ( ) ) ;
@@ -374,10 +378,18 @@ impl<'tcx> TyCtxt<'tcx> {
374378 /// which will be used if the query is not in the cache and we need
375379 /// to compute it.
376380 #[ inline( always) ]
377- fn try_get_cached < Q : QueryDescription < ' tcx > > (
381+ fn try_get_cached < Q , R , OnHit , OnMiss > (
378382 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+ {
381393 let cache = Q :: query_cache ( self ) ;
382394
383395 // We compute the key's hash once and then use it for both the
@@ -391,23 +403,17 @@ impl<'tcx> TyCtxt<'tcx> {
391403 let mut lock_guard = cache. get_shard_by_index ( shard) . lock ( ) ;
392404 let lock = & mut * lock_guard;
393405
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) ;
399407
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 ( ) ) ;
407411 }
408- }
409412
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+ }
411417 }
412418
413419 #[ inline( never) ]
@@ -418,14 +424,14 @@ impl<'tcx> TyCtxt<'tcx> {
418424 ) -> Q :: Value {
419425 debug ! ( "ty::query::get_query<{}>(key={:?}, span={:?})" , Q :: NAME , key, span) ;
420426
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+ )
429435 }
430436
431437 #[ inline( always) ]
@@ -688,19 +694,21 @@ impl<'tcx> TyCtxt<'tcx> {
688694 // We may be concurrently trying both execute and force a query.
689695 // Ensure that only one of them runs the query.
690696
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+ ) ;
704712 }
705713}
706714
0 commit comments