Skip to content

reintroduce jemalloc and use it as the Vec<T> and exchange allocator #14006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 11, 2014
Merged

reintroduce jemalloc and use it as the Vec<T> and exchange allocator #14006

merged 11 commits into from
May 11, 2014

Conversation

thestinger
Copy link
Contributor

Closes #11807


$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
@$$(call E, make: jemalloc)
cd "$(S)src/jemalloc"; autoconf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently depend on autotools, and I think that is explicitly done. Can we fork jemalloc, configure it, check in ./configure and use the fork?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we could do this via a fork - it would also be a good place to put the configure cache with the workaround for the Windows cross-compilation issue

@pnkfelix
Copy link
Member

pnkfelix commented May 7, 2014

cc me

@brson
Copy link
Contributor

brson commented May 8, 2014

I think this is going to require further discussion before merging since there's some disagreement about how we should treat allocations that require special alignment.

My preference is:

  • Our internal allocator API takes alignment paramenters
  • By default it is backed by jemalloc, which aligns as requested
  • The malloc implementation can be replaced at compile time for those that don't want or can't use jemalloc
  • malloc is not required to obey alignment requests, and therefore the default exchange heap allocator provides no alignment guarantees beyond what is specced for malloc
  • Code that must guarantee alignment is welcome to override the allocator parameter on the boxes it creates with an allocator that gives them the alignment they need

@thestinger
Copy link
Contributor Author

It's possible to build an allocator respecting alignment around malloc, realloc and free by adding padding. Rust isn't going to be able to provide portable SIMD types or an alignment attribute if type alignment requirements aren't respected, so I think it's important.

It shouldn't be necessary to rewrite all of the standard collections in order to use types with alignment requirements higher than the platform's choice. The malloc family of functions is supposed to support the alignment necessary for any built-in C type, but it's a legacy claim - no one wants to raise it above 16 bytes because it would add a lot of overhead. The highest alignment required for a built-in C type seems like a bad thing to leak as a user-facing detail into Rust's semantics, especially when platforms ignore the requirement.

The exchange allocator itself has no realloc function, so it can be implemented in terms of posix_memalign and free. On Windows, _aligned_malloc, _aligned_realloc and _aligned_free are all available in the C runtime.

The missing piece on *nix operating systems is an aligned realloc function, but calling posix_memalign and using memcpy is a viable workaround. It loses the in-place realloc optimization, but C++ std::vector implementations are plagued by this issue so it's nothing new (pardon the pun).

The malloc implementation can be replaced at compile time for those that don't want or can't use jemalloc

I don't really think this is a pressing need. I don't think there's a use case for using libc malloc instead of jemalloc, because it's portable to the same platforms as Rust. Debian and Fedora want us to provide an --external-jemalloc switch making use of a libjemalloc.so / libjemalloc.a provided by the system. They'll want the same thing for LLVM, libuv and any other third party dependency including libbacktrace and compiler-rt.

@thestinger
Copy link
Contributor Author

Statically linking jemalloc with mingw-w64 is broken. It could be dynamically linked there for now or left out... https://sourceforge.net/p/mingw-w64/bugs/395/

@thestinger
Copy link
Contributor Author

I discovered a workaround for the Windows issue, which is passing --enable-lazy-lock to avoid the global initialization. There's no harm in passing this flag so it's not even a hack. I've reported this as a mingw-w64 issue (since that appears to be the source) along with a jemalloc issue for good measure.

unsafe fn alloc(cap: uint) -> *mut Vec<()> {
let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).unwrap();
// this should use the real alignment, but the new representation will take care of that
let ret = rust_malloc(cap, 8) as *mut Vec<()>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Malloc uses 16 bytes as a default I think, shouldn't this use that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It uses 16 bytes on x86_64, but I think it uses 8 bytes on x86 and ARM. The only types we currently have with > 8 byte alignment are feature gated (f128, simd) so I'm using this as a hack until ~[T]/~str are removed. I think 8 is better since it won't regress anything.

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
In stage0, all allocations are 8-byte aligned. Passing a size and
alignment to free is not yet implemented everywhere (0 size and 8 align
are used as placeholders). Fixing this is part of #13994.

Closes #13616
This module only contains wrappers for malloc and realloc with
out-of-memory checks.
bors added a commit that referenced this pull request May 11, 2014
@bors bors closed this May 11, 2014
@bors bors merged commit 81fadbb into rust-lang:master May 11, 2014
@thestinger thestinger deleted the jemalloc branch May 11, 2014 07:49
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reintroduce jemalloc
6 participants