Skip to content

Commit 818257e

Browse files
nnethercoteeddyb
authored andcommitted
Use Mmap to open the rmeta file.
Because those files are quite large, contribute significantly to peak memory usage, but only a small fraction of the data is ever read.
1 parent f1d6183 commit 818257e

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

src/Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -2278,12 +2278,14 @@ version = "0.0.0"
22782278
dependencies = [
22792279
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
22802280
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
2281+
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
22812282
"proc_macro 0.0.0",
22822283
"rustc 0.0.0",
22832284
"rustc_data_structures 0.0.0",
22842285
"rustc_errors 0.0.0",
22852286
"rustc_target 0.0.0",
22862287
"serialize 0.0.0",
2288+
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
22872289
"syntax 0.0.0",
22882290
"syntax_ext 0.0.0",
22892291
"syntax_pos 0.0.0",

src/librustc_metadata/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ crate-type = ["dylib"]
1111
[dependencies]
1212
flate2 = "1.0"
1313
log = "0.4"
14+
memmap = "0.6"
1415
proc_macro = { path = "../libproc_macro" }
1516
rustc = { path = "../librustc" }
16-
rustc_target = { path = "../librustc_target" }
1717
rustc_data_structures = { path = "../librustc_data_structures" }
1818
rustc_errors = { path = "../librustc_errors" }
19+
rustc_target = { path = "../librustc_target" }
1920
serialize = { path = "../libserialize" }
21+
stable_deref_trait = "1.0.0"
2022
syntax = { path = "../libsyntax" }
2123
syntax_ext = { path = "../libsyntax_ext" }
2224
syntax_pos = { path = "../libsyntax_pos" }

src/librustc_metadata/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
extern crate libc;
3131
#[macro_use]
3232
extern crate log;
33+
extern crate memmap;
34+
extern crate stable_deref_trait;
3335
#[macro_use]
3436
extern crate syntax;
3537
extern crate syntax_pos;

src/librustc_metadata/locator.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,14 @@ use std::cmp;
243243
use std::fmt;
244244
use std::fs;
245245
use std::io::{self, Read};
246+
use std::ops::Deref;
246247
use std::path::{Path, PathBuf};
247248
use std::time::Instant;
248249

249250
use flate2::read::DeflateDecoder;
250251

251252
use rustc_data_structures::owning_ref::OwningRef;
253+
252254
pub struct CrateMismatch {
253255
path: PathBuf,
254256
got: String,
@@ -856,6 +858,19 @@ fn get_metadata_section(target: &Target,
856858
return ret;
857859
}
858860

861+
/// A trivial wrapper for `Mmap` that implements `StableDeref`.
862+
struct StableDerefMmap(memmap::Mmap);
863+
864+
impl Deref for StableDerefMmap {
865+
type Target = [u8];
866+
867+
fn deref(&self) -> &[u8] {
868+
self.0.deref()
869+
}
870+
}
871+
872+
unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {}
873+
859874
fn get_metadata_section_imp(target: &Target,
860875
flavor: CrateFlavor,
861876
filename: &Path,
@@ -892,9 +907,14 @@ fn get_metadata_section_imp(target: &Target,
892907
}
893908
}
894909
CrateFlavor::Rmeta => {
895-
let buf = fs::read(filename).map_err(|_|
896-
format!("failed to read rmeta metadata: '{}'", filename.display()))?;
897-
rustc_erase_owner!(OwningRef::new(buf).map_owner_box())
910+
// mmap the file, because only a small fraction of it is read.
911+
let file = std::fs::File::open(filename).map_err(|_|
912+
format!("failed to open rmeta metadata: '{}'", filename.display()))?;
913+
let mmap = unsafe { memmap::Mmap::map(&file) };
914+
let mmap = mmap.map_err(|_|
915+
format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
916+
917+
rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box())
898918
}
899919
};
900920
let blob = MetadataBlob(raw_bytes);

0 commit comments

Comments
 (0)