From 8cfa7caac9bba5b83995040ebf313559e4e2186c Mon Sep 17 00:00:00 2001 From: Yoshiki Matsuda Date: Fri, 29 Apr 2022 12:24:58 +0900 Subject: [PATCH] hold Mmap in EncodedMetadata --- compiler/rustc_metadata/src/fs.rs | 6 ++- compiler/rustc_metadata/src/rmeta/encoder.rs | 41 ++++++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index 950009397ce..fa97cda0aa3 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -94,8 +94,10 @@ pub fn encode_and_write_metadata( } else { metadata_filename }; - let raw_data = std::fs::read(metadata_filename).unwrap(); - let metadata = EncodedMetadata::from_raw_data(raw_data); + let file = std::fs::File::open(metadata_filename).unwrap(); + let metadata = EncodedMetadata::from_file(file).unwrap_or_else(|e| { + tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e)) + }); let need_metadata_module = metadata_kind == MetadataKind::Compressed; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f18a05fcb1d..6e2044d4bb0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,6 +4,7 @@ use crate::rmeta::*; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::memmap::Mmap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_hir as hir; @@ -27,7 +28,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; -use rustc_serialize::{opaque, Encodable, Encoder}; +use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::CrateType; use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib}; use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind}; @@ -2135,25 +2136,43 @@ fn prefetch_mir(tcx: TyCtxt<'_>) { // will allow us to slice the metadata to the precise length that we just // generated regardless of trailing bytes that end up in it. -#[derive(Encodable, Decodable)] pub struct EncodedMetadata { - raw_data: Vec, + mmap: Option, + decoded: Vec, } impl EncodedMetadata { #[inline] - pub fn new() -> EncodedMetadata { - EncodedMetadata { raw_data: Vec::new() } - } - - #[inline] - pub fn from_raw_data(raw_data: Vec) -> Self { - Self { raw_data } + pub fn from_file(file: std::fs::File) -> std::io::Result { + let file_metadata = file.metadata()?; + if file_metadata.len() == 0 { + return Ok(Self { mmap: None, decoded: Vec::new() }); + } + let mmap = unsafe { Some(Mmap::map(file)?) }; + Ok(Self { mmap, decoded: Vec::new() }) } #[inline] pub fn raw_data(&self) -> &[u8] { - &self.raw_data + if !self.decoded.is_empty() { + return &self.decoded; + } + self.mmap.as_ref().map(|mmap| mmap.as_ref()).unwrap_or_default() + } +} + +impl Encodable for EncodedMetadata { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + let slice = self.raw_data(); + slice.encode(s) + } +} + +impl Decodable for EncodedMetadata { + fn decode(d: &mut D) -> Self { + // FIXME: Write decorded data to a file and map to Mmap. + let decoded = Decodable::decode(d); + EncodedMetadata { mmap: None, decoded } } }