std: move allocators to sys

This commit is contained in:
joboet 2024-07-23 16:10:08 +02:00
parent a60a9e567a
commit d456814842
No known key found for this signature in database
GPG Key ID: 704E0149B0194B3C
28 changed files with 78 additions and 146 deletions

View File

@ -1,4 +1,3 @@
use super::hermit_abi;
use crate::alloc::{GlobalAlloc, Layout, System};
#[stable(feature = "alloc_system_type", since = "1.28.0")]

View File

@ -1,10 +1,18 @@
#![forbid(unsafe_op_in_unsafe_fn)]
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::{cmp, ptr};
use crate::ptr;
// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(any(
#[allow(dead_code)]
const MIN_ALIGN: usize = if cfg!(any(
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
all(target_arch = "xtensa", target_os = "espidf"),
)) {
// The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
4
} else if cfg!(any(
target_arch = "x86",
target_arch = "arm",
target_arch = "m68k",
@ -16,11 +24,11 @@ use crate::{cmp, ptr};
target_arch = "sparc",
target_arch = "wasm32",
target_arch = "hexagon",
all(target_arch = "riscv32", not(any(target_os = "espidf", target_os = "zkvm"))),
all(target_arch = "xtensa", not(target_os = "espidf")),
))]
pub const MIN_ALIGN: usize = 8;
#[cfg(any(
target_arch = "riscv32",
target_arch = "xtensa",
)) {
8
} else if cfg!(any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "arm64ec",
@ -31,16 +39,14 @@ pub const MIN_ALIGN: usize = 8;
target_arch = "sparc64",
target_arch = "riscv64",
target_arch = "wasm64",
))]
pub const MIN_ALIGN: usize = 16;
// The allocator on the esp-idf and zkvm platforms guarantee 4 byte alignment.
#[cfg(all(any(
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
all(target_arch = "xtensa", target_os = "espidf"),
)))]
pub const MIN_ALIGN: usize = 4;
)) {
16
} else {
panic!("add a value for MIN_ALIGN")
};
pub unsafe fn realloc_fallback(
#[allow(dead_code)]
unsafe fn realloc_fallback(
alloc: &System,
ptr: *mut u8,
old_layout: Layout,
@ -52,10 +58,37 @@ pub unsafe fn realloc_fallback(
let new_ptr = GlobalAlloc::alloc(alloc, new_layout);
if !new_ptr.is_null() {
let size = cmp::min(old_layout.size(), new_size);
let size = usize::min(old_layout.size(), new_size);
ptr::copy_nonoverlapping(ptr, new_ptr, size);
GlobalAlloc::dealloc(alloc, ptr, old_layout);
}
new_ptr
}
}
cfg_if::cfg_if! {
if #[cfg(any(
target_family = "unix",
target_os = "wasi",
target_os = "teeos",
))] {
mod unix;
} else if #[cfg(target_os = "windows")] {
mod windows;
} else if #[cfg(target_os = "hermit")] {
mod hermit;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
mod sgx;
} else if #[cfg(target_os = "solid_asp3")] {
mod solid;
} else if #[cfg(target_os = "uefi")] {
mod uefi;
} else if #[cfg(target_family = "wasm")] {
mod wasm;
} else if #[cfg(target_os = "xous")] {
mod xous;
} else if #[cfg(target_os = "zkvm")] {
mod zkvm;
}
}

View File

@ -1,9 +1,8 @@
use core::sync::atomic::{AtomicBool, Ordering};
use super::abi::mem as sgx_mem;
use super::waitqueue::SpinMutex;
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sys::pal::abi::mem as sgx_mem;
use crate::sys::pal::waitqueue::SpinMutex;
// Using a SpinMutex because we never want to exit the enclave waiting for the
// allocator.

View File

@ -1,5 +1,5 @@
use super::{realloc_fallback, MIN_ALIGN};
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {

View File

@ -3,9 +3,9 @@
use r_efi::protocols::loaded_image;
use super::helpers;
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::sync::OnceLock;
use crate::sys::pal::helpers;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {

View File

@ -1,6 +1,6 @@
use super::{realloc_fallback, MIN_ALIGN};
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
@ -11,7 +11,7 @@ unsafe impl GlobalAlloc for System {
// Also see <https://github.com/rust-lang/rust/issues/45955> and
// <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
libc::malloc(layout.size()) as *mut u8
unsafe { libc::malloc(layout.size()) as *mut u8 }
} else {
// `posix_memalign` returns a non-aligned value if supplied a very
// large alignment on older versions of Apple's platforms (unknown
@ -25,7 +25,7 @@ unsafe impl GlobalAlloc for System {
return ptr::null_mut();
}
}
aligned_malloc(&layout)
unsafe { aligned_malloc(&layout) }
}
}
@ -33,11 +33,11 @@ unsafe impl GlobalAlloc for System {
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
// See the comment above in `alloc` for why this check looks the way it does.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
libc::calloc(layout.size(), 1) as *mut u8
unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
} else {
let ptr = self.alloc(layout);
let ptr = unsafe { self.alloc(layout) };
if !ptr.is_null() {
ptr::write_bytes(ptr, 0, layout.size());
unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
}
ptr
}
@ -45,15 +45,15 @@ unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
libc::free(ptr as *mut libc::c_void)
unsafe { libc::free(ptr as *mut libc::c_void) }
}
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
} else {
realloc_fallback(self, ptr, layout, new_size)
unsafe { realloc_fallback(self, ptr, layout, new_size) }
}
}
}
@ -81,7 +81,7 @@ cfg_if::cfg_if! {
// posix_memalign only has one, clear requirement: that the alignment be a multiple of
// `sizeof(void*)`. Since these are all powers of 2, we can just use max.
let align = layout.align().max(crate::mem::size_of::<usize>());
let ret = libc::posix_memalign(&mut out, align, layout.size());
let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
}
}

View File

@ -1,11 +1,10 @@
use core::mem::MaybeUninit;
use super::{realloc_fallback, MIN_ALIGN};
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ffi::c_void;
use crate::mem::MaybeUninit;
use crate::ptr;
use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::sys::c;
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
#[cfg(test)]
mod tests;
@ -113,28 +112,28 @@ fn init_or_get_process_heap() -> c::HANDLE {
extern "C" fn process_heap_init_and_alloc(
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
flags: u32,
dwBytes: usize,
bytes: usize,
) -> *mut c_void {
let heap = init_or_get_process_heap();
if core::intrinsics::unlikely(heap.is_null()) {
return ptr::null_mut();
}
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
unsafe { HeapAlloc(heap, flags, dwBytes) }
unsafe { HeapAlloc(heap, flags, bytes) }
}
#[inline(never)]
fn process_heap_alloc(
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
flags: u32,
dwBytes: usize,
bytes: usize,
) -> *mut c_void {
let heap = HEAP.load(Ordering::Relaxed);
if core::intrinsics::likely(!heap.is_null()) {
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
unsafe { HeapAlloc(heap, flags, dwBytes) }
unsafe { HeapAlloc(heap, flags, bytes) }
} else {
process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes)
process_heap_init_and_alloc(MaybeUninit::uninit(), flags, bytes)
}
}

View File

@ -1,5 +1,5 @@
use super::abi;
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::sys::pal::abi;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {

View File

@ -5,6 +5,7 @@
/// descriptors.
mod pal;
mod alloc;
mod personality;
pub mod anonymous_pipe;

View File

@ -10,7 +10,6 @@
#![allow(dead_code)]
pub mod alloc;
pub mod small_c_string;
#[cfg(test)]

View File

@ -18,7 +18,6 @@
use crate::os::raw::c_char;
pub mod alloc;
pub mod args;
pub mod env;
pub mod fd;

View File

@ -9,7 +9,6 @@ use crate::io::ErrorKind;
use crate::sync::atomic::{AtomicBool, Ordering};
pub mod abi;
pub mod alloc;
pub mod args;
pub mod env;
pub mod fd;

View File

@ -16,7 +16,6 @@ pub mod itron {
use super::unsupported;
}
pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
pub mod env;

View File

@ -1,57 +0,0 @@
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
// jemalloc provides alignment less than MIN_ALIGN for small allocations.
// So only rely on MIN_ALIGN if size >= align.
// Also see <https://github.com/rust-lang/rust/issues/45955> and
// <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
unsafe { libc::malloc(layout.size()) as *mut u8 }
} else {
unsafe { aligned_malloc(&layout) }
}
}
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
// See the comment above in `alloc` for why this check looks the way it does.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
} else {
let ptr = unsafe { self.alloc(layout) };
if !ptr.is_null() {
unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
}
ptr
}
}
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
unsafe { libc::free(ptr as *mut libc::c_void) }
}
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
} else {
unsafe { realloc_fallback(self, ptr, layout, new_size) }
}
}
}
#[inline]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
let mut out = ptr::null_mut();
// posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
// Since these are all powers of 2, we can just use max.
let align = layout.align().max(crate::mem::size_of::<usize>());
let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
}

View File

@ -8,7 +8,6 @@
pub use self::rand::hashmap_random_keys;
pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
#[path = "../unsupported/env.rs"]

View File

@ -13,11 +13,11 @@
//! [`OsString`]: crate::ffi::OsString
#![forbid(unsafe_op_in_unsafe_fn)]
pub mod alloc;
pub mod args;
pub mod env;
#[path = "../unsupported/fs.rs"]
pub mod fs;
pub mod helpers;
#[path = "../unsupported/io.rs"]
pub mod io;
#[path = "../unsupported/net.rs"]
@ -30,8 +30,6 @@ pub mod stdio;
pub mod thread;
pub mod time;
mod helpers;
#[cfg(test)]
mod tests;

View File

@ -7,7 +7,6 @@ use crate::io::ErrorKind;
#[macro_use]
pub mod weak;
pub mod alloc;
pub mod args;
pub mod env;
pub mod fd;

View File

@ -1,23 +0,0 @@
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr::null_mut;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
null_mut()
}
#[inline]
unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
null_mut()
}
#[inline]
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
#[inline]
unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
null_mut()
}
}

View File

@ -1,6 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
pub mod alloc;
pub mod args;
pub mod env;
pub mod fs;

View File

@ -14,8 +14,6 @@
//! compiling for wasm. That way it's a compile time error for something that's
//! guaranteed to be a runtime error!
#[path = "../unix/alloc.rs"]
pub mod alloc;
pub mod args;
pub mod env;
pub mod fd;

View File

@ -6,8 +6,6 @@
//! To begin with, this target mirrors the wasi target 1 to 1, but over
//! time this will change significantly.
#[path = "../unix/alloc.rs"]
pub mod alloc;
#[path = "../wasi/args.rs"]
pub mod args;
#[path = "../wasi/env.rs"]

View File

@ -16,7 +16,6 @@
#![deny(unsafe_op_in_unsafe_fn)]
pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
pub mod env;

View File

@ -15,7 +15,6 @@ pub mod compat;
mod api;
pub mod alloc;
pub mod args;
pub mod c;
pub mod env;

View File

@ -1,6 +1,5 @@
#![forbid(unsafe_op_in_unsafe_fn)]
pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
#[path = "../unsupported/env.rs"]

View File

@ -10,7 +10,7 @@
const WORD_SIZE: usize = core::mem::size_of::<u32>();
pub mod alloc;
pub mod abi;
#[path = "../zkvm/args.rs"]
pub mod args;
pub mod env;
@ -26,13 +26,10 @@ pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
pub mod stdio;
#[path = "../unsupported/time.rs"]
pub mod time;
#[path = "../unsupported/thread.rs"]
pub mod thread;
mod abi;
#[path = "../unsupported/time.rs"]
pub mod time;
use crate::io as std_io;