Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e7f95ac

Browse files
committed
use rustc_serialize::opaque::FileEncoder
1 parent 5d9ba49 commit e7f95ac

File tree

4 files changed

+46
-38
lines changed

4 files changed

+46
-38
lines changed

compiler/rustc_metadata/src/fs.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,30 @@ pub fn encode_and_write_metadata(
5555
.max()
5656
.unwrap_or(MetadataKind::None);
5757

58+
let crate_name = tcx.crate_name(LOCAL_CRATE);
59+
let out_filename = filename_for_metadata(tcx.sess, crate_name.as_str(), outputs);
60+
// To avoid races with another rustc process scanning the output directory,
61+
// we need to write the file somewhere else and atomically move it to its
62+
// final destination, with an `fs::rename` call. In order for the rename to
63+
// always succeed, the temporary file needs to be on the same filesystem,
64+
// which is why we create it inside the output directory specifically.
65+
let metadata_tmpdir = TempFileBuilder::new()
66+
.prefix("rmeta")
67+
.tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
68+
.unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
69+
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
70+
let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);
5871
let metadata = match metadata_kind {
5972
MetadataKind::None => EncodedMetadata::new(),
60-
MetadataKind::Uncompressed | MetadataKind::Compressed => encode_metadata(tcx),
73+
MetadataKind::Uncompressed | MetadataKind::Compressed => {
74+
encode_metadata(tcx, metadata_filename)
75+
}
6176
};
6277

6378
let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata");
6479

6580
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
6681
if need_metadata_file {
67-
let crate_name = tcx.crate_name(LOCAL_CRATE);
68-
let out_filename = filename_for_metadata(tcx.sess, crate_name.as_str(), outputs);
69-
// To avoid races with another rustc process scanning the output directory,
70-
// we need to write the file somewhere else and atomically move it to its
71-
// final destination, with an `fs::rename` call. In order for the rename to
72-
// always succeed, the temporary file needs to be on the same filesystem,
73-
// which is why we create it inside the output directory specifically.
74-
let metadata_tmpdir = TempFileBuilder::new()
75-
.prefix("rmeta")
76-
.tempdir_in(out_filename.parent().unwrap())
77-
.unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
78-
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
7982
let metadata_filename = emit_metadata(tcx.sess, metadata.raw_data(), &metadata_tmpdir);
8083
if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
8184
tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ use rustc_middle::ty::codec::TyEncoder;
2727
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
2828
use rustc_middle::ty::query::Providers;
2929
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
30-
use rustc_serialize::opaque::MemEncoder;
31-
use rustc_serialize::{Encodable, Encoder};
30+
use rustc_serialize::{opaque, Encodable, Encoder};
3231
use rustc_session::config::CrateType;
3332
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
3433
use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind};
@@ -41,10 +40,11 @@ use std::borrow::Borrow;
4140
use std::hash::Hash;
4241
use std::iter;
4342
use std::num::NonZeroUsize;
43+
use std::path::Path;
4444
use tracing::{debug, trace};
4545

4646
pub(super) struct EncodeContext<'a, 'tcx> {
47-
opaque: MemEncoder,
47+
opaque: opaque::FileEncoder,
4848
tcx: TyCtxt<'tcx>,
4949
feat: &'tcx rustc_feature::Features,
5050

@@ -730,25 +730,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
730730
assert_eq!(total_bytes, computed_total_bytes);
731731

732732
if tcx.sess.meta_stats() {
733-
let mut zero_bytes = 0;
734-
for e in self.opaque.data.iter() {
735-
if *e == 0 {
736-
zero_bytes += 1;
737-
}
738-
}
733+
// let mut zero_bytes = 0;
734+
// for e in self.opaque.data.iter() {
735+
// if *e == 0 {
736+
// zero_bytes += 1;
737+
// }
738+
// }
739739

740740
let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
741741
let p = |label, bytes| {
742742
eprintln!("{:>21}: {:>8} bytes ({:4.1}%)", label, bytes, perc(bytes));
743743
};
744744

745745
eprintln!("");
746-
eprintln!(
747-
"{} metadata bytes, of which {} bytes ({:.1}%) are zero",
748-
total_bytes,
749-
zero_bytes,
750-
perc(zero_bytes)
751-
);
746+
// FIXME print zero bytes
747+
//eprintln!(
748+
// "{} metadata bytes, of which {} bytes ({:.1}%) are zero",
749+
// total_bytes,
750+
// zero_bytes,
751+
// perc(zero_bytes)
752+
//);
752753
p("preamble", preamble_bytes);
753754
p("dep", dep_bytes);
754755
p("lib feature", lib_feature_bytes);
@@ -2151,15 +2152,15 @@ impl EncodedMetadata {
21512152
}
21522153
}
21532154

2154-
pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
2155+
pub fn encode_metadata(tcx: TyCtxt<'_>, path: impl AsRef<Path>) -> EncodedMetadata {
21552156
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");
21562157

21572158
// Since encoding metadata is not in a query, and nothing is cached,
21582159
// there's no need to do dep-graph tracking for any of it.
21592160
tcx.dep_graph.assert_ignored();
21602161

21612162
join(
2162-
|| encode_metadata_impl(tcx),
2163+
|| encode_metadata_impl(tcx, path),
21632164
|| {
21642165
if tcx.sess.threads() == 1 {
21652166
return;
@@ -2173,8 +2174,9 @@ pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
21732174
.0
21742175
}
21752176

2176-
fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
2177-
let mut encoder = MemEncoder::new();
2177+
fn encode_metadata_impl(tcx: TyCtxt<'_>, path: impl AsRef<Path>) -> EncodedMetadata {
2178+
let mut encoder = opaque::FileEncoder::new(path.as_ref())
2179+
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
21782180
encoder.emit_raw_bytes(METADATA_HEADER);
21792181

21802182
// Will be filled with the root position after encoding everything.
@@ -2209,7 +2211,8 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
22092211
// culminating in the `CrateRoot` which points to all of it.
22102212
let root = ecx.encode_crate_root();
22112213

2212-
let mut result = ecx.opaque.finish();
2214+
ecx.opaque.flush();
2215+
let mut result = std::fs::read(path.as_ref()).unwrap();
22132216

22142217
// Encode the root position.
22152218
let header = METADATA_HEADER.len();
@@ -2219,6 +2222,8 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
22192222
result[header + 2] = (pos >> 8) as u8;
22202223
result[header + 3] = (pos >> 0) as u8;
22212224

2225+
std::fs::write(path, &result).unwrap();
2226+
22222227
// Record metadata size for self-profiling
22232228
tcx.prof.artifact_size("crate_metadata", "crate_metadata", result.len() as u64);
22242229

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
2222
use rustc_middle::ty::query::Providers;
2323
use rustc_middle::ty::{self, ReprOptions, Ty};
2424
use rustc_middle::ty::{GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
25-
use rustc_serialize::opaque::MemEncoder;
25+
use rustc_serialize::opaque::FileEncoder;
2626
use rustc_session::config::SymbolManglingVersion;
2727
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
2828
use rustc_span::edition::Edition;
@@ -323,7 +323,7 @@ macro_rules! define_tables {
323323
}
324324

325325
impl TableBuilders {
326-
fn encode(&self, buf: &mut MemEncoder) -> LazyTables {
326+
fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
327327
LazyTables {
328328
$($name: self.$name.encode(buf)),+
329329
}

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use rustc_data_structures::fingerprint::Fingerprint;
44
use rustc_hir::def::{CtorKind, CtorOf};
55
use rustc_index::vec::Idx;
66
use rustc_middle::ty::ParameterizedOverTcx;
7-
use rustc_serialize::opaque::MemEncoder;
8-
use rustc_serialize::Encoder;
7+
use rustc_serialize::opaque::FileEncoder;
8+
use rustc_serialize::Encoder as _;
99
use rustc_span::hygiene::MacroKind;
1010
use std::convert::TryInto;
1111
use std::marker::PhantomData;
@@ -281,7 +281,7 @@ where
281281
Some(value).write_to_bytes(&mut self.blocks[i]);
282282
}
283283

284-
pub(crate) fn encode<const N: usize>(&self, buf: &mut MemEncoder) -> LazyTable<I, T>
284+
pub(crate) fn encode<const N: usize>(&self, buf: &mut FileEncoder) -> LazyTable<I, T>
285285
where
286286
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
287287
{

0 commit comments

Comments
 (0)