diff options
| author | Marijn Haverbeke <[email protected]> | 2011-05-11 12:21:09 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <[email protected]> | 2011-05-11 12:32:37 +0200 |
| commit | 6b46113afc92b39594922589e768b98c854eda8d (patch) | |
| tree | b08ba0feb761c4f7f9abdd3e57b41794d93291ac /src/comp | |
| parent | Rewrite comp/middle/resolve.rs (diff) | |
| download | rust-6b46113afc92b39594922589e768b98c854eda8d.tar.xz rust-6b46113afc92b39594922589e768b98c854eda8d.zip | |
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.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/resolve.rs | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 92248ed9..1e56f514 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -43,10 +43,23 @@ tag import_state { resolving(span); resolved(Option.t[def] /* value */, Option.t[def] /* type */); } - -type env = rec(std.Map.hashmap[def_id,import_state] imports, - std.Map.hashmap[def_id,@wrap_mod] mod_map, - std.Map.hashmap[def_id,vec[ident]] ext_map, + +type ext_hash = hashmap[tup(def_id,str),def]; +fn new_ext_hash() -> ext_hash { + fn hash(&tup(def_id,str) v) -> uint { + ret Str.hash(v._1) + util.common.hash_def(v._0); + } + fn eq(&tup(def_id,str) v1, &tup(def_id,str) v2) -> bool { + ret util.common.def_eq(v1._0, v2._0) && + Str.eq(v1._1, v2._1); + } + ret std.Map.mk_hashmap[tup(def_id,str),def](hash, eq); +} + +type env = rec(hashmap[def_id,import_state] imports, + hashmap[def_id,@wrap_mod] mod_map, + hashmap[def_id,vec[ident]] ext_map, + ext_hash ext_cache, session sess); // 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 { auto e = @rec(imports = new_def_hash[import_state](), mod_map = new_def_hash[@wrap_mod](), ext_map = new_def_hash[vec[ident]](), + ext_cache = new_ext_hash(), sess = sess); map_crate(e, *crate); resolve_imports(*e); @@ -579,13 +593,21 @@ fn lookup_in_mod(&env e, def m, ident id, namespace ns, dir dr) auto defid = ast.def_id_of_def(m); // FIXME this causes way more metadata lookups than needed. Cache? if (defid._0 != 0) { // Not in this crate (FIXME use a const, not 0) + auto cached = e.ext_cache.find(tup(defid,id)); + if (cached != none[def] && check_def_by_ns(Option.get(cached), ns)) { + ret cached; + } auto path = vec(id); // def_num=-1 is a kludge to overload def_mod for external crates, // since those don't get a def num if (defid._1 != -1) { path = e.ext_map.get(defid) + path; } - ret lookup_external(e, defid._0, path, ns); + auto fnd = lookup_external(e, defid._0, path, ns); + if (fnd != none[def]) { + e.ext_cache.insert(tup(defid,id), Option.get(fnd)); + } + ret fnd; } alt (m) { case (ast.def_mod(?defid)) { @@ -704,7 +726,7 @@ fn lookup_external(&env e, int cnum, vec[ident] ids, namespace ns) e.ext_map.insert(ast.def_id_of_def(d), ids); } ret found; - } +} // Local Variables: // mode: rust |