about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYoshiki Matsuda <myskjp@gmail.com>2022-04-29 12:24:58 +0900
committerYoshiki Matsuda <myskjp@gmail.com>2022-07-02 22:51:42 +0900
commit8cfa7caac9bba5b83995040ebf313559e4e2186c (patch)
treef1a271457dab6b7f2a6412aece0d66d7a3f0b631
parentc26c461c0c0f4ee81616a794b1ac3cb41a3f17a6 (diff)
downloadrust-8cfa7caac9bba5b83995040ebf313559e4e2186c.tar.gz
rust-8cfa7caac9bba5b83995040ebf313559e4e2186c.zip
hold Mmap in EncodedMetadata
-rw-r--r--compiler/rustc_metadata/src/fs.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs39
2 files changed, 33 insertions, 12 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<u8>,
+    mmap: Option<Mmap>,
+    decoded: Vec<u8>,
 }
 
 impl EncodedMetadata {
     #[inline]
-    pub fn new() -> EncodedMetadata {
-        EncodedMetadata { raw_data: Vec::new() }
+    pub fn from_file(file: std::fs::File) -> std::io::Result<Self> {
+        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 from_raw_data(raw_data: Vec<u8>) -> Self {
-        Self { raw_data }
+    pub fn raw_data(&self) -> &[u8] {
+        if !self.decoded.is_empty() {
+            return &self.decoded;
+        }
+        self.mmap.as_ref().map(|mmap| mmap.as_ref()).unwrap_or_default()
     }
+}
 
-    #[inline]
-    pub fn raw_data(&self) -> &[u8] {
-        &self.raw_data
+impl<S: Encoder> Encodable<S> for EncodedMetadata {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
+        let slice = self.raw_data();
+        slice.encode(s)
+    }
+}
+
+impl<D: Decoder> Decodable<D> 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 }
     }
 }