Skip to content

Commit cd6850c

Browse files
committed
use RefCell for query caches in single thread
1 parent 16b9941 commit cd6850c

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

compiler/rustc_middle/src/query/plumbing.rs

+37-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use field_offset::FieldOffset;
1313
use measureme::StringId;
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_data_structures::sync::AtomicU64;
16+
#[cfg(parallel_compiler)]
17+
use rustc_data_structures::sync::DynSync;
1618
use rustc_hir::def::DefKind;
1719
use rustc_hir::def_id::{DefId, LocalDefId};
1820
use rustc_hir::hir_id::OwnerId;
@@ -97,6 +99,10 @@ pub struct QuerySystem<'tcx> {
9799
pub jobs: AtomicU64,
98100
}
99101

102+
// It's thread safe since `QueryCaches` only used under single thread
103+
#[cfg(parallel_compiler)]
104+
unsafe impl<'tcx> DynSync for QuerySystem<'tcx> {}
105+
100106
#[derive(Copy, Clone)]
101107
pub struct TyCtxtAt<'tcx> {
102108
pub tcx: TyCtxt<'tcx>,
@@ -428,18 +434,46 @@ macro_rules! define_callbacks {
428434
})*
429435
}
430436

437+
#[cfg(not(parallel_compiler))]
431438
impl<'tcx> TyCtxtAt<'tcx> {
432439
$($(#[$attr])*
440+
433441
#[inline(always)]
434442
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
435443
{
436-
restore::<$V>(with_query_caches!(query_get_at(
444+
restore::<$V>(query_get_at(
437445
self.tcx,
438446
self.tcx.query_system.fns.engine.$name,
439-
:self.tcx, $name,
447+
&self.tcx.query_system.caches.$name,
440448
self.span,
441449
key.into_query_param(),
442-
)))
450+
))
451+
})*
452+
}
453+
454+
#[cfg(parallel_compiler)]
455+
impl<'tcx> TyCtxtAt<'tcx> {
456+
$($(#[$attr])*
457+
#[inline(always)]
458+
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
459+
{
460+
if std::intrinsics::likely(self.tcx.query_system.single_thread) {
461+
restore::<$V>(query_get_at(
462+
self.tcx,
463+
self.tcx.query_system.fns.engine.$name,
464+
&self.tcx.query_system.caches.$name,
465+
self.span,
466+
key.into_query_param(),
467+
))
468+
} else {
469+
restore::<$V>(query_get_at(
470+
self.tcx,
471+
self.tcx.query_system.fns.engine.$name,
472+
&self.tcx.query_system.mt_caches.$name,
473+
self.span,
474+
key.into_query_param(),
475+
))
476+
}
443477
})*
444478
}
445479

compiler/rustc_query_system/src/query/caches.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::dep_graph::DepNodeIndex;
2+
use std::cell::RefCell;
23

34
use rustc_data_structures::fx::FxHashMap;
45
use rustc_data_structures::sharded::{self, Sharded};
@@ -41,7 +42,7 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<'tcx, V> for DefaultCacheSelecto
4142
}
4243

4344
pub struct DefaultCache<K, V> {
44-
cache: Lock<FxHashMap<K, (V, DepNodeIndex)>>,
45+
cache: RefCell<FxHashMap<K, (V, DepNodeIndex)>>,
4546
}
4647

4748
impl<K, V> Default for DefaultCache<K, V> {
@@ -61,22 +62,22 @@ where
6162
#[inline(always)]
6263
fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
6364
let key_hash = sharded::make_hash(key);
64-
let lock = self.cache.lock();
65+
let lock = self.cache.borrow_mut();
6566
let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key);
6667

6768
if let Some((_, value)) = result { Some(*value) } else { None }
6869
}
6970

7071
#[inline]
7172
fn complete(&self, key: K, value: V, index: DepNodeIndex) {
72-
let mut lock = self.cache.lock();
73+
let mut lock = self.cache.borrow_mut();
7374
// We may be overwriting another value. This is all right, since the dep-graph
7475
// will check that the fingerprint matches.
7576
lock.insert(key, (value, index));
7677
}
7778

7879
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
79-
let map = self.cache.lock();
80+
let map = self.cache.borrow_mut();
8081
for (k, v) in map.iter() {
8182
f(k, &v.0, v.1);
8283
}
@@ -186,7 +187,7 @@ impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector<K> {
186187
}
187188

188189
pub struct VecCache<K: Idx, V> {
189-
cache: Lock<IndexVec<K, Option<(V, DepNodeIndex)>>>,
190+
cache: RefCell<IndexVec<K, Option<(V, DepNodeIndex)>>>,
190191
}
191192

192193
impl<K: Idx, V> Default for VecCache<K, V> {
@@ -205,18 +206,18 @@ where
205206

206207
#[inline(always)]
207208
fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
208-
let lock = self.cache.lock();
209+
let lock = self.cache.borrow_mut();
209210
if let Some(Some(value)) = lock.get(*key) { Some(*value) } else { None }
210211
}
211212

212213
#[inline]
213214
fn complete(&self, key: K, value: V, index: DepNodeIndex) {
214-
let mut lock = self.cache.lock();
215+
let mut lock = self.cache.borrow_mut();
215216
lock.insert(key, (value, index));
216217
}
217218

218219
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
219-
let map = self.cache.lock();
220+
let map = self.cache.borrow_mut();
220221
for (k, v) in map.iter_enumerated() {
221222
if let Some(v) = v {
222223
f(&k, &v.0, v.1);

0 commit comments

Comments
 (0)