提交 a710e619 编写于 作者: B Björn Steinbrink

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%.
上级 77550180
......@@ -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)
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册