Skip to content

Commit 97717a5

Browse files
committed
Auto merge of #83682 - bjorn3:mmap_wrapper, r=cjgillot
Add an Mmap wrapper to rustc_data_structures This wrapper implements StableAddress and falls back to directly reading the file on wasm32. Taken from #83640, which I will close due to the perf regression.
2 parents 640ce99 + bda6d1f commit 97717a5

File tree

12 files changed

+63
-50
lines changed

12 files changed

+63
-50
lines changed

Cargo.lock

+1-2
Original file line numberDiff line numberDiff line change
@@ -3812,7 +3812,6 @@ dependencies = [
38123812
"itertools 0.9.0",
38133813
"jobserver",
38143814
"libc",
3815-
"memmap2",
38163815
"pathdiff",
38173816
"rustc_apfloat",
38183817
"rustc_ast",
@@ -3847,6 +3846,7 @@ dependencies = [
38473846
"jobserver",
38483847
"libc",
38493848
"measureme",
3849+
"memmap2",
38503850
"parking_lot",
38513851
"rustc-hash",
38523852
"rustc-rayon",
@@ -4146,7 +4146,6 @@ name = "rustc_metadata"
41464146
version = "0.0.0"
41474147
dependencies = [
41484148
"libc",
4149-
"memmap2",
41504149
"rustc_ast",
41514150
"rustc_attr",
41524151
"rustc_data_structures",

compiler/rustc_codegen_cranelift/Cargo.lock

-10
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,6 @@ dependencies = [
240240
"libc",
241241
]
242242

243-
[[package]]
244-
name = "memmap2"
245-
version = "0.2.1"
246-
source = "registry+https://github.com/rust-lang/crates.io-index"
247-
checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6"
248-
dependencies = [
249-
"libc",
250-
]
251-
252243
[[package]]
253244
name = "object"
254245
version = "0.23.0"
@@ -319,7 +310,6 @@ dependencies = [
319310
"gimli",
320311
"indexmap",
321312
"libloading",
322-
"memmap2",
323313
"object",
324314
"smallvec",
325315
"target-lexicon",

compiler/rustc_codegen_cranelift/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg
2222
indexmap = "1.0.2"
2323
libloading = { version = "0.6.0", optional = true }
2424
smallvec = "1.6.1"
25-
memmap2 = "0.2.1"
2625

2726
# Uncomment to use local checkout of cranelift
2827
#[patch."https://github.com/bytecodealliance/wasmtime/"]

compiler/rustc_codegen_cranelift/src/metadata.rs

+4-17
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! Reading and writing of the rustc metadata for rlibs and dylibs
22
33
use std::fs::File;
4-
use std::ops::Deref;
54
use std::path::Path;
65

76
use rustc_codegen_ssa::METADATA_FILENAME;
8-
use rustc_data_structures::owning_ref::{OwningRef, StableAddress};
7+
use rustc_data_structures::memmap::Mmap;
8+
use rustc_data_structures::owning_ref::OwningRef;
99
use rustc_data_structures::rustc_erase_owner;
1010
use rustc_data_structures::sync::MetadataRef;
1111
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
@@ -17,26 +17,13 @@ use crate::backend::WriteMetadata;
1717

1818
pub(crate) struct CraneliftMetadataLoader;
1919

20-
struct StableMmap(memmap2::Mmap);
21-
22-
impl Deref for StableMmap {
23-
type Target = [u8];
24-
25-
fn deref(&self) -> &[u8] {
26-
&*self.0
27-
}
28-
}
29-
30-
unsafe impl StableAddress for StableMmap {}
31-
3220
fn load_metadata_with(
3321
path: &Path,
3422
f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
3523
) -> Result<MetadataRef, String> {
3624
let file = File::open(path).map_err(|e| format!("{:?}", e))?;
37-
let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) }
38-
.map_err(|e| format!("{:?}", e))?;
39-
let metadata = OwningRef::new(StableMmap(data)).try_map(f)?;
25+
let data = unsafe { Mmap::map(file) }.map_err(|e| format!("{:?}", e))?;
26+
let metadata = OwningRef::new(data).try_map(f)?;
4027
return Ok(rustc_erase_owner!(metadata.map_owner_box()));
4128
}
4229

compiler/rustc_codegen_ssa/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ test = false
1111
bitflags = "1.2.1"
1212
cc = "1.0.1"
1313
itertools = "0.9"
14-
memmap2 = "0.2.1"
1514
tracing = "0.1"
1615
libc = "0.2.50"
1716
jobserver = "0.1.11"

compiler/rustc_codegen_ssa/src/back/lto.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::write::CodegenContext;
22
use crate::traits::*;
33
use crate::ModuleCodegen;
44

5+
use rustc_data_structures::memmap::Mmap;
56
use rustc_errors::FatalError;
67

78
use std::ffi::CString;
@@ -93,7 +94,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
9394
pub enum SerializedModule<M: ModuleBufferMethods> {
9495
Local(M),
9596
FromRlib(Vec<u8>),
96-
FromUncompressedFile(memmap2::Mmap),
97+
FromUncompressedFile(Mmap),
9798
}
9899

99100
impl<M: ModuleBufferMethods> SerializedModule<M> {

compiler/rustc_codegen_ssa/src/back/write.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
use crate::traits::*;
1111
use jobserver::{Acquired, Client};
1212
use rustc_data_structures::fx::FxHashMap;
13+
use rustc_data_structures::memmap::Mmap;
1314
use rustc_data_structures::profiling::SelfProfilerRef;
1415
use rustc_data_structures::profiling::TimingGuard;
1516
use rustc_data_structures::profiling::VerboseTimingGuard;
@@ -1958,7 +1959,7 @@ pub fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
19581959
.unwrap_or_else(|e| panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e));
19591960

19601961
let mmap = unsafe {
1961-
memmap2::Mmap::map(&file).unwrap_or_else(|e| {
1962+
Mmap::map(file).unwrap_or_else(|e| {
19621963
panic!("failed to mmap bitcode file `{}`: {}", bc_path.display(), e)
19631964
})
19641965
};

compiler/rustc_data_structures/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ features = ["nightly"]
3636

3737
[target.'cfg(windows)'.dependencies]
3838
winapi = { version = "0.3", features = ["fileapi", "psapi"] }
39+
40+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
41+
memmap2 = "0.2.1"

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub mod snapshot_map;
8484
pub mod stable_map;
8585
pub mod svh;
8686
pub use ena::snapshot_vec;
87+
pub mod memmap;
8788
pub mod sorted_map;
8889
pub mod stable_set;
8990
#[macro_use]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::fs::File;
2+
use std::io;
3+
use std::ops::Deref;
4+
5+
use crate::owning_ref::StableAddress;
6+
7+
/// A trivial wrapper for [`memmap2::Mmap`] that implements [`StableAddress`].
8+
#[cfg(not(target_arch = "wasm32"))]
9+
pub struct Mmap(memmap2::Mmap);
10+
11+
#[cfg(target_arch = "wasm32")]
12+
pub struct Mmap(Vec<u8>);
13+
14+
#[cfg(not(target_arch = "wasm32"))]
15+
impl Mmap {
16+
#[inline]
17+
pub unsafe fn map(file: File) -> io::Result<Self> {
18+
memmap2::Mmap::map(&file).map(Mmap)
19+
}
20+
}
21+
22+
#[cfg(target_arch = "wasm32")]
23+
impl Mmap {
24+
#[inline]
25+
pub unsafe fn map(mut file: File) -> io::Result<Self> {
26+
use std::io::Read;
27+
28+
let mut data = Vec::new();
29+
file.read_to_end(&mut data)?;
30+
Ok(Mmap(data))
31+
}
32+
}
33+
34+
impl Deref for Mmap {
35+
type Target = [u8];
36+
37+
#[inline]
38+
fn deref(&self) -> &[u8] {
39+
&*self.0
40+
}
41+
}
42+
43+
// SAFETY: On architectures other than WASM, mmap is used as backing storage. The address of this
44+
// memory map is stable. On WASM, `Vec<u8>` is used as backing storage. The `Mmap` type doesn't
45+
// export any function that can cause the `Vec` to be re-allocated. As such the address of the
46+
// bytes inside this `Vec` is stable.
47+
unsafe impl StableAddress for Mmap {}

compiler/rustc_metadata/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ doctest = false
1111
libc = "0.2"
1212
snap = "1"
1313
tracing = "0.1"
14-
memmap2 = "0.2.1"
1514
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
1615
rustc_middle = { path = "../rustc_middle" }
1716
rustc_attr = { path = "../rustc_attr" }

compiler/rustc_metadata/src/locator.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ use crate::creader::Library;
216216
use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
217217

218218
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
219+
use rustc_data_structures::memmap::Mmap;
219220
use rustc_data_structures::owning_ref::OwningRef;
220221
use rustc_data_structures::svh::Svh;
221222
use rustc_data_structures::sync::MetadataRef;
@@ -232,7 +233,6 @@ use rustc_target::spec::{Target, TargetTriple};
232233

233234
use snap::read::FrameDecoder;
234235
use std::io::{Read, Result as IoResult, Write};
235-
use std::ops::Deref;
236236
use std::path::{Path, PathBuf};
237237
use std::{cmp, fmt, fs};
238238
use tracing::{debug, info, warn};
@@ -727,19 +727,6 @@ impl<'a> CrateLocator<'a> {
727727
}
728728
}
729729

730-
/// A trivial wrapper for `Mmap` that implements `StableDeref`.
731-
struct StableDerefMmap(memmap2::Mmap);
732-
733-
impl Deref for StableDerefMmap {
734-
type Target = [u8];
735-
736-
fn deref(&self) -> &[u8] {
737-
self.0.deref()
738-
}
739-
}
740-
741-
unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {}
742-
743730
fn get_metadata_section(
744731
target: &Target,
745732
flavor: CrateFlavor,
@@ -779,11 +766,11 @@ fn get_metadata_section(
779766
// mmap the file, because only a small fraction of it is read.
780767
let file = std::fs::File::open(filename)
781768
.map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?;
782-
let mmap = unsafe { memmap2::Mmap::map(&file) };
769+
let mmap = unsafe { Mmap::map(file) };
783770
let mmap = mmap
784771
.map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?;
785772

786-
rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box())
773+
rustc_erase_owner!(OwningRef::new(mmap).map_owner_box())
787774
}
788775
};
789776
let blob = MetadataBlob::new(raw_bytes);

0 commit comments

Comments
 (0)