Skip to content

Commit 4225cb6

Browse files
committed
raw api
1 parent 51783e9 commit 4225cb6

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#![feature(crate_visibility_modifier)]
7373
#![feature(transpose_result)]
7474
#![feature(arbitrary_self_types)]
75+
#![feature(hash_raw_entry)]
7576

7677
#![recursion_limit="512"]
7778

src/librustc/ty/query/plumbing.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
2828
use rustc_data_structures::fx::{FxHashMap};
2929
use rustc_data_structures::sync::{Lrc, Lock};
3030
use rustc_data_structures::by_move::{Move, MoveSlot};
31+
use std::hash::{Hash, Hasher, BuildHasher};
3132
use std::mem;
3233
use std::ptr;
33-
use std::collections::hash_map::Entry;
34+
use std::collections::hash_map::RawEntryMut;
3435
use syntax_pos::Span;
3536
use syntax::source_map::DUMMY_SP;
3637

@@ -96,6 +97,7 @@ macro_rules! profq_query_msg {
9697
pub(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

Comments
 (0)