write to a temporary file in Decodable for EncodedMetadata

This commit is contained in:
Yoshiki Matsuda 2022-04-29 13:50:27 +09:00
parent 8cfa7caac9
commit 336af60eae
2 changed files with 32 additions and 19 deletions

View File

@ -80,7 +80,7 @@ pub fn encode_and_write_metadata(
let _prof_timer = tcx.sess.prof.generic_activity("write_crate_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 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) { if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
} }
@ -90,12 +90,12 @@ pub fn encode_and_write_metadata(
.span_diagnostic .span_diagnostic
.emit_artifact_notification(&out_filename, "metadata"); .emit_artifact_notification(&out_filename, "metadata");
} }
out_filename (out_filename, None)
} else { } else {
metadata_filename (metadata_filename, Some(metadata_tmpdir))
}; };
let file = std::fs::File::open(metadata_filename).unwrap(); let metadata =
let metadata = EncodedMetadata::from_file(file).unwrap_or_else(|e| { EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|e| {
tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e)) tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
}); });

View File

@ -7,6 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::memmap::Mmap; use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; 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 as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{ use rustc_hir::def_id::{
@ -39,9 +40,11 @@ use rustc_span::{
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::hash::Hash; use std::hash::Hash;
use std::io::Write;
use std::iter; use std::iter;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::path::Path; use std::path::{Path, PathBuf};
use tempfile::Builder as TempFileBuilder;
use tracing::{debug, trace}; use tracing::{debug, trace};
pub(super) struct EncodeContext<'a, 'tcx> { pub(super) struct EncodeContext<'a, 'tcx> {
@ -2138,25 +2141,25 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
pub struct EncodedMetadata { pub struct EncodedMetadata {
mmap: Option<Mmap>, 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 { impl EncodedMetadata {
#[inline] #[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()?; let file_metadata = file.metadata()?;
if file_metadata.len() == 0 { 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)?) }; let mmap = unsafe { Some(Mmap::map(file)?) };
Ok(Self { mmap, decoded: Vec::new() }) Ok(Self { mmap, _temp_dir: temp_dir })
} }
#[inline] #[inline]
pub fn raw_data(&self) -> &[u8] { 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() 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 { impl<D: Decoder> Decodable<D> for EncodedMetadata {
fn decode(d: &mut D) -> Self { fn decode(d: &mut D) -> Self {
// FIXME: Write decorded data to a file and map to Mmap. let temp_dir = TempFileBuilder::new().prefix("decoded").tempdir().unwrap();
let decoded = Decodable::decode(d); let temp_dir = MaybeTempDir::new(temp_dir, false);
EncodedMetadata { mmap: None, decoded } 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 ..*providers
}; }
} }