From d9bb78efdf2fbb0de9ca43a8b14e5c91c78164e9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 20 Aug 2013 14:55:54 -0700 Subject: [PATCH] librustc: Stop calling `each_path` in coherence. 10% win or so for small crates. --- src/librustc/metadata/common.rs | 3 ++ src/librustc/metadata/csearch.rs | 8 ++++ src/librustc/metadata/decoder.rs | 10 +++++ src/librustc/metadata/encoder.rs | 49 ++++++++++++++++++++++++- src/librustc/middle/typeck/coherence.rs | 19 +++------- src/libstd/rt/borrowck.rs | 4 +- src/libstd/rt/sched.rs | 2 +- 7 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index f2d8b68faa6..42959d9447e 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -182,6 +182,9 @@ pub static tag_misc_info_crate_items: uint = 0x80; pub static tag_item_method_provided_source: uint = 0x81; pub static tag_item_impl_vtables: uint = 0x82; +pub static tag_impls: uint = 0x83; +pub static tag_impls_impl: uint = 0x84; + pub struct LinkMeta { name: @str, vers: @str, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 317b9cf6ce3..4e902f2d2ec 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -246,3 +246,11 @@ pub fn get_link_args_for_crate(cstore: @mut cstore::CStore, let cdata = cstore::get_crate_data(cstore, crate_num); decoder::get_link_args_for_crate(cdata) } + +pub fn each_impl(cstore: @mut cstore::CStore, + crate_num: ast::CrateNum, + callback: &fn(ast::def_id)) { + let cdata = cstore::get_crate_data(cstore, crate_num); + decoder::each_impl(cdata, callback) +} + diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 96249cc88ab..89e09a7ae1d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1316,3 +1316,13 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] { }; result } + +pub fn each_impl(cdata: cmd, callback: &fn(ast::def_id)) { + let impls_doc = reader::get_doc(reader::Doc(cdata.data), tag_impls); + let _ = do reader::tagged_docs(impls_doc, tag_impls_impl) |impl_doc| { + callback(item_def_id(impl_doc, cdata)); + true + }; +} + + diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 1b19384af33..1b05b0b781d 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -39,6 +39,7 @@ use syntax::attr::AttrMetaMethods; use syntax::diagnostic::span_handler; use syntax::parse::token::special_idents; use syntax::ast_util; +use syntax::visit::Visitor; use syntax::visit; use syntax::parse::token; use syntax; @@ -72,6 +73,7 @@ struct Stats { dep_bytes: uint, lang_item_bytes: uint, link_args_bytes: uint, + impl_bytes: uint, misc_bytes: uint, item_bytes: uint, index_bytes: uint, @@ -1221,7 +1223,10 @@ struct EncodeVisitor { } impl visit::Visitor<()> for EncodeVisitor { - fn visit_expr(&mut self, ex:@expr, _:()) { my_visit_expr(ex); } + fn visit_expr(&mut self, ex:@expr, _:()) { + visit::walk_expr(self, ex, ()); + my_visit_expr(ex); + } fn visit_item(&mut self, i:@item, _:()) { visit::walk_item(self, i, ()); my_visit_item(i, @@ -1510,6 +1515,41 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.end_tag(); } +struct ImplVisitor<'self> { + ecx: &'self EncodeContext<'self>, + ebml_w: &'self mut writer::Encoder, +} + +impl<'self> Visitor<()> for ImplVisitor<'self> { + fn visit_item(&mut self, item: @item, _: ()) { + match item.node { + item_impl(*) => { + self.ebml_w.start_tag(tag_impls_impl); + encode_def_id(self.ebml_w, local_def(item.id)); + self.ebml_w.end_tag(); + } + _ => {} + } + visit::walk_item(self, item, ()); + } +} + +fn encode_impls(ecx: &EncodeContext, + crate: &Crate, + ebml_w: &mut writer::Encoder) { + ebml_w.start_tag(tag_impls); + + { + let mut visitor = ImplVisitor { + ecx: ecx, + ebml_w: ebml_w, + }; + visit::walk_crate(&mut visitor, crate, ()); + } + + ebml_w.end_tag(); +} + fn encode_misc_info(ecx: &EncodeContext, crate: &Crate, ebml_w: &mut writer::Encoder) { @@ -1574,6 +1614,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] { dep_bytes: 0, lang_item_bytes: 0, link_args_bytes: 0, + impl_bytes: 0, misc_bytes: 0, item_bytes: 0, index_bytes: 0, @@ -1632,6 +1673,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] { encode_link_args(&ecx, &mut ebml_w); ecx.stats.link_args_bytes = *wr.pos - i; + // Encode the def IDs of impls, for coherence checking. + i = *wr.pos; + encode_impls(&ecx, crate, &mut ebml_w); + ecx.stats.impl_bytes = *wr.pos - i; + // Encode miscellaneous info. i = *wr.pos; encode_misc_info(&ecx, crate, &mut ebml_w); @@ -1664,6 +1710,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] { printfln!(" dep bytes: %u", ecx.stats.dep_bytes); printfln!(" lang item bytes: %u", ecx.stats.lang_item_bytes); printfln!(" link args bytes: %u", ecx.stats.link_args_bytes); + printfln!(" impl bytes: %u", ecx.stats.impl_bytes); printfln!(" misc bytes: %u", ecx.stats.misc_bytes); printfln!(" item bytes: %u", ecx.stats.item_bytes); printfln!(" index bytes: %u", ecx.stats.index_bytes); diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index b659f6081b1..d4212bc5aad 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -15,10 +15,9 @@ // each trait in the system to its implementations. -use metadata::csearch::{each_path, get_impl_trait}; +use metadata::csearch::{each_impl, get_impl_trait}; use metadata::csearch; use metadata::cstore::iter_crate_data; -use metadata::decoder::{dl_def, dl_field, dl_impl}; use middle::ty::get; use middle::ty::{lookup_item_type, subst}; use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err}; @@ -680,9 +679,6 @@ impl CoherenceChecker { let tcx = self.crate_context.tcx; let implementation = @csearch::get_impl(tcx, impl_def_id); - debug!("coherence: adding impl from external crate: %s", - ty::item_path_str(tcx, implementation.did)); - // Make sure we don't visit the same implementation multiple times. if !impls_seen.insert(implementation.did) { // Skip this one. @@ -752,15 +748,10 @@ impl CoherenceChecker { let crate_store = self.crate_context.tcx.sess.cstore; do iter_crate_data(crate_store) |crate_number, _crate_metadata| { - do each_path(crate_store, crate_number) |_, def_like, _| { - match def_like { - dl_impl(def_id) => { - self.add_external_impl(&mut impls_seen, def_id) - } - dl_def(_) | dl_field => (), // Skip this. - } - true - }; + do each_impl(crate_store, crate_number) |def_id| { + assert_eq!(crate_number, def_id.crate); + self.add_external_impl(&mut impls_seen, def_id) + } } } diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs index e03a61226ad..9dc0abdfbd8 100644 --- a/src/libstd/rt/borrowck.rs +++ b/src/libstd/rt/borrowck.rs @@ -38,7 +38,7 @@ pub struct BorrowRecord { } fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> { - do Local::borrow::> |task| { + do Local::borrow |task: &mut Task| { task.borrow_list.take() } } @@ -50,7 +50,7 @@ fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) { }; let borrows = f(borrows); let borrows = Cell::new(borrows); - do Local::borrow:: |task| { + do Local::borrow |task: &mut Task| { task.borrow_list = Some(borrows.take()); } } diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index b1319321c19..5af0071f2ab 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -555,7 +555,7 @@ impl Scheduler { let current_task: &mut Task = match sched.cleanup_job { Some(CleanupJob { task: ref task, _ }) => { let task_ptr: *~Task = task; - transmute_mut_region(*transmute_mut_unsafe(task)) + transmute_mut_region(*transmute_mut_unsafe(task_ptr)) } None => { rtabort!("no cleanup job");