Skip to content
This repository was archived by the owner on Aug 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,9 @@ infrastructure. Nevertheless, `wee_alloc` is also usable with `std`.
// We aren't using the standard library.
#![no_std]

// Required to replace the global allocator.
#![feature(global_allocator)]

// Required to use the `alloc` crate and its types, the `abort` intrinsic, and a
// custom panic handler.
#![feature(alloc, core_intrinsics, lang_items)]
#![feature(alloc, core_intrinsics, panic_implementation, lang_items)]

extern crate alloc;
extern crate wee_alloc;
Expand All @@ -64,18 +61,22 @@ extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// Need to provide a tiny `panic_fmt` lang-item implementation for `#![no_std]`.
// This implementation will translate panics into traps in the resulting
// WebAssembly.
#[lang = "panic_fmt"]
extern "C" fn panic_fmt(
_args: ::core::fmt::Arguments,
_file: &'static str,
_line: u32
) -> ! {
use core::intrinsics;
// Need to provide a tiny `panic` implementation for `#![no_std]`.
// This translates into an `unreachable` instruction that will
// raise a `trap` the WebAssembly execution if we panic at runtime.
#[panic_implementation]
fn panic(_info: &::core::panic::PanicInfo) -> ! {
unsafe {
::core::intrinsics::abort();
}
}

// Need to provide a tiny `oom` lang-item implementation for
// `#![no_std]`.
#[lang = "oom"]
extern "C" fn oom() -> ! {
unsafe {
intrinsics::abort();
::core::intrinsics::abort();
}
}

Expand Down
10 changes: 5 additions & 5 deletions example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// We aren't using the standard library.
#![no_std]
// Replacing the allocator and using the `alloc` crate are still unstable.
#![feature(alloc, core_intrinsics, global_allocator, lang_items)]
#![feature(alloc, core_intrinsics, panic_implementation, lang_items)]

extern crate alloc;
extern crate wee_alloc;
Expand All @@ -15,11 +15,11 @@ extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// Need to provide a tiny `panic_fmt` lang-item implementation for
// `#![no_std]`. This translates into an `unreachable` instruction that will
// Need to provide a tiny `panic` implementation for `#![no_std]`.
// This translates into an `unreachable` instruction that will
// raise a `trap` the WebAssembly execution if we panic at runtime.
#[lang = "panic_fmt"]
extern "C" fn panic_fmt(_args: ::core::fmt::Arguments, _file: &'static str, _line: u32) -> ! {
#[panic_implementation]
fn panic(_info: &::core::panic::PanicInfo) -> ! {
unsafe {
::core::intrinsics::abort();
}
Expand Down
5 changes: 2 additions & 3 deletions test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![feature(alloc, allocator_api)]

extern crate alloc;
extern crate histo;
#[macro_use]
extern crate quickcheck;
Expand All @@ -9,7 +8,7 @@ extern crate cfg_if;
extern crate rand;
extern crate wee_alloc;

use alloc::heap::{Alloc, Layout};
use std::alloc::{Alloc, Layout};
use quickcheck::{Arbitrary, Gen};
use std::f64;
use std::fs;
Expand Down Expand Up @@ -374,7 +373,7 @@ quickcheck! {
let align = ALIGNS[align % ALIGNS.len()];

let mut w = &wee_alloc::WeeAlloc::INIT;
let layout = alloc::heap::Layout::from_size_align(size, align).unwrap();
let layout = Layout::from_size_align(size, align).unwrap();
let _ = unsafe { w.alloc(layout) };
}
}
Expand Down
2 changes: 0 additions & 2 deletions test/tests/global.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Adopted from
// https://github.com/alexcrichton/dlmalloc-rs/blob/master/tests/global.rs

#![feature(global_allocator)]

extern crate wee_alloc;

use std::collections::HashMap;
Expand Down
6 changes: 3 additions & 3 deletions wee_alloc/src/imp_static_array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use const_init::ConstInit;
use core::alloc::{AllocErr, Opaque};
use core::alloc::AllocErr;
#[cfg(feature = "extra_assertions")]
use core::cell::Cell;
use core::ptr::NonNull;
Expand All @@ -10,12 +10,12 @@ const SCRATCH_LEN_BYTES: usize = include!(concat!(env!("OUT_DIR"), "/wee_alloc_s
static mut SCRATCH_HEAP: [u8; SCRATCH_LEN_BYTES] = [0; SCRATCH_LEN_BYTES];
static mut OFFSET: Mutex<usize> = Mutex::new(0);

pub(crate) unsafe fn alloc_pages(pages: Pages) -> Result<NonNull<Opaque>, AllocErr> {
pub(crate) unsafe fn alloc_pages(pages: Pages) -> Result<NonNull<u8>, AllocErr> {
let bytes: Bytes = pages.into();
let mut offset = OFFSET.lock();
let end = bytes.0 + *offset;
if end < SCRATCH_LEN_BYTES {
let ptr = SCRATCH_HEAP[*offset..end].as_mut_ptr() as *mut u8 as *mut Opaque;
let ptr = SCRATCH_HEAP[*offset..end].as_mut_ptr() as *mut u8;
*offset = end;
NonNull::new(ptr).ok_or_else(|| AllocErr)
} else {
Expand Down
6 changes: 3 additions & 3 deletions wee_alloc/src/imp_unix.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use const_init::ConstInit;
use core::alloc::{AllocErr, Opaque};
use core::alloc::AllocErr;
use core::cell::UnsafeCell;
use core::ptr::NonNull;
use libc;
use memory_units::{Bytes, Pages};

pub(crate) fn alloc_pages(pages: Pages) -> Result<NonNull<Opaque>, AllocErr> {
pub(crate) fn alloc_pages(pages: Pages) -> Result<NonNull<u8>, AllocErr> {
unsafe {
let bytes: Bytes = pages.into();
let addr = libc::mmap(
Expand All @@ -19,7 +19,7 @@ pub(crate) fn alloc_pages(pages: Pages) -> Result<NonNull<Opaque>, AllocErr> {
if addr == libc::MAP_FAILED {
Err(AllocErr)
} else {
NonNull::new(addr as *mut Opaque).ok_or(AllocErr)
NonNull::new(addr as *mut u8).ok_or(AllocErr)
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions wee_alloc/src/imp_wasm32.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{assert_is_word_aligned, PAGE_SIZE, unchecked_unwrap};
use const_init::ConstInit;
use core::alloc::{AllocErr, Opaque};
use core::alloc::AllocErr;
use core::cell::UnsafeCell;
use core::ptr::NonNull;
use memory_units::Pages;
Expand All @@ -10,10 +10,10 @@ extern "C" {
fn grow_memory(pages: usize) -> i32;
}

pub(crate) unsafe fn alloc_pages(n: Pages) -> Result<NonNull<Opaque>, AllocErr> {
pub(crate) unsafe fn alloc_pages(n: Pages) -> Result<NonNull<u8>, AllocErr> {
let ptr = grow_memory(n.0);
if -1 != ptr {
let ptr = (ptr as usize * PAGE_SIZE.0) as *mut Opaque;
let ptr = (ptr as usize * PAGE_SIZE.0) as *mut u8;
assert_is_word_aligned(ptr as *mut u8);
Ok(unchecked_unwrap(NonNull::new(ptr)))
} else {
Expand Down
6 changes: 3 additions & 3 deletions wee_alloc/src/imp_windows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use const_init::ConstInit;
use core::alloc::{AllocErr, Opaque};
use core::alloc::AllocErr;
use core::cell::UnsafeCell;
use core::ptr::NonNull;
use memory_units::{Bytes, Pages};
Expand All @@ -12,10 +12,10 @@ use winapi::um::synchapi::{CreateMutexW, ReleaseMutex, WaitForSingleObject};
use winapi::um::winbase::{WAIT_OBJECT_0, INFINITE};
use winapi::um::winnt::{HANDLE, MEM_COMMIT, PAGE_READWRITE};

pub(crate) fn alloc_pages(pages: Pages) -> Result<NonNull<Opaque>, AllocErr> {
pub(crate) fn alloc_pages(pages: Pages) -> Result<NonNull<u8>, AllocErr> {
let bytes: Bytes = pages.into();
let ptr = unsafe { VirtualAlloc(NULL, bytes.0, MEM_COMMIT, PAGE_READWRITE) };
NonNull::new(ptr as *mut Opaque).ok_or(AllocErr)
NonNull::new(ptr as *mut u8).ok_or(AllocErr)
}

// Align to the cache line size on an i7 to avoid false sharing.
Expand Down
57 changes: 29 additions & 28 deletions wee_alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,9 @@ infrastructure. Nevertheless, `wee_alloc` is also usable with `std`.
// We aren't using the standard library.
#![no_std]

// Required to replace the global allocator.
#![feature(global_allocator)]

// Required to use the `alloc` crate and its types, the `abort` intrinsic, and a
// custom panic handler.
#![feature(alloc, core_intrinsics, lang_items)]
#![feature(alloc, core_intrinsics, panic_implementation, lang_items)]

extern crate alloc;
extern crate wee_alloc;
Expand All @@ -64,18 +61,22 @@ extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// Need to provide a tiny `panic_fmt` lang-item implementation for `#![no_std]`.
// This implementation will translate panics into traps in the resulting
// WebAssembly.
#[lang = "panic_fmt"]
extern "C" fn panic_fmt(
_args: ::core::fmt::Arguments,
_file: &'static str,
_line: u32
) -> ! {
use core::intrinsics;
// Need to provide a tiny `panic` implementation for `#![no_std]`.
// This translates into an `unreachable` instruction that will
// raise a `trap` the WebAssembly execution if we panic at runtime.
#[panic_implementation]
fn panic(_info: &::core::panic::PanicInfo) -> ! {
unsafe {
::core::intrinsics::abort();
}
}

// Need to provide a tiny `oom` lang-item implementation for
// `#![no_std]`.
#[lang = "oom"]
extern "C" fn oom() -> ! {
unsafe {
intrinsics::abort();
::core::intrinsics::abort();
}
}

Expand Down Expand Up @@ -222,7 +223,7 @@ for hacking!

#![deny(missing_docs)]
#![cfg_attr(not(feature = "use_std_for_test_debugging"), no_std)]
#![feature(alloc, allocator_api, core_intrinsics, global_allocator)]
#![feature(alloc, allocator_api, core_intrinsics)]
#![cfg_attr(target_arch = "wasm32", feature(link_llvm_intrinsics))]

#[macro_use]
Expand Down Expand Up @@ -269,7 +270,7 @@ mod neighbors;
mod size_classes;

use const_init::ConstInit;
use core::alloc::{Alloc, AllocErr, GlobalAlloc, Layout, Opaque};
use core::alloc::{Alloc, AllocErr, GlobalAlloc, Layout};
use core::cell::Cell;
use core::cmp;
use core::marker::Sync;
Expand Down Expand Up @@ -520,7 +521,7 @@ impl<'a> FreeCell<'a> {
}

unsafe fn from_uninitialized(
raw: NonNull<Opaque>,
raw: NonNull<u8>,
size: Bytes,
next_free: Option<*const FreeCell<'a>>,
policy: &AllocPolicy<'a>,
Expand Down Expand Up @@ -586,7 +587,7 @@ impl<'a> FreeCell<'a> {
let split_cell_head = split_and_aligned - size_of::<CellHeader>().0;
let split_cell = unsafe {
&*FreeCell::from_uninitialized(
unchecked_unwrap(NonNull::new(split_cell_head as *mut Opaque)),
unchecked_unwrap(NonNull::new(split_cell_head as *mut u8)),
Bytes(next - split_cell_head) - size_of::<CellHeader>(),
None,
policy,
Expand Down Expand Up @@ -951,7 +952,7 @@ unsafe fn alloc_first_fit<'a>(
align: Bytes,
head: &Cell<*const FreeCell<'a>>,
policy: &AllocPolicy<'a>,
) -> Result<NonNull<Opaque>, AllocErr> {
) -> Result<NonNull<u8>, AllocErr> {
extra_assert!(size.0 > 0);

walk_free_list(head, policy, |previous, current| {
Expand All @@ -960,7 +961,7 @@ unsafe fn alloc_first_fit<'a>(
if let Some(allocated) = current.try_alloc(previous, size, align, policy) {
assert_aligned_to(allocated.data(), align);
return Some(unchecked_unwrap(
NonNull::new(allocated.data() as *mut Opaque),
NonNull::new(allocated.data() as *mut u8),
));
}

Expand All @@ -973,7 +974,7 @@ unsafe fn alloc_with_refill<'a, 'b>(
align: Bytes,
head: &'b Cell<*const FreeCell<'a>>,
policy: &AllocPolicy<'a>,
) -> Result<NonNull<Opaque>, AllocErr> {
) -> Result<NonNull<u8>, AllocErr> {
if let Ok(result) = alloc_first_fit(size, align, head, policy) {
return Ok(result);
}
Expand Down Expand Up @@ -1072,7 +1073,7 @@ unsafe impl<'a, 'b> Alloc for &'b WeeAlloc<'a>
where
'a: 'b,
{
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
let size = Bytes(layout.size());
let align = if layout.align() == 0 {
Bytes(1)
Expand All @@ -1084,7 +1085,7 @@ where
// Ensure that our made up pointer is properly aligned by using the
// alignment as the pointer.
extra_assert!(align.0 > 0);
return Ok(NonNull::new_unchecked(align.0 as *mut Opaque));
return Ok(NonNull::new_unchecked(align.0 as *mut u8));
}

let size: Words = size.round_up_to();
Expand All @@ -1095,7 +1096,7 @@ where
})
}

unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
let size = Bytes(layout.size());
if size.0 == 0 {
return;
Expand Down Expand Up @@ -1185,15 +1186,15 @@ where
}

unsafe impl GlobalAlloc for WeeAlloc<'static> {
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let mut me = self;
match Alloc::alloc(&mut me, layout) {
Ok(ptr) => ptr.as_ptr(),
Err(AllocErr) => 0 as *mut Opaque,
Err(AllocErr) => 0 as *mut u8,
}
}

unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
if let Some(ptr) = NonNull::new(ptr) {
let mut me = self;
Alloc::dealloc(&mut me, ptr, layout);
Expand Down