about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/rt.mk12
-rw-r--r--src/liballoc_jemalloc/build.rs17
-rw-r--r--src/liballoc_jemalloc/lib.rs33
3 files changed, 47 insertions, 15 deletions
diff --git a/mk/rt.mk b/mk/rt.mk
index cfb210952bc..bd17490955d 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -148,7 +148,15 @@ ifeq ($$(CFG_WINDOWSY_$(1)),1)
 else ifeq ($(OSTYPE_$(1)), apple-ios)
   JEMALLOC_ARGS_$(1) := --disable-tls
 else ifeq ($(findstring android, $(OSTYPE_$(1))), android)
-  JEMALLOC_ARGS_$(1) := --disable-tls
+  # We force android to have prefixed symbols because apparently replacement of
+  # the libc allocator doesn't quite work. When this was tested (unprefixed
+  # symbols), it was found that the `realpath` function in libc would allocate
+  # with libc malloc (not jemalloc malloc), and then the standard library would
+  # free with jemalloc free, causing a segfault.
+  #
+  # If the test suite passes, however, without symbol prefixes then we should be
+  # good to go!
+  JEMALLOC_ARGS_$(1) := --disable-tls --with-jemalloc-prefix=je_
 endif
 
 ifdef CFG_ENABLE_DEBUG_JEMALLOC
@@ -186,7 +194,7 @@ JEMALLOC_LOCAL_$(1) := $$(JEMALLOC_BUILD_DIR_$(1))/lib/$$(JEMALLOC_REAL_NAME_$(1
 $$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
 	@$$(call E, make: jemalloc)
 	cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
-		$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
+		$$(JEMALLOC_ARGS_$(1)) $(CFG_JEMALLOC_FLAGS) \
 		--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
 		CC="$$(CC_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1))" \
 		AR="$$(AR_$(1))" \
diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs
index 4bc752af48e..c9508322a31 100644
--- a/src/liballoc_jemalloc/build.rs
+++ b/src/liballoc_jemalloc/build.rs
@@ -50,7 +50,7 @@ fn main() {
        .env("AR", &ar)
        .env("RANLIB", format!("{} s", ar.display()));
 
-    if target.contains("windows-gnu") {
+    if target.contains("windows") {
         // A bit of history here, this used to be --enable-lazy-lock added in
         // #14006 which was filed with jemalloc in jemalloc/jemalloc#83 which
         // was also reported to MinGW:
@@ -72,7 +72,19 @@ fn main() {
         //        locking, but requires passing an option due to a historical
         //        default with jemalloc.
         cmd.arg("--disable-lazy-lock");
-    } else if target.contains("ios") || target.contains("android") {
+    } else if target.contains("ios") {
+        cmd.arg("--disable-tls");
+    } else if target.contains("android") {
+        // We force android to have prefixed symbols because apparently
+        // replacement of the libc allocator doesn't quite work. When this was
+        // tested (unprefixed symbols), it was found that the `realpath`
+        // function in libc would allocate with libc malloc (not jemalloc
+        // malloc), and then the standard library would free with jemalloc free,
+        // causing a segfault.
+        //
+        // If the test suite passes, however, without symbol prefixes then we
+        // should be good to go!
+        cmd.arg("--with-jemalloc-prefix=je_");
         cmd.arg("--disable-tls");
     }
 
@@ -82,7 +94,6 @@ fn main() {
 
     // Turn off broken quarantine (see jemalloc/jemalloc#161)
     cmd.arg("--disable-fill");
-    cmd.arg("--with-jemalloc-prefix=je_");
     cmd.arg(format!("--host={}", build_helper::gnu_target(&target)));
     cmd.arg(format!("--build={}", build_helper::gnu_target(&host)));
 
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 2c46e37ac32..bda001eb4f4 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -41,12 +41,25 @@ use libc::{c_int, c_void, size_t};
 #[cfg(not(cargobuild))]
 extern {}
 
+// Note that the symbols here are prefixed by default on OSX (we don't
+// explicitly request it), and on Android we explicitly request it as
+// unprefixing cause segfaults (mismatches in allocators).
 extern {
-    fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
-    fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
-    fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
-    fn je_sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
-    fn je_nallocx(size: size_t, flags: c_int) -> size_t;
+    #[cfg_attr(any(target_os = "macos", target_os = "android"),
+               link_name = "je_mallocx")]
+    fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
+    #[cfg_attr(any(target_os = "macos", target_os = "android"),
+               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"),
+               link_name = "je_xallocx")]
+    fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
+    #[cfg_attr(any(target_os = "macos", target_os = "android"),
+               link_name = "je_sdallocx")]
+    fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
+    #[cfg_attr(any(target_os = "macos", target_os = "android"),
+               link_name = "je_nallocx")]
+    fn nallocx(size: size_t, flags: c_int) -> size_t;
 }
 
 // The minimum alignment guaranteed by the architecture. This value is used to
@@ -78,7 +91,7 @@ fn align_to_flags(align: usize) -> c_int {
 #[no_mangle]
 pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
     let flags = align_to_flags(align);
-    unsafe { je_mallocx(size as size_t, flags) as *mut u8 }
+    unsafe { mallocx(size as size_t, flags) as *mut u8 }
 }
 
 #[no_mangle]
@@ -88,7 +101,7 @@ pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                     align: usize)
                                     -> *mut u8 {
     let flags = align_to_flags(align);
-    unsafe { je_rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
+    unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
 }
 
 #[no_mangle]
@@ -98,19 +111,19 @@ pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                             align: usize)
                                             -> usize {
     let flags = align_to_flags(align);
-    unsafe { je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
+    unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
 }
 
 #[no_mangle]
 pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
     let flags = align_to_flags(align);
-    unsafe { je_sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
+    unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
 }
 
 #[no_mangle]
 pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
     let flags = align_to_flags(align);
-    unsafe { je_nallocx(size as size_t, flags) as usize }
+    unsafe { nallocx(size as size_t, flags) as usize }
 }
 
 // These symbols are used by jemalloc on android but the really old android