Skip to content

Commit 166dbc3

Browse files
committed
rustc: Keep a reference to the interners in TyCtxt.
1 parent 2fbbaf2 commit 166dbc3

File tree

1 file changed

+110
-91
lines changed

1 file changed

+110
-91
lines changed

src/librustc/ty/context.rs

Lines changed: 110 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,61 @@ impl<'tcx> CtxtArenas<'tcx> {
8080
}
8181
}
8282

83+
struct CtxtInterners<'tcx> {
84+
/// The arenas that types etc are allocated from.
85+
arenas: &'tcx CtxtArenas<'tcx>,
86+
87+
/// Specifically use a speedy hash algorithm for these hash sets,
88+
/// they're accessed quite often.
89+
type_: RefCell<FnvHashSet<InternedTy<'tcx>>>,
90+
substs: RefCell<FnvHashSet<InternedSubsts<'tcx>>>,
91+
bare_fn: RefCell<FnvHashSet<&'tcx BareFnTy<'tcx>>>,
92+
region: RefCell<FnvHashSet<&'tcx Region>>,
93+
stability: RefCell<FnvHashSet<&'tcx attr::Stability>>,
94+
layout: RefCell<FnvHashSet<&'tcx Layout>>,
95+
}
96+
97+
impl<'tcx> CtxtInterners<'tcx> {
98+
fn new(arenas: &'tcx CtxtArenas<'tcx>) -> CtxtInterners<'tcx> {
99+
CtxtInterners {
100+
arenas: arenas,
101+
type_: RefCell::new(FnvHashSet()),
102+
substs: RefCell::new(FnvHashSet()),
103+
bare_fn: RefCell::new(FnvHashSet()),
104+
region: RefCell::new(FnvHashSet()),
105+
stability: RefCell::new(FnvHashSet()),
106+
layout: RefCell::new(FnvHashSet())
107+
}
108+
}
109+
110+
fn intern_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
111+
let ty = {
112+
let mut interner = self.type_.borrow_mut();
113+
match interner.get(&st) {
114+
Some(&InternedTy { ty }) => return ty,
115+
None => ()
116+
}
117+
118+
let flags = super::flags::FlagComputation::for_sty(&st);
119+
120+
// Don't be &mut TyS.
121+
let ty: Ty = self.arenas.type_.alloc(TyS {
122+
sty: st,
123+
flags: Cell::new(flags.flags),
124+
region_depth: flags.depth,
125+
});
126+
127+
interner.insert(InternedTy { ty: ty });
128+
ty
129+
};
130+
131+
debug!("Interned type: {:?} Pointer: {:?}",
132+
ty, ty as *const TyS);
133+
ty
134+
}
135+
136+
}
137+
83138
pub struct CommonTypes<'tcx> {
84139
pub bool: Ty<'tcx>,
85140
pub char: Ty<'tcx>,
@@ -190,11 +245,8 @@ impl<'a, 'tcx> Tables<'tcx> {
190245
}
191246

192247
impl<'tcx> CommonTypes<'tcx> {
193-
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
194-
interner: &RefCell<FnvHashSet<InternedTy<'tcx>>>)
195-
-> CommonTypes<'tcx>
196-
{
197-
let mk = |sty| TyCtxt::intern_ty(arena, interner, sty);
248+
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
249+
let mk = |sty| interners.intern_ty(sty);
198250
CommonTypes {
199251
bool: mk(TyBool),
200252
char: mk(TyChar),
@@ -221,7 +273,7 @@ impl<'tcx> CommonTypes<'tcx> {
221273
#[derive(Copy, Clone)]
222274
pub struct TyCtxt<'a, 'tcx: 'a> {
223275
gcx: &'a GlobalCtxt<'tcx>,
224-
276+
interners: &'a CtxtInterners<'tcx>
225277
}
226278

227279
impl<'a, 'tcx> Deref for TyCtxt<'a, 'tcx> {
@@ -232,17 +284,7 @@ impl<'a, 'tcx> Deref for TyCtxt<'a, 'tcx> {
232284
}
233285

234286
pub struct GlobalCtxt<'tcx> {
235-
/// The arenas that types etc are allocated from.
236-
arenas: &'tcx CtxtArenas<'tcx>,
237-
238-
/// Specifically use a speedy hash algorithm for this hash map, it's used
239-
/// quite often.
240-
interner: RefCell<FnvHashSet<InternedTy<'tcx>>>,
241-
substs_interner: RefCell<FnvHashSet<InternedSubsts<'tcx>>>,
242-
bare_fn_interner: RefCell<FnvHashSet<&'tcx BareFnTy<'tcx>>>,
243-
region_interner: RefCell<FnvHashSet<&'tcx Region>>,
244-
stability_interner: RefCell<FnvHashSet<&'tcx attr::Stability>>,
245-
layout_interner: RefCell<FnvHashSet<&'tcx Layout>>,
287+
global_interners: CtxtInterners<'tcx>,
246288

247289
pub dep_graph: DepGraph,
248290

@@ -442,6 +484,16 @@ pub struct GlobalCtxt<'tcx> {
442484
pub layout_cache: RefCell<FnvHashMap<Ty<'tcx>, &'tcx Layout>>,
443485
}
444486

487+
impl<'tcx> GlobalCtxt<'tcx> {
488+
/// Get the global TyCtxt.
489+
pub fn global_tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
490+
TyCtxt {
491+
gcx: self,
492+
interners: &self.global_interners
493+
}
494+
}
495+
}
496+
445497
impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
446498
pub fn crate_name(self, cnum: ast::CrateNum) -> token::InternedString {
447499
if cnum == LOCAL_CRATE {
@@ -481,7 +533,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
481533
pub fn intern_trait_def(self, def: ty::TraitDef<'tcx>)
482534
-> &'tcx ty::TraitDef<'tcx> {
483535
let did = def.trait_ref.def_id;
484-
let interned = self.arenas.trait_defs.alloc(def);
536+
let interned = self.global_interners.arenas.trait_defs.alloc(def);
485537
if let Some(prev) = self.trait_defs.borrow_mut().insert(did, interned) {
486538
bug!("Tried to overwrite interned TraitDef: {:?}", prev)
487539
}
@@ -490,7 +542,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
490542

491543
pub fn alloc_trait_def(self, def: ty::TraitDef<'tcx>)
492544
-> &'tcx ty::TraitDef<'tcx> {
493-
self.arenas.trait_defs.alloc(def)
545+
self.global_interners.arenas.trait_defs.alloc(def)
494546
}
495547

496548
pub fn intern_adt_def(self,
@@ -499,7 +551,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
499551
variants: Vec<ty::VariantDefData<'tcx, 'tcx>>)
500552
-> ty::AdtDefMaster<'tcx> {
501553
let def = ty::AdtDefData::new(self, did, kind, variants);
502-
let interned = self.arenas.adt_defs.alloc(def);
554+
let interned = self.global_interners.arenas.adt_defs.alloc(def);
503555
// this will need a transmute when reverse-variance is removed
504556
if let Some(prev) = self.adt_defs.borrow_mut().insert(did, interned) {
505557
bug!("Tried to overwrite interned AdtDef: {:?}", prev)
@@ -508,12 +560,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
508560
}
509561

510562
pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
511-
if let Some(st) = self.stability_interner.borrow().get(&stab) {
563+
if let Some(st) = self.interners.stability.borrow().get(&stab) {
512564
return st;
513565
}
514566

515-
let interned = self.arenas.stability.alloc(stab);
516-
if let Some(prev) = self.stability_interner
567+
let interned = self.interners.arenas.stability.alloc(stab);
568+
if let Some(prev) = self.interners.stability
517569
.borrow_mut()
518570
.replace(interned) {
519571
bug!("Tried to overwrite interned Stability: {:?}", prev)
@@ -522,12 +574,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
522574
}
523575

524576
pub fn intern_layout(self, layout: Layout) -> &'tcx Layout {
525-
if let Some(layout) = self.layout_interner.borrow().get(&layout) {
577+
if let Some(layout) = self.interners.layout.borrow().get(&layout) {
526578
return layout;
527579
}
528580

529-
let interned = self.arenas.layout.alloc(layout);
530-
if let Some(prev) = self.layout_interner
581+
let interned = self.interners.arenas.layout.alloc(layout);
582+
if let Some(prev) = self.interners.layout
531583
.borrow_mut()
532584
.replace(interned) {
533585
bug!("Tried to overwrite interned Layout: {:?}", prev)
@@ -568,18 +620,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
568620
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx>) -> R
569621
{
570622
let data_layout = TargetDataLayout::parse(s);
571-
let interner = RefCell::new(FnvHashSet());
572-
let common_types = CommonTypes::new(&arenas.type_, &interner);
623+
let interners = CtxtInterners::new(arenas);
624+
let common_types = CommonTypes::new(&interners);
573625
let dep_graph = map.dep_graph.clone();
574626
let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone());
575627
tls::enter(GlobalCtxt {
576-
arenas: arenas,
577-
interner: interner,
578-
substs_interner: RefCell::new(FnvHashSet()),
579-
bare_fn_interner: RefCell::new(FnvHashSet()),
580-
region_interner: RefCell::new(FnvHashSet()),
581-
stability_interner: RefCell::new(FnvHashSet()),
582-
layout_interner: RefCell::new(FnvHashSet()),
628+
global_interners: interners,
583629
dep_graph: dep_graph.clone(),
584630
types: common_types,
585631
named_region_map: named_region_map,
@@ -653,7 +699,7 @@ pub trait Lift<'tcx> {
653699
impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
654700
type Lifted = Ty<'tcx>;
655701
fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<Ty<'tcx>> {
656-
if let Some(&InternedTy { ty }) = tcx.interner.borrow().get(&self.sty) {
702+
if let Some(&InternedTy { ty }) = tcx.interners.type_.borrow().get(&self.sty) {
657703
if *self as *const _ == ty as *const _ {
658704
return Some(ty);
659705
}
@@ -665,7 +711,7 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
665711
impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
666712
type Lifted = &'tcx Substs<'tcx>;
667713
fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
668-
if let Some(&InternedSubsts { substs }) = tcx.substs_interner.borrow().get(*self) {
714+
if let Some(&InternedSubsts { substs }) = tcx.interners.substs.borrow().get(*self) {
669715
if *self as *const _ == substs as *const _ {
670716
return Some(substs);
671717
}
@@ -697,18 +743,17 @@ pub mod tls {
697743
})
698744
}
699745

700-
pub fn enter<'tcx, F: for<'a> FnOnce(TyCtxt<'a, 'tcx>) -> R, R>(gcx: GlobalCtxt<'tcx>,
701-
f: F) -> R {
746+
pub fn enter<'tcx, F, R>(gcx: GlobalCtxt<'tcx>, f: F) -> R
747+
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx>) -> R
748+
{
702749
codemap::SPAN_DEBUG.with(|span_dbg| {
703750
let original_span_debug = span_dbg.get();
704751
span_dbg.set(span_debug);
705752
let tls_ptr = &gcx as *const _ as *const ThreadLocalGlobalCtxt;
706753
let result = TLS_TCX.with(|tls| {
707754
let prev = tls.get();
708755
tls.set(Some(tls_ptr));
709-
let ret = f(TyCtxt {
710-
gcx: &gcx
711-
});
756+
let ret = f(gcx.global_tcx());
712757
tls.set(prev);
713758
ret
714759
});
@@ -718,16 +763,18 @@ pub mod tls {
718763
}
719764

720765
pub fn with<F: FnOnce(TyCtxt) -> R, R>(f: F) -> R {
721-
TLS_TCX.with(|tcx| {
722-
let tcx = tcx.get().unwrap();
766+
TLS_TCX.with(|gcx| {
767+
let gcx = gcx.get().unwrap();
768+
let gcx = unsafe { &*(gcx as *const GlobalCtxt) };
723769
f(TyCtxt {
724-
gcx: unsafe { &*(tcx as *const GlobalCtxt) }
770+
gcx: gcx,
771+
interners: &gcx.global_interners
725772
})
726773
})
727774
}
728775

729776
pub fn with_opt<F: FnOnce(Option<TyCtxt>) -> R, R>(f: F) -> R {
730-
if TLS_TCX.with(|tcx| tcx.get().is_some()) {
777+
if TLS_TCX.with(|gcx| gcx.get().is_some()) {
731778
with(|v| f(Some(v)))
732779
} else {
733780
f(None)
@@ -760,7 +807,7 @@ macro_rules! sty_debug_print {
760807
$(let mut $variant = total;)*
761808

762809

763-
for &InternedTy { ty: t } in tcx.interner.borrow().iter() {
810+
for &InternedTy { ty: t } in tcx.interners.type_.borrow().iter() {
764811
let variant = match t.sty {
765812
ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
766813
ty::TyFloat(..) | ty::TyStr => continue,
@@ -806,11 +853,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
806853
TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
807854
TyTrait, TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
808855

809-
println!("Substs interner: #{}", self.substs_interner.borrow().len());
810-
println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
811-
println!("Region interner: #{}", self.region_interner.borrow().len());
812-
println!("Stability interner: #{}", self.stability_interner.borrow().len());
813-
println!("Layout interner: #{}", self.layout_interner.borrow().len());
856+
println!("Substs interner: #{}", self.interners.substs.borrow().len());
857+
println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len());
858+
println!("Region interner: #{}", self.interners.region.borrow().len());
859+
println!("Stability interner: #{}", self.interners.stability.borrow().len());
860+
println!("Layout interner: #{}", self.interners.layout.borrow().len());
814861
}
815862
}
816863

@@ -862,12 +909,12 @@ fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
862909
impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
863910
// Type constructors
864911
pub fn mk_substs(self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
865-
if let Some(interned) = self.substs_interner.borrow().get(&substs) {
912+
if let Some(interned) = self.interners.substs.borrow().get(&substs) {
866913
return interned.substs;
867914
}
868915

869-
let substs = self.arenas.substs.alloc(substs);
870-
self.substs_interner.borrow_mut().insert(InternedSubsts {
916+
let substs = self.interners.arenas.substs.alloc(substs);
917+
self.interners.substs.borrow_mut().insert(InternedSubsts {
871918
substs: substs
872919
});
873920
substs
@@ -884,57 +931,29 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
884931
}
885932

886933
pub fn mk_bare_fn(self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
887-
if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
934+
if let Some(bare_fn) = self.interners.bare_fn.borrow().get(&bare_fn) {
888935
return *bare_fn;
889936
}
890937

891-
let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
892-
self.bare_fn_interner.borrow_mut().insert(bare_fn);
938+
let bare_fn = self.interners.arenas.bare_fn.alloc(bare_fn);
939+
self.interners.bare_fn.borrow_mut().insert(bare_fn);
893940
bare_fn
894941
}
895942

896943
pub fn mk_region(self, region: Region) -> &'tcx Region {
897-
if let Some(region) = self.region_interner.borrow().get(&region) {
944+
if let Some(region) = self.interners.region.borrow().get(&region) {
898945
return *region;
899946
}
900947

901-
let region = self.arenas.region.alloc(region);
902-
self.region_interner.borrow_mut().insert(region);
948+
let region = self.interners.arenas.region.alloc(region);
949+
self.interners.region.borrow_mut().insert(region);
903950
region
904951
}
905952

906-
fn intern_ty(type_arena: &'tcx TypedArena<TyS<'tcx>>,
907-
interner: &RefCell<FnvHashSet<InternedTy<'tcx>>>,
908-
st: TypeVariants<'tcx>)
909-
-> Ty<'tcx> {
910-
let ty: Ty /* don't be &mut TyS */ = {
911-
let mut interner = interner.borrow_mut();
912-
match interner.get(&st) {
913-
Some(&InternedTy { ty }) => return ty,
914-
None => ()
915-
}
916-
917-
let flags = super::flags::FlagComputation::for_sty(&st);
918-
919-
let ty = match () {
920-
() => type_arena.alloc(TyS { sty: st,
921-
flags: Cell::new(flags.flags),
922-
region_depth: flags.depth, }),
923-
};
924-
925-
interner.insert(InternedTy { ty: ty });
926-
ty
927-
};
928-
929-
debug!("Interned type: {:?} Pointer: {:?}",
930-
ty, ty as *const TyS);
931-
ty
932-
}
933-
934-
// Interns a type/name combination, stores the resulting box in cx.interner,
953+
// Interns a type/name combination, stores the resulting box in cx.interners,
935954
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
936955
pub fn mk_ty(self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
937-
TyCtxt::intern_ty(&self.arenas.type_, &self.interner, st)
956+
self.interners.intern_ty(st)
938957
}
939958

940959
pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {

0 commit comments

Comments
 (0)