Skip to content

Commit 336af60

Browse files
committed
write to a temporary file in Decodable for EncodedMetadata
1 parent 8cfa7ca commit 336af60

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

compiler/rustc_metadata/src/fs.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn encode_and_write_metadata(
8080
let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata");
8181

8282
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
83-
let metadata_filename = if need_metadata_file {
83+
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
8484
if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
8585
tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
8686
}
@@ -90,14 +90,14 @@ pub fn encode_and_write_metadata(
9090
.span_diagnostic
9191
.emit_artifact_notification(&out_filename, "metadata");
9292
}
93-
out_filename
93+
(out_filename, None)
9494
} else {
95-
metadata_filename
95+
(metadata_filename, Some(metadata_tmpdir))
9696
};
97-
let file = std::fs::File::open(metadata_filename).unwrap();
98-
let metadata = EncodedMetadata::from_file(file).unwrap_or_else(|e| {
99-
tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
100-
});
97+
let metadata =
98+
EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|e| {
99+
tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
100+
});
101101

102102
let need_metadata_module = metadata_kind == MetadataKind::Compressed;
103103

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
77
use rustc_data_structures::memmap::Mmap;
88
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
99
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
10+
use rustc_data_structures::temp_dir::MaybeTempDir;
1011
use rustc_hir as hir;
1112
use rustc_hir::def::DefKind;
1213
use rustc_hir::def_id::{
@@ -39,9 +40,11 @@ use rustc_span::{
3940
use rustc_target::abi::VariantIdx;
4041
use std::borrow::Borrow;
4142
use std::hash::Hash;
43+
use std::io::Write;
4244
use std::iter;
4345
use std::num::NonZeroUsize;
44-
use std::path::Path;
46+
use std::path::{Path, PathBuf};
47+
use tempfile::Builder as TempFileBuilder;
4548
use tracing::{debug, trace};
4649

4750
pub(super) struct EncodeContext<'a, 'tcx> {
@@ -2138,25 +2141,25 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
21382141

21392142
pub struct EncodedMetadata {
21402143
mmap: Option<Mmap>,
2141-
decoded: Vec<u8>,
2144+
// We need to carry MaybeTempDir to avoid deleting the temporary
2145+
// directory while accessing the Mmap.
2146+
_temp_dir: Option<MaybeTempDir>,
21422147
}
21432148

21442149
impl EncodedMetadata {
21452150
#[inline]
2146-
pub fn from_file(file: std::fs::File) -> std::io::Result<Self> {
2151+
pub fn from_path(path: PathBuf, temp_dir: Option<MaybeTempDir>) -> std::io::Result<Self> {
2152+
let file = std::fs::File::open(&path)?;
21472153
let file_metadata = file.metadata()?;
21482154
if file_metadata.len() == 0 {
2149-
return Ok(Self { mmap: None, decoded: Vec::new() });
2155+
return Ok(Self { mmap: None, _temp_dir: temp_dir });
21502156
}
21512157
let mmap = unsafe { Some(Mmap::map(file)?) };
2152-
Ok(Self { mmap, decoded: Vec::new() })
2158+
Ok(Self { mmap, _temp_dir: temp_dir })
21532159
}
21542160

21552161
#[inline]
21562162
pub fn raw_data(&self) -> &[u8] {
2157-
if !self.decoded.is_empty() {
2158-
return &self.decoded;
2159-
}
21602163
self.mmap.as_ref().map(|mmap| mmap.as_ref()).unwrap_or_default()
21612164
}
21622165
}
@@ -2170,9 +2173,19 @@ impl<S: Encoder> Encodable<S> for EncodedMetadata {
21702173

21712174
impl<D: Decoder> Decodable<D> for EncodedMetadata {
21722175
fn decode(d: &mut D) -> Self {
2173-
// FIXME: Write decorded data to a file and map to Mmap.
2174-
let decoded = Decodable::decode(d);
2175-
EncodedMetadata { mmap: None, decoded }
2176+
let temp_dir = TempFileBuilder::new().prefix("decoded").tempdir().unwrap();
2177+
let temp_dir = MaybeTempDir::new(temp_dir, false);
2178+
let filename = temp_dir.as_ref().join("decoded");
2179+
let file = std::fs::File::create(&filename).unwrap();
2180+
let mut file = std::io::BufWriter::new(file);
2181+
2182+
let len = d.read_usize();
2183+
for _ in 0..len {
2184+
file.write(&[d.read_u8()]).unwrap();
2185+
}
2186+
file.flush().unwrap();
2187+
2188+
Self::from_path(filename, Some(temp_dir)).unwrap()
21762189
}
21772190
}
21782191

@@ -2269,5 +2282,5 @@ pub fn provide(providers: &mut Providers) {
22692282
},
22702283

22712284
..*providers
2272-
};
2285+
}
22732286
}

0 commit comments

Comments
 (0)