From dd713edd4a16036d2b4e862e92b9633f271a22a3 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 26 May 2026 20:38:09 +0800 Subject: [PATCH] fix(sys): vendor Apple THREAD_LOCAL patch in napi-rs/mimalloc fork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple targets in mimalloc v3 default to MI_TLS_MODEL_FIXED_SLOT, which stores the per-thread heap pointer in TCB[108]/[109] — a hardcoded slot shared by every image in the process. Two napi addons statically linking mimalloc into the same Node.js process collide on that slot, crashing the second one on load. The earlier -DMI_HAS_TLS_SLOT=0 workaround (routing Apple to MI_TLS_MODEL_DYNAMIC_PTHREADS) leaks a pthread key on process exit, which causes background threads (e.g. rayon workers from oxc) to abort when they next allocate. Switch to THREAD_LOCAL + RECURSE_GUARD by carrying the patch directly in our mimalloc fork (napi-rs/mimalloc, branch dev3) instead of rewriting prim.h at build time. Per-image __thread storage gives addons their own heap pointer; no pthread key means nothing for the destructor to break. - Repoint mimalloc3 submodule URL → https://github.com/napi-rs/mimalloc branch dev3 (currently v3.3.2 + the prim.h patch on top). - Drop the build.rs -DMI_HAS_TLS_SLOT=0 workaround. Supersedes #67. Co-Authored-By: Claude Opus 4.7 --- .gitmodules | 3 ++- libmimalloc-sys/build.rs | 32 ++++---------------------------- libmimalloc-sys/c_src/mimalloc3 | 2 +- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6dc00a5..58b35de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,5 @@ url = https://github.com/microsoft/mimalloc.git [submodule "libmimalloc-sys/c_src/mimalloc3"] path = libmimalloc-sys/c_src/mimalloc3 - url = https://github.com/microsoft/mimalloc.git + url = https://github.com/napi-rs/mimalloc.git + branch = dev3 diff --git a/libmimalloc-sys/build.rs b/libmimalloc-sys/build.rs index 3cfc819..6048cb3 100644 --- a/libmimalloc-sys/build.rs +++ b/libmimalloc-sys/build.rs @@ -76,34 +76,10 @@ fn main() { cmake_config.define("MI_LOCAL_DYNAMIC_TLS", "ON"); } - // On Apple targets, mimalloc v3's `prim.h` selects - // `MI_TLS_MODEL_FIXED_SLOT` and hardcodes the per-thread `theap` - // pointer at TCB[108]/[109], reading/writing the slot directly - // through `tpidrro_el0` (arm64) or `%gs:` (x86_64) rather than - // through `pthread_setspecific`. The slot numbers are not allocated - // via `pthread_key_create`; the same header notes the caveat: - // "This goes wrong though if the OS or a library uses the same - // fixed slot." - // - // When a process loads more than one image that statically links - // mimalloc-safe (e.g. two napi addons in one Node.js process), - // each image has its own mimalloc state but every image's - // `_mi_theap_default()` reads and writes the same TCB[108] on any - // given thread — the instances overwrite each other's pointers. - // - // `-DMI_HAS_TLS_SLOT=0` makes the cascade in `prim.h` skip the - // FIXED_SLOT branch on Apple and fall through to - // `MI_TLS_MODEL_DYNAMIC_PTHREADS`, whose accessors use - // `pthread_{get,set}specific` with a key allocated per image via - // `pthread_key_create`. Different images then use distinct keys and - // no longer share TLS storage. `prim.h` notes this path is "a bit - // slower"; the impact has not been measured here. - // - // Gated on the `v3` feature: v2 has a separate Apple fast path - // controlled by `MI_TLS_SLOT` and is not affected by this define. - if target_os == "macos" && env::var_os("CARGO_FEATURE_V3").is_some() { - cmake_config.cflag("-DMI_HAS_TLS_SLOT=0"); - } + // Note: the previous `-DMI_HAS_TLS_SLOT=0` workaround for Apple has been + // replaced by a vendored source patch in our mimalloc fork (napi-rs/mimalloc + // dev3) that routes Apple to `MI_TLS_MODEL_THREAD_LOCAL + MI_TLS_RECURSE_GUARD` + // directly in `include/mimalloc/prim.h`. See that patch for the full rationale. if (target_os == "linux" || target_os == "android") && env::var_os("CARGO_FEATURE_NO_THP").is_some() diff --git a/libmimalloc-sys/c_src/mimalloc3 b/libmimalloc-sys/c_src/mimalloc3 index 30b2d9d..9a15529 160000 --- a/libmimalloc-sys/c_src/mimalloc3 +++ b/libmimalloc-sys/c_src/mimalloc3 @@ -1 +1 @@ -Subproject commit 30b2d9d89099bee08e9f67a1ffb3e12e7ba45227 +Subproject commit 9a15529dc99d27fb7983eed37b4290b541834c86