solana_bpf_loader_program/
allocator_bump.rs

1#![allow(clippy::integer_arithmetic)]
2
3use {
4    solana_program_runtime::invoke_context::{Alloc, AllocErr},
5    solana_rbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN},
6    std::alloc::Layout,
7};
8
9#[derive(Debug)]
10pub struct BpfAllocator {
11    #[allow(dead_code)]
12    heap: AlignedMemory<HOST_ALIGN>,
13    start: u64,
14    len: u64,
15    pos: u64,
16}
17
18impl BpfAllocator {
19    pub fn new(heap: AlignedMemory<HOST_ALIGN>, virtual_address: u64) -> Self {
20        let len = heap.len() as u64;
21        Self {
22            heap,
23            start: virtual_address,
24            len,
25            pos: 0,
26        }
27    }
28
29    pub fn get_heap(&mut self) -> &mut [u8] {
30        self.heap.as_slice_mut()
31    }
32}
33
34impl Alloc for BpfAllocator {
35    fn alloc(&mut self, layout: Layout) -> Result<u64, AllocErr> {
36        let bytes_to_align = (self.pos as *const u8).align_offset(layout.align()) as u64;
37        if self
38            .pos
39            .saturating_add(layout.size() as u64)
40            .saturating_add(bytes_to_align)
41            <= self.len
42        {
43            self.pos += bytes_to_align;
44            let addr = self.start + self.pos;
45            self.pos += layout.size() as u64;
46            Ok(addr)
47        } else {
48            Err(AllocErr)
49        }
50    }
51
52    fn dealloc(&mut self, _addr: u64, _layout: Layout) {
53        // It's a bump allocator, free not supported
54    }
55}