Skip to content

Commit

Permalink
Don't grow memory on first allocation (#1712)
Browse files Browse the repository at this point in the history
* Don't always request a new page

* Fix some spacing nits

* fmt

---------

Co-authored-by: Andrew Jones <[email protected]>
Co-authored-by: Hernando Castano <[email protected]>
  • Loading branch information
3 people authored Aug 6, 2023
1 parent 3d6784c commit c2af398
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions crates/allocator/src/bump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,22 @@ use core::alloc::{
/// A page in Wasm is `64KiB`
const PAGE_SIZE: usize = 64 * 1024;

static mut INNER: InnerAlloc = InnerAlloc::new();
static mut INNER: Option<InnerAlloc> = None;

/// A bump allocator suitable for use in a Wasm environment.
pub struct BumpAllocator;

unsafe impl GlobalAlloc for BumpAllocator {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
match INNER.alloc(layout) {
if INNER.is_none() {
INNER = Some(InnerAlloc::new());
};
match INNER
.as_mut()
.expect("We just set the value above; qed")
.alloc(layout)
{
Some(start) => start as *mut u8,
None => core::ptr::null_mut(),
}
Expand Down Expand Up @@ -66,7 +73,7 @@ struct InnerAlloc {
}

impl InnerAlloc {
const fn new() -> Self {
fn new() -> Self {
Self {
next: Self::heap_start(),
upper_limit: Self::heap_end(),
Expand All @@ -75,11 +82,11 @@ impl InnerAlloc {

cfg_if::cfg_if! {
if #[cfg(test)] {
const fn heap_start() -> usize {
fn heap_start() -> usize {
0
}

const fn heap_end() -> usize {
fn heap_end() -> usize {
0
}

Expand All @@ -93,11 +100,11 @@ impl InnerAlloc {
Some(self.upper_limit)
}
} else if #[cfg(feature = "std")] {
const fn heap_start() -> usize {
fn heap_start() -> usize {
0
}

const fn heap_end() -> usize {
fn heap_end() -> usize {
0
}

Expand All @@ -108,12 +115,24 @@ impl InnerAlloc {
)
}
} else if #[cfg(target_arch = "wasm32")] {
const fn heap_start() -> usize {
0
fn heap_start() -> usize {
extern "C" {
static __heap_base: usize;
}
// # SAFETY
//
// The `__heap_base` symbol is defined by the wasm linker and is guaranteed
// to point to the start of the heap.
let heap_start = unsafe { &__heap_base as *const usize as usize };
// if the symbol isn't found it will resolve to 0
// for that to happen the rust compiler or linker need to break or change
assert_ne!(heap_start, 0, "Can't find `__heap_base` symbol.");
heap_start
}

const fn heap_end() -> usize {
0
fn heap_end() -> usize {
// Cannot overflow on this architecture
core::arch::wasm32::memory_size(0) * PAGE_SIZE
}

/// Request a `pages` number of pages of Wasm memory. Each page is `64KiB` in size.
Expand All @@ -125,7 +144,8 @@ impl InnerAlloc {
return None;
}

prev_page.checked_mul(PAGE_SIZE)
// Cannot overflow on this architecture
Some(prev_page * PAGE_SIZE)
}
} else if #[cfg(target_arch = "riscv32")] {
const fn heap_start() -> usize {
Expand Down

0 comments on commit c2af398

Please sign in to comment.