about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <github6541940@oli-obk.de>2015-05-23 19:03:19 +0200
committerOliver Schneider <github6541940@oli-obk.de>2015-05-23 19:03:19 +0200
commit9aa88c99f73b872d7737e0027216b742e6dc705b (patch)
treef2ca130d9333d7c715a1f97df35c3c5bae35faa6
parentd21f41ce6b28cb7a96cbbaa6b5f7373853a1ef78 (diff)
parent5dc03a8246e76e9e3900d98f2f5d2574abaeaa6b (diff)
downloadrust-9aa88c99f73b872d7737e0027216b742e6dc705b.tar.gz
rust-9aa88c99f73b872d7737e0027216b742e6dc705b.zip
Rollup merge of #25703 - eddyb:lazier-loads, r=pnkfelix
Reduces pre-trans heap baseline (tested on `fn main() {}`) from 1.2MB to 696kB.
Most of the remaining allocations are used by imported macros.
While it might be possible to also load macros lazily, doing so is non-trivial and this PR doesn't tackle that.
-rw-r--r--src/librustc/metadata/creader.rs10
-rw-r--r--src/librustc/metadata/cstore.rs21
-rw-r--r--src/librustc/middle/astencode.rs26
3 files changed, 35 insertions, 22 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 12112fd45eb..8562d8c01cc 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<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| {
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 1f18b13fc46..885e7ffb305 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<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 {
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 226010aaa81..b7e57819b93 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)
     }