0

Is there any way to find the current amount of stack and heap usage in a solana program? I'm hitting stack AND heap limitations :(

2

1 Answer 1

2

If you are running out of heap you can use a custom allocator, here is one similar to the Solana implementation:

pub struct BumpAllocator {
    pub start: usize,
    pub len: usize,
}

impl BumpAllocator {
    const RESERVED_MEM: usize = 1 * size_of::<*mut u8>();

    /// Return heap position as of this call
    pub unsafe fn pos(&self) -> usize {
        let pos_ptr = self.start as *mut usize;
        *pos_ptr
    }

    /// Reset heap start cursor to position. 
    /// ### This is very unsafe, use wisely
    pub unsafe fn move_cursor(&self, pos: usize) {
        let pos_ptr = self.start as *mut usize;
        *pos_ptr = pos;
    }
}
unsafe impl std::alloc::GlobalAlloc for BumpAllocator {
    #[inline]
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let pos_ptr = self.start as *mut usize;

        let mut pos = *pos_ptr;
        if pos == 0 {
            // First time, set starting position
            pos = self.start + self.len;
        }
        pos = pos.saturating_sub(layout.size());
        pos &= !(layout.align().wrapping_sub(1));
        if pos < self.start + BumpAllocator::RESERVED_MEM {
            return null_mut();
        }
        *pos_ptr = pos;
        pos as *mut u8
    }
    #[inline]
    unsafe fn dealloc(&self, _: *mut u8, _: Layout) { 
        // no dellaoc in Solana runtime :*(
    }
}

#[global_allocator]
static A: BumpAllocator = BumpAllocator {
    start: HEAP_START_ADDRESS as usize,
    len: HEAP_LENGTH,
};

Now you can read the heap's pointer to see what byte you are at, or to reset the heap pointer back to an earlier point:

        let heap_start = unsafe { A.pos() };
        msg!("heap ptr: {:?}", heap_start);
        some_big_heap_function();
        unsafe { A.move_cursor(heap_start); }
1
  • thanks, i think this works for me
    – Ripleys 0x
    Commented Sep 27, 2023 at 6:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.