rustc_data_structures/memmap.rs
1use std::fs::File;
2use std::io;
3use std::ops::{Deref, DerefMut};
4
5/// A trivial wrapper for [`memmap2::Mmap`] (or `Vec<u8>` on WASM).
6#[cfg(not(any(miri, target_arch = "wasm32")))]
7pub struct Mmap(memmap2::Mmap);
8
9#[cfg(any(miri, target_arch = "wasm32"))]
10pub struct Mmap(Vec<u8>);
11
12#[cfg(not(any(miri, target_arch = "wasm32")))]
13impl Mmap {
14 /// # Safety
15 ///
16 /// The given file must not be mutated (i.e., not written, not truncated, ...) until the mapping is closed.
17 ///
18 /// However in practice most callers do not ensure this, so uses of this function are likely unsound.
19 #[inline]
20 pub unsafe fn map(file: File) -> io::Result<Self> {
21 // By default, memmap2 creates shared mappings, implying that we could see updates to the
22 // file through the mapping. That would violate our precondition; so by requesting a
23 // map_copy_read_only we do not lose anything.
24 // This mapping mode also improves our support for filesystems such as cacheless virtiofs.
25 // For more details see https://github.com/rust-lang/rust/issues/122262
26 //
27 // SAFETY: The caller must ensure that this is safe.
28 unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file).map(Mmap) }
29 }
30}
31
32#[cfg(any(miri, target_arch = "wasm32"))]
33impl Mmap {
34 #[inline]
35 pub unsafe fn map(mut file: File) -> io::Result<Self> {
36 use std::io::Read;
37
38 let mut data = Vec::new();
39 file.read_to_end(&mut data)?;
40 Ok(Mmap(data))
41 }
42}
43
44impl Deref for Mmap {
45 type Target = [u8];
46
47 #[inline]
48 fn deref(&self) -> &[u8] {
49 &self.0
50 }
51}
52
53impl AsRef<[u8]> for Mmap {
54 fn as_ref(&self) -> &[u8] {
55 &self.0
56 }
57}
58
59#[cfg(not(any(miri, target_arch = "wasm32")))]
60pub struct MmapMut(memmap2::MmapMut);
61
62#[cfg(any(miri, target_arch = "wasm32"))]
63pub struct MmapMut(Vec<u8>);
64
65#[cfg(not(any(miri, target_arch = "wasm32")))]
66impl MmapMut {
67 #[inline]
68 pub fn map_anon(len: usize) -> io::Result<Self> {
69 let mmap = memmap2::MmapMut::map_anon(len)?;
70 Ok(MmapMut(mmap))
71 }
72
73 #[inline]
74 pub fn flush(&mut self) -> io::Result<()> {
75 self.0.flush()
76 }
77
78 #[inline]
79 pub fn make_read_only(self) -> std::io::Result<Mmap> {
80 let mmap = self.0.make_read_only()?;
81 Ok(Mmap(mmap))
82 }
83}
84
85#[cfg(any(miri, target_arch = "wasm32"))]
86impl MmapMut {
87 #[inline]
88 pub fn map_anon(len: usize) -> io::Result<Self> {
89 let data = Vec::with_capacity(len);
90 Ok(MmapMut(data))
91 }
92
93 #[inline]
94 pub fn flush(&mut self) -> io::Result<()> {
95 Ok(())
96 }
97
98 #[inline]
99 pub fn make_read_only(self) -> std::io::Result<Mmap> {
100 Ok(Mmap(self.0))
101 }
102}
103
104impl Deref for MmapMut {
105 type Target = [u8];
106
107 #[inline]
108 fn deref(&self) -> &[u8] {
109 &self.0
110 }
111}
112
113impl DerefMut for MmapMut {
114 #[inline]
115 fn deref_mut(&mut self) -> &mut [u8] {
116 &mut self.0
117 }
118}