mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
add back jemalloc to the tree
This adds a `std::rt::heap` module with a nice allocator API. It's a step towards fixing #13094 and is a starting point for working on a generic allocator trait. The revision used for the jemalloc submodule is the stable 3.6.0 release. Closes #11807
This commit is contained in:
parent
11571cd9c1
commit
1b1ca6d546
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
1
configure
vendored
1
configure
vendored
@ -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
|
||||
|
@ -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
|
||||
|
52
mk/rt.mk
52
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
|
||||
@ -220,6 +229,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
|
||||
################################################################################
|
||||
|
@ -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 \
|
||||
|
1
src/jemalloc
Submodule
1
src/jemalloc
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 6a96910f2eaea6d2c705bb12379b23576b30d7d5
|
97
src/libstd/rt/heap.rs
Normal file
97
src/libstd/rt/heap.rs
Normal file
@ -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 }
|
||||
}
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user