Lazy-load filemaps from external crates.

This commit is contained in:
Eduard Burtescu 2015-05-22 16:15:21 +03:00
parent c3d60aba6c
commit 5dc03a8246
3 changed files with 35 additions and 22 deletions

View File

@ -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<cstore::ImportedFileMap> {
pub fn import_codemap(local_codemap: &codemap::CodeMap,
metadata: &MetadataBlob)
-> Vec<cstore::ImportedFileMap> {
let external_codemap = decoder::get_imported_filemaps(metadata.as_slice());
let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| {

View File

@ -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<ImportedFileMap>,
pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
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<ImportedFileMap>> {
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 {

View File

@ -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)
}