From 684dd9473f4cd64ce1c9f3f16f8a6d40d65a25e5 Mon Sep 17 00:00:00 2001 From: Dylan Conway Date: Sat, 18 Apr 2026 13:59:18 -0700 Subject: [PATCH 1/2] deps(mimalloc): set MI_OVERRIDE=OFF on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mimalloc's CMake defaults MI_OVERRIDE to ON. The Windows branch in mimalloc.ts was a comment ("use mimalloc's defaults — no override"), which was wrong about the default and set nothing. This was harmless before dev3 because alloc-override.c's _MSC_VER block was a no-op ("cannot override malloc unless using a dll"). Upstream microsoft/mimalloc#1259/#1263 filled it in with real CRT symbol definitions (_expand/_msize/free), so the static lib now exports them and lld-link fails Windows debug builds with: duplicate symbol: _expand defined in mimalloc-debug.lib(alloc.c.obj) and libucrtd.lib(expand.obj) Bun links the static CRT and calls mi_* directly on Windows; nothing routes through CRT malloc, so override has no benefit. Setting OFF restores the effective pre-dev3 behavior. CI didn't catch this because all ci-* profiles use buildType: Release, which links /MT (libucrt) — its expand.obj isn't pulled into the link. Only /MTd (libucrtd) drags expand.obj in for its debug-heap symbols. --- scripts/build/deps/mimalloc.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/build/deps/mimalloc.ts b/scripts/build/deps/mimalloc.ts index 8347f8d9e2c..d2c367c0c40 100644 --- a/scripts/build/deps/mimalloc.ts +++ b/scripts/build/deps/mimalloc.ts @@ -83,9 +83,14 @@ export const mimalloc: Dependency = { args.MI_OVERRIDE = "ON"; args.MI_OSX_ZONE = "OFF"; args.MI_OSX_INTERPOSE = "OFF"; + } else if (cfg.windows) { + // Bun links the static CRT and calls mi_* directly; nothing routes + // through CRT malloc. With override ON, dev3's alloc-override.c + // emits _expand/_msize/free into the static lib and lld-link + // duplicates against libucrt(d). mimalloc's *default* is ON, so + // this must be explicit. + args.MI_OVERRIDE = "OFF"; } - // Windows: use mimalloc's defaults (no override; Windows has its own - // mechanism via the static CRT we link). if (cfg.debug) { // Heavy debug checks: guard bytes, freed-memory poisoning, double-free From 1432ab396d3e9a53f646ba3cf71ecbe9813e7713 Mon Sep 17 00:00:00 2001 From: Dylan Conway Date: Sat, 18 Apr 2026 14:06:28 -0700 Subject: [PATCH 2/2] deps(mimalloc): add Windows row to override decision matrix --- scripts/build/deps/mimalloc.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/scripts/build/deps/mimalloc.ts b/scripts/build/deps/mimalloc.ts index d2c367c0c40..b9576eda953 100644 --- a/scripts/build/deps/mimalloc.ts +++ b/scripts/build/deps/mimalloc.ts @@ -59,13 +59,16 @@ export const mimalloc: Dependency = { // ─── Override behavior (global malloc replacement) ─── // The decision matrix: - // ASAN: always OFF — ASAN interceptors must see the real malloc. - // macOS: OFF — macOS's malloc zones are sufficient and overriding - // causes issues with system frameworks (SecureTransport, etc.) - // that have their own allocator expectations. - // Linux: ON — this is the main win. All malloc/free goes through - // mimalloc, including WebKit's bmalloc when it falls back - // to system malloc. + // ASAN: always OFF — ASAN interceptors must see the real malloc. + // macOS: OFF — macOS's malloc zones are sufficient and overriding + // causes issues with system frameworks (SecureTransport, etc.) + // that have their own allocator expectations. + // Linux: ON — this is the main win. All malloc/free goes through + // mimalloc, including WebKit's bmalloc when it falls back + // to system malloc. + // Windows: OFF — Bun links the static CRT and calls mi_* directly; + // dev3's alloc-override.c emits _expand/_msize/free which + // duplicate against libucrt(d) at link time. if (cfg.asan) { args.MI_TRACK_ASAN = "ON"; args.MI_OVERRIDE = "OFF"; @@ -84,11 +87,7 @@ export const mimalloc: Dependency = { args.MI_OSX_ZONE = "OFF"; args.MI_OSX_INTERPOSE = "OFF"; } else if (cfg.windows) { - // Bun links the static CRT and calls mi_* directly; nothing routes - // through CRT malloc. With override ON, dev3's alloc-override.c - // emits _expand/_msize/free into the static lib and lld-link - // duplicates against libucrt(d). mimalloc's *default* is ON, so - // this must be explicit. + // mimalloc's *default* is ON, so this must be explicit. args.MI_OVERRIDE = "OFF"; }