]> git.lizzy.rs Git - rust.git/commitdiff
Use `Mmap` to open the rmeta file.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 31 Oct 2018 21:59:32 +0000 (08:59 +1100)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Wed, 14 Nov 2018 03:55:10 +0000 (05:55 +0200)
Because those files are quite large, contribute significantly to peak
memory usage, but only a small fraction of the data is ever read.

src/Cargo.lock
src/librustc_metadata/Cargo.toml
src/librustc_metadata/lib.rs
src/librustc_metadata/locator.rs

index 0c08e35c18df33d53a1ea3b6a82480ca1da76423..64e18899c9d0503298b153a0ffd76abeccd6a8dc 100644 (file)
@@ -2278,12 +2278,14 @@ version = "0.0.0"
 dependencies = [
  "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
  "serialize 0.0.0",
+ "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_ext 0.0.0",
  "syntax_pos 0.0.0",
index 338824d5efe4caa862256121941b11a7e38bdbce..276e2a911e6978966bef1d5857fd1b50d55af00c 100644 (file)
@@ -11,12 +11,14 @@ crate-type = ["dylib"]
 [dependencies]
 flate2 = "1.0"
 log = "0.4"
+memmap = "0.6"
 proc_macro = { path = "../libproc_macro" }
 rustc = { path = "../librustc" }
-rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
+rustc_target = { path = "../librustc_target" }
 serialize = { path = "../libserialize" }
+stable_deref_trait = "1.0.0"
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
index 0cc0707a3a51f263bcdf0f5ca347ed71c41f56af..0322c888ad5c96c5e144420b5c9b09b0a0595d45 100644 (file)
@@ -30,6 +30,8 @@
 extern crate libc;
 #[macro_use]
 extern crate log;
+extern crate memmap;
+extern crate stable_deref_trait;
 #[macro_use]
 extern crate syntax;
 extern crate syntax_pos;
index a732446d5048139b6f7534caa8cc1c90ba1a9932..528c96f240dbac252bc2e8a112092da66dd2796c 100644 (file)
 use std::fmt;
 use std::fs;
 use std::io::{self, Read};
+use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::time::Instant;
 
 use flate2::read::DeflateDecoder;
 
 use rustc_data_structures::owning_ref::OwningRef;
+
 pub struct CrateMismatch {
     path: PathBuf,
     got: String,
@@ -856,6 +858,19 @@ fn get_metadata_section(target: &Target,
     return ret;
 }
 
+/// A trivial wrapper for `Mmap` that implements `StableDeref`.
+struct StableDerefMmap(memmap::Mmap);
+
+impl Deref for StableDerefMmap {
+    type Target = [u8];
+
+    fn deref(&self) -> &[u8] {
+        self.0.deref()
+    }
+}
+
+unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {}
+
 fn get_metadata_section_imp(target: &Target,
                             flavor: CrateFlavor,
                             filename: &Path,
@@ -892,9 +907,14 @@ fn get_metadata_section_imp(target: &Target,
             }
         }
         CrateFlavor::Rmeta => {
-            let buf = fs::read(filename).map_err(|_|
-                format!("failed to read rmeta metadata: '{}'", filename.display()))?;
-            rustc_erase_owner!(OwningRef::new(buf).map_owner_box())
+            // mmap the file, because only a small fraction of it is read.
+            let file = std::fs::File::open(filename).map_err(|_|
+                format!("failed to open rmeta metadata: '{}'", filename.display()))?;
+            let mmap = unsafe { memmap::Mmap::map(&file) };
+            let mmap = mmap.map_err(|_|
+                format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
+
+            rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box())
         }
     };
     let blob = MetadataBlob(raw_bytes);