@@ -34,7 +34,7 @@ use rustc_middle::ty::Instance;
34
34
use rustc_middle:: ty:: { self , AdtKind , GeneratorSubsts , ParamEnv , Ty , TyCtxt } ;
35
35
use rustc_middle:: { bug, span_bug} ;
36
36
use rustc_session:: config:: { self , DebugInfo } ;
37
- use rustc_span:: symbol:: { Interner , Symbol } ;
37
+ use rustc_span:: symbol:: Symbol ;
38
38
use rustc_span:: FileNameDisplayPreference ;
39
39
use rustc_span:: { self , SourceFile , SourceFileHash , Span } ;
40
40
use rustc_target:: abi:: { Abi , Align , HasDataLayout , Integer , TagEncoding } ;
@@ -89,8 +89,54 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
89
89
90
90
pub const NO_SCOPE_METADATA : Option < & DIScope > = None ;
91
91
92
- #[ derive( Copy , Debug , Hash , Eq , PartialEq , Clone ) ]
93
- pub struct UniqueTypeId ( Symbol ) ;
92
+ mod unique_type_id {
93
+ use super :: * ;
94
+ use rustc_arena:: DroplessArena ;
95
+
96
+ #[ derive( Copy , Hash , Eq , PartialEq , Clone ) ]
97
+ pub ( super ) struct UniqueTypeId ( u32 ) ;
98
+
99
+ // The `&'static str`s in this type actually point into the arena.
100
+ //
101
+ // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
102
+ // found that to regress performance up to 2% in some cases. This might be
103
+ // revisited after further improvements to `indexmap`.
104
+ #[ derive( Default ) ]
105
+ pub ( super ) struct TypeIdInterner {
106
+ arena : DroplessArena ,
107
+ names : FxHashMap < & ' static str , UniqueTypeId > ,
108
+ strings : Vec < & ' static str > ,
109
+ }
110
+
111
+ impl TypeIdInterner {
112
+ #[ inline]
113
+ pub ( super ) fn intern ( & mut self , string : & str ) -> UniqueTypeId {
114
+ if let Some ( & name) = self . names . get ( string) {
115
+ return name;
116
+ }
117
+
118
+ let name = UniqueTypeId ( self . strings . len ( ) as u32 ) ;
119
+
120
+ // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
121
+ // UTF-8.
122
+ let string: & str =
123
+ unsafe { std:: str:: from_utf8_unchecked ( self . arena . alloc_slice ( string. as_bytes ( ) ) ) } ;
124
+ // It is safe to extend the arena allocation to `'static` because we only access
125
+ // these while the arena is still alive.
126
+ let string: & ' static str = unsafe { & * ( string as * const str ) } ;
127
+ self . strings . push ( string) ;
128
+ self . names . insert ( string, name) ;
129
+ name
130
+ }
131
+
132
+ // Get the symbol as a string. `Symbol::as_str()` should be used in
133
+ // preference to this function.
134
+ pub ( super ) fn get ( & self , symbol : UniqueTypeId ) -> & str {
135
+ self . strings [ symbol. 0 as usize ]
136
+ }
137
+ }
138
+ }
139
+ use unique_type_id:: * ;
94
140
95
141
/// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
96
142
/// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
@@ -99,7 +145,7 @@ pub struct UniqueTypeId(Symbol);
99
145
#[ derive( Default ) ]
100
146
pub struct TypeMap < ' ll , ' tcx > {
101
147
/// The `UniqueTypeId`s created so far.
102
- unique_id_interner : Interner ,
148
+ unique_id_interner : TypeIdInterner ,
103
149
/// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping.
104
150
unique_id_to_metadata : FxHashMap < UniqueTypeId , & ' ll DIType > ,
105
151
/// A map from types to debuginfo metadata. This is an N:1 mapping.
@@ -166,8 +212,7 @@ impl TypeMap<'ll, 'tcx> {
166
212
/// Gets the string representation of a `UniqueTypeId`. This method will fail if
167
213
/// the ID is unknown.
168
214
fn get_unique_type_id_as_string ( & self , unique_type_id : UniqueTypeId ) -> & str {
169
- let UniqueTypeId ( interner_key) = unique_type_id;
170
- self . unique_id_interner . get ( interner_key)
215
+ self . unique_id_interner . get ( unique_type_id)
171
216
}
172
217
173
218
/// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given
@@ -197,9 +242,9 @@ impl TypeMap<'ll, 'tcx> {
197
242
let unique_type_id = hasher. finish :: < Fingerprint > ( ) . to_hex ( ) ;
198
243
199
244
let key = self . unique_id_interner . intern ( & unique_type_id) ;
200
- self . type_to_unique_id . insert ( type_, UniqueTypeId ( key) ) ;
245
+ self . type_to_unique_id . insert ( type_, key) ;
201
246
202
- UniqueTypeId ( key)
247
+ key
203
248
}
204
249
205
250
/// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really
@@ -215,7 +260,7 @@ impl TypeMap<'ll, 'tcx> {
215
260
let enum_variant_type_id =
216
261
format ! ( "{}::{}" , self . get_unique_type_id_as_string( enum_type_id) , variant_name) ;
217
262
let interner_key = self . unique_id_interner . intern ( & enum_variant_type_id) ;
218
- UniqueTypeId ( interner_key)
263
+ interner_key
219
264
}
220
265
221
266
/// Gets the unique type ID string for an enum variant part.
0 commit comments