@@ -12,26 +12,27 @@ use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobI
12
12
use crate :: query:: SerializedDepNodeIndex ;
13
13
use crate :: query:: { QueryContext , QueryMap , QuerySideEffects , QueryStackFrame } ;
14
14
use crate :: HandleCycleError ;
15
+ use hashbrown:: hash_map:: RawEntryMut ;
15
16
use rustc_data_structures:: fingerprint:: Fingerprint ;
16
- use rustc_data_structures:: fx:: FxHashMap ;
17
- use rustc_data_structures:: sharded:: Sharded ;
17
+ use rustc_data_structures:: sharded:: { self , Sharded } ;
18
18
use rustc_data_structures:: stack:: ensure_sufficient_stack;
19
19
use rustc_data_structures:: sync:: Lock ;
20
20
#[ cfg( parallel_compiler) ]
21
21
use rustc_data_structures:: { cold_path, sync} ;
22
22
use rustc_errors:: { DiagnosticBuilder , ErrorGuaranteed , FatalError } ;
23
+ use rustc_hash:: FxHasher ;
23
24
use rustc_span:: { Span , DUMMY_SP } ;
24
25
use std:: cell:: Cell ;
25
- use std:: collections:: hash_map:: Entry ;
26
26
use std:: fmt:: Debug ;
27
+ use std:: hash:: BuildHasherDefault ;
27
28
use std:: hash:: Hash ;
28
29
use std:: mem;
29
30
use thin_vec:: ThinVec ;
30
31
31
32
use super :: QueryConfig ;
32
33
33
34
pub struct QueryState < K > {
34
- active : Sharded < FxHashMap < K , QueryResult > > ,
35
+ active : Sharded < hashbrown :: HashMap < K , QueryResult , BuildHasherDefault < FxHasher > > > ,
35
36
}
36
37
37
38
/// Indicates the state of a query for a given key in a query map.
@@ -142,7 +143,7 @@ where
142
143
{
143
144
/// Completes the query by updating the query cache with the `result`,
144
145
/// signals the waiter and forgets the JobOwner, so it won't poison the query
145
- fn complete < C > ( self , cache : & C , result : C :: Value , dep_node_index : DepNodeIndex )
146
+ fn complete < C > ( self , cache : & C , key_hash : u64 , result : C :: Value , dep_node_index : DepNodeIndex )
146
147
where
147
148
C : QueryCache < Key = K > ,
148
149
{
@@ -154,13 +155,17 @@ where
154
155
155
156
// Mark as complete before we remove the job from the active state
156
157
// so no other thread can re-execute this query.
157
- cache. complete ( key, result, dep_node_index) ;
158
+ cache. complete ( key, key_hash , result, dep_node_index) ;
158
159
159
160
let job = {
160
- let mut lock = state. active . lock_shard_by_value ( & key) ;
161
- match lock. remove ( & key) . unwrap ( ) {
162
- QueryResult :: Started ( job) => job,
163
- QueryResult :: Poisoned => panic ! ( ) ,
161
+ let mut lock = state. active . lock_shard_by_hash ( key_hash) ;
162
+
163
+ match lock. raw_entry_mut ( ) . from_key_hashed_nocheck ( key_hash, & key) {
164
+ RawEntryMut :: Vacant ( _) => panic ! ( ) ,
165
+ RawEntryMut :: Occupied ( occupied) => match occupied. remove ( ) {
166
+ QueryResult :: Started ( job) => job,
167
+ QueryResult :: Poisoned => panic ! ( ) ,
168
+ } ,
164
169
}
165
170
} ;
166
171
@@ -209,7 +214,8 @@ where
209
214
C : QueryCache ,
210
215
Tcx : DepContext ,
211
216
{
212
- match cache. lookup ( & key) {
217
+ let key_hash = sharded:: make_hash ( key) ;
218
+ match cache. lookup ( & key, key_hash) {
213
219
Some ( ( value, index) ) => {
214
220
tcx. profiler ( ) . query_cache_hit ( index. into ( ) ) ;
215
221
tcx. dep_graph ( ) . read_index ( index) ;
@@ -246,6 +252,7 @@ fn wait_for_query<Q, Qcx>(
246
252
qcx : Qcx ,
247
253
span : Span ,
248
254
key : Q :: Key ,
255
+ key_hash : u64 ,
249
256
latch : QueryLatch ,
250
257
current : Option < QueryJobId > ,
251
258
) -> ( Q :: Value , Option < DepNodeIndex > )
@@ -264,7 +271,7 @@ where
264
271
265
272
match result {
266
273
Ok ( ( ) ) => {
267
- let Some ( ( v, index) ) = query. query_cache ( qcx) . lookup ( & key) else {
274
+ let Some ( ( v, index) ) = query. query_cache ( qcx) . lookup ( & key, key_hash ) else {
268
275
cold_path ( || {
269
276
// We didn't find the query result in the query cache. Check if it was
270
277
// poisoned due to a panic instead.
@@ -301,7 +308,8 @@ where
301
308
Qcx : QueryContext ,
302
309
{
303
310
let state = query. query_state ( qcx) ;
304
- let mut state_lock = state. active . lock_shard_by_value ( & key) ;
311
+ let key_hash = sharded:: make_hash ( & key) ;
312
+ let mut state_lock = state. active . lock_shard_by_hash ( key_hash) ;
305
313
306
314
// For the parallel compiler we need to check both the query cache and query state structures
307
315
// while holding the state lock to ensure that 1) the query has not yet completed and 2) the
@@ -310,28 +318,28 @@ where
310
318
// executing, but another thread may have already completed the query and stores it result
311
319
// in the query cache.
312
320
if cfg ! ( parallel_compiler) && qcx. dep_context ( ) . sess ( ) . threads ( ) > 1 {
313
- if let Some ( ( value, index) ) = query. query_cache ( qcx) . lookup ( & key) {
321
+ if let Some ( ( value, index) ) = query. query_cache ( qcx) . lookup ( & key, key_hash ) {
314
322
qcx. dep_context ( ) . profiler ( ) . query_cache_hit ( index. into ( ) ) ;
315
323
return ( value, Some ( index) ) ;
316
324
}
317
325
}
318
326
319
327
let current_job_id = qcx. current_query_job ( ) ;
320
328
321
- match state_lock. entry ( key) {
322
- Entry :: Vacant ( entry) => {
329
+ match state_lock. raw_entry_mut ( ) . from_key_hashed_nocheck ( key_hash , & key) {
330
+ RawEntryMut :: Vacant ( entry) => {
323
331
// Nothing has computed or is computing the query, so we start a new job and insert it in the
324
332
// state map.
325
333
let id = qcx. next_job_id ( ) ;
326
334
let job = QueryJob :: new ( id, span, current_job_id) ;
327
- entry. insert ( QueryResult :: Started ( job) ) ;
335
+ entry. insert_hashed_nocheck ( key_hash , key , QueryResult :: Started ( job) ) ;
328
336
329
337
// Drop the lock before we start executing the query
330
338
drop ( state_lock) ;
331
339
332
- execute_job :: < _ , _ , INCR > ( query, qcx, state, key, id, dep_node)
340
+ execute_job :: < _ , _ , INCR > ( query, qcx, state, key, key_hash , id, dep_node)
333
341
}
334
- Entry :: Occupied ( mut entry) => {
342
+ RawEntryMut :: Occupied ( mut entry) => {
335
343
match entry. get_mut ( ) {
336
344
QueryResult :: Started ( job) => {
337
345
#[ cfg( parallel_compiler) ]
@@ -342,7 +350,15 @@ where
342
350
343
351
// Only call `wait_for_query` if we're using a Rayon thread pool
344
352
// as it will attempt to mark the worker thread as blocked.
345
- return wait_for_query ( query, qcx, span, key, latch, current_job_id) ;
353
+ return wait_for_query (
354
+ query,
355
+ qcx,
356
+ span,
357
+ key,
358
+ key_hash,
359
+ latch,
360
+ current_job_id,
361
+ ) ;
346
362
}
347
363
348
364
let id = job. id ;
@@ -364,6 +380,7 @@ fn execute_job<Q, Qcx, const INCR: bool>(
364
380
qcx : Qcx ,
365
381
state : & QueryState < Q :: Key > ,
366
382
key : Q :: Key ,
383
+ key_hash : u64 ,
367
384
id : QueryJobId ,
368
385
dep_node : Option < DepNode > ,
369
386
) -> ( Q :: Value , Option < DepNodeIndex > )
@@ -395,7 +412,7 @@ where
395
412
// This can't happen, as query feeding adds the very dependencies to the fed query
396
413
// as its feeding query had. So if the fed query is red, so is its feeder, which will
397
414
// get evaluated first, and re-feed the query.
398
- if let Some ( ( cached_result, _) ) = cache. lookup ( & key) {
415
+ if let Some ( ( cached_result, _) ) = cache. lookup ( & key, key_hash ) {
399
416
let Some ( hasher) = query. hash_result ( ) else {
400
417
panic ! (
401
418
"no_hash fed query later has its value computed.\n \
@@ -427,7 +444,7 @@ where
427
444
}
428
445
}
429
446
}
430
- job_owner. complete ( cache, result, dep_node_index) ;
447
+ job_owner. complete ( cache, key_hash , result, dep_node_index) ;
431
448
432
449
( result, Some ( dep_node_index) )
433
450
}
@@ -826,7 +843,7 @@ where
826
843
{
827
844
// We may be concurrently trying both execute and force a query.
828
845
// Ensure that only one of them runs the query.
829
- if let Some ( ( _, index) ) = query. query_cache ( qcx) . lookup ( & key) {
846
+ if let Some ( ( _, index) ) = query. query_cache ( qcx) . lookup ( & key, sharded :: make_hash ( & key ) ) {
830
847
qcx. dep_context ( ) . profiler ( ) . query_cache_hit ( index. into ( ) ) ;
831
848
return ;
832
849
}
0 commit comments