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    /// * `huge_page_support`: The huge page support option to use when quarantining the address range.
70    /// * `anno`: Human-readable annotation to apply to newly mapped memory ranges.
71    fn quarantine_address_range(
72        &self,
73        start: Address,
74        pages: usize,
75        huge_page_option: HugePageSupport,
76        anno: &MmapAnnotation,
77    ) -> MmapResult<()>;
78
79    /// Quarantine/reserve address range at any available address and return the base address.
80    /// The returned address is aligned to the mmapper's granularity.
81    ///
82    /// Arguments:
83    /// * `pages`: Number of pages to quarantine
84    /// * `huge_page_support`: The huge page support option to use when quarantining the address range.
85    /// * `anno`: Human-readable annotation to apply to newly mapped memory ranges.
86    fn quarantine_address_range_anywhere(
87        &self,
88        pages: usize,
89        huge_page_option: HugePageSupport,
90        anno: &MmapAnnotation,
91    ) -> std::io::Result<Address>;
92
93    /// Ensure that a range of pages is mmapped (or equivalent).  If the
94    /// pages are not yet mapped, demand-zero map them. Note that mapping
95    /// occurs at chunk granularity, not page granularity.
96    ///
97    /// Arguments:
98    /// * `start`: The start of the range to be mapped.
99    /// * `pages`: The size of the range to be mapped, in pages
100    /// * `strategy`: The mmap strategy.
101    /// * `anno`: Human-readable annotation to apply to newly mapped memory ranges.
102    // NOTE: There is a monotonicity assumption so that only updates require lock
103    // acquisition.
104    // TODO: Fix the above to support unmapping.
105    fn ensure_mapped(
106        &self,
107        start: Address,
108        pages: usize,
109        huge_page_option: HugePageSupport,
110        prot: MmapProtection,
111        anno: &MmapAnnotation,
112    ) -> MmapResult<()>;
113
114    /// Is the page pointed to by this address mapped? Returns true if
115    /// the page at the given address is mapped.
116    ///
117    /// Arguments:
118    /// * `addr`: Address in question
119    fn is_mapped_address(&self, addr: Address) -> bool;
120}