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}