Skip to content

Commit 289cbc4

Browse files
committed
add flag to split sourcemap into a secondary rmeta file
1 parent 084d249 commit 289cbc4

File tree

6 files changed

+47
-5
lines changed

6 files changed

+47
-5
lines changed

compiler/rustc_metadata/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub use native_libs::{
3333
NativeLibSearchFallback, find_native_static_library, try_find_native_dynamic_library,
3434
try_find_native_static_library, walk_native_lib_search_dirs,
3535
};
36-
pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const};
36+
pub use rmeta::{
37+
EncodedMetadata, METADATA_EXTRA_HEADER, METADATA_HEADER, encode_metadata, rendered_const,
38+
};
3739

3840
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::rmeta::*;
3939

4040
pub(super) struct EncodeContext<'a, 'tcx> {
4141
opaque: opaque::FileEncoder,
42+
opaque_extra: Option<opaque::FileEncoder>,
4243
tcx: TyCtxt<'tcx>,
4344
feat: &'tcx rustc_feature::Features,
4445
tables: TableBuilders,
@@ -600,7 +601,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
600601
adapted.set_some(on_disk_index, self.lazy(adapted_source_file));
601602
}
602603

603-
adapted.encode(&mut self.opaque)
604+
if let Some(opaque_extra) = &mut self.opaque_extra {
605+
let table = adapted.encode(opaque_extra);
606+
// leave a hole full of zeros in the original location in rmeta to avoid messing with offsets of subsequent items
607+
for _ in 0..table.size() {
608+
const WIDTH: usize =
609+
std::mem::size_of::<Option<LazyValue<rustc_span::SourceFile>>>();
610+
self.opaque.emit_raw_bytes(&[0; WIDTH]);
611+
}
612+
table
613+
} else {
614+
adapted.encode(&mut self.opaque)
615+
}
604616
}
605617

606618
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
@@ -2432,6 +2444,16 @@ fn with_encode_metadata_header(
24322444
// Will be filled with the root position after encoding everything.
24332445
encoder.emit_raw_bytes(&0u64.to_le_bytes());
24342446

2447+
let encoder_extra = if tcx.sess.is_split_rmeta_enabled() {
2448+
let path = path.with_extension("rmeta-extra");
2449+
let mut encoder = opaque::FileEncoder::new(path)
2450+
.unwrap_or_else(|err| tcx.dcx().emit_fatal(FailCreateFileEncoder { err }));
2451+
encoder.emit_raw_bytes(METADATA_EXTRA_HEADER);
2452+
Some(encoder)
2453+
} else {
2454+
None
2455+
};
2456+
24352457
let source_map_files = tcx.sess.source_map().files();
24362458
let source_file_cache = (Arc::clone(&source_map_files[0]), 0);
24372459
let required_source_files = Some(FxIndexSet::default());
@@ -2441,6 +2463,7 @@ fn with_encode_metadata_header(
24412463

24422464
let mut ecx = EncodeContext {
24432465
opaque: encoder,
2466+
opaque_extra: encoder_extra,
24442467
tcx,
24452468
feat: tcx.features(),
24462469
tables: Default::default(),
@@ -2468,6 +2491,12 @@ fn with_encode_metadata_header(
24682491
tcx.dcx().emit_fatal(FailWriteFile { path: &path, err });
24692492
}
24702493

2494+
if let Some(opaque_extra) = &mut ecx.opaque_extra {
2495+
if let Err((path, err)) = opaque_extra.finish() {
2496+
tcx.dcx().emit_fatal(FailWriteFile { path: &path, err });
2497+
}
2498+
}
2499+
24712500
let file = ecx.opaque.file();
24722501
if let Err(err) = encode_root_position(file, root_position) {
24732502
tcx.dcx().emit_fatal(FailWriteFile { path: ecx.opaque.path(), err });

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ const METADATA_VERSION: u8 = 10;
6565
/// unsigned integer, and further followed by the rustc version string.
6666
pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
6767

68+
/// Metadata extras header which includes `METADATA_VERSION`.
69+
///
70+
/// This header is followed by the length of the compressed data
71+
pub const METADATA_EXTRA_HEADER: &[u8] = &[b'R', b'U', b'S', b'T', 0, 0, 0, METADATA_VERSION];
72+
6873
/// A value of type T referred to by its absolute position
6974
/// in the metadata, and which can be decoded lazily.
7075
///

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,6 +2537,8 @@ written to standard error output)"),
25372537
by the linker"),
25382538
split_lto_unit: Option<bool> = (None, parse_opt_bool, [TRACKED],
25392539
"enable LTO unit splitting (default: no)"),
2540+
split_rmeta: Option<bool> = (None, parse_opt_bool, [TRACKED],
2541+
"split extra rmeta data that isn't relevant rlib ABI into a separate file"),
25402542
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
25412543
"hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
25422544
#[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")]

compiler/rustc_session/src/session.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ impl Session {
400400
self.opts.unstable_opts.split_lto_unit == Some(true)
401401
}
402402

403+
pub fn is_split_rmeta_enabled(&self) -> bool {
404+
self.opts.unstable_opts.split_rmeta == Some(true)
405+
}
406+
403407
/// Check whether this compile session and crate type use static crt.
404408
pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool {
405409
if !self.target.crt_static_respected {

tests/run-make/rdr-ignores-comments/rmake.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// tests that changing the content of a comment will cause a change in the rmeta of a file
1+
// tests that changing the content of a comment will not cause a change in the rmeta of a library if -Zsplit-rmeta is enabled
22
use run_make_support::{rfs, rustc};
33
use std::hash::{Hash, Hasher};
44
use std::path::Path;
@@ -7,15 +7,15 @@ fn main() {
77
let before = check_and_hash("before.rs");
88
let after = check_and_hash("after.rs");
99
dbg!(before, after);
10-
assert_neq!(before, after);
10+
assert_eq!(before, after);
1111
}
1212

1313
fn check_and_hash<P>(filename: P) -> u64
1414
where
1515
P: AsRef<Path>,
1616
{
1717
rfs::rename(filename, "foo.rs");
18-
rustc().input("foo.rs").emit("metadata").run();
18+
rustc().input("foo.rs").emit("metadata").arg("-Zsplit-rmeta").run();
1919
// hash the output
2020
let bytes = rfs::read("libfoo.rmeta");
2121
let mut hasher = std::hash::DefaultHasher::new();

0 commit comments

Comments
 (0)