Skip to content

Commit 4c0e9de

Browse files
committed
use RefCell for query caches in single thread
1 parent 2ff0b3a commit 4c0e9de

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;
@@ -98,6 +100,10 @@ pub struct QuerySystem<'tcx> {
98100
pub jobs: AtomicU64,
99101
}
100102

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

438+
#[cfg(not(parallel_compiler))]
432439
impl<'tcx> TyCtxtAt<'tcx> {
433440
$($(#[$attr])*
441+
434442
#[inline(always)]
435443
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
436444
{
437-
restore::<$V>(with_query_caches!(query_get_at(
445+
restore::<$V>(query_get_at(
438446
self.tcx,
439447
self.tcx.query_system.fns.engine.$name,
440-
:self.tcx, $name,
448+
&self.tcx.query_system.caches.$name,
441449
self.span,
442450
key.into_query_param(),
443-
)))
451+
))
452+
})*
453+
}
454+
455+
#[cfg(parallel_compiler)]
456+
impl<'tcx> TyCtxtAt<'tcx> {
457+
$($(#[$attr])*
458+
#[inline(always)]
459+
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
460+
{
461+
if std::intrinsics::likely(self.tcx.query_system.single_thread) {
462+
restore::<$V>(query_get_at(
463+
self.tcx,
464+
self.tcx.query_system.fns.engine.$name,
465+
&self.tcx.query_system.caches.$name,
466+
self.span,
467+
key.into_query_param(),
468+
))
469+
} else {
470+
restore::<$V>(query_get_at(
471+
self.tcx,
472+
self.tcx.query_system.fns.engine.$name,
473+
&self.tcx.query_system.mt_caches.$name,
474+
self.span,
475+
key.into_query_param(),
476+
))
477+
}
444478
})*
445479
}
446480

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
}
@@ -185,7 +186,7 @@ impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector<K> {
185186
}
186187

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

191192
impl<K: Idx, V> Default for VecCache<K, V> {
@@ -204,18 +205,18 @@ where
204205

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

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

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

0 commit comments

Comments
 (0)