Skip to content

Commit c52836c

Browse files
debuginfo: Use TypeIdHasher to create global type identifiers for debuginfo.
1 parent 6f3edb0 commit c52836c

File tree

1 file changed

+41
-197
lines changed

1 file changed

+41
-197
lines changed

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 41 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use self::EnumDiscriminantInfo::*;
1616
use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
1717
get_namespace_and_span_for_item, create_DIArray, is_node_local_to_unit};
1818
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;
2020
use super::{CrateDebugContext};
2121
use context::SharedCrateContext;
2222
use session::Session;
@@ -26,8 +26,11 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DI
2626

2727
use rustc::hir::def::CtorKind;
2828
use rustc::hir::def_id::DefId;
29+
use rustc::ty::fold::TypeVisitor;
2930
use rustc::ty::subst::Substs;
31+
use rustc::ty::util::TypeIdHasher;
3032
use rustc::hir;
33+
use rustc_data_structures::blake2b;
3134
use {type_of, machine, monomorphize};
3235
use common::CrateContext;
3336
use type_::Type;
@@ -38,6 +41,7 @@ use util::common::path2cstr;
3841

3942
use libc::{c_uint, c_longlong};
4043
use std::ffi::CString;
44+
use std::fmt::Write;
4145
use std::path::Path;
4246
use std::ptr;
4347
use std::rc::Rc;
@@ -46,6 +50,7 @@ use syntax::ast;
4650
use syntax::parse::token;
4751
use syntax_pos::{self, Span};
4852

53+
4954
// From DWARF 5.
5055
// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
5156
const DW_LANG_RUST: c_uint = 0x1c;
@@ -138,219 +143,58 @@ impl<'tcx> TypeMap<'tcx> {
138143
// ID will be generated and stored for later lookup.
139144
fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
140145
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
161147
match self.type_to_unique_id.get(&type_).cloned() {
162148
Some(unique_type_id) => return unique_type_id,
163149
None => { /* generate one */}
164150
};
165151

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();
207156

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);
217158

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+
}
255162

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));
257165

258-
let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig);
166+
return UniqueTypeId(key);
259167

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;
268171

269-
if sig.variadic {
270-
unique_type_id.push_str("...");
271-
}
172+
struct DebugInfoTypeIdHasher {
173+
state: blake2b::Blake2bCtx
174+
}
272175

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!()
294179
}
295-
};
296-
297-
unique_type_id.push('}');
298180

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+
}
325186

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, &[])
351191
}
192+
}
352193

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
354198
}
355199
}
356200
}

0 commit comments

Comments
 (0)