mmtk/util/heap/
externalpageresource.rs

1use super::layout::VMMap;
2use super::pageresource::{PRAllocFail, PRAllocResult};
3use super::PageResource;
4use crate::util::address::Address;
5use crate::util::constants::BYTES_IN_PAGE;
6use crate::util::constants::LOG_BYTES_IN_PAGE;
7use crate::util::heap::pageresource::CommonPageResource;
8use crate::util::heap::space_descriptor::SpaceDescriptor;
9use crate::util::opaque_pointer::*;
10use crate::vm::VMBinding;
11
12use std::marker::PhantomData;
13use std::sync::{Mutex, MutexGuard};
14
15/// A special page resource that records some external pages that are not mmapped by us,
16/// but are used by our space (namely VM space). Unlike other page resources, we cannot
17/// allocate from this page resource.
18pub struct ExternalPageResource<VM: VMBinding> {
19    common: CommonPageResource,
20    ranges: Mutex<Vec<ExternalPages>>,
21    _p: PhantomData<VM>,
22}
23
24#[derive(Copy, Clone, Debug)]
25pub struct ExternalPages {
26    pub start: Address,
27    pub end: Address,
28}
29
30impl<VM: VMBinding> PageResource<VM> for ExternalPageResource<VM> {
31    fn common(&self) -> &CommonPageResource {
32        &self.common
33    }
34
35    fn common_mut(&mut self) -> &mut CommonPageResource {
36        &mut self.common
37    }
38
39    fn reserve_pages(&self, _pages: usize) -> usize {
40        unreachable!()
41    }
42    fn commit_pages(&self, _reserved_pages: usize, _actual_pages: usize, _tls: VMThread) {
43        unreachable!()
44    }
45
46    fn get_available_physical_pages(&self) -> usize {
47        0
48    }
49
50    fn alloc_pages(
51        &self,
52        _space_descriptor: SpaceDescriptor,
53        _reserved_pages: usize,
54        _required_pages: usize,
55        _tls: VMThread,
56    ) -> Result<PRAllocResult, PRAllocFail> {
57        panic!("Cannot allocate from ExternalPageResource")
58    }
59}
60
61impl<VM: VMBinding> ExternalPageResource<VM> {
62    pub fn new(vm_map: &'static dyn VMMap) -> Self {
63        Self {
64            common: CommonPageResource::new(false, false, vm_map),
65            ranges: Mutex::new(vec![]),
66            _p: PhantomData,
67        }
68    }
69
70    pub fn add_new_external_pages(&self, pages: ExternalPages) {
71        assert!(pages.start.is_aligned_to(BYTES_IN_PAGE));
72        assert!(pages.end.is_aligned_to(BYTES_IN_PAGE));
73
74        let mut lock = self.ranges.lock().unwrap();
75        let n_pages = (pages.end - pages.start) >> LOG_BYTES_IN_PAGE;
76        self.common.accounting.reserve_and_commit(n_pages);
77        lock.push(pages);
78    }
79
80    pub fn get_external_pages(&self) -> MutexGuard<'_, Vec<ExternalPages>> {
81        self.ranges.lock().unwrap()
82    }
83}