Skip to content

Commit 9a59789

Browse files
committed
Store query jobs and query results in separate maps to reduce memory usage
1 parent 987631d commit 9a59789

File tree

3 files changed

+23
-25
lines changed

3 files changed

+23
-25
lines changed

src/librustc/ty/maps/job.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@ use ty::context::TyCtxt;
1717
use errors::Diagnostic;
1818

1919
/// Indicates the state of a query for a given key in a query map
20-
pub(super) enum QueryResult<'tcx, T> {
20+
pub(super) enum QueryResult<'tcx> {
2121
/// An already executing query. The query job can be used to await for its completion
2222
Started(Lrc<QueryJob<'tcx>>),
2323

24-
/// The query is complete and produced `T`
25-
Complete(T),
26-
2724
/// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
2825
Poisoned,
2926
}

src/librustc/ty/maps/on_disk_cache.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use syntax::codemap::{CodeMap, StableFilemapId};
3030
use syntax_pos::{BytePos, Span, DUMMY_SP, FileMap};
3131
use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo};
3232
use ty;
33-
use ty::maps::job::QueryResult;
3433
use ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
3534
use ty::context::TyCtxt;
3635
use util::common::time;
@@ -240,13 +239,11 @@ impl<'sess> OnDiskCache<'sess> {
240239

241240
// const eval is special, it only encodes successfully evaluated constants
242241
use ty::maps::QueryConfig;
243-
for (key, entry) in const_eval::query_map(tcx).borrow().map.iter() {
242+
let map = const_eval::query_map(tcx).borrow();
243+
assert!(map.active.is_empty());
244+
for (key, entry) in map.results.iter() {
244245
use ty::maps::config::QueryDescription;
245246
if const_eval::cache_on_disk(key.clone()) {
246-
let entry = match *entry {
247-
QueryResult::Complete(ref v) => v,
248-
_ => panic!("incomplete query"),
249-
};
250247
if let Ok(ref value) = entry.value {
251248
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
252249

@@ -1133,12 +1130,10 @@ fn encode_query_results<'enc, 'a, 'tcx, Q, E>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11331130

11341131
time(tcx.sess, desc, || {
11351132

1136-
for (key, entry) in Q::query_map(tcx).borrow().map.iter() {
1133+
let map = Q::query_map(tcx).borrow();
1134+
assert!(map.active.is_empty());
1135+
for (key, entry) in map.results.iter() {
11371136
if Q::cache_on_disk(key.clone()) {
1138-
let entry = match *entry {
1139-
QueryResult::Complete(ref v) => v,
1140-
_ => panic!("incomplete query"),
1141-
};
11421137
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
11431138

11441139
// Record position of the cache entry

src/librustc/ty/maps/plumbing.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ use syntax_pos::Span;
3636
use syntax::codemap::DUMMY_SP;
3737

3838
pub struct QueryMap<'tcx, D: QueryConfig<'tcx> + ?Sized> {
39-
pub(super) map: FxHashMap<D::Key, QueryResult<'tcx, QueryValue<D::Value>>>,
39+
pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
40+
pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
4041
}
4142

4243
pub(super) struct QueryValue<T> {
@@ -58,7 +59,8 @@ impl<T> QueryValue<T> {
5859
impl<'tcx, M: QueryConfig<'tcx>> QueryMap<'tcx, M> {
5960
pub(super) fn new() -> QueryMap<'tcx, M> {
6061
QueryMap {
61-
map: FxHashMap(),
62+
results: FxHashMap(),
63+
active: FxHashMap(),
6264
}
6365
}
6466
}
@@ -111,15 +113,15 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
111113
let map = Q::query_map(tcx);
112114
loop {
113115
let mut lock = map.borrow_mut();
114-
let job = match lock.map.entry((*key).clone()) {
116+
if let Some(value) = lock.results.get(key) {
117+
profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
118+
let result = Ok((value.value.clone(), value.index));
119+
return TryGetJob::JobCompleted(result);
120+
}
121+
let job = match lock.active.entry((*key).clone()) {
115122
Entry::Occupied(entry) => {
116123
match *entry.get() {
117124
QueryResult::Started(ref job) => job.clone(),
118-
QueryResult::Complete(ref value) => {
119-
profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
120-
let result = Ok((value.value.clone(), value.index));
121-
return TryGetJob::JobCompleted(result);
122-
},
123125
QueryResult::Poisoned => FatalError.raise(),
124126
}
125127
}
@@ -161,7 +163,11 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
161163
mem::forget(self);
162164

163165
let value = QueryValue::new(result.clone(), dep_node_index);
164-
map.borrow_mut().map.insert(key, QueryResult::Complete(value));
166+
{
167+
let mut lock = map.borrow_mut();
168+
lock.active.remove(&key);
169+
lock.results.insert(key, value);
170+
}
165171

166172
job.signal_complete();
167173
}
@@ -205,7 +211,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
205211
impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
206212
fn drop(&mut self) {
207213
// Poison the query so jobs waiting on it panic
208-
self.map.borrow_mut().map.insert(self.key.clone(), QueryResult::Poisoned);
214+
self.map.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
209215
// Also signal the completion of the job, so waiters
210216
// will continue execution
211217
self.job.signal_complete();

0 commit comments

Comments
 (0)