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}