Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store CtxtInterners for local values in AllArenas #57214

Merged
merged 1 commit into from
Jun 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use crate::ty::fold::{TypeFolder, TypeFoldable};
use crate::ty::relate::RelateResult;
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners, InferConst};
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, InferConst};
use crate::ty::{FloatVid, IntVid, TyVid, ConstVid};
use crate::util::nodemap::FxHashMap;

use arena::SyncDroplessArena;
use errors::DiagnosticBuilder;
use rustc_data_structures::unify as ut;
use std::cell::{Cell, Ref, RefCell, RefMut};
Expand Down Expand Up @@ -468,17 +467,13 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>)`.
pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
arena: SyncDroplessArena,
interners: Option<CtxtInterners<'tcx>>,
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
InferCtxtBuilder {
global_tcx: self,
arena: SyncDroplessArena::default(),
interners: None,
fresh_tables: None,
}
}
Expand Down Expand Up @@ -518,14 +513,10 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
let InferCtxtBuilder {
global_tcx,
ref arena,
ref mut interners,
ref fresh_tables,
} = *self;
let in_progress_tables = fresh_tables.as_ref();
// Check that we haven't entered before
assert!(interners.is_none());
global_tcx.enter_local(arena, interners, |tcx| {
global_tcx.enter_local(|tcx| {
f(InferCtxt {
tcx,
in_progress_tables,
Expand Down
44 changes: 28 additions & 16 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,15 @@ use crate::hir;
pub struct AllArenas<'tcx> {
pub global: WorkerLocal<GlobalArenas<'tcx>>,
pub interner: SyncDroplessArena,
pub local_interner: SyncDroplessArena,
}

impl<'tcx> AllArenas<'tcx> {
pub fn new() -> Self {
AllArenas {
global: WorkerLocal::new(|_| GlobalArenas::default()),
interner: SyncDroplessArena::default(),
local_interner: SyncDroplessArena::default(),
}
}
}
Expand Down Expand Up @@ -154,7 +156,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
/// Intern a type
#[inline(never)]
fn intern_ty(
local: &CtxtInterners<'tcx>,
local: &CtxtInterners<'gcx>,
global: &CtxtInterners<'gcx>,
st: TyKind<'tcx>
) -> Ty<'tcx> {
Expand All @@ -179,6 +181,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
&ty_struct);
}

// This is safe because all the types the ty_struct can point to
// already is in the local arena or the global arena
let ty_struct: TyS<'gcx> = unsafe {
mem::transmute(ty_struct)
};

Interned(local.arena.alloc(ty_struct))
}).0
} else {
Expand Down Expand Up @@ -1029,8 +1037,8 @@ pub struct FreeRegionInfo {
#[derive(Copy, Clone)]
pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
gcx: &'gcx GlobalCtxt<'gcx>,
interners: &'tcx CtxtInterners<'tcx>,
dummy: PhantomData<&'a ()>,
interners: &'gcx CtxtInterners<'gcx>,
dummy: PhantomData<(&'a (), &'tcx ())>,
}

impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
Expand All @@ -1045,6 +1053,7 @@ pub struct GlobalCtxt<'tcx> {
pub arena: WorkerLocal<Arena<'tcx>>,
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
global_interners: CtxtInterners<'tcx>,
local_interners: CtxtInterners<'tcx>,

cstore: &'tcx CrateStoreDyn,

Expand Down Expand Up @@ -1262,6 +1271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
s.fatal(&err);
});
let interners = CtxtInterners::new(&arenas.interner);
let local_interners = CtxtInterners::new(&arenas.local_interner);
let common = Common {
empty_predicates: ty::GenericPredicates {
parent: None,
Expand Down Expand Up @@ -1321,6 +1331,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
arena: WorkerLocal::new(|_| Arena::default()),
global_arenas: &arenas.global,
global_interners: interners,
local_interners: local_interners,
dep_graph,
common,
types: common_types,
Expand Down Expand Up @@ -1716,18 +1727,15 @@ impl<'gcx> GlobalCtxt<'gcx> {
/// with the same lifetime as `arena`.
pub fn enter_local<'tcx, F, R>(
&'gcx self,
arena: &'tcx SyncDroplessArena,
interners: &'tcx mut Option<CtxtInterners<'tcx>>,
f: F
) -> R
where
F: FnOnce(TyCtxt<'tcx, 'gcx, 'tcx>) -> R,
'gcx: 'tcx,
{
*interners = Some(CtxtInterners::new(&arena));
let tcx = TyCtxt {
gcx: self,
interners: interners.as_ref().unwrap(),
interners: &self.local_interners,
dummy: PhantomData,
};
ty::tls::with_related_context(tcx.global_tcx(), |icx| {
Expand Down Expand Up @@ -2333,6 +2341,17 @@ macro_rules! intern_method {
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
let key = ($alloc_to_key)(&v);

let alloc = |v, interners: &'gcx CtxtInterners<'gcx>| {
// This transmutes $alloc<'tcx> to $alloc<'gcx>
let v = unsafe {
mem::transmute(v)
};
let i: &$lt_tcx $ty = $alloc_method(&interners.arena, v);
// Cast to 'gcx
let i = unsafe { mem::transmute(i) };
Interned(i)
};

// HACK(eddyb) Depend on flags being accurate to
// determine that all contents are in the global tcx.
// See comments on Lift for why we can't use that.
Expand All @@ -2346,18 +2365,11 @@ macro_rules! intern_method {
v);
}

Interned($alloc_method(&self.interners.arena, v))
alloc(v, &self.interners)
}).0
} else {
self.global_interners.$name.borrow_mut().intern_ref(key, || {
// This transmutes $alloc<'tcx> to $alloc<'gcx>
let v = unsafe {
mem::transmute(v)
};
let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
// Cast to 'gcx
let i = unsafe { mem::transmute(i) };
Interned(i)
alloc(v, &self.global_interners)
}).0
}
}
Expand Down