@@ -28,9 +28,10 @@ use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
2828use rustc_data_structures:: fx:: { FxHashMap } ;
2929use rustc_data_structures:: sync:: { Lrc , Lock } ;
3030use rustc_data_structures:: by_move:: { Move , MoveSlot } ;
31+ use std:: hash:: { Hash , Hasher , BuildHasher } ;
3132use std:: mem;
3233use std:: ptr;
33- use std:: collections:: hash_map:: Entry ;
34+ use std:: collections:: hash_map:: RawEntryMut ;
3435use syntax_pos:: Span ;
3536use syntax:: source_map:: DUMMY_SP ;
3637
@@ -96,6 +97,7 @@ macro_rules! profq_query_msg {
9697pub ( super ) struct JobOwner < ' a , ' tcx : ' a , Q : QueryDescription < ' tcx > + ' a > {
9798 cache : & ' a Lock < QueryCache < ' tcx , Q > > ,
9899 key : Q :: Key ,
100+ key_hash : u64 ,
99101 job : Lrc < QueryJob < ' tcx > > ,
100102 // FIXME: Remove ImplicitCtxt.layout_depth to get rid of this field
101103 layout_depth : usize ,
@@ -120,7 +122,16 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
120122 let cache = Q :: query_cache ( tcx) ;
121123 loop {
122124 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) {
124135 profq_msg ! ( tcx, ProfileQueriesMsg :: CacheHit ) ;
125136 tcx. sess . profiler ( |p| {
126137 p. record_query ( Q :: CATEGORY ) ;
@@ -130,14 +141,14 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
130141 let result = Ok ( ( value. value . clone ( ) , value. index ) ) ;
131142 return TryGetJob :: JobCompleted ( result) ;
132143 }
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) => {
135146 match * entry. get ( ) {
136147 QueryResult :: Started ( ref job) => job. clone ( ) ,
137148 QueryResult :: Poisoned => FatalError . raise ( ) ,
138149 }
139150 }
140- Entry :: Vacant ( entry) => {
151+ RawEntryMut :: Vacant ( entry) => {
141152 // No job entry for this query. Return a new one to be started later
142153 return tls:: with_related_context ( tcx, |icx| {
143154 let info = QueryInfo {
@@ -149,9 +160,13 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
149160 cache,
150161 job : job. clone ( ) ,
151162 key : ( * key) . clone ( ) ,
163+ key_hash,
152164 layout_depth : icx. layout_depth ,
153165 } ) ;
154- entry. insert ( QueryResult :: Started ( job) ) ;
166+ entry. insert_hashed_nocheck (
167+ key_hash,
168+ key. clone ( ) ,
169+ QueryResult :: Started ( job) ) ;
155170 TryGetJob :: NotYetStarted ( owner)
156171 } )
157172 }
@@ -177,6 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
177192 // We can move out of `self` here because we `mem::forget` it below
178193 let key = unsafe { ptr:: read ( & self . key ) } ;
179194 let job = unsafe { ptr:: read ( & self . job ) } ;
195+ let key_hash = self . key_hash ;
180196 let cache = self . cache ;
181197
182198 // Forget ourself so our destructor won't poison the query
@@ -185,8 +201,13 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
185201 let value = QueryValue :: new ( result. clone ( ) , dep_node_index) ;
186202 {
187203 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) ;
190211 }
191212
192213 job. signal_complete ( ) ;
0 commit comments