@@ -31,7 +31,7 @@ use hir::FreevarMap;
3131use ty:: { BareFnTy , InferTy , ParamTy , ProjectionTy , TraitTy } ;
3232use ty:: { TyVar , TyVid , IntVar , IntVid , FloatVar , FloatVid } ;
3333use ty:: TypeVariants :: * ;
34- use ty:: layout:: TargetDataLayout ;
34+ use ty:: layout:: { Layout , TargetDataLayout } ;
3535use ty:: maps;
3636use util:: common:: MemoizationMap ;
3737use util:: nodemap:: { NodeMap , NodeSet , DefIdMap , DefIdSet } ;
@@ -56,6 +56,7 @@ pub struct CtxtArenas<'tcx> {
5656 bare_fn : TypedArena < BareFnTy < ' tcx > > ,
5757 region : TypedArena < Region > ,
5858 stability : TypedArena < attr:: Stability > ,
59+ layout : TypedArena < Layout > ,
5960
6061 // references
6162 trait_defs : TypedArena < ty:: TraitDef < ' tcx > > ,
@@ -70,6 +71,7 @@ impl<'tcx> CtxtArenas<'tcx> {
7071 bare_fn : TypedArena :: new ( ) ,
7172 region : TypedArena :: new ( ) ,
7273 stability : TypedArena :: new ( ) ,
74+ layout : TypedArena :: new ( ) ,
7375
7476 trait_defs : TypedArena :: new ( ) ,
7577 adt_defs : TypedArena :: new ( )
@@ -230,6 +232,7 @@ pub struct TyCtxt<'tcx> {
230232 bare_fn_interner : RefCell < FnvHashMap < & ' tcx BareFnTy < ' tcx > , & ' tcx BareFnTy < ' tcx > > > ,
231233 region_interner : RefCell < FnvHashMap < & ' tcx Region , & ' tcx Region > > ,
232234 stability_interner : RefCell < FnvHashMap < & ' tcx attr:: Stability , & ' tcx attr:: Stability > > ,
235+ layout_interner : RefCell < FnvHashMap < & ' tcx Layout , & ' tcx Layout > > ,
233236
234237 pub dep_graph : DepGraph ,
235238
@@ -423,6 +426,9 @@ pub struct TyCtxt<'tcx> {
423426
424427 /// Data layout specification for the current target.
425428 pub data_layout : TargetDataLayout ,
429+
430+ /// Cache for layouts computed from types.
431+ pub layout_cache : RefCell < FnvHashMap < Ty < ' tcx > , & ' tcx Layout > > ,
426432}
427433
428434impl < ' tcx > TyCtxt < ' tcx > {
@@ -504,6 +510,20 @@ impl<'tcx> TyCtxt<'tcx> {
504510 interned
505511 }
506512
513+ pub fn intern_layout ( & self , layout : Layout ) -> & ' tcx Layout {
514+ if let Some ( layout) = self . layout_interner . borrow ( ) . get ( & layout) {
515+ return layout;
516+ }
517+
518+ let interned = self . arenas . layout . alloc ( layout) ;
519+ if let Some ( prev) = self . layout_interner
520+ . borrow_mut ( )
521+ . insert ( interned, interned) {
522+ bug ! ( "Tried to overwrite interned Layout: {:?}" , prev)
523+ }
524+ interned
525+ }
526+
507527 pub fn store_free_region_map ( & self , id : NodeId , map : FreeRegionMap ) {
508528 if self . free_region_maps . borrow_mut ( ) . insert ( id, map) . is_some ( ) {
509529 bug ! ( "Tried to overwrite interned FreeRegionMap for NodeId {:?}" , id)
@@ -547,6 +567,7 @@ impl<'tcx> TyCtxt<'tcx> {
547567 bare_fn_interner : RefCell :: new ( FnvHashMap ( ) ) ,
548568 region_interner : RefCell :: new ( FnvHashMap ( ) ) ,
549569 stability_interner : RefCell :: new ( FnvHashMap ( ) ) ,
570+ layout_interner : RefCell :: new ( FnvHashMap ( ) ) ,
550571 dep_graph : dep_graph. clone ( ) ,
551572 types : common_types,
552573 named_region_map : named_region_map,
@@ -595,6 +616,7 @@ impl<'tcx> TyCtxt<'tcx> {
595616 fragment_infos : RefCell :: new ( DefIdMap ( ) ) ,
596617 crate_name : token:: intern_and_get_ident ( crate_name) ,
597618 data_layout : data_layout,
619+ layout_cache : RefCell :: new ( FnvHashMap ( ) ) ,
598620 } , f)
599621 }
600622}
@@ -768,6 +790,7 @@ impl<'tcx> TyCtxt<'tcx> {
768790 println ! ( "BareFnTy interner: #{}" , self . bare_fn_interner. borrow( ) . len( ) ) ;
769791 println ! ( "Region interner: #{}" , self . region_interner. borrow( ) . len( ) ) ;
770792 println ! ( "Stability interner: #{}" , self . stability_interner. borrow( ) . len( ) ) ;
793+ println ! ( "Layout interner: #{}" , self . layout_interner. borrow( ) . len( ) ) ;
771794 }
772795}
773796
0 commit comments