@@ -52,6 +52,7 @@ use ty::BindingMode;
52
52
use ty:: CanonicalTy ;
53
53
use util:: nodemap:: { DefIdSet , ItemLocalMap } ;
54
54
use util:: nodemap:: { FxHashMap , FxHashSet } ;
55
+ use rustc_data_structures:: fx:: FxInterner ;
55
56
use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
56
57
use rustc_data_structures:: stable_hasher:: { HashStable , hash_stable_hashmap,
57
58
StableHasher , StableHasherResult ,
@@ -124,15 +125,15 @@ impl<'tcx> GlobalArenas<'tcx> {
124
125
}
125
126
}
126
127
127
- type InternedSet < ' tcx , T > = Lock < FxHashSet < Interned < ' tcx , T > > > ;
128
+ type InternedSet < ' tcx , T > = Lock < FxInterner < Interned < ' tcx , T > > > ;
128
129
129
130
pub struct CtxtInterners < ' tcx > {
130
131
/// The arena that types, regions, etc are allocated from
131
132
arena : & ' tcx SyncDroplessArena ,
132
133
133
134
/// Specifically use a speedy hash algorithm for these hash sets,
134
135
/// they're accessed quite often.
135
- type_ : InternedSet < ' tcx , TyS < ' tcx > > ,
136
+ type_ : Lock < FxInterner < Interned < ' tcx , TyS < ' tcx > > > > ,
136
137
type_list : InternedSet < ' tcx , Slice < Ty < ' tcx > > > ,
137
138
substs : InternedSet < ' tcx , Substs < ' tcx > > ,
138
139
canonical_var_infos : InternedSet < ' tcx , Slice < CanonicalVarInfo > > ,
@@ -173,51 +174,39 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
173
174
// determine that all contents are in the global tcx.
174
175
// See comments on Lift for why we can't use that.
175
176
if flags. flags . intersects ( ty:: TypeFlags :: KEEP_IN_LOCAL_TCX ) {
176
- let mut interner = local. type_ . borrow_mut ( ) ;
177
- if let Some ( & Interned ( ty) ) = interner. get ( & st) {
178
- return ty;
179
- }
180
-
181
- let ty_struct = TyS {
182
- sty : st,
183
- flags : flags. flags ,
184
- outer_exclusive_binder : flags. outer_exclusive_binder ,
185
- } ;
177
+ local. type_ . borrow_mut ( ) . intern ( st, |st| {
178
+ let ty_struct = TyS {
179
+ sty : st,
180
+ flags : flags. flags ,
181
+ outer_exclusive_binder : flags. outer_exclusive_binder ,
182
+ } ;
186
183
187
- // Make sure we don't end up with inference
188
- // types/regions in the global interner
189
- if local as * const _ as usize == global as * const _ as usize {
190
- bug ! ( "Attempted to intern `{:?}` which contains \
191
- inference types/regions in the global type context",
192
- & ty_struct) ;
193
- }
184
+ // Make sure we don't end up with inference
185
+ // types/regions in the global interner
186
+ if local as * const _ as usize == global as * const _ as usize {
187
+ bug ! ( "Attempted to intern `{:?}` which contains \
188
+ inference types/regions in the global type context",
189
+ & ty_struct) ;
190
+ }
194
191
195
- // Don't be &mut TyS.
196
- let ty: Ty < ' tcx > = local. arena . alloc ( ty_struct) ;
197
- interner. insert ( Interned ( ty) ) ;
198
- ty
192
+ Interned ( local. arena . alloc ( ty_struct) )
193
+ } ) . 0
199
194
} else {
200
- let mut interner = global. type_ . borrow_mut ( ) ;
201
- if let Some ( & Interned ( ty) ) = interner. get ( & st) {
202
- return ty;
203
- }
204
-
205
- let ty_struct = TyS {
206
- sty : st,
207
- flags : flags. flags ,
208
- outer_exclusive_binder : flags. outer_exclusive_binder ,
209
- } ;
195
+ global. type_ . borrow_mut ( ) . intern ( st, |st| {
196
+ let ty_struct = TyS {
197
+ sty : st,
198
+ flags : flags. flags ,
199
+ outer_exclusive_binder : flags. outer_exclusive_binder ,
200
+ } ;
210
201
211
- // This is safe because all the types the ty_struct can point to
212
- // already is in the global arena
213
- let ty_struct: TyS < ' gcx > = unsafe {
214
- mem:: transmute ( ty_struct)
215
- } ;
202
+ // This is safe because all the types the ty_struct can point to
203
+ // already is in the global arena
204
+ let ty_struct: TyS < ' gcx > = unsafe {
205
+ mem:: transmute ( ty_struct)
206
+ } ;
216
207
217
- // Don't be &mut TyS.
218
- let ty: Ty < ' gcx > = global. arena . alloc ( ty_struct) ;
219
- interner. insert ( Interned ( ty) ) ;
220
- ty
208
+ Interned ( global. arena . alloc ( ty_struct) )
209
+ } ) . 0
221
210
}
222
211
}
223
212
}
@@ -800,12 +789,9 @@ impl<'tcx> CommonTypes<'tcx> {
800
789
801
790
let mk = |sty| CtxtInterners :: intern_ty ( interners, interners, sty) ;
802
791
let mk_region = |r| {
803
- if let Some ( r) = interners. region . borrow ( ) . get ( & r) {
804
- return r. 0 ;
805
- }
806
- let r = interners. arena . alloc ( r) ;
807
- interners. region . borrow_mut ( ) . insert ( Interned ( r) ) ;
808
- & * r
792
+ interners. region . borrow_mut ( ) . intern ( r, |r| {
793
+ Interned ( interners. arena . alloc ( r) )
794
+ } ) . 0
809
795
} ;
810
796
CommonTypes {
811
797
bool : mk ( TyBool ) ,
@@ -916,14 +902,14 @@ pub struct GlobalCtxt<'tcx> {
916
902
/// Data layout specification for the current target.
917
903
pub data_layout : TargetDataLayout ,
918
904
919
- stability_interner : Lock < FxHashSet < & ' tcx attr:: Stability > > ,
905
+ stability_interner : Lock < FxInterner < & ' tcx attr:: Stability > > ,
920
906
921
907
/// Stores the value of constants (and deduplicates the actual memory)
922
- allocation_interner : Lock < FxHashSet < & ' tcx Allocation > > ,
908
+ allocation_interner : Lock < FxInterner < & ' tcx Allocation > > ,
923
909
924
910
pub alloc_map : Lock < interpret:: AllocMap < ' tcx , & ' tcx Allocation > > ,
925
911
926
- layout_interner : Lock < FxHashSet < & ' tcx LayoutDetails > > ,
912
+ layout_interner : Lock < FxInterner < & ' tcx LayoutDetails > > ,
927
913
928
914
/// A general purpose channel to throw data out the back towards LLVM worker
929
915
/// threads.
@@ -1006,16 +992,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1006
992
self ,
1007
993
alloc : Allocation ,
1008
994
) -> & ' gcx Allocation {
1009
- let allocs = & mut self . allocation_interner . borrow_mut ( ) ;
1010
- if let Some ( alloc) = allocs. get ( & alloc) {
1011
- return alloc;
1012
- }
1013
-
1014
- let interned = self . global_arenas . const_allocs . alloc ( alloc) ;
1015
- if let Some ( prev) = allocs. replace ( interned) {
1016
- bug ! ( "Tried to overwrite interned Allocation: {:#?}" , prev)
1017
- }
1018
- interned
995
+ self . allocation_interner . borrow_mut ( ) . intern ( alloc, |alloc| {
996
+ self . global_arenas . const_allocs . alloc ( alloc)
997
+ } )
1019
998
}
1020
999
1021
1000
/// Allocates a byte or string literal for `mir::interpret`
@@ -1027,29 +1006,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1027
1006
}
1028
1007
1029
1008
pub fn intern_stability ( self , stab : attr:: Stability ) -> & ' gcx attr:: Stability {
1030
- let mut stability_interner = self . stability_interner . borrow_mut ( ) ;
1031
- if let Some ( st) = stability_interner. get ( & stab) {
1032
- return st;
1033
- }
1034
-
1035
- let interned = self . global_interners . arena . alloc ( stab) ;
1036
- if let Some ( prev) = stability_interner. replace ( interned) {
1037
- bug ! ( "Tried to overwrite interned Stability: {:?}" , prev)
1038
- }
1039
- interned
1009
+ self . stability_interner . borrow_mut ( ) . intern ( stab, |stab| {
1010
+ self . global_interners . arena . alloc ( stab)
1011
+ } )
1040
1012
}
1041
1013
1042
1014
pub fn intern_layout ( self , layout : LayoutDetails ) -> & ' gcx LayoutDetails {
1043
- let mut layout_interner = self . layout_interner . borrow_mut ( ) ;
1044
- if let Some ( layout) = layout_interner. get ( & layout) {
1045
- return layout;
1046
- }
1047
-
1048
- let interned = self . global_arenas . layout . alloc ( layout) ;
1049
- if let Some ( prev) = layout_interner. replace ( interned) {
1050
- bug ! ( "Tried to overwrite interned Layout: {:?}" , prev)
1051
- }
1052
- interned
1015
+ self . layout_interner . borrow_mut ( ) . intern ( layout, |layout| {
1016
+ self . global_arenas . layout . alloc ( layout)
1017
+ } )
1053
1018
}
1054
1019
1055
1020
pub fn lift < T : ?Sized + Lift < ' tcx > > ( self , value : & T ) -> Option < T :: Lifted > {
@@ -1171,9 +1136,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1171
1136
evaluation_cache : traits:: EvaluationCache :: new ( ) ,
1172
1137
crate_name : Symbol :: intern ( crate_name) ,
1173
1138
data_layout,
1174
- layout_interner : Lock :: new ( FxHashSet ( ) ) ,
1175
- stability_interner : Lock :: new ( FxHashSet ( ) ) ,
1176
- allocation_interner : Lock :: new ( FxHashSet ( ) ) ,
1139
+ layout_interner : Default :: default ( ) ,
1140
+ stability_interner : Default :: default ( ) ,
1141
+ allocation_interner : Default :: default ( ) ,
1177
1142
alloc_map : Lock :: new ( interpret:: AllocMap :: new ( ) ) ,
1178
1143
tx_to_llvm_workers : Lock :: new ( tx) ,
1179
1144
output_filenames : Arc :: new ( output_filenames. clone ( ) ) ,
@@ -1909,7 +1874,7 @@ macro_rules! sty_debug_print {
1909
1874
( $ctxt: expr, $( $variant: ident) ,* ) => { {
1910
1875
// curious inner module to allow variant names to be used as
1911
1876
// variable names.
1912
- #[ allow( non_snake_case) ]
1877
+ #[ allow( non_snake_case, warnings ) ]
1913
1878
mod inner {
1914
1879
use ty:: { self , TyCtxt } ;
1915
1880
use ty:: context:: Interned ;
@@ -1929,7 +1894,7 @@ macro_rules! sty_debug_print {
1929
1894
} ;
1930
1895
$( let mut $variant = total; ) *
1931
1896
1932
-
1897
+ /*
1933
1898
for &Interned(t) in tcx.interners.type_.borrow().iter() {
1934
1899
let variant = match t.sty {
1935
1900
ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
@@ -1945,7 +1910,7 @@ macro_rules! sty_debug_print {
1945
1910
if region { total.region_infer += 1; variant.region_infer += 1 }
1946
1911
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1947
1912
if region && ty { total.both_infer += 1; variant.both_infer += 1 }
1948
- }
1913
+ }*/
1949
1914
println!( "Ty interner total ty region both" ) ;
1950
1915
$( println!( " {:18}: {uses:6} {usespc:4.1}%, \
1951
1916
{ty:4.1}% {region:5.1}% {both:4.1}%",
@@ -2096,37 +2061,28 @@ macro_rules! intern_method {
2096
2061
// determine that all contents are in the global tcx.
2097
2062
// See comments on Lift for why we can't use that.
2098
2063
if ( $keep_in_local_tcx) ( & v) {
2099
- let mut interner = self . interners. $name. borrow_mut( ) ;
2100
- if let Some ( & Interned ( v) ) = interner. get( key) {
2101
- return v;
2102
- }
2103
-
2104
- // Make sure we don't end up with inference
2105
- // types/regions in the global tcx.
2106
- if self . is_global( ) {
2107
- bug!( "Attempted to intern `{:?}` which contains \
2108
- inference types/regions in the global type context",
2109
- v) ;
2110
- }
2111
-
2112
- let i = $alloc_method( & self . interners. arena, v) ;
2113
- interner. insert( Interned ( i) ) ;
2114
- i
2064
+ self . interners. $name. borrow_mut( ) . intern_ref( key, || {
2065
+ // Make sure we don't end up with inference
2066
+ // types/regions in the global tcx.
2067
+ if self . is_global( ) {
2068
+ bug!( "Attempted to intern `{:?}` which contains \
2069
+ inference types/regions in the global type context",
2070
+ v) ;
2071
+ }
2072
+
2073
+ Interned ( $alloc_method( & self . interners. arena, v) )
2074
+ } ) . 0
2115
2075
} else {
2116
- let mut interner = self . global_interners. $name. borrow_mut( ) ;
2117
- if let Some ( & Interned ( v) ) = interner. get( key) {
2118
- return v;
2119
- }
2120
-
2121
- // This transmutes $alloc<'tcx> to $alloc<'gcx>
2122
- let v = unsafe {
2123
- mem:: transmute( v)
2124
- } ;
2125
- let i: & $lt_tcx $ty = $alloc_method( & self . global_interners. arena, v) ;
2126
- // Cast to 'gcx
2127
- let i = unsafe { mem:: transmute( i) } ;
2128
- interner. insert( Interned ( i) ) ;
2129
- i
2076
+ self . global_interners. $name. borrow_mut( ) . intern_ref( key, || {
2077
+ // This transmutes $alloc<'tcx> to $alloc<'gcx>
2078
+ let v = unsafe {
2079
+ mem:: transmute( v)
2080
+ } ;
2081
+ let i: & $lt_tcx $ty = $alloc_method( & self . global_interners. arena, v) ;
2082
+ // Cast to 'gcx
2083
+ let i = unsafe { mem:: transmute( i) } ;
2084
+ Interned ( i)
2085
+ } ) . 0
2130
2086
}
2131
2087
}
2132
2088
}
0 commit comments