Skip to content

Commit 6b46113

Browse files
committed
Cache external crate lookups in resolve.rs
According to --time-passes, resolution went from 2 to 0 seconds. Not really the bottleneck... but if we want to be crazy fast, just consider this a future bottleneck that was fixed very timely.
1 parent e9c12ab commit 6b46113

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

src/comp/middle/resolve.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,23 @@ tag import_state {
4343
resolving(span);
4444
resolved(Option.t[def] /* value */, Option.t[def] /* type */);
4545
}
46-
47-
type env = rec(std.Map.hashmap[def_id,import_state] imports,
48-
std.Map.hashmap[def_id,@wrap_mod] mod_map,
49-
std.Map.hashmap[def_id,vec[ident]] ext_map,
46+
47+
type ext_hash = hashmap[tup(def_id,str),def];
48+
fn new_ext_hash() -> ext_hash {
49+
fn hash(&tup(def_id,str) v) -> uint {
50+
ret Str.hash(v._1) + util.common.hash_def(v._0);
51+
}
52+
fn eq(&tup(def_id,str) v1, &tup(def_id,str) v2) -> bool {
53+
ret util.common.def_eq(v1._0, v2._0) &&
54+
Str.eq(v1._1, v2._1);
55+
}
56+
ret std.Map.mk_hashmap[tup(def_id,str),def](hash, eq);
57+
}
58+
59+
type env = rec(hashmap[def_id,import_state] imports,
60+
hashmap[def_id,@wrap_mod] mod_map,
61+
hashmap[def_id,vec[ident]] ext_map,
62+
ext_hash ext_cache,
5063
session sess);
5164

5265
// Used to distinguish between lookups from outside and from inside modules,
@@ -62,6 +75,7 @@ fn resolve_crate(session sess, @ast.crate crate) -> @ast.crate {
6275
auto e = @rec(imports = new_def_hash[import_state](),
6376
mod_map = new_def_hash[@wrap_mod](),
6477
ext_map = new_def_hash[vec[ident]](),
78+
ext_cache = new_ext_hash(),
6579
sess = sess);
6680
map_crate(e, *crate);
6781
resolve_imports(*e);
@@ -579,13 +593,21 @@ fn lookup_in_mod(&env e, def m, ident id, namespace ns, dir dr)
579593
auto defid = ast.def_id_of_def(m);
580594
// FIXME this causes way more metadata lookups than needed. Cache?
581595
if (defid._0 != 0) { // Not in this crate (FIXME use a const, not 0)
596+
auto cached = e.ext_cache.find(tup(defid,id));
597+
if (cached != none[def] && check_def_by_ns(Option.get(cached), ns)) {
598+
ret cached;
599+
}
582600
auto path = vec(id);
583601
// def_num=-1 is a kludge to overload def_mod for external crates,
584602
// since those don't get a def num
585603
if (defid._1 != -1) {
586604
path = e.ext_map.get(defid) + path;
587605
}
588-
ret lookup_external(e, defid._0, path, ns);
606+
auto fnd = lookup_external(e, defid._0, path, ns);
607+
if (fnd != none[def]) {
608+
e.ext_cache.insert(tup(defid,id), Option.get(fnd));
609+
}
610+
ret fnd;
589611
}
590612
alt (m) {
591613
case (ast.def_mod(?defid)) {
@@ -704,7 +726,7 @@ fn lookup_external(&env e, int cnum, vec[ident] ids, namespace ns)
704726
e.ext_map.insert(ast.def_id_of_def(d), ids);
705727
}
706728
ret found;
707-
}
729+
}
708730

709731
// Local Variables:
710732
// mode: rust

0 commit comments

Comments
 (0)