about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Huss <eric@huss.org>2020-08-20 11:00:41 -0700
committerEric Huss <eric@huss.org>2020-09-15 07:01:13 -0700
commitcfb955da6f67b4d11d266f0d2957c8ddab26b66f (patch)
tree7d4b3bd6a425ffd45ba342cdd5e304510ee6a97a
parent5a4098ed0fb0b8aea373a7af8ace57da98b09fec (diff)
downloadrust-cfb955da6f67b4d11d266f0d2957c8ddab26b66f.tar.gz
rust-cfb955da6f67b4d11d266f0d2957c8ddab26b66f.zip
Consolidate wasi alloc with unix alloc.
-rw-r--r--library/std/src/sys/unix/alloc.rs86
-rw-r--r--library/std/src/sys/wasi/alloc.rs69
-rw-r--r--library/std/src/sys/wasi/mod.rs1
3 files changed, 45 insertions, 111 deletions
diff --git a/library/std/src/sys/unix/alloc.rs b/library/std/src/sys/unix/alloc.rs
index 8e193935460..964abe8b8c9 100644
--- a/library/std/src/sys/unix/alloc.rs
+++ b/library/std/src/sys/unix/alloc.rs
@@ -52,46 +52,48 @@ unsafe impl GlobalAlloc for System {
     }
 }
 
-#[cfg(any(
-    target_os = "android",
-    target_os = "illumos",
-    target_os = "redox",
-    target_os = "solaris"
-))]
-#[inline]
-unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
-    // On android we currently target API level 9 which unfortunately
-    // doesn't have the `posix_memalign` API used below. Instead we use
-    // `memalign`, but this unfortunately has the property on some systems
-    // where the memory returned cannot be deallocated by `free`!
-    //
-    // Upon closer inspection, however, this appears to work just fine with
-    // Android, so for this platform we should be fine to call `memalign`
-    // (which is present in API level 9). Some helpful references could
-    // possibly be chromium using memalign [1], attempts at documenting that
-    // memalign + free is ok [2] [3], or the current source of chromium
-    // which still uses memalign on android [4].
-    //
-    // [1]: https://codereview.chromium.org/10796020/
-    // [2]: https://code.google.com/p/android/issues/detail?id=35391
-    // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
-    // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
-    //                                       /memory/aligned_memory.cc
-    libc::memalign(layout.align(), layout.size()) as *mut u8
-}
-
-#[cfg(not(any(
-    target_os = "android",
-    target_os = "illumos",
-    target_os = "redox",
-    target_os = "solaris"
-)))]
-#[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 = libc::posix_memalign(&mut out, align, layout.size());
-    if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
+cfg_if::cfg_if! {
+    if #[cfg(any(
+        target_os = "android",
+        target_os = "illumos",
+        target_os = "redox",
+        target_os = "solaris"
+    ))] {
+        #[inline]
+        unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
+            // On android we currently target API level 9 which unfortunately
+            // doesn't have the `posix_memalign` API used below. Instead we use
+            // `memalign`, but this unfortunately has the property on some systems
+            // where the memory returned cannot be deallocated by `free`!
+            //
+            // Upon closer inspection, however, this appears to work just fine with
+            // Android, so for this platform we should be fine to call `memalign`
+            // (which is present in API level 9). Some helpful references could
+            // possibly be chromium using memalign [1], attempts at documenting that
+            // memalign + free is ok [2] [3], or the current source of chromium
+            // which still uses memalign on android [4].
+            //
+            // [1]: https://codereview.chromium.org/10796020/
+            // [2]: https://code.google.com/p/android/issues/detail?id=35391
+            // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
+            // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
+            //                                       /memory/aligned_memory.cc
+            libc::memalign(layout.align(), layout.size()) as *mut u8
+        }
+    } else if #[cfg(target_os = "wasi")] {
+        #[inline]
+        unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
+            libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
+        }
+    } else {
+        #[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 = libc::posix_memalign(&mut out, align, layout.size());
+            if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
+        }
+    }
 }
diff --git a/library/std/src/sys/wasi/alloc.rs b/library/std/src/sys/wasi/alloc.rs
deleted file mode 100644
index 4d0afe27bb8..00000000000
--- a/library/std/src/sys/wasi/alloc.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-#![deny(unsafe_op_in_unsafe_fn)]
-
-use crate::alloc::{GlobalAlloc, Layout, System};
-use crate::ptr;
-use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
-
-// SAFETY: All methods implemented follow the contract rules defined
-// in `GlobalAlloc`.
-#[stable(feature = "alloc_system_type", since = "1.28.0")]
-unsafe impl GlobalAlloc for System {
-    #[inline]
-    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
-        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            // SAFETY: `libc::malloc` is guaranteed to be safe, it will allocate
-            // `layout.size()` bytes of memory and return a pointer to it
-            unsafe { libc::malloc(layout.size()) as *mut u8 }
-        } else {
-            // SAFETY: `libc::aligned_alloc` is guaranteed to be safe if
-            // `layout.size()` is a multiple of `layout.align()`. This
-            // constraint can be satisfied if `pad_to_align` is called,
-            // which creates a layout by rounding the size of this layout up
-            // to a multiple of the layout's alignment
-            let aligned_layout = layout.pad_to_align();
-            unsafe { libc::aligned_alloc(aligned_layout.align(), aligned_layout.size()) as *mut u8 }
-        }
-    }
-
-    #[inline]
-    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
-        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            // SAFETY: `libc::calloc` is safe as long that `layout.size() * 1`
-            // would not result in integer overflow which cannot happen,
-            // multiplying by one never overflows
-            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
-        } else {
-            // SAFETY: The safety contract for `alloc` must be upheld by the caller
-            let ptr = unsafe { self.alloc(layout.clone()) };
-            if !ptr.is_null() {
-                // SAFETY: in the case of the `ptr` being not null
-                // it will be properly aligned and a valid ptr
-                // which satisfies `ptr::write_bytes` safety constrains
-                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
-            }
-            ptr
-        }
-    }
-
-    #[inline]
-    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-        // SAFETY: `libc::free` is guaranteed to be safe if `ptr` is allocated
-        // by this allocator or if `ptr` is NULL
-        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 {
-            // SAFETY: `libc::realloc` is safe if `ptr` is allocated by this
-            // allocator or NULL
-            // - If `new_size` is 0 and `ptr` is not NULL, it will act as `libc::free`
-            // - If `new_size` is not 0 and `ptr` is NULL, it will act as `libc::malloc`
-            // - Else, it will resize the block accordingly
-            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
-        } else {
-            // SAFETY: The safety contract for `realloc_fallback` must be upheld by the caller
-            unsafe { realloc_fallback(self, ptr, layout, new_size) }
-        }
-    }
-}
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index e1aa596503b..a379fc891a8 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -17,6 +17,7 @@
 use crate::io as std_io;
 use crate::mem;
 
+#[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
 #[path = "../unsupported/cmath.rs"]