@@ -17,6 +17,7 @@ use errors::Diagnostic;
17
17
use errors:: FatalError ;
18
18
use rustc_data_structures:: fx:: { FxHashMap } ;
19
19
use rustc_data_structures:: sync:: { Lrc , Lock } ;
20
+ use rustc_data_structures:: sharded:: Sharded ;
20
21
use rustc_data_structures:: thin_vec:: ThinVec ;
21
22
#[ cfg( not( parallel_compiler) ) ]
22
23
use rustc_data_structures:: cold_path;
@@ -90,7 +91,7 @@ macro_rules! profq_query_msg {
90
91
/// A type representing the responsibility to execute the job in the `job` field.
91
92
/// This will poison the relevant query if dropped.
92
93
pub ( super ) struct JobOwner < ' a , ' tcx , Q : QueryDescription < ' tcx > > {
93
- cache : & ' a Lock < QueryCache < ' tcx , Q > > ,
94
+ cache : & ' a Sharded < QueryCache < ' tcx , Q > > ,
94
95
key : Q :: Key ,
95
96
job : Lrc < QueryJob < ' tcx > > ,
96
97
}
@@ -107,7 +108,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
107
108
pub ( super ) fn try_get ( tcx : TyCtxt < ' tcx > , span : Span , key : & Q :: Key ) -> TryGetJob < ' a , ' tcx , Q > {
108
109
let cache = Q :: query_cache ( tcx) ;
109
110
loop {
110
- let mut lock = cache. borrow_mut ( ) ;
111
+ let mut lock = cache. get_shard_by_value ( key ) . lock ( ) ;
111
112
if let Some ( value) = lock. results . get ( key) {
112
113
profq_msg ! ( tcx, ProfileQueriesMsg :: CacheHit ) ;
113
114
tcx. sess . profiler ( |p| p. record_query_hit ( Q :: NAME ) ) ;
@@ -191,7 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
191
192
192
193
let value = QueryValue :: new ( result. clone ( ) , dep_node_index) ;
193
194
{
194
- let mut lock = cache. borrow_mut ( ) ;
195
+ let mut lock = cache. get_shard_by_value ( & key ) . lock ( ) ;
195
196
lock. active . remove ( & key) ;
196
197
lock. results . insert ( key, value) ;
197
198
}
@@ -215,7 +216,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
215
216
#[ cold]
216
217
fn drop ( & mut self ) {
217
218
// 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 ) ;
219
221
// Also signal the completion of the job, so waiters
220
222
// will continue execution
221
223
self . job . signal_complete ( ) ;
@@ -708,7 +710,7 @@ macro_rules! define_queries_inner {
708
710
use std:: mem;
709
711
#[ cfg( parallel_compiler) ]
710
712
use ty:: query:: job:: QueryResult ;
711
- use rustc_data_structures:: sync :: Lock ;
713
+ use rustc_data_structures:: sharded :: Sharded ;
712
714
use crate :: {
713
715
rustc_data_structures:: stable_hasher:: HashStable ,
714
716
rustc_data_structures:: stable_hasher:: StableHasherResult ,
@@ -740,18 +742,17 @@ macro_rules! define_queries_inner {
740
742
pub fn collect_active_jobs( & self ) -> Vec <Lrc <QueryJob <$tcx>>> {
741
743
let mut jobs = Vec :: new( ) ;
742
744
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
744
746
// deadlock handler, and this shouldn't be locked.
745
747
$(
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
+ ) ) ) ;
755
756
) *
756
757
757
758
jobs
@@ -773,26 +774,27 @@ macro_rules! define_queries_inner {
773
774
774
775
fn stats<' tcx, Q : QueryConfig <' tcx>>(
775
776
name: & ' static str ,
776
- map: & QueryCache <' tcx, Q >
777
+ map: & Sharded < QueryCache <' tcx, Q >> ,
777
778
) -> QueryStats {
779
+ let map = map. lock_shards( ) ;
778
780
QueryStats {
779
781
name,
780
782
#[ cfg( debug_assertions) ]
781
- cache_hits: map. cache_hits,
783
+ cache_hits: map. iter ( ) . map ( |shard| shard . cache_hits) . sum ( ) ,
782
784
#[ cfg( not( debug_assertions) ) ]
783
785
cache_hits: 0 ,
784
786
key_size: mem:: size_of:: <Q :: Key >( ) ,
785
787
key_type: type_name:: <Q :: Key >( ) ,
786
788
value_size: mem:: size_of:: <Q :: Value >( ) ,
787
789
value_type: type_name:: <Q :: Value >( ) ,
788
- entry_count: map. results. len( ) ,
790
+ entry_count: map. iter ( ) . map ( |shard| shard . results. len( ) ) . sum ( ) ,
789
791
}
790
792
}
791
793
792
794
$(
793
795
queries. push( stats:: <queries:: $name<' _>>(
794
796
stringify!( $name) ,
795
- & * self . $name. lock ( )
797
+ & self . $name,
796
798
) ) ;
797
799
) *
798
800
@@ -967,7 +969,7 @@ macro_rules! define_queries_inner {
967
969
}
968
970
969
971
#[ 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 >> {
971
973
& tcx. queries. $name
972
974
}
973
975
@@ -1099,7 +1101,7 @@ macro_rules! define_queries_struct {
1099
1101
providers: IndexVec <CrateNum , Providers <$tcx>>,
1100
1102
fallback_extern_providers: Box <Providers <$tcx>>,
1101
1103
1102
- $( $( #[ $attr] ) * $name: Lock <QueryCache <$tcx, queries:: $name<$tcx>>>, ) *
1104
+ $( $( #[ $attr] ) * $name: Sharded <QueryCache <$tcx, queries:: $name<$tcx>>>, ) *
1103
1105
}
1104
1106
} ;
1105
1107
}
0 commit comments