Fix deadlocks with RUST_LOG=rustc::middle::ty

These are RefCell deadlocks that cause the rustc task to die with the stderr
lock held, causing a real deadlock.

Fixes #26717.
This commit is contained in:
Ariel Ben-Yehuda 2015-07-01 23:07:26 +03:00
parent 40db46c6ba
commit 2fc8571861
6 changed files with 68 additions and 56 deletions

View file

@ -1656,7 +1656,7 @@ fn decode_side_tables(dcx: &DecodeContext,
c::tag_table_tcache => {
let type_scheme = val_dsr.read_type_scheme(dcx);
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
dcx.tcx.tcache.borrow_mut().insert(lid, type_scheme);
dcx.tcx.register_item_type(lid, type_scheme);
}
c::tag_table_param_defs => {
let bounds = val_dsr.read_type_param_def(dcx);

View file

@ -3198,10 +3198,10 @@ pub trait ClosureTyper<'tcx> {
impl<'tcx> CommonTypes<'tcx> {
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>)
-> CommonTypes<'tcx>
{
let mut mk = |sty| ctxt::intern_ty(arena, interner, sty);
let mk = |sty| ctxt::intern_ty(arena, interner, sty);
CommonTypes {
bool: mk(TyBool),
char: mk(TyChar),
@ -3430,12 +3430,12 @@ impl<'tcx> ctxt<'tcx> {
f: F) -> (Session, R)
where F: FnOnce(&ctxt<'tcx>) -> R
{
let mut interner = FnvHashMap();
let common_types = CommonTypes::new(&arenas.type_, &mut interner);
let interner = RefCell::new(FnvHashMap());
let common_types = CommonTypes::new(&arenas.type_, &interner);
tls::enter(ctxt {
arenas: arenas,
interner: RefCell::new(interner),
interner: interner,
substs_interner: RefCell::new(FnvHashMap()),
bare_fn_interner: RefCell::new(FnvHashMap()),
region_interner: RefCell::new(FnvHashMap()),
@ -3563,35 +3563,37 @@ impl<'tcx> ctxt<'tcx> {
}
fn intern_ty(type_arena: &'tcx TypedArena<TyS<'tcx>>,
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
st: TypeVariants<'tcx>)
-> Ty<'tcx> {
match interner.get(&st) {
Some(ty) => return *ty,
_ => ()
}
let ty: Ty /* don't be &mut TyS */ = {
let mut interner = interner.borrow_mut();
match interner.get(&st) {
Some(ty) => return *ty,
_ => ()
}
let flags = FlagComputation::for_sty(&st);
let flags = FlagComputation::for_sty(&st);
let ty = match () {
() => type_arena.alloc(TyS { sty: st,
flags: Cell::new(flags.flags),
region_depth: flags.depth, }),
let ty = match () {
() => type_arena.alloc(TyS { sty: st,
flags: Cell::new(flags.flags),
region_depth: flags.depth, }),
};
interner.insert(InternedTy { ty: ty }, ty);
ty
};
debug!("Interned type: {:?} Pointer: {:?}",
ty, ty as *const TyS);
interner.insert(InternedTy { ty: ty }, ty);
ty
}
// Interns a type/name combination, stores the resulting box in cx.interner,
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
let mut interner = self.interner.borrow_mut();
ctxt::intern_ty(&self.arenas.type_, &mut *interner, st)
ctxt::intern_ty(&self.arenas.type_, &self.interner, st)
}
pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> {
@ -5930,6 +5932,10 @@ impl<'tcx> ctxt<'tcx> {
.clone()
}
// Register a given item type
pub fn register_item_type(&self, did: ast::DefId, ty: TypeScheme<'tcx>) {
self.tcache.borrow_mut().insert(did, ty);
}
// If the given item is in an external crate, looks up its type and adds it to
// the type cache. Returns the type parameters and type.
@ -6006,8 +6012,8 @@ impl<'tcx> ctxt<'tcx> {
if id.krate == ast::LOCAL_CRATE {
self.node_id_to_type(id.node)
} else {
let mut tcache = self.tcache.borrow_mut();
tcache.entry(id).or_insert_with(|| csearch::get_field_type(self, struct_id, id)).ty
memoized(&self.tcache, id,
|id| csearch::get_field_type(self, struct_id, id)).ty
}
}

View file

@ -680,8 +680,15 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
TyError => write!(f, "[type error]"),
TyParam(ref param_ty) => write!(f, "{}", param_ty),
TyEnum(did, substs) | TyStruct(did, substs) => {
parameterized(f, substs, did, &[],
|tcx| tcx.lookup_item_type(did).generics)
ty::tls::with(|tcx| {
if did.krate == ast::LOCAL_CRATE &&
!tcx.tcache.borrow().contains_key(&did) {
write!(f, "{}<..>", tcx.item_path_str(did))
} else {
parameterized(f, substs, did, &[],
|tcx| tcx.lookup_item_type(did).generics)
}
})
}
TyTrait(ref data) => write!(f, "{}", data),
ty::TyProjection(ref data) => write!(f, "{}", data),