Skip to content

Commit 67712d7

Browse files
committed
Auto merge of #49390 - Zoxc:sync-syntax, r=michaelwoerister
More thread-safety changes r? @michaelwoerister
2 parents a1c21ed + 1e3f638 commit 67712d7

File tree

14 files changed

+101
-89
lines changed

14 files changed

+101
-89
lines changed

Diff for: src/librustc/hir/map/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ use hir::svh::Svh;
3333
use util::nodemap::{DefIdMap, FxHashMap};
3434

3535
use arena::TypedArena;
36-
use std::cell::RefCell;
3736
use std::io;
3837
use ty::TyCtxt;
3938

39+
use rustc_data_structures::sync::Lock;
40+
4041
pub mod blocks;
4142
mod collector;
4243
mod def_collector;
@@ -264,7 +265,7 @@ pub struct Map<'hir> {
264265
definitions: &'hir Definitions,
265266

266267
/// Bodies inlined from other crates are cached here.
267-
inlined_bodies: RefCell<DefIdMap<&'hir Body>>,
268+
inlined_bodies: Lock<DefIdMap<&'hir Body>>,
268269

269270
/// The reverse mapping of `node_to_hir_id`.
270271
hir_to_node_id: FxHashMap<HirId, NodeId>,
@@ -927,8 +928,13 @@ impl<'hir> Map<'hir> {
927928
}
928929

929930
pub fn intern_inlined_body(&self, def_id: DefId, body: Body) -> &'hir Body {
931+
let mut inlined_bodies = self.inlined_bodies.borrow_mut();
932+
if let Some(&b) = inlined_bodies.get(&def_id) {
933+
debug_assert_eq!(&body, b);
934+
return b;
935+
}
930936
let body = self.forest.inlined_bodies.alloc(body);
931-
self.inlined_bodies.borrow_mut().insert(def_id, body);
937+
inlined_bodies.insert(def_id, body);
932938
body
933939
}
934940

@@ -1189,7 +1195,7 @@ pub fn map_crate<'hir>(sess: &::session::Session,
11891195
map,
11901196
hir_to_node_id,
11911197
definitions,
1192-
inlined_bodies: RefCell::new(DefIdMap()),
1198+
inlined_bodies: Lock::new(DefIdMap()),
11931199
};
11941200

11951201
hir_id_validator::check_crate(&map);

Diff for: src/librustc/lint/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
pub use self::Level::*;
3232
pub use self::LintSource::*;
3333

34-
use rustc_data_structures::sync::Lrc;
34+
use rustc_data_structures::sync::{self, Lrc};
3535

3636
use errors::{DiagnosticBuilder, DiagnosticId};
3737
use hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -287,8 +287,9 @@ pub trait EarlyLintPass: LintPass {
287287
}
288288

289289
/// A lint pass boxed up as a trait object.
290-
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + 'static>;
291-
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + 'static>;
290+
pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>;
291+
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
292+
+ sync::Sync + 'static>;
292293

293294
/// Identifies a lint known to the compiler.
294295
#[derive(Clone, Copy, Debug)]

Diff for: src/librustc/mir/cache.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::cell::{Ref, RefCell};
1211
use rustc_data_structures::indexed_vec::IndexVec;
12+
use rustc_data_structures::sync::{RwLock, ReadGuard};
1313
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
1414
StableHasherResult};
1515
use ich::StableHashingContext;
@@ -19,7 +19,7 @@ use rustc_serialize as serialize;
1919

2020
#[derive(Clone, Debug)]
2121
pub struct Cache {
22-
predecessors: RefCell<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>>
22+
predecessors: RwLock<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>>
2323
}
2424

2525

@@ -46,7 +46,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Cache {
4646
impl Cache {
4747
pub fn new() -> Self {
4848
Cache {
49-
predecessors: RefCell::new(None)
49+
predecessors: RwLock::new(None)
5050
}
5151
}
5252

@@ -55,12 +55,12 @@ impl Cache {
5555
*self.predecessors.borrow_mut() = None;
5656
}
5757

58-
pub fn predecessors(&self, mir: &Mir) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> {
58+
pub fn predecessors(&self, mir: &Mir) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
5959
if self.predecessors.borrow().is_none() {
6060
*self.predecessors.borrow_mut() = Some(calculate_predecessors(mir));
6161
}
6262

63-
Ref::map(self.predecessors.borrow(), |p| p.as_ref().unwrap())
63+
ReadGuard::map(self.predecessors.borrow(), |p| p.as_ref().unwrap())
6464
}
6565
}
6666

Diff for: src/librustc/mir/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use util::ppaux;
3434
use std::slice;
3535
use hir::{self, InlineAsm};
3636
use std::borrow::{Cow};
37-
use std::cell::Ref;
37+
use rustc_data_structures::sync::ReadGuard;
3838
use std::fmt::{self, Debug, Formatter, Write};
3939
use std::{iter, mem, u32};
4040
use std::ops::{Index, IndexMut};
@@ -187,13 +187,13 @@ impl<'tcx> Mir<'tcx> {
187187
}
188188

189189
#[inline]
190-
pub fn predecessors(&self) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> {
190+
pub fn predecessors(&self) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
191191
self.cache.predecessors(self)
192192
}
193193

194194
#[inline]
195-
pub fn predecessors_for(&self, bb: BasicBlock) -> Ref<Vec<BasicBlock>> {
196-
Ref::map(self.predecessors(), |p| &p[bb])
195+
pub fn predecessors_for(&self, bb: BasicBlock) -> ReadGuard<Vec<BasicBlock>> {
196+
ReadGuard::map(self.predecessors(), |p| &p[bb])
197197
}
198198

199199
#[inline]

Diff for: src/librustc/ty/context.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5858
StableVec};
5959
use arena::{TypedArena, DroplessArena};
6060
use rustc_data_structures::indexed_vec::IndexVec;
61-
use rustc_data_structures::sync::Lrc;
61+
use rustc_data_structures::sync::{Lrc, Lock};
6262
use std::any::Any;
6363
use std::borrow::Borrow;
6464
use std::cell::{Cell, RefCell};
@@ -131,28 +131,28 @@ pub struct CtxtInterners<'tcx> {
131131

132132
/// Specifically use a speedy hash algorithm for these hash sets,
133133
/// they're accessed quite often.
134-
type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
135-
type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
136-
substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
137-
canonical_var_infos: RefCell<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>,
138-
region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>,
139-
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
140-
predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
141-
const_: RefCell<FxHashSet<Interned<'tcx, Const<'tcx>>>>,
134+
type_: Lock<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
135+
type_list: Lock<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
136+
substs: Lock<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
137+
canonical_var_infos: Lock<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>,
138+
region: Lock<FxHashSet<Interned<'tcx, RegionKind>>>,
139+
existential_predicates: Lock<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
140+
predicates: Lock<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
141+
const_: Lock<FxHashSet<Interned<'tcx, Const<'tcx>>>>,
142142
}
143143

144144
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
145145
fn new(arena: &'tcx DroplessArena) -> CtxtInterners<'tcx> {
146146
CtxtInterners {
147-
arena,
148-
type_: RefCell::new(FxHashSet()),
149-
type_list: RefCell::new(FxHashSet()),
150-
substs: RefCell::new(FxHashSet()),
151-
region: RefCell::new(FxHashSet()),
152-
existential_predicates: RefCell::new(FxHashSet()),
153-
canonical_var_infos: RefCell::new(FxHashSet()),
154-
predicates: RefCell::new(FxHashSet()),
155-
const_: RefCell::new(FxHashSet()),
147+
arena: arena,
148+
type_: Lock::new(FxHashSet()),
149+
type_list: Lock::new(FxHashSet()),
150+
substs: Lock::new(FxHashSet()),
151+
canonical_var_infos: Lock::new(FxHashSet()),
152+
region: Lock::new(FxHashSet()),
153+
existential_predicates: Lock::new(FxHashSet()),
154+
predicates: Lock::new(FxHashSet()),
155+
const_: Lock::new(FxHashSet()),
156156
}
157157
}
158158

@@ -892,11 +892,11 @@ pub struct GlobalCtxt<'tcx> {
892892
/// by `proc-macro` crates.
893893
pub derive_macros: RefCell<NodeMap<Symbol>>,
894894

895-
stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>,
895+
stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
896896

897897
pub interpret_interner: InterpretInterner<'tcx>,
898898

899-
layout_interner: RefCell<FxHashSet<&'tcx LayoutDetails>>,
899+
layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
900900

901901
/// A vector of every trait accessible in the whole crate
902902
/// (i.e. including those from subcrates). This is used only for
@@ -910,15 +910,15 @@ pub struct GlobalCtxt<'tcx> {
910910
/// This is intended to only get used during the trans phase of the compiler
911911
/// when satisfying the query for a particular codegen unit. Internally in
912912
/// the query it'll send data along this channel to get processed later.
913-
pub tx_to_llvm_workers: mpsc::Sender<Box<dyn Any + Send>>,
913+
pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<dyn Any + Send>>>,
914914

915915
output_filenames: Arc<OutputFilenames>,
916916
}
917917

918918
/// Everything needed to efficiently work with interned allocations
919919
#[derive(Debug, Default)]
920920
pub struct InterpretInterner<'tcx> {
921-
inner: RefCell<InterpretInternerInner<'tcx>>,
921+
inner: Lock<InterpretInternerInner<'tcx>>,
922922
}
923923

924924
#[derive(Debug, Default)]
@@ -1278,13 +1278,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12781278
evaluation_cache: traits::EvaluationCache::new(),
12791279
crate_name: Symbol::intern(crate_name),
12801280
data_layout,
1281-
layout_interner: RefCell::new(FxHashSet()),
1281+
layout_interner: Lock::new(FxHashSet()),
12821282
layout_depth: Cell::new(0),
12831283
derive_macros: RefCell::new(NodeMap()),
1284-
stability_interner: RefCell::new(FxHashSet()),
1284+
stability_interner: Lock::new(FxHashSet()),
12851285
interpret_interner: Default::default(),
12861286
all_traits: RefCell::new(None),
1287-
tx_to_llvm_workers: tx,
1287+
tx_to_llvm_workers: Lock::new(tx),
12881288
output_filenames: Arc::new(output_filenames.clone()),
12891289
};
12901290

Diff for: src/librustc/ty/steal.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::cell::{Ref, RefCell};
11+
use rustc_data_structures::sync::{RwLock, ReadGuard};
1212
use std::mem;
1313

1414
/// The `Steal` struct is intended to used as the value for a query.
@@ -32,25 +32,25 @@ use std::mem;
3232
///
3333
/// FIXME(#41710) -- what is the best way to model linear queries?
3434
pub struct Steal<T> {
35-
value: RefCell<Option<T>>
35+
value: RwLock<Option<T>>
3636
}
3737

3838
impl<T> Steal<T> {
3939
pub fn new(value: T) -> Self {
4040
Steal {
41-
value: RefCell::new(Some(value))
41+
value: RwLock::new(Some(value))
4242
}
4343
}
4444

45-
pub fn borrow(&self) -> Ref<T> {
46-
Ref::map(self.value.borrow(), |opt| match *opt {
45+
pub fn borrow(&self) -> ReadGuard<T> {
46+
ReadGuard::map(self.value.borrow(), |opt| match *opt {
4747
None => bug!("attempted to read from stolen value"),
4848
Some(ref v) => v
4949
})
5050
}
5151

5252
pub fn steal(&self) -> T {
53-
let value_ref = &mut *self.value.borrow_mut();
53+
let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
5454
let value = mem::replace(value_ref, None);
5555
value.expect("attempt to read from stolen value")
5656
}

Diff for: src/librustc_borrowck/borrowck/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
128128
// Note that `mir_validated` is a "stealable" result; the
129129
// thief, `optimized_mir()`, forces borrowck, so we know that
130130
// is not yet stolen.
131-
tcx.mir_validated(owner_def_id).borrow();
131+
ty::maps::queries::mir_validated::ensure(tcx, owner_def_id);
132132

133133
// option dance because you can't capture an uninitialized variable
134134
// by mut-ref.

Diff for: src/librustc_data_structures/sync.rs

+12
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,18 @@ impl<T> RwLock<T> {
388388
f(&*self.read())
389389
}
390390

391+
#[cfg(not(parallel_queries))]
392+
#[inline(always)]
393+
pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
394+
self.0.try_borrow_mut().map_err(|_| ())
395+
}
396+
397+
#[cfg(parallel_queries)]
398+
#[inline(always)]
399+
pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
400+
self.0.try_write().ok_or(())
401+
}
402+
391403
#[cfg(not(parallel_queries))]
392404
#[inline(always)]
393405
pub fn write(&self) -> WriteGuard<T> {

Diff for: src/librustc_trans/back/write.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ pub fn start_async_translation(tcx: TyCtxt,
10351035
crate_info,
10361036

10371037
time_graph,
1038-
coordinator_send: tcx.tx_to_llvm_workers.clone(),
1038+
coordinator_send: tcx.tx_to_llvm_workers.lock().clone(),
10391039
trans_worker_receive,
10401040
shared_emitter_main,
10411041
future: coordinator_thread,
@@ -1428,7 +1428,7 @@ fn start_executing_work(tcx: TyCtxt,
14281428
metadata_config: Arc<ModuleConfig>,
14291429
allocator_config: Arc<ModuleConfig>)
14301430
-> thread::JoinHandle<Result<CompiledModules, ()>> {
1431-
let coordinator_send = tcx.tx_to_llvm_workers.clone();
1431+
let coordinator_send = tcx.tx_to_llvm_workers.lock().clone();
14321432
let sess = tcx.sess;
14331433

14341434
// Compute the set of symbols we need to retain when doing LTO (if we need to)
@@ -2340,7 +2340,7 @@ pub(crate) fn submit_translated_module_to_llvm(tcx: TyCtxt,
23402340
mtrans: ModuleTranslation,
23412341
cost: u64) {
23422342
let llvm_work_item = WorkItem::Optimize(mtrans);
2343-
drop(tcx.tx_to_llvm_workers.send(Box::new(Message::TranslationDone {
2343+
drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::TranslationDone {
23442344
llvm_work_item,
23452345
cost,
23462346
})));

0 commit comments

Comments
 (0)