1815 Commits
Author SHA1 Message Date
Tony Printezis ff80bf2d0c Cleanup LG_HUGEPAGE == 0 conditions
* ensure that LG_HUGEPAGE > LG_PAGE
* add sanity checks
* remove any LG_HUGEPAGE == 0 or equivalent conditions
2026-09-10 18:34:33 -04:00
Slobodan Predolac a3ac9c6e34 Remove total_elapsed_ns_per_ps stat 2026-09-09 16:13:32 -04:00
Slobodan Predolac fe33667230 Expose JEMALLOC_INFALLIBLE_NEW in the public header 2026-09-02 15:32:11 -07:00
guangli-dai e46e021986 Silently tolerate invalid experimental_ and deprecated options without sending stderr. 2026-09-02 15:31:51 -07:00
Azat Khuzhin 61dc1da395 Fix possible tcache corruption on fiber migration (under --enable-experimental-fiber-safe-tls)
Under LTO `&tsd_tls` is hoisted out of the inlined malloc/free and
survives swapcontext in a callee-saved register: a fiber resumed on
another OS thread races on the old thread's tcache.

Fix it by taking the address in a noinline volatile-asm barrier accessor.

It is done under option (--enable-experimental-fiber-safe-tls), because
it make the fastpath slower, on a microbench (that is very heavy depends
on the most optimal case) the overhead is 35%, but this is unlikely the
real world scenario.

Anyway here are some numbers for microbench.c compiled with LTO:

type    |vanilla (ns)|`--enable-experimental-fiber-safe-tls` (ns)|optimized (ns) [1]
--------|------------|-------------------------------------------|------------------
malloc  |6.51        |8.77 **(+34%)**                            |6.79 (4%)
mallocx |8.48        |10.62 **(25%)**                            |8.76 (3%)
free    |6.46        |8.68 **(34%)**                             |6.76 (5%)
dallocx |8.190       |10.97 **(33%)**                            |8.74 (7%)

  [1]: https://github.com/jemalloc/jemalloc/pull/2944

This patch also adds a separate lane for CI with LTO
2026-09-01 22:10:15 -04:00
guangli-dai 278d90a502 Parse pid namespace parsing without using glibc dependencies.
This prevents touch static buffer as well as providing better tailored
format detections.  Also change the return type of pid namespace from
long to uint64_t to be more robust.
2026-09-01 15:30:09 -07:00
guangli-dai 29e3db6767 Move /etc/malloc.conf symlink reading to OS layer 2026-09-01 15:30:09 -07:00
guangli-dai c86489bf4f Move spin.h's thread-yield to OS layer 2026-09-01 15:30:09 -07:00
guangli-dai f99cb055c7 Move background thread's CPU-affinity setting to OS layer 2026-09-01 15:30:09 -07:00
guangli-dai 81020da62f Move profiling's proc-maps dumping and pid-namespace lookup to OS layer 2026-09-01 15:30:09 -07:00
guangli-dai c303c02882 Remove redundant _WIN32 check in mutex.c's pthread_create() intercept
configure.ac force-disables JEMALLOC_LAZY_LOCK on every Windows build
already, so there is no need to do another _WIN32 check here after the
JEMALLOC_LAZY_LOCK check.  Same for JEMALLOC_MAPS_COLESCE and
JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS.
2026-09-01 15:30:09 -07:00
Slobodan Predolac d13fe91afd Adapt tcache fill and retention
Replace divisor-based small-bin refill control and fixed GC flushing
with per-bin fill and retention targets based on use between GC events.
Keep the bounds valid for all configured capacities, and ensure a
full-bin flush always frees a slot.

Simplify the configuration space by removing and deprecating
experimental_tcache_gc, lg_tcache_nslots_mul,
tcache_nslots_small_min, tcache_nslots_small_max, tcache_nslots_large,
tcache_gc_delay_bytes, lg_tcache_flush_small_div, and
lg_tcache_flush_large_div. Per-size-class cache capacity remains
configurable through tcache_ncached_max.
2026-09-01 11:51:32 -04:00
Tony Printezis e36a0fa5bc Fix prof-sampling / guard-page interaction bug in the SAN
Due to an incorrect condition, a prof-promoted small allocation
was incorrectly wrapped in large-extent guard pages. This consumed
the large-guard budget, so the next genuinely large allocation that
should have been guarded got skipped.
2026-08-10 09:16:09 -04:00
guangli-dai 1ec505b751 Move FMTd32-family printf macros to OS layer
Move macros defining the FMT module to OS layer.
2026-08-04 21:31:35 -07:00
guangli-dai 21ddfb1e8e Move error-code handling to OS layer
Move error-code handling functions, namely, errno_set, errno_get, and
strerror to OS layer.
2026-08-04 21:31:35 -07:00
guangli-dai 2c87eff72c Move boot and overcommit setup to the OS layer.
This commit also migrates some detection in configure.ac into OS
dipatcher since they both rely on the same preprocessor OS flags.
2026-08-04 21:31:35 -07:00
guangli-dai c8e2e0134c Move VM reserve/release/purge/commit/decommit/guards/trim to OS layer
Migrates some VM functions namely, reserve, release, purge, commit,
decommit, guards (mark and unmark), and trim to OS layer.
2026-08-04 21:31:35 -07:00
guangli-dai 89b9aef8f7 Move process write part (atfork) to OS layer
Migrates pthread_atfork(3) registration onto the existing os/process.h
dispatcher.
2026-08-04 21:31:35 -07:00
guangli-dai 85599c8b12 Move CPU facility to OS layer
Migrates CPU-count detection, current-CPU-index, and CPU deterministic
queries onto the OS layer.
2026-07-31 16:51:20 -07:00
guangli-dai 192271fb82 Move sync (mutex) + cond + sigmask to OS layer
Migrates the mutex backend selection out of mutex.h/mutex.c, and the
background thread's condition-variable and signal-masking code out of
background_thread.c, onto the OS layer dispatcher pattern.
2026-07-31 16:51:20 -07:00
guangli-dai c5b082c470 Move time facility to OS layer
Migrates the Time facility to the OS layer.
2026-07-31 16:51:20 -07:00
guangli-dai 5421943db7 Add comments to retain context for syscall usage in file read/write. 2026-07-31 12:57:31 -07:00
guangli-dai b62e7d2b06 Move file I/O and process ID retrieval to OS layer
Adds the File I/O and Process facilities to the OS layer, following
the os.h dispatcher pattern:
2026-07-30 09:43:34 -07:00
guangli-dai c4158acac9 OS layer scaffolding (dispatcher)
Introduce the `os.h` dispatcher pattern under
`include/jemalloc/internal/os/`, with no modules wired in yet.

  - os.h        - documents the os/<module>.h dispatcher / os/posix/
                  default / os/<os>/ override pattern that every
                  facility will follow.
  - os/detect.h - JEMALLOC_OS_POSIX platform detection, shared by every
                  module dispatcher.
2026-07-30 09:43:34 -07:00
guangli-dai 6957341f19 Fix potential deadlokc during arena_reset. 2026-07-27 15:02:59 -07:00
Slobodan Predolac 04aad97faa Expose stats table columns in JSON output and simplify code 2026-07-21 09:38:27 -04:00
Slobodan Predolac 80c8fcb4f9 Refactor stats tables around descriptor-driven row emission 2026-07-21 09:38:27 -04:00
Slobodan Predolac 184f304dd3 Refactor stats.c: separate gathering from emission; read top-down
src/stats.c fused mallctl reads with dual-format (text/JSON) emission inside a
few very large, bottom-up functions, behind dense macros, with the public entry
point at the very bottom.  Rework it to be output-preserving but much easier to
read and extend:

- Separate gathering from emission where it is worth it: most sections become a
  small gather (stats_gather_*, the mallctl reads into a typed struct) plus an
  emit that renders it, with the plumbing macros (CTL_*, COL*) and gather
  structs moved to internal header (stats_internal.h).  This is a balance,
  not a rule: the per-size-class tables stay O(1) streaming (per-row gather+emit,
  no large stack buffers, avoiding heap buffering), the mutex rows keep reading
  straight into emitter columns, and the already-readable config/opt probes are
  left as they are.

- Read like the output: open with a table-of-contents comment and the public
  stats_print(), then the section functions top-down, keeping the
  interval/boot/fork plumbing at the bottom.  The ToC names the function that
  prints each section, and its JSON sub-path.

- Keep one emission engine: the emitter remains the single dual-format renderer,
  so each section has one rendering path rather than parallel renderers (the two
  formats are not field-identical).  Move some table-only concerns into it --
  gap-collapsing ("---") and a dual columnar row op (emitter_row) -- so section
  code carries less table-format detail.

Output-preserving: text is byte-identical and JSON keys/values are unchanged.
2026-07-20 07:30:52 -04:00
Tony Printezis c597d73778 Remove frameptr-based unwinder.
The frameptr-based unwinder was an interim solution while issues with
libunwind were resolved. It's better if we remove it,
so we don't have to support it moving forward.
2026-07-18 11:51:02 -07:00
guangli-dai d410f43e1f Remove thin arena_* deferral/decay wrappers; call pa directly. 2026-07-16 21:52:34 -07:00
guangli-dai f1f0792370 Move background thread state operations into background thread modules.
Move operations touch background thread's lifecycle and states back into
its own module.
2026-07-16 21:52:34 -07:00
guangli-dai 01df5c96e0 Move deferred-work orchestration from arena into pa/pac.
Move most arena-owned PAC deferral & background thread relevant codes
out to pa/pac for decoupling purposes.
2026-07-16 21:52:34 -07:00
guangli-dai e16ebfe27e Refactor deferral constants into corresponding headers.
Currently there are deferral-relevant constants in arena.c and
background_thread.c. This commit moves them out into corresponding PAC
and HPA headers. Those commonly needed by both are put into a new header
deferral.h where the contract of deferral are clearly stated.
2026-07-16 21:52:34 -07:00
guangli-dai 7f52ac7af3 Symmetrize deferred-work execution by moving it from arena to PAC 2026-07-16 21:52:34 -07:00
Antonio Andelic 8361239b03 Detect monotonic condvar support at configure time 2026-07-14 09:25:21 -07:00
Slobodan Predolac fb5499aa9c Handle jemalloc calls after TSD teardown
This only changes behavior for the tsd_generic path, where
pthread_getspecific() can report no TSD after the pthread key destructor
has finished.  Other TSD backends keep tsd_teardown_done() as a constant
false, so the added checks compile out there.

Avoid recreating TSD for late deallocations.  Preserve existing
reincarnation behavior for late allocations and nonzero reallocations.

Add Linux CI coverage for force_tls=0, with and without --enable-debug,
to exercise the Android-equivalent generic TSD path.
2026-07-09 11:30:15 -04:00
Raúl MarínandClaude Opus 4.8 82e379b8f2 Address review: block-comment style and document the macOS 12+ requirement
Reformat the malloc_getcpu Apple comment to the block style and note that the
tpidr_el0/sidt scheme requires macOS 12+: macOS 11 and earlier kept the CPU
number in tpidrro_el0's low 3 bits (now retired). Cite xnu's
__TPIDR_CPU_NUM_MASK / MACHDEP_TPIDR_CPUNUM_MASK, kept in sync with
_os_cpu_number, as the source of truth.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:21:17 -07:00
Raúl MarínandClaude Opus 4.8 5aabbc87bf Fix malloc_getcpu on macOS to read the current CPU number correctly
The Apple branch read the CPU number from the low 3 bits of `tpidrro_el0`.
That layout no longer holds on Apple Silicon: those bits read back as 0, so
`malloc_getcpu` returned 0 for every thread. `percpu_arena` then funneled all
allocations into arena 0, or was disabled outright at init.

Read the CPU number the same way as libplatform's `_os_cpu_number`: the low 12
bits of `tpidr_el0` on arm64, or of the IDT base (via `sidt`) on x86. Also move
the Apple branch ahead of the `rdtscp` one so Apple x86 uses `sidt` rather than
`rdtscp`, whose `ecx` is not the CPU id under XNU.
https://github.com/apple-oss-distributions/xnu/blob/main/libsyscall/os/tsd.h

Verified on a 12-CPU M2 Pro: with `percpu_arena:percpu`, `opt.percpu_arena` now
stays `percpu` and `thread.arena` spreads across all 12 arenas {0..11}; the old
code collapsed every thread onto arena 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:21:17 -07:00
Farid Zakaria b859093d28 Limit TSD bootstrap hook to tests 2026-07-06 18:26:40 -04:00
Farid Zakaria 7c34a482c1 Add TSD reentrant stress test 2026-07-06 18:26:40 -04:00
Schalk Krüger 43a8adc187 Remove experimental_hpa_max_purge_nhp option
It is unused and no longer needed: hpa_dirty_mult, hpa_purge_threshold,
hpa_min_purge_interval_ms, and hpa_min_purge_delay_ms now provide finer
control over the purge rate.
2026-06-27 22:57:48 -04:00
Slobodan Predolac db15a39d75 Keep pac last in pa_shard_s to fix SEC-in-PAC layout regression
9c1a484e embedded sec_t in pac_t (+~48B). Since pac sits before the hot
hpa/edata_cache fields in pa_shard_s, the larger pac_t shifts them and
regresses the free/extent paths ~2% on the fill-flush microbenchmark --
even though SEC is disabled by default and no SEC code runs; it is purely
a struct-layout effect.

Move pac to the last field so its growth shifts only the trailing
all_bins[] flex array. Pure reorder, no functional change.

Validated with the fill-flush microbenchmark (500 threads, 256 B,
MALLOC_CONF=tcache:true,prof:true), turbo pinned, interleaved medians:
on AMD EPYC 9D64 (x86-64) bad regresses ~2% and the reorder restores the
baseline; on ARM Neoverse-V2 (aarch64) there is no measurable regression
and the reorder is neutral.
2026-06-27 17:02:43 -07:00
Bin Liu 9c1a484e1d Use SEC in PAC to reduce lock contention on the ecaches
Add a small extent cache in front of the PAC ecaches. Allocs and dallocs
that fit are served from per-shard SEC bins without taking the ecache
mutex; overflow falls through to the backing ecaches, including
ecache_pinned for pinned extents.

The feature is gated behind experimental_pac_sec_nshards (default 0,
disabled). To support independent HPA and PAC SEC instances,
sec_alloc/sec_dalloc/sec_fill take an explicit shard argument, with HPA
and PAC using separate TSD shard slots.
2026-06-24 10:54:34 -07:00
Bin Liu 2043c6ab58 Make SEC stats lockless
Per-bin SEC stats (bytes_cur, nmisses, nhits, ndalloc_flush,
ndalloc_noflush, noverfills) become atomic_zu_t fields directly inside
sec_bin_t.  Writers continue to hold bin->mtx; sec_stats_merge now reads
them lock-free with ATOMIC_RELAXED instead of acquiring bin->mtx.

This removes a lock-rank reversal that would otherwise occur whenever
stats aggregation runs while holding arena->stats.mtx.
2026-06-24 10:54:34 -07:00
Slobodan Predolac 9f37c70826 Replace JET_WRAP_ with JET_EXTERN_INLINE macro 2026-06-18 13:02:23 -04:00
Slobodan Predolac dfb276f035 Speculative fix for Veracode integer overflow/underflow in sz.h
Veracode flags CWE-190/191 on the `size + mask` round-ups in
sz_s2u_compute_using_delta, sz_s2u_compute and sz_sa2u. We believe these are
false positives: the arithmetic is unsigned size_t (overflow is well-defined in
C, not UB), `size` is already bounded by the SC_LARGE_MAXCLASS guard, and the
masks are tiny, so the additions cannot actually overflow.

CodeQL's security-extended suite (CWE-190/191) does not flag these. Its
uncontrolled-arithmetic query only reports *signed* overflow ("unsigned overflow
is well-defined"), and its tainted-arithmetic query credits the existing
upper-bound guard. Veracode instead treats the public-API size/alignment as
tainted and ignores guards placed above the expression, so piling on more
pre-checks does not satisfy it.

Effect on the malloc/free hot path is zero instructions as verified with
clang -O3 and ThinLTO objdump
2026-06-16 21:02:51 -04:00
Slobodan Predolac 4de3a4c3d1 De-export test-only helpers via JET_EXTERN / #ifdef JEMALLOC_JET; declare in unit tests, not headers 2026-06-11 11:45:05 -04:00
Slobodan Predolac 6db4d0c468 Make ehooks_default_merge static (export was vestigial after merge fast-path removal) 2026-06-11 11:45:05 -04:00
Slobodan Predolac aae199f40f Make single-TU internal helpers static; remove dead hpa_expand/hpa_shrink/pac_reset 2026-06-11 11:45:05 -04:00
Slobodan Predolac 160ab9d7f6 Replace experimental_infallible_new with compile-time flag
The runtime option aborted on every OOM, breaking new(std::nothrow)
semantics. Replace with configure-time --enable-cxx-infallible-new
(default off): when on, throwing new aborts (size logged) and
nothrow returns null; when off, standard new_handler + bad_alloc /
null behavior is preserved. Under LTO the on-path lets the compiler
prove operator new is no-throw.
2026-06-06 09:50:37 -04:00