Skip to content

Commit a710e61

Browse files
committed
Add caches for method and impl metadata
The lookups for these items in external crates currently cause repeated decoding of the EBML metadata, which is pretty slow. Adding caches to avoid the repeated decoding reduces the time required for the type checking of librustc by about 25%.
1 parent 7755018 commit a710e61

File tree

4 files changed

+53
-43
lines changed

4 files changed

+53
-43
lines changed

src/librustc/middle/trans/base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,7 @@ pub fn trans_crate(sess: session::Session,
30943094
const_globals: @mut HashMap::new(),
30953095
const_values: @mut HashMap::new(),
30963096
extern_const_values: @mut HashMap::new(),
3097+
impl_method_cache: @mut HashMap::new(),
30973098
module_data: @mut HashMap::new(),
30983099
lltypes: @mut HashMap::new(),
30993100
llsizingtypes: @mut HashMap::new(),

src/librustc/middle/trans/common.rs

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ pub struct CrateContext {
205205
// Cache of external const values
206206
extern_const_values: @mut HashMap<ast::def_id, ValueRef>,
207207

208+
impl_method_cache: @mut HashMap<(ast::def_id, ast::ident), ast::def_id>,
209+
208210
module_data: @mut HashMap<~str, ValueRef>,
209211
lltypes: @mut HashMap<ty::t, TypeRef>,
210212
llsizingtypes: @mut HashMap<ty::t, TypeRef>,

src/librustc/middle/trans/meth.rs

+30-28
Original file line numberDiff line numberDiff line change
@@ -381,35 +381,37 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident)
381381
pub fn method_with_name_or_default(ccx: @CrateContext,
382382
impl_id: ast::def_id,
383383
name: ast::ident) -> ast::def_id {
384-
if impl_id.crate == ast::local_crate {
385-
match ccx.tcx.items.get_copy(&impl_id.node) {
386-
ast_map::node_item(@ast::item {
387-
node: ast::item_impl(_, _, _, ref ms), _
388-
}, _) => {
389-
let did = method_from_methods(*ms, name);
390-
if did.is_some() {
391-
return did.get();
392-
} else {
393-
// Look for a default method
394-
let pmm = ccx.tcx.provided_methods;
395-
match pmm.find(&impl_id) {
396-
Some(pmis) => {
397-
for pmis.each |pmi| {
398-
if pmi.method_info.ident == name {
399-
debug!("pmi.method_info.did = %?", pmi.method_info.did);
400-
return pmi.method_info.did;
401-
}
402-
}
403-
fail!()
404-
}
405-
None => fail!()
406-
}
407-
}
408-
}
409-
_ => fail!("method_with_name")
384+
*do ccx.impl_method_cache.find_or_insert_with((impl_id, name)) |_| {
385+
if impl_id.crate == ast::local_crate {
386+
match ccx.tcx.items.get_copy(&impl_id.node) {
387+
ast_map::node_item(@ast::item {
388+
node: ast::item_impl(_, _, _, ref ms), _
389+
}, _) => {
390+
let did = method_from_methods(*ms, name);
391+
if did.is_some() {
392+
did.get()
393+
} else {
394+
// Look for a default method
395+
let pmm = ccx.tcx.provided_methods;
396+
match pmm.find(&impl_id) {
397+
Some(pmis) => {
398+
for pmis.each |pmi| {
399+
if pmi.method_info.ident == name {
400+
debug!("pmi.method_info.did = %?", pmi.method_info.did);
401+
return pmi.method_info.did;
402+
}
403+
}
404+
fail!()
405+
}
406+
None => fail!()
407+
}
408+
}
409+
}
410+
_ => fail!("method_with_name")
411+
}
412+
} else {
413+
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
410414
}
411-
} else {
412-
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
413415
}
414416
}
415417

src/librustc/middle/ty.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ struct ctxt_ {
271271
// A cache for the trait_methods() routine
272272
trait_methods_cache: @mut HashMap<def_id, @~[@Method]>,
273273

274+
impl_trait_cache: @mut HashMap<ast::def_id, Option<@ty::TraitRef>>,
275+
274276
trait_refs: @mut HashMap<node_id, @TraitRef>,
275277
trait_defs: @mut HashMap<def_id, @TraitDef>,
276278

@@ -967,6 +969,7 @@ pub fn mk_ctxt(s: session::Session,
967969
methods: @mut HashMap::new(),
968970
trait_method_def_ids: @mut HashMap::new(),
969971
trait_methods_cache: @mut HashMap::new(),
972+
impl_trait_cache: @mut HashMap::new(),
970973
ty_param_defs: @mut HashMap::new(),
971974
adjustments: @mut HashMap::new(),
972975
normalized_cache: new_ty_hash(),
@@ -3749,22 +3752,24 @@ pub fn trait_method_def_ids(cx: ctxt, id: ast::def_id) -> @~[def_id] {
37493752
}
37503753

37513754
pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
3752-
if id.crate == ast::local_crate {
3753-
debug!("(impl_trait_ref) searching for trait impl %?", id);
3754-
match cx.items.find(&id.node) {
3755-
Some(&ast_map::node_item(@ast::item {
3756-
node: ast::item_impl(_, opt_trait, _, _),
3757-
_},
3758-
_)) => {
3759-
match opt_trait {
3760-
Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
3761-
None => None
3762-
}
3763-
}
3764-
_ => None
3755+
*do cx.impl_trait_cache.find_or_insert_with(id) |_| {
3756+
if id.crate == ast::local_crate {
3757+
debug!("(impl_trait_ref) searching for trait impl %?", id);
3758+
match cx.items.find(&id.node) {
3759+
Some(&ast_map::node_item(@ast::item {
3760+
node: ast::item_impl(_, opt_trait, _, _),
3761+
_},
3762+
_)) => {
3763+
match opt_trait {
3764+
Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
3765+
None => None
3766+
}
3767+
}
3768+
_ => None
3769+
}
3770+
} else {
3771+
csearch::get_impl_trait(cx, id)
37653772
}
3766-
} else {
3767-
csearch::get_impl_trait(cx, id)
37683773
}
37693774
}
37703775

0 commit comments

Comments
 (0)