about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-14 20:28:09 -0700
committerbors <bors@rust-lang.org>2013-06-14 20:28:09 -0700
commit1104e659d539faf40773cd6dc01015c00df498cd (patch)
tree07b437b036b3bf1b0ddbdc5ffbdb1a90a2345096 /src
parent104e6120b1161e6d242644c987b65525daa5ad5a (diff)
parenta710e619038c9ff96c332eedb72a8c77a3a370be (diff)
downloadrust-1104e659d539faf40773cd6dc01015c00df498cd.tar.gz
rust-1104e659d539faf40773cd6dc01015c00df498cd.zip
auto merge of #7144 : dotdash/rust/caches, r=graydon
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%.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/base.rs1
-rw-r--r--src/librustc/middle/trans/common.rs2
-rw-r--r--src/librustc/middle/trans/meth.rs58
-rw-r--r--src/librustc/middle/ty.rs35
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<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>,
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<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)
     }
 }