Skip to content

Commit 2ce0e6d

Browse files
committed
rustc_trans: use the TypeId hashing mechanism instead of metadata.
1 parent 02c4155 commit 2ce0e6d

File tree

5 files changed

+45
-67
lines changed

5 files changed

+45
-67
lines changed

src/librustc/middle/cstore.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,6 @@ pub trait CrateStore<'tcx> {
258258
// utility functions
259259
fn metadata_filename(&self) -> &str;
260260
fn metadata_section_name(&self, target: &Target) -> &str;
261-
fn encode_type<'a>(&self,
262-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
263-
ty: Ty<'tcx>,
264-
def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
265-
-> Vec<u8>;
266261
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
267262
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
268263
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
@@ -469,13 +464,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
469464
// utility functions
470465
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
471466
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
472-
fn encode_type<'a>(&self,
473-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
474-
ty: Ty<'tcx>,
475-
def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
476-
-> Vec<u8> {
477-
bug!("encode_type")
478-
}
479467
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
480468
{ vec![] }
481469
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }

src/librustc/ty/util.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
352352
/// Creates a hash of the type `Ty` which will be the same no matter what crate
353353
/// context it's calculated within. This is used by the `type_id` intrinsic.
354354
pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
355-
let mut hasher = TypeIdHasher {
356-
tcx: self,
357-
state: SipHasher::new()
358-
};
355+
let mut hasher = TypeIdHasher::new(self, SipHasher::new());
359356
hasher.visit_ty(ty);
360-
hasher.state.finish()
357+
hasher.finish()
361358
}
362359

363360
/// Returns true if this ADT is a dtorck type.
@@ -391,16 +388,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
391388
}
392389
}
393390

394-
struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
391+
pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, H> {
395392
tcx: TyCtxt<'a, 'gcx, 'tcx>,
396-
state: SipHasher
393+
state: H
397394
}
398395

399-
impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> {
400-
fn hash<T: Hash>(&mut self, x: T) {
396+
impl<'a, 'gcx, 'tcx, H: Hasher> TypeIdHasher<'a, 'gcx, 'tcx, H> {
397+
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, state: H) -> Self {
398+
TypeIdHasher {
399+
tcx: tcx,
400+
state: state
401+
}
402+
}
403+
404+
pub fn hash<T: Hash>(&mut self, x: T) {
401405
x.hash(&mut self.state);
402406
}
403407

408+
pub fn finish(self) -> u64 {
409+
self.state.finish()
410+
}
411+
404412
fn hash_discriminant_u8<T>(&mut self, x: &T) {
405413
let v = unsafe {
406414
intrinsics::discriminant_value(x)
@@ -419,7 +427,7 @@ impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> {
419427
}
420428
}
421429

422-
impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
430+
impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, H> {
423431
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
424432
// Distinguish between the Ty variants uniformly.
425433
self.hash_discriminant_u8(&ty.sty);

src/librustc_metadata/csearch.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -677,14 +677,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
677677
{
678678
loader::meta_section_name(target)
679679
}
680-
fn encode_type<'a>(&self,
681-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
682-
ty: Ty<'tcx>,
683-
def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
684-
-> Vec<u8>
685-
{
686-
encoder::encoded_ty(tcx, ty, def_id_to_string)
687-
}
688680

689681
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
690682
{

src/librustc_metadata/encoder.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ use rustc::session::config::{self, PanicStrategy, CrateTypeRustcMacro};
3636
use rustc::util::nodemap::{FnvHashMap, NodeSet};
3737

3838
use rustc_serialize::{Encodable, SpecializedEncoder};
39-
use std::cell::RefCell;
4039
use std::io::prelude::*;
41-
use std::io::{Cursor, SeekFrom};
40+
use std::io::SeekFrom;
4241
use std::ops::{Deref, DerefMut};
4342
use std::rc::Rc;
4443
use std::u32;
@@ -1891,17 +1890,3 @@ fn encode_metadata_inner(ecx: &mut EncodeContext, krate: &hir::Crate) {
18911890
println!(" total bytes: {}", stats.total_bytes);
18921891
}
18931892
}
1894-
1895-
// Get the encoded string for a type
1896-
pub fn encoded_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1897-
t: Ty<'tcx>,
1898-
def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
1899-
-> Vec<u8> {
1900-
let mut wr = Cursor::new(Vec::new());
1901-
tyencode::enc_ty(&mut wr, &tyencode::ctxt {
1902-
ds: def_id_to_string,
1903-
tcx: tcx,
1904-
abbrevs: &RefCell::new(FnvHashMap())
1905-
}, t);
1906-
wr.into_inner()
1907-
}

src/librustc_trans/back/symbol_names.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,10 @@ use monomorphize::Instance;
102102
use util::sha2::{Digest, Sha256};
103103

104104
use rustc::middle::weak_lang_items;
105-
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
105+
use rustc::hir::def_id::LOCAL_CRATE;
106106
use rustc::hir::map as hir_map;
107-
use rustc::ty::{Ty, TyCtxt, TypeFoldable};
107+
use rustc::ty::{self, Ty, TypeFoldable};
108+
use rustc::ty::fold::TypeVisitor;
108109
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
109110
use rustc::ty::subst::Substs;
110111
use rustc::hir::map::definitions::{DefPath, DefPathData};
@@ -114,9 +115,18 @@ use syntax::attr;
114115
use syntax::parse::token::{self, InternedString};
115116
use serialize::hex::ToHex;
116117

117-
pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> String {
118-
let def_path = tcx.def_path(def_id);
119-
def_path.to_string(tcx)
118+
use std::hash::Hasher;
119+
120+
struct Sha256Hasher<'a>(&'a mut Sha256);
121+
122+
impl<'a> Hasher for Sha256Hasher<'a> {
123+
fn write(&mut self, msg: &[u8]) {
124+
self.0.input(msg)
125+
}
126+
127+
fn finish(&self) -> u64 {
128+
bug!("Sha256Hasher::finish should not be called");
129+
}
120130
}
121131

122132
fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
@@ -132,48 +142,43 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
132142

133143
// values for generic type parameters,
134144
// if any.
135-
substs: Option<&Substs<'tcx>>)
145+
substs: Option<&'tcx Substs<'tcx>>)
136146
-> String {
137147
debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
138148
def_path, substs);
139149

140150
let tcx = scx.tcx();
141151

142-
return record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
143-
let mut hash_state = scx.symbol_hasher().borrow_mut();
144-
152+
let mut hash_state = scx.symbol_hasher().borrow_mut();
153+
record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
145154
hash_state.reset();
146155

156+
let mut hasher = ty::util::TypeIdHasher::new(tcx, Sha256Hasher(&mut hash_state));
147157
// the main symbol name is not necessarily unique; hash in the
148158
// compiler's internal def-path, guaranteeing each symbol has a
149159
// truly unique path
150-
hash_state.input_str(&def_path.to_string(tcx));
160+
hasher.hash(def_path.to_string(tcx));
151161

152162
// Include the main item-type. Note that, in this case, the
153163
// assertions about `needs_subst` may not hold, but this item-type
154164
// ought to be the same for every reference anyway.
155165
assert!(!item_type.has_erasable_regions());
156-
let encoded_item_type = tcx.sess.cstore.encode_type(tcx, item_type, def_id_to_string);
157-
hash_state.input(&encoded_item_type[..]);
166+
hasher.visit_ty(item_type);
158167

159168
// also include any type parameters (for generic items)
160169
if let Some(substs) = substs {
161-
for t in substs.types() {
162-
assert!(!t.has_erasable_regions());
163-
assert!(!t.needs_subst());
164-
let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
165-
hash_state.input(&encoded_type[..]);
166-
}
170+
assert!(!substs.has_erasable_regions());
171+
assert!(!substs.needs_subst());
172+
substs.visit_with(&mut hasher);
167173
}
168-
169-
format!("h{}", truncated_hash_result(&mut *hash_state))
170174
});
171-
172175
fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
173176
let output = symbol_hasher.result_bytes();
174177
// 64 bits should be enough to avoid collisions.
175178
output[.. 8].to_hex()
176179
}
180+
181+
format!("h{}", truncated_hash_result(&mut hash_state))
177182
}
178183

179184
impl<'a, 'tcx> Instance<'tcx> {

0 commit comments

Comments
 (0)