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 CHUNK_MARK = (global: true, log_num_of_bits: 3, log_bytes_in_region: crate::util::heap::chunk_map::Chunk::LOG_BYTES),
64);
65
66define_side_metadata_specs!(
68 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
69 last_spec_as LAST_LOCAL_SIDE_METADATA_SPEC,
70 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),
72 MS_OFFSET_MALLOC = (global: false, log_num_of_bits: 0, log_bytes_in_region: LOG_MIN_OBJECT_SIZE as usize),
74 IX_LINE_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::line::Line::LOG_BYTES),
76 IX_BLOCK_DEFRAG = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
78 IX_BLOCK_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::immix::block::Block::LOG_BYTES),
80 MS_BLOCK_MARK = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
82 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),
84 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),
86 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),
88 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),
90 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),
92 MS_FREE = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::marksweepspace::native_ms::Block::LOG_BYTES),
94 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),
97 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),
99 COMPRESSOR_MARK = (global: false, log_num_of_bits: 0, log_bytes_in_region: LOG_BYTES_IN_WORD as usize),
101 COMPRESSOR_OFFSET_VECTOR = (global: false, log_num_of_bits: LOG_BITS_IN_ADDRESS, log_bytes_in_region: crate::policy::compressor::forwarding::Block::LOG_BYTES),
103);
104
105#[cfg(test)]
106mod tests {
107 #![allow(clippy::assertions_on_constants)]
109
110 use super::*;
111 #[test]
112 fn first_global_spec() {
113 define_side_metadata_specs!(
114 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
115 last_spec_as LAST_GLOBAL_SPEC,
116 TEST_SPEC = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
117 );
118 assert!(TEST_SPEC.is_global);
119 assert!(TEST_SPEC.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
120 assert_eq!(TEST_SPEC.log_num_of_bits, 0);
121 assert_eq!(TEST_SPEC.log_bytes_in_region, 3);
122 assert_eq!(TEST_SPEC, LAST_GLOBAL_SPEC);
123 }
124
125 #[test]
126 fn first_local_spec() {
127 define_side_metadata_specs!(
128 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
129 last_spec_as LAST_LOCAL_SPEC,
130 TEST_SPEC = (global: false, log_num_of_bits: 0, log_bytes_in_region: 3),
131 );
132 assert!(!TEST_SPEC.is_global);
133 assert!(TEST_SPEC.offset == LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT);
134 assert_eq!(TEST_SPEC.log_num_of_bits, 0);
135 assert_eq!(TEST_SPEC.log_bytes_in_region, 3);
136 assert_eq!(TEST_SPEC, LAST_LOCAL_SPEC);
137 }
138
139 #[test]
140 fn two_global_specs() {
141 define_side_metadata_specs!(
142 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
143 last_spec_as LAST_GLOBAL_SPEC,
144 TEST_SPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
145 TEST_SPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
146 );
147
148 assert!(TEST_SPEC1.is_global);
149 assert!(TEST_SPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
150 assert_eq!(TEST_SPEC1.log_num_of_bits, 0);
151 assert_eq!(TEST_SPEC1.log_bytes_in_region, 3);
152
153 assert!(TEST_SPEC2.is_global);
154 assert!(TEST_SPEC2.offset == side_metadata_offset_after(&TEST_SPEC1));
155 assert_eq!(TEST_SPEC2.log_num_of_bits, 1);
156 assert_eq!(TEST_SPEC2.log_bytes_in_region, 4);
157
158 assert_eq!(TEST_SPEC2, LAST_GLOBAL_SPEC);
159 }
160
161 #[test]
162 fn three_global_specs() {
163 define_side_metadata_specs!(
164 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
165 last_spec_as LAST_GLOBAL_SPEC,
166 TEST_SPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
167 TEST_SPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
168 TEST_SPEC3 = (global: true, log_num_of_bits: 2, log_bytes_in_region: 5),
169 );
170
171 assert!(TEST_SPEC1.is_global);
172 assert!(TEST_SPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
173 assert_eq!(TEST_SPEC1.log_num_of_bits, 0);
174 assert_eq!(TEST_SPEC1.log_bytes_in_region, 3);
175
176 assert!(TEST_SPEC2.is_global);
177 assert!(TEST_SPEC2.offset == side_metadata_offset_after(&TEST_SPEC1));
178 assert_eq!(TEST_SPEC2.log_num_of_bits, 1);
179 assert_eq!(TEST_SPEC2.log_bytes_in_region, 4);
180
181 assert!(TEST_SPEC3.is_global);
182 assert!(TEST_SPEC3.offset == side_metadata_offset_after(&TEST_SPEC2));
183 assert_eq!(TEST_SPEC3.log_num_of_bits, 2);
184 assert_eq!(TEST_SPEC3.log_bytes_in_region, 5);
185
186 assert_eq!(TEST_SPEC3, LAST_GLOBAL_SPEC);
187 }
188
189 #[test]
190 fn both_global_and_local() {
191 define_side_metadata_specs!(
192 base_offset GLOBAL_SIDE_METADATA_BASE_OFFSET,
193 last_spec_as LAST_GLOBAL_SPEC,
194 TEST_GSPEC1 = (global: true, log_num_of_bits: 0, log_bytes_in_region: 3),
195 TEST_GSPEC2 = (global: true, log_num_of_bits: 1, log_bytes_in_region: 4),
196 );
197 define_side_metadata_specs!(
198 base_offset LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT,
199 last_spec_as LAST_LOCAL_SPEC,
200 TEST_LSPEC1 = (global: false, log_num_of_bits: 2, log_bytes_in_region: 5),
201 TEST_LSPEC2 = (global: false, log_num_of_bits: 3, log_bytes_in_region: 6),
202 );
203
204 assert!(TEST_GSPEC1.is_global);
205 assert!(TEST_GSPEC1.offset == GLOBAL_SIDE_METADATA_BASE_OFFSET);
206 assert_eq!(TEST_GSPEC1.log_num_of_bits, 0);
207 assert_eq!(TEST_GSPEC1.log_bytes_in_region, 3);
208
209 assert!(TEST_GSPEC2.is_global);
210 assert!(TEST_GSPEC2.offset == side_metadata_offset_after(&TEST_GSPEC1));
211 assert_eq!(TEST_GSPEC2.log_num_of_bits, 1);
212 assert_eq!(TEST_GSPEC2.log_bytes_in_region, 4);
213
214 assert_eq!(TEST_GSPEC2, LAST_GLOBAL_SPEC);
215
216 assert!(!TEST_LSPEC1.is_global);
217 assert!(TEST_LSPEC1.offset == LOCAL_SIDE_METADATA_BASE_OFFSET_FOR_LAYOUT);
218 assert_eq!(TEST_LSPEC1.log_num_of_bits, 2);
219 assert_eq!(TEST_LSPEC1.log_bytes_in_region, 5);
220
221 assert!(!TEST_LSPEC2.is_global);
222 assert!(TEST_LSPEC2.offset == side_metadata_offset_after(&TEST_LSPEC1));
223 assert_eq!(TEST_LSPEC2.log_num_of_bits, 3);
224 assert_eq!(TEST_LSPEC2.log_bytes_in_region, 6);
225
226 assert_eq!(TEST_LSPEC2, LAST_LOCAL_SPEC);
227 }
228}