Skip to content

Commit 18efa58

Browse files
authored
Add manual heap space allocation (#126)
* Add manual heap space allocation * Remove initial offset
1 parent 673067b commit 18efa58

File tree

1 file changed

+35
-0
lines changed
  • sdk/pinocchio/src/entrypoint

1 file changed

+35
-0
lines changed

sdk/pinocchio/src/entrypoint/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,41 @@ macro_rules! no_allocator {
344344
#[cfg(target_os = "solana")]
345345
#[global_allocator]
346346
static A: $crate::entrypoint::NoAllocator = $crate::entrypoint::NoAllocator;
347+
348+
/// Allocates memory for the given type `T` at the specified offset in the
349+
/// heap reserved address space.
350+
///
351+
/// # Safety
352+
///
353+
/// It is the caller's responsibility to ensure that the offset does not
354+
/// overlap with previous allocations and that type `T` can hold the bit-pattern
355+
/// `0` as a valid value.
356+
///
357+
/// For types that cannot hold the bit-pattern `0` as a valid value, use
358+
/// `core::mem::MaybeUninit<T>` to allocate memory for the type and
359+
/// initialize it later.
360+
#[inline]
361+
pub const unsafe fn allocate_unchecked<T: Sized>(offset: usize) -> &'static mut T {
362+
unsafe {
363+
let start = $crate::entrypoint::HEAP_START_ADDRESS as usize + offset;
364+
let end = start + core::mem::size_of::<T>();
365+
366+
// Assert if the allocation does not exceed the heap size.
367+
assert!(
368+
end <= $crate::entrypoint::HEAP_START_ADDRESS as usize
369+
+ $crate::entrypoint::HEAP_LENGTH,
370+
"allocation exceeds heap size"
371+
);
372+
373+
// Assert if the pointer is aligned to `T`.
374+
assert!(
375+
start % core::mem::align_of::<T>() == 0,
376+
"offset is not aligned"
377+
);
378+
379+
&mut *(start as *mut T)
380+
}
381+
}
347382
};
348383
}
349384

0 commit comments

Comments
 (0)