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%.
This commit is contained in:
parent
7755018074
commit
a710e61903
@ -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(),
|
||||
|
@ -205,6 +205,8 @@ pub struct CrateContext {
|
||||
// Cache of external const values
|
||||
extern_const_values: @mut HashMap<ast::def_id, ValueRef>,
|
||||
|
||||
impl_method_cache: @mut HashMap<(ast::def_id, ast::ident), ast::def_id>,
|
||||
|
||||
module_data: @mut HashMap<~str, ValueRef>,
|
||||
lltypes: @mut HashMap<ty::t, TypeRef>,
|
||||
llsizingtypes: @mut HashMap<ty::t, TypeRef>,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +271,8 @@ struct ctxt_ {
|
||||
// A cache for the trait_methods() routine
|
||||
trait_methods_cache: @mut HashMap<def_id, @~[@Method]>,
|
||||
|
||||
impl_trait_cache: @mut HashMap<ast::def_id, Option<@ty::TraitRef>>,
|
||||
|
||||
trait_refs: @mut HashMap<node_id, @TraitRef>,
|
||||
trait_defs: @mut HashMap<def_id, @TraitDef>,
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user