mmtk/util/heap/layout/mmapper/
mod.rs

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