1use crate::util::constants::*;
2use crate::util::heap::layout::vm_layout::*;
3use crate::util::linear_scan::Region;
4use crate::util::metadata::side_metadata::layout::{
5 GLOBAL_SIDE_METADATA_BASE_OFFSET, LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
6};
7use crate::util::metadata::side_metadata::side_metadata_offset_after;
8use crate::util::metadata::side_metadata::SideMetadataSpec;
9
10macro_rules! define_side_metadata_specs {
15 (@first_spec $base_offset: expr, $name: ident = (global: $is_global: expr, log_num_of_bits: $log_num_of_bits: expr, log_bytes_in_region: $log_bytes_in_region: expr)) => {
19 pub const $name: SideMetadataSpec = SideMetadataSpec {
20 name: stringify!($name),
21 is_global: $is_global,
22 offset: $base_offset,
23 log_num_of_bits: $log_num_of_bits,
24 log_bytes_in_region: $log_bytes_in_region,
25 };
26 };
27 (@prev_spec $last_spec: ident as $last_spec_ident: ident, $name: ident = (global: $is_global: expr, log_num_of_bits: $log_num_of_bits: expr, log_bytes_in_region: $log_bytes_in_region: expr), $($tail:tt)*) => {
29 pub const $name: SideMetadataSpec = SideMetadataSpec {
30 name: stringify!($name),
31 is_global: $is_global,
32 offset: side_metadata_offset_after(&$last_spec),
33 log_num_of_bits: $log_num_of_bits,
34 log_bytes_in_region: $log_bytes_in_region,
35 };
36 define_side_metadata_specs!(@prev_spec $name as $last_spec_ident, $($tail)*);
37 };
38 (@prev_spec $last_spec: ident as $last_spec_ident: ident,) => {
40 pub const $last_spec_ident: SideMetadataSpec = $last_spec;
41 };
42
43 (base_offset $base_offset: expr, last_spec_as $last_spec_ident: ident, $name0: ident = (global: $is_global0: expr, log_num_of_bits: $log_num_of_bits0: expr, log_bytes_in_region: $log_bytes_in_region0: expr), $($tail:tt)*) => {
47 define_side_metadata_specs!(@first_spec $base_offset, $name0 = (global: $is_global0, log_num_of_bits: $log_num_of_bits0, log_bytes_in_region: $log_bytes_in_region0));
49 define_side_metadata_specs!(@prev_spec $name0 as $last_spec_ident, $($tail)*);
51 };
52}
53
54define_side_metadata_specs!(
56 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
57 last_spec_as LAST_GLOBAL_SIDE_METADATA_SPEC,
58 VO_BIT = (global: true, log_num_of_bits: 0, log_bytes_in_region: LOG_MIN_OBJECT_SIZE as usize),
60 SFT_DENSE_CHUNK_MAP_INDEX = (global: true, log_num_of_bits: 3, log_bytes_in_region: LOG_BYTES_IN_CHUNK),
62 RC_TABLE = (global: true, log_num_of_bits: crate::util::rc::LOG_REF_COUNT_BITS, log_bytes_in_region: crate::util::rc::LOG_MIN_OBJECT_SIZE),
64 CHUNK_MARK = (global: true, log_num_of_bits: 3, log_bytes_in_region: crate::util::heap::chunk_map::Chunk::LOG_BYTES),
66);
67
68define_side_metadata_specs!(
70 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
71 last_spec_as LAST_LOCAL_SIDE_METADATA_SPEC,
72 MALLOC_MS_ACTIVE_PAGE = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::util::malloc::library::LOG_BYTES_IN_MALLOC_PAGE as usize),
74 MS_OFFSET_MALLOC = (global: false, log_num_of_bits: 0, log_bytes_in_region: LOG_MIN_OBJECT_SIZE as usize),
76 IX_LINE_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::line::Line::LOG_BYTES),
78 IX_BLOCK_DEFRAG = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
80 IX_BLOCK_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
82 RC_STRADDLE_LINES = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::line::Line::LOG_BYTES),
84 IX_BLOCK_LOG = (global: false, log_num_of_bits: 0, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
86 NURSERY_PROMOTION_STATE = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
87 PHASE_EPOCH = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
88 IX_LINE_REUSE_COUNT = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::line::Line::LOG_BYTES),
89 LOS_PAGE_REUSE_COUNT = (global: false, log_num_of_bits: 3, log_bytes_in_region: LOG_BYTES_IN_PAGE as usize),
90 MS_BLOCK_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
92 MS_BLOCK_NEXT = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
94 MS_BLOCK_PREV = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
96 MS_BLOCK_LIST = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
98 MS_BLOCK_SIZE = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
100 MS_BLOCK_TLS = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
102 MS_FREE = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
104 MS_LOCAL_FREE = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
107 MS_THREAD_FREE = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
109 OVC_MARK = (global: false, log_num_of_bits: 0, log_bytes_in_region: LOG_BYTES_IN_WORD as usize),
111 OVC_OFFSET_VECTOR = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::ovc::forwarding::Block::LOG_BYTES),
113);
114
115#[cfg(test)]
116mod tests {
117 #![allow(clippy::assertions_on_constants)]
119
120 use super::*;
121 #[test]
122 fn first_global_spec() {
123 define_side_metadata_specs!(
124 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
125 last_spec_as LAST_GLOBAL_SPEC,
126 TEST_SPEC = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
127 );
128 assert!(TEST_SPEC.is_global);
129 assert!(TEST_SPEC.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
130 assert_eq!(TEST_SPEC.log_num_of_bits, 0);
131 assert_eq!(TEST_SPEC.log_bytes_in_region, 3);
132 assert_eq!(TEST_SPEC, LAST_GLOBAL_SPEC);
133 }
134
135 #[test]
136 fn first_local_spec() {
137 define_side_metadata_specs!(
138 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
139 last_spec_as LAST_LOCAL_SPEC,
140 TEST_SPEC = (global: false, log_num_of_bits: 0, log_bytes_in_region: 3),
141 );
142 assert!(!TEST_SPEC.is_global);
143 assert!(TEST_SPEC.offset == LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT);
144 assert_eq!(TEST_SPEC.log_num_of_bits, 0);
145 assert_eq!(TEST_SPEC.log_bytes_in_region, 3);
146 assert_eq!(TEST_SPEC, LAST_LOCAL_SPEC);
147 }
148
149 #[test]
150 fn two_global_specs() {
151 define_side_metadata_specs!(
152 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
153 last_spec_as LAST_GLOBAL_SPEC,
154 TEST_SPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
155 TEST_SPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
156 );
157
158 assert!(TEST_SPEC1.is_global);
159 assert!(TEST_SPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
160 assert_eq!(TEST_SPEC1.log_num_of_bits, 0);
161 assert_eq!(TEST_SPEC1.log_bytes_in_region, 3);
162
163 assert!(TEST_SPEC2.is_global);
164 assert!(TEST_SPEC2.offset == side_metadata_offset_after(&TEST_SPEC1));
165 assert_eq!(TEST_SPEC2.log_num_of_bits, 1);
166 assert_eq!(TEST_SPEC2.log_bytes_in_region, 4);
167
168 assert_eq!(TEST_SPEC2, LAST_GLOBAL_SPEC);
169 }
170
171 #[test]
172 fn three_global_specs() {
173 define_side_metadata_specs!(
174 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
175 last_spec_as LAST_GLOBAL_SPEC,
176 TEST_SPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
177 TEST_SPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
178 TEST_SPEC3 = (global: true, log_num_of_bits: 2, log_bytes_in_region: 5),
179 );
180
181 assert!(TEST_SPEC1.is_global);
182 assert!(TEST_SPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
183 assert_eq!(TEST_SPEC1.log_num_of_bits, 0);
184 assert_eq!(TEST_SPEC1.log_bytes_in_region, 3);
185
186 assert!(TEST_SPEC2.is_global);
187 assert!(TEST_SPEC2.offset == side_metadata_offset_after(&TEST_SPEC1));
188 assert_eq!(TEST_SPEC2.log_num_of_bits, 1);
189 assert_eq!(TEST_SPEC2.log_bytes_in_region, 4);
190
191 assert!(TEST_SPEC3.is_global);
192 assert!(TEST_SPEC3.offset == side_metadata_offset_after(&TEST_SPEC2));
193 assert_eq!(TEST_SPEC3.log_num_of_bits, 2);
194 assert_eq!(TEST_SPEC3.log_bytes_in_region, 5);
195
196 assert_eq!(TEST_SPEC3, LAST_GLOBAL_SPEC);
197 }
198
199 #[test]
200 fn both_global_and_local() {
201 define_side_metadata_specs!(
202 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
203 last_spec_as LAST_GLOBAL_SPEC,
204 TEST_GSPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
205 TEST_GSPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
206 );
207 define_side_metadata_specs!(
208 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
209 last_spec_as LAST_LOCAL_SPEC,
210 TEST_LSPEC1 = (global: false, log_num_of_bits: 2, log_bytes_in_region: 5),
211 TEST_LSPEC2 = (global: false, log_num_of_bits: 3, log_bytes_in_region: 6),
212 );
213
214 assert!(TEST_GSPEC1.is_global);
215 assert!(TEST_GSPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
216 assert_eq!(TEST_GSPEC1.log_num_of_bits, 0);
217 assert_eq!(TEST_GSPEC1.log_bytes_in_region, 3);
218
219 assert!(TEST_GSPEC2.is_global);
220 assert!(TEST_GSPEC2.offset == side_metadata_offset_after(&TEST_GSPEC1));
221 assert_eq!(TEST_GSPEC2.log_num_of_bits, 1);
222 assert_eq!(TEST_GSPEC2.log_bytes_in_region, 4);
223
224 assert_eq!(TEST_GSPEC2, LAST_GLOBAL_SPEC);
225
226 assert!(!TEST_LSPEC1.is_global);
227 assert!(TEST_LSPEC1.offset == LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT);
228 assert_eq!(TEST_LSPEC1.log_num_of_bits, 2);
229 assert_eq!(TEST_LSPEC1.log_bytes_in_region, 5);
230
231 assert!(!TEST_LSPEC2.is_global);
232 assert!(TEST_LSPEC2.offset == side_metadata_offset_after(&TEST_LSPEC1));
233 assert_eq!(TEST_LSPEC2.log_num_of_bits, 3);
234 assert_eq!(TEST_LSPEC2.log_bytes_in_region, 6);
235
236 assert_eq!(TEST_LSPEC2, LAST_LOCAL_SPEC);
237 }
238}