Only lookup types in one interner
This commit is contained in:
parent
9b97705f9e
commit
e245d69322
1 changed files with 68 additions and 77 deletions
|
@ -162,66 +162,65 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Intern a type. global_interners is Some only if this is
|
/// Intern a type
|
||||||
/// a local interner and global_interners is its counterpart.
|
fn intern_ty(
|
||||||
fn intern_ty(&self, st: TypeVariants<'tcx>,
|
local: &CtxtInterners<'tcx>,
|
||||||
global_interners: Option<&CtxtInterners<'gcx>>)
|
global: &CtxtInterners<'gcx>,
|
||||||
-> Ty<'tcx> {
|
st: TypeVariants<'tcx>
|
||||||
let ty = {
|
) -> Ty<'tcx> {
|
||||||
let mut interner = self.type_.borrow_mut();
|
let flags = super::flags::FlagComputation::for_sty(&st);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
|
||||||
|
let mut interner = local.type_.borrow_mut();
|
||||||
if let Some(&Interned(ty)) = interner.get(&st) {
|
if let Some(&Interned(ty)) = interner.get(&st) {
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
let global_interner = global_interners.map(|interners| {
|
|
||||||
(interners.type_.borrow_mut(), &interners.arena)
|
|
||||||
});
|
|
||||||
if let Some((ref type_, _)) = global_interner {
|
|
||||||
if let Some(&Interned(ty)) = type_.get(&st) {
|
|
||||||
return ty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let flags = super::flags::FlagComputation::for_sty(&st);
|
|
||||||
let ty_struct = TyS {
|
let ty_struct = TyS {
|
||||||
sty: st,
|
sty: st,
|
||||||
flags: flags.flags,
|
flags: flags.flags,
|
||||||
region_depth: flags.depth,
|
region_depth: flags.depth,
|
||||||
};
|
};
|
||||||
|
|
||||||
// HACK(eddyb) Depend on flags being accurate to
|
// Make sure we don't end up with inference
|
||||||
// determine that all contents are in the global tcx.
|
// types/regions in the global interner
|
||||||
// See comments on Lift for why we can't use that.
|
if local as *const _ as usize == global as *const _ as usize {
|
||||||
if !flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
|
bug!("Attempted to intern `{:?}` which contains \
|
||||||
if let Some((mut type_, arena)) = global_interner {
|
inference types/regions in the global type context",
|
||||||
let ty_struct: TyS<'gcx> = unsafe {
|
&ty_struct);
|
||||||
mem::transmute(ty_struct)
|
|
||||||
};
|
|
||||||
let ty: Ty<'gcx> = arena.alloc(ty_struct);
|
|
||||||
type_.insert(Interned(ty));
|
|
||||||
return ty;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Make sure we don't end up with inference
|
|
||||||
// types/regions in the global tcx.
|
|
||||||
if global_interner.is_none() {
|
|
||||||
drop(interner);
|
|
||||||
bug!("Attempted to intern `{:?}` which contains \
|
|
||||||
inference types/regions in the global type context",
|
|
||||||
&ty_struct);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't be &mut TyS.
|
// Don't be &mut TyS.
|
||||||
let ty: Ty<'tcx> = self.arena.alloc(ty_struct);
|
let ty: Ty<'tcx> = local.arena.alloc(ty_struct);
|
||||||
interner.insert(Interned(ty));
|
interner.insert(Interned(ty));
|
||||||
ty
|
ty
|
||||||
};
|
} else {
|
||||||
|
let mut interner = global.type_.borrow_mut();
|
||||||
|
if let Some(&Interned(ty)) = interner.get(&st) {
|
||||||
|
return ty;
|
||||||
|
}
|
||||||
|
|
||||||
debug!("Interned type: {:?} Pointer: {:?}",
|
let ty_struct = TyS {
|
||||||
ty, ty as *const TyS);
|
sty: st,
|
||||||
ty
|
flags: flags.flags,
|
||||||
|
region_depth: flags.depth,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is safe because all the types the ty_struct can point to
|
||||||
|
// already is in the global arena
|
||||||
|
let ty_struct: TyS<'gcx> = unsafe {
|
||||||
|
mem::transmute(ty_struct)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't be &mut TyS.
|
||||||
|
let ty: Ty<'gcx> = global.arena.alloc(ty_struct);
|
||||||
|
interner.insert(Interned(ty));
|
||||||
|
ty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommonTypes<'tcx> {
|
pub struct CommonTypes<'tcx> {
|
||||||
|
@ -796,7 +795,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
|
||||||
|
|
||||||
impl<'tcx> CommonTypes<'tcx> {
|
impl<'tcx> CommonTypes<'tcx> {
|
||||||
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
|
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
|
||||||
let mk = |sty| interners.intern_ty(sty, None);
|
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
|
||||||
let mk_region = |r| {
|
let mk_region = |r| {
|
||||||
if let Some(r) = interners.region.borrow().get(&r) {
|
if let Some(r) = interners.region.borrow().get(&r) {
|
||||||
return r.0;
|
return r.0;
|
||||||
|
@ -2130,31 +2129,17 @@ macro_rules! intern_method {
|
||||||
$keep_in_local_tcx:expr) -> $ty:ty) => {
|
$keep_in_local_tcx:expr) -> $ty:ty) => {
|
||||||
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
|
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
|
||||||
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
|
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
|
||||||
{
|
let key = ($alloc_to_key)(&v);
|
||||||
let key = ($alloc_to_key)(&v);
|
|
||||||
if let Some(i) = self.interners.$name.borrow().get(key) {
|
|
||||||
return i.0;
|
|
||||||
}
|
|
||||||
if !self.is_global() {
|
|
||||||
if let Some(i) = self.global_interners.$name.borrow().get(key) {
|
|
||||||
return i.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK(eddyb) Depend on flags being accurate to
|
// HACK(eddyb) Depend on flags being accurate to
|
||||||
// determine that all contents are in the global tcx.
|
// determine that all contents are in the global tcx.
|
||||||
// See comments on Lift for why we can't use that.
|
// See comments on Lift for why we can't use that.
|
||||||
if !($keep_in_local_tcx)(&v) {
|
if ($keep_in_local_tcx)(&v) {
|
||||||
if !self.is_global() {
|
let mut interner = self.interners.$name.borrow_mut();
|
||||||
let v = unsafe {
|
if let Some(&Interned(v)) = interner.get(key) {
|
||||||
mem::transmute(v)
|
return v;
|
||||||
};
|
|
||||||
let i = ($alloc_to_ret)(self.global_interners.arena.$alloc_method(v));
|
|
||||||
self.global_interners.$name.borrow_mut().insert(Interned(i));
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Make sure we don't end up with inference
|
// Make sure we don't end up with inference
|
||||||
// types/regions in the global tcx.
|
// types/regions in the global tcx.
|
||||||
if self.is_global() {
|
if self.is_global() {
|
||||||
|
@ -2162,11 +2147,24 @@ macro_rules! intern_method {
|
||||||
inference types/regions in the global type context",
|
inference types/regions in the global type context",
|
||||||
v);
|
v);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let i = ($alloc_to_ret)(self.interners.arena.$alloc_method(v));
|
let i = ($alloc_to_ret)(self.interners.arena.$alloc_method(v));
|
||||||
self.interners.$name.borrow_mut().insert(Interned(i));
|
interner.insert(Interned(i));
|
||||||
i
|
i
|
||||||
|
} else {
|
||||||
|
let mut interner = self.global_interners.$name.borrow_mut();
|
||||||
|
if let Some(&Interned(v)) = interner.get(key) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This transmutes $alloc<'tcx> to $alloc<'gcx>
|
||||||
|
let v = unsafe {
|
||||||
|
mem::transmute(v)
|
||||||
|
};
|
||||||
|
let i = ($alloc_to_ret)(self.global_interners.arena.$alloc_method(v));
|
||||||
|
interner.insert(Interned(i));
|
||||||
|
i
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2274,15 +2272,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.mk_fn_ptr(converted_sig)
|
self.mk_fn_ptr(converted_sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interns a type/name combination, stores the resulting box in cx.interners,
|
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
|
||||||
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
|
CtxtInterners::intern_ty(&self.interners, &self.global_interners, st)
|
||||||
pub fn mk_ty(self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
|
|
||||||
let global_interners = if !self.is_global() {
|
|
||||||
Some(&self.global_interners)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.interners.intern_ty(st, global_interners)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
|
pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue