diff options
Diffstat (limited to 'src/liballoc_system')
| -rw-r--r-- | src/liballoc_system/Cargo.toml | 4 | ||||
| -rw-r--r-- | src/liballoc_system/lib.rs | 90 |
2 files changed, 94 insertions, 0 deletions
diff --git a/src/liballoc_system/Cargo.toml b/src/liballoc_system/Cargo.toml index a725a8608be..f9a57f7d97a 100644 --- a/src/liballoc_system/Cargo.toml +++ b/src/liballoc_system/Cargo.toml @@ -13,3 +13,7 @@ doc = false alloc = { path = "../liballoc" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } + +# See comments in the source for what this dependency is +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] +dlmalloc = { path = "../rustc/dlmalloc_shim" } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 7aa5f8a9186..05cacf6e881 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -34,12 +34,14 @@ target_arch = "powerpc64", target_arch = "asmjs", target_arch = "wasm32")))] +#[allow(dead_code)] const MIN_ALIGN: usize = 8; #[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "mips64", target_arch = "s390x", target_arch = "sparc64")))] +#[allow(dead_code)] const MIN_ALIGN: usize = 16; extern crate alloc; @@ -458,3 +460,91 @@ mod platform { } } } + +// This is an implementation of a global allocator on the wasm32 platform when +// emscripten is not in use. In that situation there's no actual runtime for us +// to lean on for allocation, so instead we provide our own! +// +// The wasm32 instruction set has two instructions for getting the current +// amount of memory and growing the amount of memory. These instructions are the +// foundation on which we're able to build an allocator, so we do so! Note that +// the instructions are also pretty "global" and this is the "global" allocator +// after all! +// +// The current allocator here is the `dlmalloc` crate which we've got included +// in the rust-lang/rust repository as a submodule. The crate is a port of +// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust" +// for now which is currently technically required (can't link with C yet). +// +// The crate itself provides a global allocator which on wasm has no +// synchronization as there are no threads! +#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] +mod platform { + extern crate dlmalloc; + + use alloc::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace}; + use System; + use self::dlmalloc::GlobalDlmalloc; + + #[unstable(feature = "allocator_api", issue = "32838")] + unsafe impl<'a> Alloc for &'a System { + #[inline] + unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { + GlobalDlmalloc.alloc(layout) + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) + -> Result<*mut u8, AllocErr> + { + GlobalDlmalloc.alloc_zeroed(layout) + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { + GlobalDlmalloc.dealloc(ptr, layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: *mut u8, + old_layout: Layout, + new_layout: Layout) -> Result<*mut u8, AllocErr> { + GlobalDlmalloc.realloc(ptr, old_layout, new_layout) + } + + #[inline] + fn usable_size(&self, layout: &Layout) -> (usize, usize) { + GlobalDlmalloc.usable_size(layout) + } + + #[inline] + unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> { + GlobalDlmalloc.alloc_excess(layout) + } + + #[inline] + unsafe fn realloc_excess(&mut self, + ptr: *mut u8, + layout: Layout, + new_layout: Layout) -> Result<Excess, AllocErr> { + GlobalDlmalloc.realloc_excess(ptr, layout, new_layout) + } + + #[inline] + unsafe fn grow_in_place(&mut self, + ptr: *mut u8, + layout: Layout, + new_layout: Layout) -> Result<(), CannotReallocInPlace> { + GlobalDlmalloc.grow_in_place(ptr, layout, new_layout) + } + + #[inline] + unsafe fn shrink_in_place(&mut self, + ptr: *mut u8, + layout: Layout, + new_layout: Layout) -> Result<(), CannotReallocInPlace> { + GlobalDlmalloc.shrink_in_place(ptr, layout, new_layout) + } + } +} |
