From 5dc03a8246e76e9e3900d98f2f5d2574abaeaa6b Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Fri, 22 May 2015 16:15:21 +0300 Subject: [PATCH] Lazy-load filemaps from external crates. --- src/librustc/metadata/creader.rs | 10 +++++----- src/librustc/metadata/cstore.rs | 21 +++++++++++++++++---- src/librustc/middle/astencode.rs | 26 +++++++++++++------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 12112fd45ebe9..8562d8c01cc67 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -21,6 +21,7 @@ use metadata::decoder; use metadata::loader; use metadata::loader::CratePaths; +use std::cell::RefCell; use std::path::PathBuf; use std::rc::Rc; use std::fs; @@ -376,14 +377,13 @@ impl<'a> CrateReader<'a> { let loader::Library { dylib, rlib, metadata } = lib; let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), span); - let codemap_import_info = import_codemap(self.sess.codemap(), &metadata); let cmeta = Rc::new( cstore::crate_metadata { name: name.to_string(), data: metadata, cnum_map: cnum_map, cnum: cnum, - codemap_import_info: codemap_import_info, + codemap_import_info: RefCell::new(vec![]), span: span, }); @@ -616,9 +616,9 @@ impl<'a> CrateReader<'a> { /// file they represent, just information about length, line breaks, and /// multibyte characters. This information is enough to generate valid debuginfo /// for items inlined from other crates. -fn import_codemap(local_codemap: &codemap::CodeMap, - metadata: &MetadataBlob) - -> Vec { +pub fn import_codemap(local_codemap: &codemap::CodeMap, + metadata: &MetadataBlob) + -> Vec { let external_codemap = decoder::get_imported_filemaps(metadata.as_slice()); let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| { diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 1f18b13fc46fe..885e7ffb3050e 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -18,12 +18,11 @@ pub use self::LinkagePreference::*; pub use self::NativeLibraryKind::*; use back::svh::Svh; -use metadata::decoder; -use metadata::loader; +use metadata::{creader, decoder, loader}; use session::search_paths::PathKind; use util::nodemap::{FnvHashMap, NodeMap}; -use std::cell::RefCell; +use std::cell::{RefCell, Ref}; use std::rc::Rc; use std::path::PathBuf; use flate::Bytes; @@ -58,7 +57,7 @@ pub struct crate_metadata { pub data: MetadataBlob, pub cnum_map: cnum_map, pub cnum: ast::CrateNum, - pub codemap_import_info: Vec, + pub codemap_import_info: RefCell>, pub span: codemap::Span, } @@ -240,6 +239,20 @@ impl crate_metadata { pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() } pub fn name(&self) -> String { decoder::get_crate_name(self.data()) } pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) } + pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap) + -> Ref<'a, Vec> { + let filemaps = self.codemap_import_info.borrow(); + if filemaps.is_empty() { + drop(filemaps); + let filemaps = creader::import_codemap(codemap, &self.data); + + // This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref. + *self.codemap_import_info.borrow_mut() = filemaps; + self.codemap_import_info.borrow() + } else { + filemaps + } + } } impl MetadataBlob { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 226010aaa817c..b7e57819b93b4 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -233,8 +233,6 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { /// codemap as a side-effect of creating the crate_metadata's /// `codemap_import_info`. pub fn tr_span(&self, span: Span) -> Span { - let imported_filemaps = &self.cdata.codemap_import_info[..]; - let span = if span.lo > span.hi { // Currently macro expansion sometimes produces invalid Span values // where lo > hi. In order not to crash the compiler when trying to @@ -248,16 +246,18 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { span }; - let filemap_index = { + let imported_filemaps = self.cdata.imported_filemaps(self.tcx.sess.codemap()); + let filemap = { // Optimize for the case that most spans within a translated item // originate from the same filemap. let last_filemap_index = self.last_filemap_index.get(); + let last_filemap = &imported_filemaps[last_filemap_index]; - if span.lo >= imported_filemaps[last_filemap_index].original_start_pos && - span.lo <= imported_filemaps[last_filemap_index].original_end_pos && - span.hi >= imported_filemaps[last_filemap_index].original_start_pos && - span.hi <= imported_filemaps[last_filemap_index].original_end_pos { - last_filemap_index + if span.lo >= last_filemap.original_start_pos && + span.lo <= last_filemap.original_end_pos && + span.hi >= last_filemap.original_start_pos && + span.hi <= last_filemap.original_end_pos { + last_filemap } else { let mut a = 0; let mut b = imported_filemaps.len(); @@ -272,14 +272,14 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { } self.last_filemap_index.set(a); - a + &imported_filemaps[a] } }; - let lo = (span.lo - imported_filemaps[filemap_index].original_start_pos) + - imported_filemaps[filemap_index].translated_filemap.start_pos; - let hi = (span.hi - imported_filemaps[filemap_index].original_start_pos) + - imported_filemaps[filemap_index].translated_filemap.start_pos; + let lo = (span.lo - filemap.original_start_pos) + + filemap.translated_filemap.start_pos; + let hi = (span.hi - filemap.original_start_pos) + + filemap.translated_filemap.start_pos; codemap::mk_sp(lo, hi) }