@@ -28,9 +28,10 @@ use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
28
28
use rustc_data_structures:: fx:: { FxHashMap } ;
29
29
use rustc_data_structures:: sync:: { Lrc , Lock } ;
30
30
use rustc_data_structures:: by_move:: { Move , MoveSlot } ;
31
+ use std:: hash:: { Hash , Hasher , BuildHasher } ;
31
32
use std:: mem;
32
33
use std:: ptr;
33
- use std:: collections:: hash_map:: Entry ;
34
+ use std:: collections:: hash_map:: RawEntryMut ;
34
35
use syntax_pos:: Span ;
35
36
use syntax:: source_map:: DUMMY_SP ;
36
37
@@ -96,6 +97,7 @@ macro_rules! profq_query_msg {
96
97
pub ( super ) struct JobOwner < ' a , ' tcx : ' a , Q : QueryDescription < ' tcx > + ' a > {
97
98
cache : & ' a Lock < QueryCache < ' tcx , Q > > ,
98
99
key : Q :: Key ,
100
+ key_hash : u64 ,
99
101
job : Lrc < QueryJob < ' tcx > > ,
100
102
// FIXME: Remove ImplicitCtxt.layout_depth to get rid of this field
101
103
layout_depth : usize ,
@@ -120,7 +122,16 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
120
122
let cache = Q :: query_cache ( tcx) ;
121
123
loop {
122
124
let mut lock = cache. borrow_mut ( ) ;
123
- if let Some ( value) = lock. results . get ( key) {
125
+
126
+ // Calculate the key hash
127
+ let mut hasher = lock. results . hasher ( ) . build_hasher ( ) ;
128
+ key. hash ( & mut hasher) ;
129
+ let key_hash = hasher. finish ( ) ;
130
+
131
+ // QueryCache::results and QueryCache::active use the same
132
+ // hasher so we can reuse the hash for the key
133
+ if let Some ( ( _, value) ) = lock. results . raw_entry ( )
134
+ . from_key_hashed_nocheck ( key_hash, key) {
124
135
profq_msg ! ( tcx, ProfileQueriesMsg :: CacheHit ) ;
125
136
tcx. sess . profiler ( |p| {
126
137
p. record_query ( Q :: CATEGORY ) ;
@@ -130,14 +141,14 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
130
141
let result = Ok ( ( value. value . clone ( ) , value. index ) ) ;
131
142
return TryGetJob :: JobCompleted ( result) ;
132
143
}
133
- let job = match lock. active . entry ( ( * key ) . clone ( ) ) {
134
- Entry :: Occupied ( entry) => {
144
+ let job = match lock. active . raw_entry_mut ( ) . from_key_hashed_nocheck ( key_hash , key ) {
145
+ RawEntryMut :: Occupied ( entry) => {
135
146
match * entry. get ( ) {
136
147
QueryResult :: Started ( ref job) => job. clone ( ) ,
137
148
QueryResult :: Poisoned => FatalError . raise ( ) ,
138
149
}
139
150
}
140
- Entry :: Vacant ( entry) => {
151
+ RawEntryMut :: Vacant ( entry) => {
141
152
// No job entry for this query. Return a new one to be started later
142
153
return tls:: with_related_context ( tcx, |icx| {
143
154
let info = QueryInfo {
@@ -149,9 +160,13 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
149
160
cache,
150
161
job : job. clone ( ) ,
151
162
key : ( * key) . clone ( ) ,
163
+ key_hash,
152
164
layout_depth : icx. layout_depth ,
153
165
} ) ;
154
- entry. insert ( QueryResult :: Started ( job) ) ;
166
+ entry. insert_hashed_nocheck (
167
+ key_hash,
168
+ key. clone ( ) ,
169
+ QueryResult :: Started ( job) ) ;
155
170
TryGetJob :: NotYetStarted ( owner)
156
171
} )
157
172
}
@@ -177,6 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
177
192
// We can move out of `self` here because we `mem::forget` it below
178
193
let key = unsafe { ptr:: read ( & self . key ) } ;
179
194
let job = unsafe { ptr:: read ( & self . job ) } ;
195
+ let key_hash = self . key_hash ;
180
196
let cache = self . cache ;
181
197
182
198
// Forget ourself so our destructor won't poison the query
@@ -185,8 +201,13 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
185
201
let value = QueryValue :: new ( result. clone ( ) , dep_node_index) ;
186
202
{
187
203
let mut lock = cache. borrow_mut ( ) ;
188
- lock. active . remove ( & key) ;
189
- lock. results . insert ( key, value) ;
204
+
205
+ match lock. active . raw_entry_mut ( ) . from_key_hashed_nocheck ( key_hash, & key) {
206
+ RawEntryMut :: Occupied ( entry) => entry. remove ( ) ,
207
+ _ => unreachable ! ( ) ,
208
+ } ;
209
+ lock. results . raw_entry_mut ( ) . from_key_hashed_nocheck ( key_hash, & key)
210
+ . or_insert ( key, value) ;
190
211
}
191
212
192
213
job. signal_complete ( ) ;
0 commit comments