about summary refs log tree commit diff
path: root/src/liballoc_jemalloc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-04-16 19:13:52 +0000
committerbors <bors@rust-lang.org>2017-04-16 19:13:52 +0000
commit7627e3d31dd641ae9042675e9032857f58d0c5d1 (patch)
treea9e6a160ae903447feee5c907ac67b1f2281750e /src/liballoc_jemalloc
parent9af79f52d0ab43e318bdf3aa73d939c4482cc946 (diff)
parentaad2062073f46f28c6d1269463cc6c19df1e0199 (diff)
downloadrust-7627e3d31dd641ae9042675e9032857f58d0c5d1.tar.gz
rust-7627e3d31dd641ae9042675e9032857f58d0c5d1.zip
Auto merge of #40409 - mbrubeck:calloc, r=sfackler
Specialize Vec::from_elem to use calloc

Fixes #38723.  This specializes the implementation for `u8` only, but it could be extended to other zeroable types if desired.

I haven't tested this extensively, but I did verify that it gives the expected performance boost for large `vec![0; n]` allocations with both alloc_system and jemalloc, on Linux.  (I have not tested or even built the Windows code.)
Diffstat (limited to 'src/liballoc_jemalloc')
-rw-r--r--src/liballoc_jemalloc/lib.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 83cc1ef09c2..288531cb5b2 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -40,6 +40,10 @@ mod imp {
         fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
         #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
                        target_os = "dragonfly", target_os = "windows", target_env = "musl"),
+                   link_name = "je_calloc")]
+        fn calloc(size: size_t, flags: c_int) -> *mut c_void;
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
                    link_name = "je_rallocx")]
         fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
         #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
@@ -56,6 +60,8 @@ mod imp {
         fn nallocx(size: size_t, flags: c_int) -> size_t;
     }
 
+    const MALLOCX_ZERO: c_int = 0x40;
+
     // The minimum alignment guaranteed by the architecture. This value is used to
     // add fast paths for low alignment values. In practice, the alignment is a
     // constant at the call site and the branch will be optimized out.
@@ -92,6 +98,16 @@ mod imp {
     }
 
     #[no_mangle]
+    pub extern "C" fn __rust_allocate_zeroed(size: usize, align: usize) -> *mut u8 {
+        if align <= MIN_ALIGN {
+            unsafe { calloc(size as size_t, 1) as *mut u8 }
+        } else {
+            let flags = align_to_flags(align) | MALLOCX_ZERO;
+            unsafe { mallocx(size as size_t, flags) as *mut u8 }
+        }
+    }
+
+    #[no_mangle]
     pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                         _old_size: usize,
                                         size: usize,
@@ -136,6 +152,11 @@ mod imp {
     }
 
     #[no_mangle]
+    pub extern "C" fn __rust_allocate_zeroed(_size: usize, _align: usize) -> *mut u8 {
+        bogus()
+    }
+
+    #[no_mangle]
     pub extern "C" fn __rust_reallocate(_ptr: *mut u8,
                                         _old_size: usize,
                                         _size: usize,