From a710e619038c9ff96c332eedb72a8c77a3a370be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 15 Jun 2013 04:28:19 +0200 Subject: [PATCH] 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%. --- src/librustc/middle/trans/base.rs | 1 + src/librustc/middle/trans/common.rs | 2 + src/librustc/middle/trans/meth.rs | 58 +++++++++++++++-------------- src/librustc/middle/ty.rs | 35 +++++++++-------- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 60725fa6b73..001f85f46f4 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3094,6 +3094,7 @@ pub fn trans_crate(sess: session::Session, const_globals: @mut HashMap::new(), const_values: @mut HashMap::new(), extern_const_values: @mut HashMap::new(), + impl_method_cache: @mut HashMap::new(), module_data: @mut HashMap::new(), lltypes: @mut HashMap::new(), llsizingtypes: @mut HashMap::new(), diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index a12ce790d04..2c80ef7980d 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -205,6 +205,8 @@ pub struct CrateContext { // Cache of external const values extern_const_values: @mut HashMap, + impl_method_cache: @mut HashMap<(ast::def_id, ast::ident), ast::def_id>, + module_data: @mut HashMap<~str, ValueRef>, lltypes: @mut HashMap, llsizingtypes: @mut HashMap, diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index d118c900b81..93587d81dd6 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -381,35 +381,37 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident) pub fn method_with_name_or_default(ccx: @CrateContext, impl_id: ast::def_id, name: ast::ident) -> ast::def_id { - if impl_id.crate == ast::local_crate { - match ccx.tcx.items.get_copy(&impl_id.node) { - ast_map::node_item(@ast::item { - node: ast::item_impl(_, _, _, ref ms), _ - }, _) => { - let did = method_from_methods(*ms, name); - if did.is_some() { - return did.get(); - } else { - // Look for a default method - let pmm = ccx.tcx.provided_methods; - match pmm.find(&impl_id) { - Some(pmis) => { - for pmis.each |pmi| { - if pmi.method_info.ident == name { - debug!("pmi.method_info.did = %?", pmi.method_info.did); - return pmi.method_info.did; - } - } - fail!() - } - None => fail!() - } - } - } - _ => fail!("method_with_name") + *do ccx.impl_method_cache.find_or_insert_with((impl_id, name)) |_| { + if impl_id.crate == ast::local_crate { + match ccx.tcx.items.get_copy(&impl_id.node) { + ast_map::node_item(@ast::item { + node: ast::item_impl(_, _, _, ref ms), _ + }, _) => { + let did = method_from_methods(*ms, name); + if did.is_some() { + did.get() + } else { + // Look for a default method + let pmm = ccx.tcx.provided_methods; + match pmm.find(&impl_id) { + Some(pmis) => { + for pmis.each |pmi| { + if pmi.method_info.ident == name { + debug!("pmi.method_info.did = %?", pmi.method_info.did); + return pmi.method_info.did; + } + } + fail!() + } + None => fail!() + } + } + } + _ => fail!("method_with_name") + } + } else { + csearch::get_impl_method(ccx.sess.cstore, impl_id, name) } - } else { - csearch::get_impl_method(ccx.sess.cstore, impl_id, name) } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index fe533f6ad80..271bc6bfd6c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -271,6 +271,8 @@ struct ctxt_ { // A cache for the trait_methods() routine trait_methods_cache: @mut HashMap, + impl_trait_cache: @mut HashMap>, + trait_refs: @mut HashMap, trait_defs: @mut HashMap, @@ -967,6 +969,7 @@ pub fn mk_ctxt(s: session::Session, methods: @mut HashMap::new(), trait_method_def_ids: @mut HashMap::new(), trait_methods_cache: @mut HashMap::new(), + impl_trait_cache: @mut HashMap::new(), ty_param_defs: @mut HashMap::new(), adjustments: @mut HashMap::new(), normalized_cache: new_ty_hash(), @@ -3749,22 +3752,24 @@ pub fn trait_method_def_ids(cx: ctxt, id: ast::def_id) -> @~[def_id] { } pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> { - if id.crate == ast::local_crate { - debug!("(impl_trait_ref) searching for trait impl %?", id); - match cx.items.find(&id.node) { - Some(&ast_map::node_item(@ast::item { - node: ast::item_impl(_, opt_trait, _, _), - _}, - _)) => { - match opt_trait { - Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), - None => None - } - } - _ => None + *do cx.impl_trait_cache.find_or_insert_with(id) |_| { + if id.crate == ast::local_crate { + debug!("(impl_trait_ref) searching for trait impl %?", id); + match cx.items.find(&id.node) { + Some(&ast_map::node_item(@ast::item { + node: ast::item_impl(_, opt_trait, _, _), + _}, + _)) => { + match opt_trait { + Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), + None => None + } + } + _ => None + } + } else { + csearch::get_impl_trait(cx, id) } - } else { - csearch::get_impl_trait(cx, id) } } -- GitLab