@@ -17,6 +17,7 @@ use errors::Diagnostic;
1717use errors:: FatalError ;
1818use rustc_data_structures:: fx:: { FxHashMap } ;
1919use rustc_data_structures:: sync:: { Lrc , Lock } ;
20+ use rustc_data_structures:: sharded:: Sharded ;
2021use rustc_data_structures:: thin_vec:: ThinVec ;
2122#[ cfg( not( parallel_compiler) ) ]
2223use rustc_data_structures:: cold_path;
@@ -90,7 +91,7 @@ macro_rules! profq_query_msg {
9091/// A type representing the responsibility to execute the job in the `job` field.
9192/// This will poison the relevant query if dropped.
9293pub ( super ) struct JobOwner < ' a , ' tcx , Q : QueryDescription < ' tcx > > {
93- cache : & ' a Lock < QueryCache < ' tcx , Q > > ,
94+ cache : & ' a Sharded < QueryCache < ' tcx , Q > > ,
9495 key : Q :: Key ,
9596 job : Lrc < QueryJob < ' tcx > > ,
9697}
@@ -107,7 +108,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
107108 pub ( super ) fn try_get ( tcx : TyCtxt < ' tcx > , span : Span , key : & Q :: Key ) -> TryGetJob < ' a , ' tcx , Q > {
108109 let cache = Q :: query_cache ( tcx) ;
109110 loop {
110- let mut lock = cache. borrow_mut ( ) ;
111+ let mut lock = cache. get_shard_by_value ( key ) . lock ( ) ;
111112 if let Some ( value) = lock. results . get ( key) {
112113 profq_msg ! ( tcx, ProfileQueriesMsg :: CacheHit ) ;
113114 tcx. sess . profiler ( |p| p. record_query_hit ( Q :: NAME ) ) ;
@@ -191,7 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
191192
192193 let value = QueryValue :: new ( result. clone ( ) , dep_node_index) ;
193194 {
194- let mut lock = cache. borrow_mut ( ) ;
195+ let mut lock = cache. get_shard_by_value ( & key ) . lock ( ) ;
195196 lock. active . remove ( & key) ;
196197 lock. results . insert ( key, value) ;
197198 }
@@ -215,7 +216,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
215216 #[ cold]
216217 fn drop ( & mut self ) {
217218 // Poison the query so jobs waiting on it panic
218- self . cache . borrow_mut ( ) . active . insert ( self . key . clone ( ) , QueryResult :: Poisoned ) ;
219+ let shard = self . cache . get_shard_by_value ( & self . key ) ;
220+ shard. lock ( ) . active . insert ( self . key . clone ( ) , QueryResult :: Poisoned ) ;
219221 // Also signal the completion of the job, so waiters
220222 // will continue execution
221223 self . job . signal_complete ( ) ;
@@ -708,7 +710,7 @@ macro_rules! define_queries_inner {
708710 use std:: mem;
709711 #[ cfg( parallel_compiler) ]
710712 use ty:: query:: job:: QueryResult ;
711- use rustc_data_structures:: sync :: Lock ;
713+ use rustc_data_structures:: sharded :: Sharded ;
712714 use crate :: {
713715 rustc_data_structures:: stable_hasher:: HashStable ,
714716 rustc_data_structures:: stable_hasher:: StableHasherResult ,
@@ -740,18 +742,17 @@ macro_rules! define_queries_inner {
740742 pub fn collect_active_jobs( & self ) -> Vec <Lrc <QueryJob <$tcx>>> {
741743 let mut jobs = Vec :: new( ) ;
742744
743- // We use try_lock here since we are only called from the
745+ // We use try_lock_shards here since we are only called from the
744746 // deadlock handler, and this shouldn't be locked.
745747 $(
746- jobs. extend(
747- self . $name. try_lock( ) . unwrap( ) . active. values( ) . filter_map( |v|
748- if let QueryResult :: Started ( ref job) = * v {
749- Some ( job. clone( ) )
750- } else {
751- None
752- }
753- )
754- ) ;
748+ let shards = self . $name. try_lock_shards( ) . unwrap( ) ;
749+ jobs. extend( shards. iter( ) . flat_map( |shard| shard. active. values( ) . filter_map( |v|
750+ if let QueryResult :: Started ( ref job) = * v {
751+ Some ( job. clone( ) )
752+ } else {
753+ None
754+ }
755+ ) ) ) ;
755756 ) *
756757
757758 jobs
@@ -773,26 +774,27 @@ macro_rules! define_queries_inner {
773774
774775 fn stats<' tcx, Q : QueryConfig <' tcx>>(
775776 name: & ' static str ,
776- map: & QueryCache <' tcx, Q >
777+ map: & Sharded < QueryCache <' tcx, Q >> ,
777778 ) -> QueryStats {
779+ let map = map. lock_shards( ) ;
778780 QueryStats {
779781 name,
780782 #[ cfg( debug_assertions) ]
781- cache_hits: map. cache_hits,
783+ cache_hits: map. iter ( ) . map ( |shard| shard . cache_hits) . sum ( ) ,
782784 #[ cfg( not( debug_assertions) ) ]
783785 cache_hits: 0 ,
784786 key_size: mem:: size_of:: <Q :: Key >( ) ,
785787 key_type: type_name:: <Q :: Key >( ) ,
786788 value_size: mem:: size_of:: <Q :: Value >( ) ,
787789 value_type: type_name:: <Q :: Value >( ) ,
788- entry_count: map. results. len( ) ,
790+ entry_count: map. iter ( ) . map ( |shard| shard . results. len( ) ) . sum ( ) ,
789791 }
790792 }
791793
792794 $(
793795 queries. push( stats:: <queries:: $name<' _>>(
794796 stringify!( $name) ,
795- & * self . $name. lock ( )
797+ & self . $name,
796798 ) ) ;
797799 ) *
798800
@@ -967,7 +969,7 @@ macro_rules! define_queries_inner {
967969 }
968970
969971 #[ inline( always) ]
970- fn query_cache<' a>( tcx: TyCtxt <$tcx>) -> & ' a Lock <QueryCache <$tcx, Self >> {
972+ fn query_cache<' a>( tcx: TyCtxt <$tcx>) -> & ' a Sharded <QueryCache <$tcx, Self >> {
971973 & tcx. queries. $name
972974 }
973975
@@ -1099,7 +1101,7 @@ macro_rules! define_queries_struct {
10991101 providers: IndexVec <CrateNum , Providers <$tcx>>,
11001102 fallback_extern_providers: Box <Providers <$tcx>>,
11011103
1102- $( $( #[ $attr] ) * $name: Lock <QueryCache <$tcx, queries:: $name<$tcx>>>, ) *
1104+ $( $( #[ $attr] ) * $name: Sharded <QueryCache <$tcx, queries:: $name<$tcx>>>, ) *
11031105 }
11041106 } ;
11051107}
0 commit comments