1
1
use crate :: dep_graph:: DepNodeIndex ;
2
- use crate :: query:: plumbing:: { QueryCacheStore , QueryLookup } ;
3
2
4
3
use rustc_arena:: TypedArena ;
5
4
use rustc_data_structures:: fx:: FxHashMap ;
5
+ use rustc_data_structures:: sharded;
6
+ #[ cfg( parallel_compiler) ]
6
7
use rustc_data_structures:: sharded:: Sharded ;
8
+ #[ cfg( not( parallel_compiler) ) ]
9
+ use rustc_data_structures:: sync:: Lock ;
7
10
use rustc_data_structures:: sync:: WorkerLocal ;
8
11
use std:: default:: Default ;
9
12
use std:: fmt:: Debug ;
@@ -25,35 +28,23 @@ pub trait QueryStorage {
25
28
26
29
pub trait QueryCache : QueryStorage + Sized {
27
30
type Key : Hash + Eq + Clone + Debug ;
28
- type Sharded : Default ;
29
31
30
32
/// Checks if the query is already computed and in the cache.
31
33
/// It returns the shard index and a lock guard to the shard,
32
34
/// which will be used if the query is not in the cache and we need
33
35
/// to compute it.
34
- fn lookup < ' s , R , OnHit > (
36
+ fn lookup < R , OnHit > (
35
37
& self ,
36
- state : & ' s QueryCacheStore < Self > ,
37
38
key : & Self :: Key ,
38
39
// `on_hit` can be called while holding a lock to the query state shard.
39
40
on_hit : OnHit ,
40
- ) -> Result < R , QueryLookup >
41
+ ) -> Result < R , ( ) >
41
42
where
42
43
OnHit : FnOnce ( & Self :: Stored , DepNodeIndex ) -> R ;
43
44
44
- fn complete (
45
- & self ,
46
- lock_sharded_storage : & mut Self :: Sharded ,
47
- key : Self :: Key ,
48
- value : Self :: Value ,
49
- index : DepNodeIndex ,
50
- ) -> Self :: Stored ;
45
+ fn complete ( & self , key : Self :: Key , value : Self :: Value , index : DepNodeIndex ) -> Self :: Stored ;
51
46
52
- fn iter (
53
- & self ,
54
- shards : & Sharded < Self :: Sharded > ,
55
- f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ,
56
- ) ;
47
+ fn iter ( & self , f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ) ;
57
48
}
58
49
59
50
pub struct DefaultCacheSelector ;
@@ -62,11 +53,16 @@ impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
62
53
type Cache = DefaultCache < K , V > ;
63
54
}
64
55
65
- pub struct DefaultCache < K , V > ( PhantomData < ( K , V ) > ) ;
56
+ pub struct DefaultCache < K , V > {
57
+ #[ cfg( parallel_compiler) ]
58
+ cache : Sharded < FxHashMap < K , ( V , DepNodeIndex ) > > ,
59
+ #[ cfg( not( parallel_compiler) ) ]
60
+ cache : Lock < FxHashMap < K , ( V , DepNodeIndex ) > > ,
61
+ }
66
62
67
63
impl < K , V > Default for DefaultCache < K , V > {
68
64
fn default ( ) -> Self {
69
- DefaultCache ( PhantomData )
65
+ DefaultCache { cache : Default :: default ( ) }
70
66
}
71
67
}
72
68
@@ -87,49 +83,51 @@ where
87
83
V : Clone + Debug ,
88
84
{
89
85
type Key = K ;
90
- type Sharded = FxHashMap < K , ( V , DepNodeIndex ) > ;
91
86
92
87
#[ inline( always) ]
93
- fn lookup < ' s , R , OnHit > (
94
- & self ,
95
- state : & ' s QueryCacheStore < Self > ,
96
- key : & K ,
97
- on_hit : OnHit ,
98
- ) -> Result < R , QueryLookup >
88
+ fn lookup < R , OnHit > ( & self , key : & K , on_hit : OnHit ) -> Result < R , ( ) >
99
89
where
100
90
OnHit : FnOnce ( & V , DepNodeIndex ) -> R ,
101
91
{
102
- let ( lookup, lock) = state. get_lookup ( key) ;
103
- let result = lock. raw_entry ( ) . from_key_hashed_nocheck ( lookup. key_hash , key) ;
92
+ let key_hash = sharded:: make_hash ( key) ;
93
+ #[ cfg( parallel_compiler) ]
94
+ let lock = self . cache . get_shard_by_hash ( key_hash) . lock ( ) ;
95
+ #[ cfg( not( parallel_compiler) ) ]
96
+ let lock = self . cache . lock ( ) ;
97
+ let result = lock. raw_entry ( ) . from_key_hashed_nocheck ( key_hash, key) ;
104
98
105
99
if let Some ( ( _, value) ) = result {
106
100
let hit_result = on_hit ( & value. 0 , value. 1 ) ;
107
101
Ok ( hit_result)
108
102
} else {
109
- Err ( lookup )
103
+ Err ( ( ) )
110
104
}
111
105
}
112
106
113
107
#[ inline]
114
- fn complete (
115
- & self ,
116
- lock_sharded_storage : & mut Self :: Sharded ,
117
- key : K ,
118
- value : V ,
119
- index : DepNodeIndex ,
120
- ) -> Self :: Stored {
121
- lock_sharded_storage. insert ( key, ( value. clone ( ) , index) ) ;
108
+ fn complete ( & self , key : K , value : V , index : DepNodeIndex ) -> Self :: Stored {
109
+ #[ cfg( parallel_compiler) ]
110
+ let mut lock = self . cache . get_shard_by_value ( & key) . lock ( ) ;
111
+ #[ cfg( not( parallel_compiler) ) ]
112
+ let mut lock = self . cache . lock ( ) ;
113
+ lock. insert ( key, ( value. clone ( ) , index) ) ;
122
114
value
123
115
}
124
116
125
- fn iter (
126
- & self ,
127
- shards : & Sharded < Self :: Sharded > ,
128
- f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ,
129
- ) {
130
- let shards = shards. lock_shards ( ) ;
131
- for shard in shards. iter ( ) {
132
- for ( k, v) in shard. iter ( ) {
117
+ fn iter ( & self , f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ) {
118
+ #[ cfg( parallel_compiler) ]
119
+ {
120
+ let shards = self . cache . lock_shards ( ) ;
121
+ for shard in shards. iter ( ) {
122
+ for ( k, v) in shard. iter ( ) {
123
+ f ( k, & v. 0 , v. 1 ) ;
124
+ }
125
+ }
126
+ }
127
+ #[ cfg( not( parallel_compiler) ) ]
128
+ {
129
+ let map = self . cache . lock ( ) ;
130
+ for ( k, v) in map. iter ( ) {
133
131
f ( k, & v. 0 , v. 1 ) ;
134
132
}
135
133
}
@@ -144,12 +142,15 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<K, V> for ArenaCacheSelector<'tc
144
142
145
143
pub struct ArenaCache < ' tcx , K , V > {
146
144
arena : WorkerLocal < TypedArena < ( V , DepNodeIndex ) > > ,
147
- phantom : PhantomData < ( K , & ' tcx V ) > ,
145
+ #[ cfg( parallel_compiler) ]
146
+ cache : Sharded < FxHashMap < K , & ' tcx ( V , DepNodeIndex ) > > ,
147
+ #[ cfg( not( parallel_compiler) ) ]
148
+ cache : Lock < FxHashMap < K , & ' tcx ( V , DepNodeIndex ) > > ,
148
149
}
149
150
150
151
impl < ' tcx , K , V > Default for ArenaCache < ' tcx , K , V > {
151
152
fn default ( ) -> Self {
152
- ArenaCache { arena : WorkerLocal :: new ( |_| TypedArena :: default ( ) ) , phantom : PhantomData }
153
+ ArenaCache { arena : WorkerLocal :: new ( |_| TypedArena :: default ( ) ) , cache : Default :: default ( ) }
153
154
}
154
155
}
155
156
@@ -171,51 +172,53 @@ where
171
172
V : Debug ,
172
173
{
173
174
type Key = K ;
174
- type Sharded = FxHashMap < K , & ' tcx ( V , DepNodeIndex ) > ;
175
175
176
176
#[ inline( always) ]
177
- fn lookup < ' s , R , OnHit > (
178
- & self ,
179
- state : & ' s QueryCacheStore < Self > ,
180
- key : & K ,
181
- on_hit : OnHit ,
182
- ) -> Result < R , QueryLookup >
177
+ fn lookup < R , OnHit > ( & self , key : & K , on_hit : OnHit ) -> Result < R , ( ) >
183
178
where
184
179
OnHit : FnOnce ( & & ' tcx V , DepNodeIndex ) -> R ,
185
180
{
186
- let ( lookup, lock) = state. get_lookup ( key) ;
187
- let result = lock. raw_entry ( ) . from_key_hashed_nocheck ( lookup. key_hash , key) ;
181
+ let key_hash = sharded:: make_hash ( key) ;
182
+ #[ cfg( parallel_compiler) ]
183
+ let lock = self . cache . get_shard_by_hash ( key_hash) . lock ( ) ;
184
+ #[ cfg( not( parallel_compiler) ) ]
185
+ let lock = self . cache . lock ( ) ;
186
+ let result = lock. raw_entry ( ) . from_key_hashed_nocheck ( key_hash, key) ;
188
187
189
188
if let Some ( ( _, value) ) = result {
190
189
let hit_result = on_hit ( & & value. 0 , value. 1 ) ;
191
190
Ok ( hit_result)
192
191
} else {
193
- Err ( lookup )
192
+ Err ( ( ) )
194
193
}
195
194
}
196
195
197
196
#[ inline]
198
- fn complete (
199
- & self ,
200
- lock_sharded_storage : & mut Self :: Sharded ,
201
- key : K ,
202
- value : V ,
203
- index : DepNodeIndex ,
204
- ) -> Self :: Stored {
197
+ fn complete ( & self , key : K , value : V , index : DepNodeIndex ) -> Self :: Stored {
205
198
let value = self . arena . alloc ( ( value, index) ) ;
206
199
let value = unsafe { & * ( value as * const _ ) } ;
207
- lock_sharded_storage. insert ( key, value) ;
200
+ #[ cfg( parallel_compiler) ]
201
+ let mut lock = self . cache . get_shard_by_value ( & key) . lock ( ) ;
202
+ #[ cfg( not( parallel_compiler) ) ]
203
+ let mut lock = self . cache . lock ( ) ;
204
+ lock. insert ( key, value) ;
208
205
& value. 0
209
206
}
210
207
211
- fn iter (
212
- & self ,
213
- shards : & Sharded < Self :: Sharded > ,
214
- f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ,
215
- ) {
216
- let shards = shards. lock_shards ( ) ;
217
- for shard in shards. iter ( ) {
218
- for ( k, v) in shard. iter ( ) {
208
+ fn iter ( & self , f : & mut dyn FnMut ( & Self :: Key , & Self :: Value , DepNodeIndex ) ) {
209
+ #[ cfg( parallel_compiler) ]
210
+ {
211
+ let shards = self . cache . lock_shards ( ) ;
212
+ for shard in shards. iter ( ) {
213
+ for ( k, v) in shard. iter ( ) {
214
+ f ( k, & v. 0 , v. 1 ) ;
215
+ }
216
+ }
217
+ }
218
+ #[ cfg( not( parallel_compiler) ) ]
219
+ {
220
+ let map = self . cache . lock ( ) ;
221
+ for ( k, v) in map. iter ( ) {
219
222
f ( k, & v. 0 , v. 1 ) ;
220
223
}
221
224
}
0 commit comments