1use self::page_resource::PageResource;
2use crate::util::*;
3use std::ops::Range;
4pub mod freelist_space;
5pub mod immortal_space;
6pub mod large_object_space;
7pub mod meta;
8pub mod page_resource;
9pub(crate) mod page_table;
10use std::marker::ConstParamTy;
11
12#[repr(transparent)]
13#[derive(Debug, Clone, Copy, PartialEq, Eq, ConstParamTy)]
14pub struct SpaceId(pub(crate) u8);
15
16impl SpaceId {
17 pub const LOG_MAX_SPACE_SIZE: usize = 41;
18 pub(crate) const SHIFT: usize = Self::LOG_MAX_SPACE_SIZE;
19 pub(crate) const MASK: usize = 0b1111 << Self::SHIFT;
20
21 pub const DEFAULT: Self = Self(1);
22 pub const LARGE_OBJECT_SPACE: Self = Self::DEFAULT.next();
23
24 pub const fn next(&self) -> Self {
25 debug_assert!(self.0 != 0b1111);
26 let new_id = self.0 + 1;
27 if new_id == 15 {
28 Self(new_id + 1)
29 } else {
30 Self(new_id)
31 }
32 }
33
34 pub fn from(addr: Address) -> Self {
35 let id = (usize::from(addr) & Self::MASK) >> Self::SHIFT;
36 Self(id as u8)
37 }
38
39 pub fn contains(&self, addr: Address) -> bool {
40 Self::from(addr).0 == self.0
41 }
42}
43
44pub trait Space: Sized + 'static {
45 const MAX_ALLOCATION_SIZE: usize = usize::MAX;
46 type PR: PageResource;
47
48 fn new(id: SpaceId) -> Self;
49 fn id(&self) -> SpaceId;
50 fn page_resource(&self) -> &Self::PR;
51
52 fn get_layout(ptr: Address) -> Layout;
53
54 fn contains(&self, address: Address) -> bool {
55 SpaceId::from(address) == self.id()
56 }
57
58 fn reserved_bytes(&self) -> usize {
59 self.page_resource().reserved_bytes()
60 }
61
62 fn acquire<S: PageSize>(&self, pages: usize) -> Option<Range<Page<S>>> {
63 self.page_resource().acquire_pages(pages)
64 }
65
66 fn release<S: PageSize>(&self, start: Page<S>) {
67 self.page_resource().release_pages(start)
68 }
69}
70
71pub trait Allocator {
72 fn alloc(&mut self, layout: Layout) -> Option<Address>;
73
74 fn dealloc(&mut self, ptr: Address);
75
76 }