mmtk/util/heap/layout/mmapper/mod.rs
1use crate::util::{os::*, Address};
2
3#[allow(unused)] // Used in doc comment.
4use crate::util::constants::LOG_BYTES_IN_PAGE;
5
6pub mod csm;
7
8/// An `Mmapper` manages the mmap state of memory used by the heap and side metadata of MMTk.
9///
10/// For the efficiency of implementation, an `Mmapper` operates at the granularity of
11/// [`Mmapper::granularity()`]. Methods that take memory ranges as arguments will round the range
12/// to the overlapping chunks.
13///
14/// From the perspective of the `Mmapper`, each memory range can be in one of the three states:
15/// Unmapped, Quarantined, and Mapped. The state transition graph is:
16///
17/// ```text
18/// ┌────────┐ ensure_mapped / mark_as_mapped ┌──────┐
19/// │Unmapped├────────────────────────────────────►Mapped│
20/// └───┬────┘ └───▲──┘
21/// │ ┌───────────┐ │
22/// └───────────────►Quarantined├─────────────────┘
23/// quarantine └───────────┘ ensure_mapped
24/// ```
25///
26/// - **Unmapped** means the memory is not mapped by the `Mmapper`, and may be mapped by other
27/// components of the process.
28/// - **Quarantined** means the `Mmapper` has reserved the memory for MMTk, usually by using
29/// `mmap` with `PROT_NONE`.
30/// - **Mapped** means `Mmapper` has mapped the memory, and the memory can be read and written by
31/// MMTk.
32pub trait Mmapper: Sync {
33 /// The logarithm of granularity of this `Mmapper`, in bytes. Must be at least
34 /// [`LOG_BYTES_IN_PAGE`].
35 ///
36 /// See trait-level doc for [`Mmapper`] for details.
37 fn log_granularity(&self) -> u8;
38
39 /// The logarithm of the address space size this `Mmapper` can handle.
40 ///
41 /// In other words, this `Mmapper` cannot handle addresses greater than or equal to
42 /// `1 << self.log_mappable_bytes()`.
43 fn log_mappable_bytes(&self) -> u8;
44
45 /// The granularity of `Mmapper`. Don't override this method. Override
46 /// [`Mmapper::log_granularity`] instead.
47 ///
48 /// See trait-level doc for [`Mmapper`] for details.
49 fn granularity(&self) -> usize {
50 1 << self.log_granularity()
51 }
52
53 /// Mark a number of pages as mapped, without making any
54 /// request to the operating system. Used to mark pages
55 /// that the VM has already mapped.
56 ///
57 /// Arguments:
58 /// * `start`: Address of the first page to be mapped
59 /// * `bytes`: Number of bytes to ensure mapped
60 fn mark_as_mapped(&self, start: Address, bytes: usize);
61
62 /// Quarantine/reserve address range. We mmap from the OS with no reserve and with PROT_NONE,
63 /// which should be little overhead. This ensures that we can reserve certain address range that
64 /// we can use if needed. Quarantined memory needs to be mapped before it can be used.
65 ///
66 /// Arguments:
67 /// * `start`: Address of the first page to be quarantined
68 /// * `pages`: Number of pages to quarantine from the start
69 /// * `strategy`: The mmap strategy. The `prot` field is ignored because we always use
70 /// `PROT_NONE`.
71 /// * `anno`: Human-readable annotation to apply to newly mapped memory ranges.
72 fn quarantine_address_range(
73 &self,
74 start: Address,
75 pages: usize,
76 huge_page_option: HugePageSupport,
77 anno: &MmapAnnotation,
78 ) -> MmapResult<()>;
79
80 /// Ensure that a range of pages is mmapped (or equivalent). If the
81 /// pages are not yet mapped, demand-zero map them. Note that mapping
82 /// occurs at chunk granularity, not page granularity.
83 ///
84 /// Arguments:
85 /// * `start`: The start of the range to be mapped.
86 /// * `pages`: The size of the range to be mapped, in pages
87 /// * `strategy`: The mmap strategy.
88 /// * `anno`: Human-readable annotation to apply to newly mapped memory ranges.
89 // NOTE: There is a monotonicity assumption so that only updates require lock
90 // acquisition.
91 // TODO: Fix the above to support unmapping.
92 fn ensure_mapped(
93 &self,
94 start: Address,
95 pages: usize,
96 huge_page_option: HugePageSupport,
97 prot: MmapProtection,
98 anno: &MmapAnnotation,
99 ) -> MmapResult<()>;
100
101 /// Is the page pointed to by this address mapped? Returns true if
102 /// the page at the given address is mapped.
103 ///
104 /// Arguments:
105 /// * `addr`: Address in question
106 fn is_mapped_address(&self, addr: Address) -> bool;
107}