diff options
| author | Yoshiki Matsuda <myskjp@gmail.com> | 2022-04-29 13:50:27 +0900 |
|---|---|---|
| committer | Yoshiki Matsuda <myskjp@gmail.com> | 2022-07-02 22:51:42 +0900 |
| commit | 336af60eae7cd272f702f0420723a733008f0161 (patch) | |
| tree | c80653cdddf9f3c06327ba3397e463224c7fe428 | |
| parent | 8cfa7caac9bba5b83995040ebf313559e4e2186c (diff) | |
| download | rust-336af60eae7cd272f702f0420723a733008f0161.tar.gz rust-336af60eae7cd272f702f0420723a733008f0161.zip | |
write to a temporary file in Decodable for EncodedMetadata
| -rw-r--r-- | compiler/rustc_metadata/src/fs.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 37 |
2 files changed, 32 insertions, 19 deletions
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index fa97cda0aa3..f6373438491 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -80,7 +80,7 @@ pub fn encode_and_write_metadata( let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata"); let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata); - let metadata_filename = if need_metadata_file { + let (metadata_filename, metadata_tmpdir) = if need_metadata_file { if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) { tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); } @@ -90,14 +90,14 @@ pub fn encode_and_write_metadata( .span_diagnostic .emit_artifact_notification(&out_filename, "metadata"); } - out_filename + (out_filename, None) } else { - metadata_filename + (metadata_filename, Some(metadata_tmpdir)) }; - 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 metadata = + EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).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 6e2044d4bb0..68da815dc30 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -7,6 +7,7 @@ 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_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{ @@ -39,9 +40,11 @@ use rustc_span::{ use rustc_target::abi::VariantIdx; use std::borrow::Borrow; use std::hash::Hash; +use std::io::Write; use std::iter; use std::num::NonZeroUsize; -use std::path::Path; +use std::path::{Path, PathBuf}; +use tempfile::Builder as TempFileBuilder; use tracing::{debug, trace}; pub(super) struct EncodeContext<'a, 'tcx> { @@ -2138,25 +2141,25 @@ fn prefetch_mir(tcx: TyCtxt<'_>) { pub struct EncodedMetadata { mmap: Option<Mmap>, - decoded: Vec<u8>, + // We need to carry MaybeTempDir to avoid deleting the temporary + // directory while accessing the Mmap. + _temp_dir: Option<MaybeTempDir>, } impl EncodedMetadata { #[inline] - pub fn from_file(file: std::fs::File) -> std::io::Result<Self> { + pub fn from_path(path: PathBuf, temp_dir: Option<MaybeTempDir>) -> std::io::Result<Self> { + let file = std::fs::File::open(&path)?; let file_metadata = file.metadata()?; if file_metadata.len() == 0 { - return Ok(Self { mmap: None, decoded: Vec::new() }); + return Ok(Self { mmap: None, _temp_dir: temp_dir }); } let mmap = unsafe { Some(Mmap::map(file)?) }; - Ok(Self { mmap, decoded: Vec::new() }) + Ok(Self { mmap, _temp_dir: temp_dir }) } #[inline] 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() } } @@ -2170,9 +2173,19 @@ impl<S: Encoder> Encodable<S> for EncodedMetadata { 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 } + let temp_dir = TempFileBuilder::new().prefix("decoded").tempdir().unwrap(); + let temp_dir = MaybeTempDir::new(temp_dir, false); + let filename = temp_dir.as_ref().join("decoded"); + let file = std::fs::File::create(&filename).unwrap(); + let mut file = std::io::BufWriter::new(file); + + let len = d.read_usize(); + for _ in 0..len { + file.write(&[d.read_u8()]).unwrap(); + } + file.flush().unwrap(); + + Self::from_path(filename, Some(temp_dir)).unwrap() } } @@ -2269,5 +2282,5 @@ pub fn provide(providers: &mut Providers) { }, ..*providers - }; + } } |
