Skip to content

Commit b9816c5

Browse files
incr.comp.: Already hash HIR bodies during metadata export so they don't have to be hashed in downstream crates.
1 parent e3f9131 commit b9816c5

File tree

11 files changed

+163
-55
lines changed

11 files changed

+163
-55
lines changed

src/librustc/ich/hcx.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,40 @@ impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx>
202202
}
203203
}
204204

205+
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
206+
#[inline]
207+
fn hash_stable<W: StableHasherResult>(&self,
208+
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
209+
hasher: &mut StableHasher<W>) {
210+
match hcx.node_id_hashing_mode {
211+
NodeIdHashingMode::Ignore => {
212+
// Don't do anything.
213+
}
214+
NodeIdHashingMode::HashDefPath => {
215+
let hir::HirId {
216+
owner,
217+
local_id,
218+
} = *self;
219+
220+
hcx.tcx.hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher);
221+
local_id.hash_stable(hcx, hasher);
222+
}
223+
}
224+
}
225+
}
226+
227+
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
228+
type KeyType = (DefPathHash, hir::ItemLocalId);
229+
230+
#[inline]
231+
fn to_stable_hash_key(&self,
232+
hcx: &StableHashingContext<'a, 'gcx, 'tcx>)
233+
-> (DefPathHash, hir::ItemLocalId) {
234+
let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner);
235+
(def_path_hash, self.local_id)
236+
}
237+
}
238+
205239
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId {
206240
fn hash_stable<W: StableHasherResult>(&self,
207241
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,

src/librustc/ich/impls_cstore.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//! This module contains `HashStable` implementations for various data types
1212
//! from rustc::middle::cstore in no particular order.
1313
14+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
15+
1416
use middle;
1517

1618
impl_stable_hash_for!(enum middle::cstore::DepKind {
@@ -51,3 +53,29 @@ impl_stable_hash_for!(struct middle::cstore::CrateSource {
5153
rlib,
5254
rmeta
5355
});
56+
57+
impl<HCX> HashStable<HCX> for middle::cstore::ExternBodyNestedBodies {
58+
fn hash_stable<W: StableHasherResult>(&self,
59+
hcx: &mut HCX,
60+
hasher: &mut StableHasher<W>) {
61+
let middle::cstore::ExternBodyNestedBodies {
62+
nested_bodies: _,
63+
fingerprint,
64+
} = *self;
65+
66+
fingerprint.hash_stable(hcx, hasher);
67+
}
68+
}
69+
70+
impl<'a, HCX> HashStable<HCX> for middle::cstore::ExternConstBody<'a> {
71+
fn hash_stable<W: StableHasherResult>(&self,
72+
hcx: &mut HCX,
73+
hasher: &mut StableHasher<W>) {
74+
let middle::cstore::ExternConstBody {
75+
body: _,
76+
fingerprint,
77+
} = *self;
78+
79+
fingerprint.hash_stable(hcx, hasher);
80+
}
81+
}

src/librustc/ich/impls_hir.rs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,6 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for D
3838
}
3939
}
4040

41-
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
42-
#[inline]
43-
fn hash_stable<W: StableHasherResult>(&self,
44-
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
45-
hasher: &mut StableHasher<W>) {
46-
let hir::HirId {
47-
owner,
48-
local_id,
49-
} = *self;
50-
51-
hcx.tcx().hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher);
52-
local_id.hash_stable(hcx, hasher);
53-
}
54-
}
55-
56-
impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId {
57-
type KeyType = (DefPathHash, hir::ItemLocalId);
58-
59-
#[inline]
60-
fn to_stable_hash_key(&self,
61-
hcx: &StableHashingContext<'a, 'gcx, 'tcx>)
62-
-> (DefPathHash, hir::ItemLocalId) {
63-
let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner);
64-
(def_path_hash, self.local_id)
65-
}
66-
}
67-
6841
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum {
6942
#[inline]
7043
fn hash_stable<W: StableHasherResult>(&self,
@@ -415,6 +388,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P
415388
ref span
416389
} = *self;
417390

391+
418392
node.hash_stable(hcx, hasher);
419393
span.hash_stable(hcx, hasher);
420394
}
@@ -1003,11 +977,23 @@ impl_stable_hash_for!(struct hir::Arg {
1003977
hir_id
1004978
});
1005979

1006-
impl_stable_hash_for!(struct hir::Body {
1007-
arguments,
1008-
value,
1009-
is_generator
1010-
});
980+
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Body {
981+
fn hash_stable<W: StableHasherResult>(&self,
982+
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
983+
hasher: &mut StableHasher<W>) {
984+
let hir::Body {
985+
ref arguments,
986+
ref value,
987+
is_generator,
988+
} = *self;
989+
990+
hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
991+
arguments.hash_stable(hcx, hasher);
992+
value.hash_stable(hcx, hasher);
993+
is_generator.hash_stable(hcx, hasher);
994+
});
995+
}
996+
}
1011997

1012998
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
1013999
fn hash_stable<W: StableHasherResult>(&self,

src/librustc/middle/cstore.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//! are *mostly* used as a part of that interface, but these should
2323
//! probably get a better home if someone can find one.
2424
25+
use hir;
2526
use hir::def;
2627
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
2728
use hir::map as hir_map;
@@ -34,6 +35,7 @@ use session::search_paths::PathKind;
3435
use util::nodemap::NodeSet;
3536

3637
use std::any::Any;
38+
use std::collections::BTreeMap;
3739
use std::path::{Path, PathBuf};
3840
use std::rc::Rc;
3941
use owning_ref::ErasedBoxRef;
@@ -218,6 +220,26 @@ pub trait MetadataLoader {
218220
-> Result<ErasedBoxRef<[u8]>, String>;
219221
}
220222

223+
#[derive(Clone)]
224+
pub struct ExternConstBody<'tcx> {
225+
pub body: &'tcx hir::Body,
226+
227+
// It would require a lot of infrastructure to enable stable-hashing Bodies
228+
// from other crates, so we hash on export and just store the fingerprint
229+
// with them.
230+
pub fingerprint: ich::Fingerprint,
231+
}
232+
233+
#[derive(Clone)]
234+
pub struct ExternBodyNestedBodies {
235+
pub nested_bodies: Rc<BTreeMap<hir::BodyId, hir::Body>>,
236+
237+
// It would require a lot of infrastructure to enable stable-hashing Bodies
238+
// from other crates, so we hash on export and just store the fingerprint
239+
// with them.
240+
pub fingerprint: ich::Fingerprint,
241+
}
242+
221243
/// A store of Rust crates, through with their metadata
222244
/// can be accessed.
223245
///

src/librustc/ty/maps.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ use hir::{self, TraitCandidate, ItemLocalId};
1616
use hir::svh::Svh;
1717
use lint;
1818
use middle::const_val;
19-
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary};
20-
use middle::cstore::{NativeLibraryKind, DepKind, CrateSource};
19+
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary,
20+
ExternBodyNestedBodies};
21+
use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody};
2122
use middle::privacy::AccessLevels;
2223
use middle::reachable::ReachableSet;
2324
use middle::region;
@@ -50,7 +51,6 @@ use std::fmt::Debug;
5051
use std::hash::Hash;
5152
use std::marker::PhantomData;
5253
use std::mem;
53-
use std::collections::BTreeMap;
5454
use std::ops::Deref;
5555
use std::rc::Rc;
5656
use std::sync::Arc;
@@ -1321,8 +1321,7 @@ define_maps! { <'tcx>
13211321
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
13221322
[] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
13231323
[] fn is_exported_symbol: IsExportedSymbol(DefId) -> bool,
1324-
[] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId)
1325-
-> Rc<BTreeMap<hir::BodyId, hir::Body>>,
1324+
[] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> ExternBodyNestedBodies,
13261325
[] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
13271326
[] fn is_mir_available: IsMirAvailable(DefId) -> bool,
13281327

@@ -1402,7 +1401,7 @@ define_maps! { <'tcx>
14021401
[] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
14031402
[] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefId, usize)>>,
14041403
[] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
1405-
[] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body,
1404+
[] fn extern_const_body: ExternConstBody(DefId) -> ExternConstBody<'tcx>,
14061405
[] fn visible_parent_map: visible_parent_map_node(CrateNum)
14071406
-> Rc<DefIdMap<DefId>>,
14081407
[] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,

src/librustc_const_eval/eval.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use syntax_pos::Span;
3434
use std::cmp::Ordering;
3535

3636
use rustc_const_math::*;
37-
3837
macro_rules! signal {
3938
($e:expr, $exn:expr) => {
4039
return Err(ConstEvalErr { span: $e.span, kind: $exn })
@@ -366,7 +365,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
366365
}
367366
} else {
368367
if tcx.is_const_fn(def_id) {
369-
tcx.extern_const_body(def_id)
368+
tcx.extern_const_body(def_id).body
370369
} else {
371370
signal!(e, TypeckError)
372371
}
@@ -790,7 +789,7 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
790789
tcx.mir_const_qualif(def_id);
791790
tcx.hir.body(tcx.hir.body_owned_by(id))
792791
} else {
793-
tcx.extern_const_body(def_id)
792+
tcx.extern_const_body(def_id).body
794793
};
795794
ConstContext::new(tcx, key.param_env.and(substs), tables).eval(&body.value)
796795
}

src/librustc_const_eval/pattern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
607607
let body = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
608608
self.tcx.hir.body(self.tcx.hir.body_owned_by(id))
609609
} else {
610-
self.tcx.extern_const_body(def_id)
610+
self.tcx.extern_const_body(def_id).body
611611
};
612612
let pat = self.lower_const_expr(&body.value, pat_id, span);
613613
self.tables = old_tables;

src/librustc_metadata/astencode.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,46 @@ use schema::*;
1616
use rustc::hir;
1717
use rustc::ty::{self, TyCtxt};
1818

19+
use rustc::ich::{StableHashingContext, Fingerprint};
20+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
21+
1922
#[derive(RustcEncodable, RustcDecodable)]
2023
pub struct Ast<'tcx> {
2124
pub body: Lazy<hir::Body>,
2225
pub tables: Lazy<ty::TypeckTables<'tcx>>,
2326
pub nested_bodies: LazySeq<hir::Body>,
2427
pub rvalue_promotable_to_static: bool,
28+
pub stable_bodies_hash: Fingerprint,
2529
}
2630

2731
impl_stable_hash_for!(struct Ast<'tcx> {
2832
body,
2933
tables,
3034
nested_bodies,
31-
rvalue_promotable_to_static
35+
rvalue_promotable_to_static,
36+
stable_bodies_hash
3237
});
3338

3439
impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> {
3540
pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy<Ast<'tcx>> {
3641
let body = self.tcx.hir.body(body_id);
37-
let lazy_body = self.lazy(body);
3842

43+
// In order to avoid having to hash hir::Bodies from extern crates, we
44+
// hash them here, during export, and store the hash with metadata.
45+
let stable_bodies_hash = {
46+
let mut hcx = StableHashingContext::new(self.tcx);
47+
let mut hasher = StableHasher::new();
48+
49+
hcx.while_hashing_hir_bodies(true, |hcx| {
50+
hcx.while_hashing_spans(false, |hcx| {
51+
body.hash_stable(hcx, &mut hasher);
52+
});
53+
});
54+
55+
hasher.finish()
56+
};
57+
58+
let lazy_body = self.lazy(body);
3959
let tables = self.tcx.body_tables(body_id);
4060
let lazy_tables = self.lazy(tables);
4161

@@ -54,6 +74,7 @@ impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> {
5474
tables: lazy_tables,
5575
nested_bodies: lazy_nested_bodies,
5676
rvalue_promotable_to_static,
77+
stable_bodies_hash,
5778
})
5879
}
5980
}

src/librustc_metadata/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
159159
is_exported_symbol => {
160160
cdata.exported_symbols.contains(&def_id.index)
161161
}
162-
item_body_nested_bodies => { Rc::new(cdata.item_body_nested_bodies(def_id.index)) }
162+
item_body_nested_bodies => { cdata.item_body_nested_bodies(def_id.index) }
163163
const_is_rvalue_promotable_to_static => {
164164
cdata.const_is_rvalue_promotable_to_static(def_id.index)
165165
}

src/librustc_metadata/decoder.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
1717
use rustc::hir;
1818

1919
use rustc::middle::const_val::ByteArray;
20-
use rustc::middle::cstore::LinkagePreference;
20+
use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
21+
ExternBodyNestedBodies};
2122
use rustc::hir::def::{self, Def, CtorKind};
2223
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
24+
use rustc::ich::Fingerprint;
2325
use rustc::middle::lang_items;
2426
use rustc::session::Session;
2527
use rustc::ty::{self, Ty, TyCtxt};
@@ -775,12 +777,16 @@ impl<'a, 'tcx> CrateMetadata {
775777
pub fn extern_const_body(&self,
776778
tcx: TyCtxt<'a, 'tcx, 'tcx>,
777779
id: DefIndex)
778-
-> &'tcx hir::Body {
780+
-> ExternConstBody<'tcx> {
779781
assert!(!self.is_proc_macro(id));
780782
let ast = self.entry(id).ast.unwrap();
781783
let def_id = self.local_def_id(id);
782-
let body = ast.decode((self, tcx)).body.decode((self, tcx));
783-
tcx.hir.intern_inlined_body(def_id, body)
784+
let ast = ast.decode((self, tcx));
785+
let body = ast.body.decode((self, tcx));
786+
ExternConstBody {
787+
body: tcx.hir.intern_inlined_body(def_id, body),
788+
fingerprint: ast.stable_bodies_hash,
789+
}
784790
}
785791

786792
pub fn item_body_tables(&self,
@@ -791,10 +797,23 @@ impl<'a, 'tcx> CrateMetadata {
791797
tcx.alloc_tables(ast.tables.decode((self, tcx)))
792798
}
793799

794-
pub fn item_body_nested_bodies(&self, id: DefIndex) -> BTreeMap<hir::BodyId, hir::Body> {
795-
self.entry(id).ast.into_iter().flat_map(|ast| {
796-
ast.decode(self).nested_bodies.decode(self).map(|body| (body.id(), body))
797-
}).collect()
800+
pub fn item_body_nested_bodies(&self, id: DefIndex) -> ExternBodyNestedBodies {
801+
if let Some(ref ast) = self.entry(id).ast {
802+
let ast = ast.decode(self);
803+
let nested_bodies: BTreeMap<_, _> = ast.nested_bodies
804+
.decode(self)
805+
.map(|body| (body.id(), body))
806+
.collect();
807+
ExternBodyNestedBodies {
808+
nested_bodies: Rc::new(nested_bodies),
809+
fingerprint: ast.stable_bodies_hash,
810+
}
811+
} else {
812+
ExternBodyNestedBodies {
813+
nested_bodies: Rc::new(BTreeMap::new()),
814+
fingerprint: Fingerprint::zero(),
815+
}
816+
}
798817
}
799818

800819
pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool {

0 commit comments

Comments
 (0)