about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rwxr-xr-xconfigure1
-rw-r--r--mk/crates.mk2
-rw-r--r--mk/rt.mk52
-rw-r--r--mk/tests.mk4
m---------src/jemalloc0
-rw-r--r--src/libstd/rt/heap.rs97
-rw-r--r--src/libstd/rt/mod.rs5
8 files changed, 157 insertions, 7 deletions
diff --git a/.gitmodules b/.gitmodules
index f9da507b72a..37dbb30c82a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -15,3 +15,6 @@
 [submodule "src/rt/hoedown"]
 	path = src/rt/hoedown
 	url = https://github.com/rust-lang/hoedown.git
+[submodule "src/jemalloc"]
+	path = src/jemalloc
+	url = https://github.com/rust-lang/jemalloc.git
diff --git a/configure b/configure
index d189c8cb6cd..3ab71f762f2 100755
--- a/configure
+++ b/configure
@@ -782,6 +782,7 @@ do
   for s in 0 1 2 3
   do
     make_dir $t/rt/stage$s
+    make_dir $t/rt/jemalloc
     make_dir $t/rt/libuv
     make_dir $t/rt/libuv/src/ares
     make_dir $t/rt/libuv/src/eio
diff --git a/mk/crates.mk b/mk/crates.mk
index b75b5ba81e2..0437e08de28 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -57,7 +57,7 @@ CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
 
 DEPS_core :=
-DEPS_std := core libc native:rustrt native:compiler-rt native:backtrace
+DEPS_std := core libc native:rustrt native:compiler-rt native:backtrace native:jemalloc
 DEPS_green := std rand native:context_switch
 DEPS_rustuv := std native:uv native:uv_support
 DEPS_native := std
diff --git a/mk/rt.mk b/mk/rt.mk
index df47f4a12d9..e4a548dd7bf 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -122,10 +122,13 @@ $(foreach lib,$(NATIVE_LIBS),					    \
 ################################################################################
 # Building third-party targets with external build systems
 #
-# The only current member of this section is libuv, but long ago this used to
-# also be occupied by jemalloc. This location is meant for dependencies which
-# have external build systems. It is still assumed that the output of each of
-# these steps is a static library in the correct location.
+# This location is meant for dependencies which have external build systems. It
+# is still assumed that the output of each of these steps is a static library
+# in the correct location.
+################################################################################
+
+################################################################################
+# libuv
 ################################################################################
 
 define DEF_LIBUV_ARCH_VAR
@@ -154,6 +157,11 @@ define DEF_THIRD_PARTY_TARGETS
 
 ifeq ($$(CFG_WINDOWSY_$(1)), 1)
   LIBUV_OSTYPE_$(1) := win
+  # This isn't necessarily a desired option, but it's harmless and works around
+  # what appears to be a mingw-w64 bug.
+  #
+  # https://sourceforge.net/p/mingw-w64/bugs/395/
+  JEMALLOC_ARGS_$(1) := --enable-lazy-lock
 else ifeq ($(OSTYPE_$(1)), apple-darwin)
   LIBUV_OSTYPE_$(1) := mac
 else ifeq ($(OSTYPE_$(1)), unknown-freebsd)
@@ -161,6 +169,7 @@ else ifeq ($(OSTYPE_$(1)), unknown-freebsd)
 else ifeq ($(OSTYPE_$(1)), linux-androideabi)
   LIBUV_OSTYPE_$(1) := android
   LIBUV_ARGS_$(1) := PLATFORM=android host=android OS=linux
+  JEMALLOC_ARGS_$(1) := --disable-tls
 else
   LIBUV_OSTYPE_$(1) := linux
 endif
@@ -221,6 +230,41 @@ $$(LIBUV_DIR_$(1))/Release/libuv.a: $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) \
 endif
 
 ################################################################################
+# jemalloc
+################################################################################
+
+ifdef CFG_ENABLE_FAST_MAKE
+JEMALLOC_DEPS := $(S)/.gitmodules
+else
+JEMALLOC_DEPS := $(wildcard \
+		   $(S)src/jemalloc/* \
+		   $(S)src/jemalloc/*/* \
+		   $(S)src/jemalloc/*/*/* \
+		   $(S)src/jemalloc/*/*/*/*)
+endif
+
+JEMALLOC_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc)
+ifeq ($$(CFG_WINDOWSY_$(1)),1)
+  JEMALLOC_REAL_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc_s)
+else
+  JEMALLOC_REAL_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc_pic)
+endif
+JEMALLOC_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(JEMALLOC_NAME_$(1))
+JEMALLOC_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/jemalloc
+
+$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
+	@$$(call E, make: jemalloc)
+	cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
+		$$(JEMALLOC_ARGS_$(1)) --enable-cc-silence --with-jemalloc-prefix=je_ \
+		--disable-experimental --build=$(CFG_BUILD) --host=$(1) \
+		CC="$$(CC_$(1))" \
+		AR="$$(AR_$(1))" \
+		RANLIB="$$(AR_$(1)) s" \
+		EXTRA_CFLAGS="$$(CFG_GCCISH_CFLAGS)"
+	$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
+	$$(Q)cp $$(JEMALLOC_BUILD_DIR_$(1))/lib/$$(JEMALLOC_REAL_NAME_$(1)) $$(JEMALLOC_LIB_$(1))
+
+################################################################################
 # compiler-rt
 ################################################################################
 
diff --git a/mk/tests.mk b/mk/tests.mk
index 012ec0e862d..71d56d11a73 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -240,6 +240,7 @@ ALL_HS := $(filter-out $(S)src/rt/vg/valgrind.h \
 tidy:
 		@$(call E, check: formatting)
 		$(Q)find $(S)src -name '*.r[sc]' \
+		| grep '^$(S)src/jemalloc' -v \
 		| grep '^$(S)src/libuv' -v \
 		| grep '^$(S)src/llvm' -v \
 		| grep '^$(S)src/gyp' -v \
@@ -264,8 +265,9 @@ tidy:
 		$(Q)find $(S)src -type f -perm +111 \
 		    -not -name '*.rs' -and -not -name '*.py' \
 		    -and -not -name '*.sh' \
-		| grep '^$(S)src/llvm' -v \
+		| grep '^$(S)src/jemalloc' -v \
 		| grep '^$(S)src/libuv' -v \
+		| grep '^$(S)src/llvm' -v \
 		| grep '^$(S)src/rt/hoedown' -v \
 		| grep '^$(S)src/gyp' -v \
 		| grep '^$(S)src/etc' -v \
diff --git a/src/jemalloc b/src/jemalloc
new file mode 160000
+Subproject 6a96910f2eaea6d2c705bb12379b23576b30d7d
diff --git a/src/libstd/rt/heap.rs b/src/libstd/rt/heap.rs
new file mode 100644
index 00000000000..b4b44fbf5c7
--- /dev/null
+++ b/src/libstd/rt/heap.rs
@@ -0,0 +1,97 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use intrinsics::{abort, cttz32};
+use libc::{c_int, c_void, size_t};
+use ptr::RawPtr;
+
+#[link(name = "jemalloc", kind = "static")]
+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_dallocx(ptr: *mut c_void, flags: c_int);
+    fn je_nallocx(size: size_t, flags: c_int) -> size_t;
+}
+
+// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
+#[cfg(not(windows))]
+#[link(name = "pthread")]
+extern {}
+
+// MALLOCX_ALIGN(a) macro
+#[inline(always)]
+fn mallocx_align(a: uint) -> c_int { unsafe { cttz32(a as u32) as c_int } }
+
+/// Return a pointer to `size` bytes of memory.
+///
+/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The
+/// alignment must be no larger than the largest supported page size on the platform.
+#[inline]
+pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
+    let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8;
+    if ptr.is_null() {
+        abort()
+    }
+    ptr
+}
+
+/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory.
+///
+/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The
+/// alignment must be no larger than the largest supported page size on the platform.
+///
+/// The `old_size` and `align` parameters are the parameters that were used to create the
+/// allocation referenced by `ptr`. The `old_size` parameter may also be the value returned by
+/// `usable_size` for the requested size.
+#[inline]
+#[allow(unused_variable)] // for the parameter names in the documentation
+pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> *mut u8 {
+    let ptr = je_rallocx(ptr as *mut c_void, size as size_t, mallocx_align(align)) as *mut u8;
+    if ptr.is_null() {
+        abort()
+    }
+    ptr
+}
+
+/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory in-place.
+///
+/// Return true if successful, otherwise false if the allocation was not altered.
+///
+/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The
+/// alignment must be no larger than the largest supported page size on the platform.
+///
+/// The `old_size` and `align` parameters are the parameters that were used to
+/// create the allocation referenced by `ptr`. The `old_size` parameter may be
+/// any value in range_inclusive(requested_size, usable_size).
+#[inline]
+#[allow(unused_variable)] // for the parameter names in the documentation
+pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> bool {
+    je_xallocx(ptr as *mut c_void, size as size_t, 0, mallocx_align(align)) == size as size_t
+}
+
+/// Deallocate the memory referenced by `ptr`.
+///
+/// The `ptr` parameter must not be null.
+///
+/// The `size` and `align` parameters are the parameters that were used to create the
+/// allocation referenced by `ptr`. The `size` parameter may also be the value returned by
+/// `usable_size` for the requested size.
+#[inline]
+#[allow(unused_variable)] // for the parameter names in the documentation
+pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
+    je_dallocx(ptr as *mut c_void, mallocx_align(align))
+}
+
+/// Return the usable size of an allocation created with the specified the `size` and `align`.
+#[inline]
+pub fn usable_size(size: uint, align: uint) -> uint {
+    unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint }
+}
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 5b9c314d42b..904921cfa18 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -89,7 +89,10 @@ mod macros;
 // The global (exchange) heap.
 pub mod global_heap;
 
-// Implementations of language-critical runtime features like @.
+/// The low-level memory allocation API.
+pub mod heap;
+
+/// Implementations of language-critical runtime features like @.
 pub mod task;
 
 // The EventLoop and internal synchronous I/O interface.