@@ -16,7 +16,7 @@ use self::EnumDiscriminantInfo::*;
16
16
use super :: utils:: { debug_context, DIB , span_start, bytes_to_bits, size_and_align_of,
17
17
get_namespace_and_span_for_item, create_DIArray, is_node_local_to_unit} ;
18
18
use super :: namespace:: mangled_name_of_item;
19
- use super :: type_names:: { compute_debuginfo_type_name, push_debuginfo_type_name } ;
19
+ use super :: type_names:: compute_debuginfo_type_name;
20
20
use super :: { CrateDebugContext } ;
21
21
use context:: SharedCrateContext ;
22
22
use session:: Session ;
@@ -26,8 +26,11 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DI
26
26
27
27
use rustc:: hir:: def:: CtorKind ;
28
28
use rustc:: hir:: def_id:: DefId ;
29
+ use rustc:: ty:: fold:: TypeVisitor ;
29
30
use rustc:: ty:: subst:: Substs ;
31
+ use rustc:: ty:: util:: TypeIdHasher ;
30
32
use rustc:: hir;
33
+ use rustc_data_structures:: blake2b;
31
34
use { type_of, machine, monomorphize} ;
32
35
use common:: CrateContext ;
33
36
use type_:: Type ;
@@ -38,6 +41,7 @@ use util::common::path2cstr;
38
41
39
42
use libc:: { c_uint, c_longlong} ;
40
43
use std:: ffi:: CString ;
44
+ use std:: fmt:: Write ;
41
45
use std:: path:: Path ;
42
46
use std:: ptr;
43
47
use std:: rc:: Rc ;
@@ -46,6 +50,7 @@ use syntax::ast;
46
50
use syntax:: parse:: token;
47
51
use syntax_pos:: { self , Span } ;
48
52
53
+
49
54
// From DWARF 5.
50
55
// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
51
56
const DW_LANG_RUST : c_uint = 0x1c ;
@@ -138,219 +143,58 @@ impl<'tcx> TypeMap<'tcx> {
138
143
// ID will be generated and stored for later lookup.
139
144
fn get_unique_type_id_of_type < ' a > ( & mut self , cx : & CrateContext < ' a , ' tcx > ,
140
145
type_ : Ty < ' tcx > ) -> UniqueTypeId {
141
-
142
- // basic type -> {:name of the type:}
143
- // tuple -> {tuple_(:param-uid:)*}
144
- // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
145
- // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
146
- // enum variant -> {variant_:variant-name:_:enum-uid:}
147
- // reference (&) -> {& :pointee-uid:}
148
- // mut reference (&mut) -> {&mut :pointee-uid:}
149
- // ptr (*) -> {* :pointee-uid:}
150
- // mut ptr (*mut) -> {*mut :pointee-uid:}
151
- // unique ptr (box) -> {box :pointee-uid:}
152
- // @-ptr (@) -> {@ :pointee-uid:}
153
- // sized vec ([T; x]) -> {[:size:] :element-uid:}
154
- // unsized vec ([T]) -> {[] :element-uid:}
155
- // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
156
- // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
157
- // :return-type-uid: : (:bounds:)*}
158
- // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
159
- // :return-type-uid:}
160
-
146
+ // Let's see if we already have something in the cache
161
147
match self . type_to_unique_id . get ( & type_) . cloned ( ) {
162
148
Some ( unique_type_id) => return unique_type_id,
163
149
None => { /* generate one */ }
164
150
} ;
165
151
166
- let mut unique_type_id = String :: with_capacity ( 256 ) ;
167
- unique_type_id. push ( '{' ) ;
168
-
169
- match type_. sty {
170
- ty:: TyNever |
171
- ty:: TyBool |
172
- ty:: TyChar |
173
- ty:: TyStr |
174
- ty:: TyInt ( _) |
175
- ty:: TyUint ( _) |
176
- ty:: TyFloat ( _) => {
177
- push_debuginfo_type_name ( cx, type_, false , & mut unique_type_id) ;
178
- } ,
179
- ty:: TyAdt ( def, substs) => {
180
- unique_type_id. push_str ( & ( String :: from ( def. descr ( ) ) + " " ) ) ;
181
- from_def_id_and_substs ( self , cx, def. did , substs, & mut unique_type_id) ;
182
- }
183
- ty:: TyTuple ( component_types) if component_types. is_empty ( ) => {
184
- push_debuginfo_type_name ( cx, type_, false , & mut unique_type_id) ;
185
- } ,
186
- ty:: TyTuple ( component_types) => {
187
- unique_type_id. push_str ( "tuple " ) ;
188
- for & component_type in component_types {
189
- let component_type_id =
190
- self . get_unique_type_id_of_type ( cx, component_type) ;
191
- let component_type_id =
192
- self . get_unique_type_id_as_string ( component_type_id) ;
193
- unique_type_id. push_str ( & component_type_id[ ..] ) ;
194
- }
195
- } ,
196
- ty:: TyBox ( inner_type) => {
197
- unique_type_id. push_str ( "box " ) ;
198
- let inner_type_id = self . get_unique_type_id_of_type ( cx, inner_type) ;
199
- let inner_type_id = self . get_unique_type_id_as_string ( inner_type_id) ;
200
- unique_type_id. push_str ( & inner_type_id[ ..] ) ;
201
- } ,
202
- ty:: TyRawPtr ( ty:: TypeAndMut { ty : inner_type, mutbl } ) => {
203
- unique_type_id. push ( '*' ) ;
204
- if mutbl == hir:: MutMutable {
205
- unique_type_id. push_str ( "mut" ) ;
206
- }
152
+ let mut type_id_hasher = TypeIdHasher :: new ( cx. tcx ( ) ,
153
+ DebugInfoTypeIdHasher :: new ( ) ) ;
154
+ type_id_hasher. visit_ty ( type_) ;
155
+ let hash = type_id_hasher. into_inner ( ) . into_hash ( ) ;
207
156
208
- let inner_type_id = self . get_unique_type_id_of_type ( cx, inner_type) ;
209
- let inner_type_id = self . get_unique_type_id_as_string ( inner_type_id) ;
210
- unique_type_id. push_str ( & inner_type_id[ ..] ) ;
211
- } ,
212
- ty:: TyRef ( _, ty:: TypeAndMut { ty : inner_type, mutbl } ) => {
213
- unique_type_id. push ( '&' ) ;
214
- if mutbl == hir:: MutMutable {
215
- unique_type_id. push_str ( "mut" ) ;
216
- }
157
+ let mut unique_type_id = String :: with_capacity ( TYPE_ID_HASH_LENGTH * 2 ) ;
217
158
218
- let inner_type_id = self . get_unique_type_id_of_type ( cx, inner_type) ;
219
- let inner_type_id = self . get_unique_type_id_as_string ( inner_type_id) ;
220
- unique_type_id. push_str ( & inner_type_id[ ..] ) ;
221
- } ,
222
- ty:: TyArray ( inner_type, len) => {
223
- unique_type_id. push_str ( & format ! ( "[{}]" , len) ) ;
224
-
225
- let inner_type_id = self . get_unique_type_id_of_type ( cx, inner_type) ;
226
- let inner_type_id = self . get_unique_type_id_as_string ( inner_type_id) ;
227
- unique_type_id. push_str ( & inner_type_id[ ..] ) ;
228
- } ,
229
- ty:: TySlice ( inner_type) => {
230
- unique_type_id. push_str ( "[]" ) ;
231
-
232
- let inner_type_id = self . get_unique_type_id_of_type ( cx, inner_type) ;
233
- let inner_type_id = self . get_unique_type_id_as_string ( inner_type_id) ;
234
- unique_type_id. push_str ( & inner_type_id[ ..] ) ;
235
- } ,
236
- ty:: TyTrait ( ref trait_data) => {
237
- unique_type_id. push_str ( "trait " ) ;
238
-
239
- let principal = cx. tcx ( ) . erase_late_bound_regions_and_normalize (
240
- & trait_data. principal ) ;
241
-
242
- from_def_id_and_substs ( self ,
243
- cx,
244
- principal. def_id ,
245
- principal. substs ,
246
- & mut unique_type_id) ;
247
- } ,
248
- ty:: TyFnDef ( .., & ty:: BareFnTy { unsafety, abi, ref sig } ) |
249
- ty:: TyFnPtr ( & ty:: BareFnTy { unsafety, abi, ref sig } ) => {
250
- if unsafety == hir:: Unsafety :: Unsafe {
251
- unique_type_id. push_str ( "unsafe " ) ;
252
- }
253
-
254
- unique_type_id. push_str ( abi. name ( ) ) ;
159
+ for byte in hash. into_iter ( ) {
160
+ write ! ( & mut unique_type_id, "{:x}" , byte) . unwrap ( ) ;
161
+ }
255
162
256
- unique_type_id. push_str ( " fn(" ) ;
163
+ let key = self . unique_id_interner . intern ( & unique_type_id) ;
164
+ self . type_to_unique_id . insert ( type_, UniqueTypeId ( key) ) ;
257
165
258
- let sig = cx . tcx ( ) . erase_late_bound_regions_and_normalize ( sig ) ;
166
+ return UniqueTypeId ( key ) ;
259
167
260
- for & parameter_type in & sig. inputs {
261
- let parameter_type_id =
262
- self . get_unique_type_id_of_type ( cx, parameter_type) ;
263
- let parameter_type_id =
264
- self . get_unique_type_id_as_string ( parameter_type_id) ;
265
- unique_type_id. push_str ( & parameter_type_id[ ..] ) ;
266
- unique_type_id. push ( ',' ) ;
267
- }
168
+ // The hasher we are using to generate the UniqueTypeId. We want
169
+ // something that provides more than the 64 bits of the DefaultHasher.
170
+ const TYPE_ID_HASH_LENGTH : usize = 20 ;
268
171
269
- if sig . variadic {
270
- unique_type_id . push_str ( "..." ) ;
271
- }
172
+ struct DebugInfoTypeIdHasher {
173
+ state : blake2b :: Blake2bCtx
174
+ }
272
175
273
- unique_type_id. push_str ( ")->" ) ;
274
- let return_type_id = self . get_unique_type_id_of_type ( cx, sig. output ) ;
275
- let return_type_id = self . get_unique_type_id_as_string ( return_type_id) ;
276
- unique_type_id. push_str ( & return_type_id[ ..] ) ;
277
- } ,
278
- ty:: TyClosure ( _, substs) if substs. upvar_tys . is_empty ( ) => {
279
- push_debuginfo_type_name ( cx, type_, false , & mut unique_type_id) ;
280
- } ,
281
- ty:: TyClosure ( _, substs) => {
282
- unique_type_id. push_str ( "closure " ) ;
283
- for upvar_type in substs. upvar_tys {
284
- let upvar_type_id =
285
- self . get_unique_type_id_of_type ( cx, upvar_type) ;
286
- let upvar_type_id =
287
- self . get_unique_type_id_as_string ( upvar_type_id) ;
288
- unique_type_id. push_str ( & upvar_type_id[ ..] ) ;
289
- }
290
- } ,
291
- _ => {
292
- bug ! ( "get_unique_type_id_of_type() - unexpected type: {:?}" ,
293
- type_)
176
+ impl :: std:: hash:: Hasher for DebugInfoTypeIdHasher {
177
+ fn finish ( & self ) -> u64 {
178
+ unimplemented ! ( )
294
179
}
295
- } ;
296
-
297
- unique_type_id. push ( '}' ) ;
298
180
299
- // Trim to size before storing permanently
300
- unique_type_id. shrink_to_fit ( ) ;
301
-
302
- let key = self . unique_id_interner . intern ( & unique_type_id) ;
303
- self . type_to_unique_id . insert ( type_, UniqueTypeId ( key) ) ;
304
-
305
- return UniqueTypeId ( key) ;
306
-
307
- fn from_def_id_and_substs < ' a , ' tcx > ( type_map : & mut TypeMap < ' tcx > ,
308
- cx : & CrateContext < ' a , ' tcx > ,
309
- def_id : DefId ,
310
- substs : & Substs < ' tcx > ,
311
- output : & mut String ) {
312
- // First, find out the 'real' def_id of the type. Items inlined from
313
- // other crates have to be mapped back to their source.
314
- let def_id = if let Some ( node_id) = cx. tcx ( ) . map . as_local_node_id ( def_id) {
315
- if cx. tcx ( ) . map . is_inlined_node_id ( node_id) {
316
- // The given def_id identifies the inlined copy of a
317
- // type definition, let's take the source of the copy.
318
- cx. defid_for_inlined_node ( node_id) . unwrap ( )
319
- } else {
320
- def_id
321
- }
322
- } else {
323
- def_id
324
- } ;
181
+ #[ inline]
182
+ fn write ( & mut self , bytes : & [ u8 ] ) {
183
+ blake2b:: blake2b_update ( & mut self . state , bytes) ;
184
+ }
185
+ }
325
186
326
- // Get the crate name/disambiguator as first part of the identifier.
327
- let crate_name = if def_id. is_local ( ) {
328
- cx. tcx ( ) . crate_name . clone ( )
329
- } else {
330
- cx. sess ( ) . cstore . original_crate_name ( def_id. krate )
331
- } ;
332
- let crate_disambiguator = cx. tcx ( ) . crate_disambiguator ( def_id. krate ) ;
333
-
334
- output. push_str ( & crate_name[ ..] ) ;
335
- output. push_str ( "/" ) ;
336
- output. push_str ( & crate_disambiguator[ ..] ) ;
337
- output. push_str ( "/" ) ;
338
- // Add the def-index as the second part
339
- output. push_str ( & format ! ( "{:x}" , def_id. index. as_usize( ) ) ) ;
340
-
341
- if substs. types ( ) . next ( ) . is_some ( ) {
342
- output. push ( '<' ) ;
343
-
344
- for type_parameter in substs. types ( ) {
345
- let param_type_id =
346
- type_map. get_unique_type_id_of_type ( cx, type_parameter) ;
347
- let param_type_id =
348
- type_map. get_unique_type_id_as_string ( param_type_id) ;
349
- output. push_str ( & param_type_id[ ..] ) ;
350
- output. push ( ',' ) ;
187
+ impl DebugInfoTypeIdHasher {
188
+ fn new ( ) -> DebugInfoTypeIdHasher {
189
+ DebugInfoTypeIdHasher {
190
+ state : blake2b:: blake2b_new ( TYPE_ID_HASH_LENGTH , & [ ] )
351
191
}
192
+ }
352
193
353
- output. push ( '>' ) ;
194
+ fn into_hash ( self ) -> [ u8 ; TYPE_ID_HASH_LENGTH ] {
195
+ let mut hash = [ 0u8 ; TYPE_ID_HASH_LENGTH ] ;
196
+ blake2b:: blake2b_final ( self . state , & mut hash) ;
197
+ hash
354
198
}
355
199
}
356
200
}
0 commit comments