Skip to content

Commit

Permalink
Update mimalloc, enable for glibc Linux aarch64, explicitly disable f…
Browse files Browse the repository at this point in the history
…or wasm and musl (vercel/turborepo#8462)

# Description
    
- **Update mimalloc** dependency.
- **Enable mimalloc for Linux on aarch64 with glibc:** it seems to work
  just fine!
- **Disable mimalloc for wasm and musl.** Mimalloc is already disabled
  for these platforms in next-swc, but I want to centralize these platform
  checks:
  https://github.com/vercel/next.js/blob/73918c6711b538678dd66303fdbd61bfd10b288c/packages/next-swc/crates/napi/src/lib.rs#L71
- **Reduce duplicate code across platforms.** The two implementations of
  `TurboMalloc` were identical, aside from the base allocator used. Move
  the compile-time branch into an inlined function.

**Related Next.JS PR:** #66815

# Testing

## On glibc Linux aarch64

```
pnpm pack-next
```

Install into a test project and try running the development server.

## Other platforms

I have not tested other platforms, and will rely on CI for those (here
and in #66815)
  • Loading branch information
bgw authored Jun 14, 2024
1 parent c04a578 commit 5173a3c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 47 deletions.
10 changes: 5 additions & 5 deletions crates/turbo-tasks-malloc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[package]
name = "turbo-tasks-malloc"
version = "0.1.0"
description = "TBD"
description = "A wrapper around mimalloc or the system allocator that tracks allocations"
license = "MPL-2.0"
edition = "2021"
autobenches = false

[lib]
bench = false

[target.'cfg(not(target_os = "linux"))'.dependencies]
mimalloc = { version = "0.1.32", features = [], optional = true }
[target.'cfg(not(any(target_os = "linux", target_family = "wasm", target_env = "musl")))'.dependencies]
mimalloc = { version = "0.1.42", features = [], optional = true }

[target.'cfg(all(target_os = "linux", not(target_arch = "aarch64")))'.dependencies]
mimalloc = { version = "0.1.32", features = [
[target.'cfg(all(target_os = "linux", not(any(target_family = "wasm", target_env = "musl"))))'.dependencies]
mimalloc = { version = "0.1.42", features = [
"local_dynamic_tls",
], optional = true }

Expand Down
59 changes: 17 additions & 42 deletions crates/turbo-tasks-malloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,70 +67,45 @@ impl TurboMalloc {
}
}

#[cfg(all(
feature = "custom_allocator",
not(all(target_os = "linux", target_arch = "aarch64"))
))]
unsafe impl GlobalAlloc for TurboMalloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ret = mimalloc::MiMalloc.alloc(layout);
if !ret.is_null() {
add(layout.size());
}
ret
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
mimalloc::MiMalloc.dealloc(ptr, layout);
remove(layout.size());
}

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let ret = mimalloc::MiMalloc.alloc_zeroed(layout);
if !ret.is_null() {
add(layout.size());
}
ret
}

unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let ret = mimalloc::MiMalloc.realloc(ptr, layout, new_size);
if !ret.is_null() {
let old_size = layout.size();
update(old_size, new_size);
}
ret
}
/// Get the allocator for this platform that we should wrap with TurboMalloc.
#[inline]
fn base_alloc() -> &'static impl GlobalAlloc {
#[cfg(all(
feature = "custom_allocator",
not(any(target_family = "wasm", target_env = "musl"))
))]
return &mimalloc::MiMalloc;
#[cfg(any(
not(feature = "custom_allocator"),
any(target_family = "wasm", target_env = "musl")
))]
return &std::alloc::System;
}

#[cfg(any(
not(feature = "custom_allocator"),
all(target_os = "linux", target_arch = "aarch64")
))]
unsafe impl GlobalAlloc for TurboMalloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ret = std::alloc::System.alloc(layout);
let ret = base_alloc().alloc(layout);
if !ret.is_null() {
add(layout.size());
}
ret
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
std::alloc::System.dealloc(ptr, layout);
base_alloc().dealloc(ptr, layout);
remove(layout.size());
}

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let ret = std::alloc::System.alloc_zeroed(layout);
let ret = base_alloc().alloc_zeroed(layout);
if !ret.is_null() {
add(layout.size());
}
ret
}

unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let ret = std::alloc::System.realloc(ptr, layout, new_size);
let ret = base_alloc().realloc(ptr, layout, new_size);
if !ret.is_null() {
let old_size = layout.size();
update(old_size, new_size);
Expand Down

0 comments on commit 5173a3c

Please sign in to comment.