jit_allocator/
util.rs

1use core::mem::size_of;
2
3pub fn align_down(x: usize, alignment: usize) -> usize {
4    x & !(alignment - 1)
5}
6
7pub fn align_up(x: usize, alignment: usize) -> usize {
8    x.wrapping_add(alignment.wrapping_sub(1)) & !(alignment - 1)
9}
10
11pub fn bit_vector_get_bit(buf: &[u32], index: usize) -> bool {
12    let vec_index = index / 32;
13    let bit_index = index % 32;
14
15    ((buf[vec_index] >> bit_index) & 1) != 0
16}
17
18pub fn bit_vector_set_bit(buf: &mut [u32], index: usize, value: bool) {
19    let vec_index = index / 32;
20    let bit_index = index % 32;
21
22    if value {
23        buf[vec_index] |= 1 << bit_index;
24    } else {
25        buf[vec_index] &= !(1 << bit_index);
26    }
27}
28
29pub fn bit_vector_flip_bit(buf: &mut [u32], index: usize) {
30    let vec_index = index / 32;
31    let bit_index = index % 32;
32
33    buf[vec_index] ^= 1 << bit_index;
34}
35
36macro_rules! bitvector_op {
37    ($name: ident, $op: expr, $opf: expr) => {
38        pub fn $name(mut buf: &mut [u32], index: usize, mut count: usize) {
39            if count == 0 {
40                return;
41            }
42
43            let vec_index = index / 32;
44            let bit_index = index % 32;
45
46            buf = &mut buf[vec_index..];
47
48            const FILL_MASK: u32 = u32::MAX;
49
50            let first_n_bits = (32usize.wrapping_sub(bit_index)).min(count);
51
52            buf[0] = $op(
53                buf[0],
54                (FILL_MASK >> (32 - first_n_bits as u32)) << bit_index as u32,
55            );
56
57            buf = &mut buf[1..];
58
59            count -= first_n_bits;
60
61            while count >= 32 {
62                buf[0] = $opf(buf[0], FILL_MASK);
63                buf = &mut buf[1..];
64                count -= 32;
65            }
66
67            if count != 0 {
68                buf[0] = $op(buf[0], FILL_MASK >> (32 - count as u32));
69            }
70        }
71    };
72}
73
74bitvector_op!(bit_vector_fill, |x, y| x | y, |_, x| x);
75bitvector_op!(bit_vector_clear, |x: u32, y: u32| x & !y, |_, y: u32| !y);
76
77pub fn bit_vector_index_of(buf: &[u32], start: usize, value: bool) -> usize {
78    let vec_index = start / 32;
79    let bit_index = start % 32;
80
81    let mut p = &buf[vec_index..];
82    const FILL_MASK: u32 = u32::MAX;
83
84    let flip_mask = if value { 0 } else { FILL_MASK };
85
86    let mut bits = (p[0] ^ flip_mask) & (FILL_MASK << bit_index as u32);
87
88    loop {
89        if bits != 0 {
90            return ((p.as_ptr() as usize - buf.as_ptr() as usize) / size_of::<u32>()) * 32
91                + bits.trailing_zeros() as usize;
92        }
93
94        p = &p[1..];
95
96        if p.is_empty() {
97            return buf.len() * 32;
98        }
99
100        bits = p[0] ^ flip_mask;
101    }
102}