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

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