Lazy-load filemaps from external crates.
This commit is contained in:
parent
c3d60aba6c
commit
5dc03a8246
@ -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| {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user