Skip to content

refactor(allocator): fixed size allocators handle their own deallocation#22085

Merged
graphite-app[bot] merged 1 commit intomainfrom
om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation
May 2, 2026
Merged

refactor(allocator): fixed size allocators handle their own deallocation#22085
graphite-app[bot] merged 1 commit intomainfrom
om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation

Conversation

@overlookmotel
Copy link
Copy Markdown
Member

@overlookmotel overlookmotel commented May 2, 2026

Arena's chunks already store the pointer and layout of their backing allocations in their ChunkFooters.

However, it still wasn't safe for them to handle Drop themselves, because fixed-size Arenas obtain backing memory direct from the System allocator, bypassing the usual global allocator (which can be switched to e.g. Mimalloc). Therefore, special handling was required to ensure the backing memory was also freed via System allocator - unlike normal Arenas.

Fix that by storing an is_fixed_size flag in ChunkFooter. This flag is set in Arenas created by Arena::from_raw_parts (and so, by extension, by Arena::new_fixed_size). When is_fixed_size flag is set on a chunk, the Arena correctly frees the chunk's backing memory via System allocator. When it's not set (normal Arenas), global allocator is used as usual.

Arenas created with from_raw_parts / new_fixed_size can now manage the entire lifecycle of the memory they own. Arena::new_fixed_size therefore doesn't need to be an unsafe method any more.

All deallocation now goes through dealloc_arena_chunk which Arena provides, which correctly checks the is_fixed_size flag to determine which allocator to return the backing memory to.

Copy link
Copy Markdown
Member Author

overlookmotel commented May 2, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 2, 2026

Merging this PR will not alter performance

✅ 48 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation (2c044b5) with main (d58f594)2

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (2c044b5) during the generation of this report, so d58f594 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@overlookmotel overlookmotel self-assigned this May 2, 2026
@overlookmotel overlookmotel marked this pull request as ready for review May 2, 2026 21:20
Copilot AI review requested due to automatic review settings May 2, 2026 21:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors oxc_allocator fixed-size arena chunks to self-manage deallocation safely by recording which allocator (System vs global) produced the backing allocation, eliminating the need for external/manual System deallocation and allowing new_fixed_size to be safe.

Changes:

  • Add an is_fixed_size flag to ChunkFooter and set it for arenas created via from_raw_parts / fixed-size paths.
  • Centralize chunk deallocation through dealloc_arena_chunk, selecting System.dealloc vs alloc::dealloc based on is_fixed_size.
  • Make Arena::new_fixed_size / Allocator::new_fixed_size safe and update fixed-size pool teardown to use the shared deallocation helper.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/oxc_allocator/src/pool/fixed_size.rs Switch fixed-size allocator teardown to dealloc_arena_chunk and remove manual System dealloc handling.
crates/oxc_allocator/src/fixed_size.rs Make Allocator::new_fixed_size safe and rely on arena-managed lifecycle.
crates/oxc_allocator/src/arena/mod.rs Extend ChunkFooter with is_fixed_size and re-export dealloc helper for fixed-size feature.
crates/oxc_allocator/src/arena/from_raw_parts.rs Mark raw-parts arenas as fixed-size for System-backed deallocation.
crates/oxc_allocator/src/arena/fixed_size.rs Make Arena::new_fixed_size safe and construct via from_raw_parts.
crates/oxc_allocator/src/arena/drop.rs Add dealloc_arena_chunk and route chunk list deallocation through it with allocator selection.
crates/oxc_allocator/src/arena/create.rs Initialize ChunkFooter.is_fixed_size to false for normal (global-alloc) chunks.

Comment thread crates/oxc_allocator/src/pool/fixed_size.rs Outdated
Comment thread crates/oxc_allocator/src/arena/drop.rs Outdated
Comment thread crates/oxc_allocator/src/arena/drop.rs
@overlookmotel overlookmotel added C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior A-allocator Area - Allocator labels May 2, 2026
@overlookmotel overlookmotel force-pushed the om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation branch from b90bd7e to bd7048a Compare May 2, 2026 21:56
@graphite-app
Copy link
Copy Markdown
Contributor

graphite-app Bot commented May 2, 2026

Merge activity

…ion (#22085)

`Arena`'s chunks already store the pointer and layout of their backing allocations in their `ChunkFooter`s.

However, it still wasn't safe for them to handle `Drop` themselves, because fixed-size `Arena`s obtain backing memory direct from the `System` allocator, bypassing the usual global allocator (which can be switched to e.g. Mimalloc). Therefore, special handling was required to ensure the backing memory was also freed via `System` allocator - unlike normal `Arena`s.

Fix that by storing an `is_fixed_size` flag in `ChunkFooter`. This flag is set in `Arena`s created by `Arena::from_raw_parts` (and so, by extension, by `Arena::new_fixed_size`). When `is_fixed_size` flag is set on a chunk, the `Arena` correctly frees the chunk's backing memory via `System` allocator. When it's not set (normal `Arena`s), global allocator is used as usual.

`Arena`s created with `from_raw_parts` / `new_fixed_size` can now manage the entire lifecycle of the memory they own. `Arena::new_fixed_size` therefore doesn't need to be an unsafe method any more.

All deallocation now goes through `dealloc_arena_chunk` which `Arena` provides, which correctly checks the `is_fixed_size `flag to determine which allocator to return the backing memory to.
@graphite-app graphite-app Bot force-pushed the om/05-02-refactor_allocator_add_allocator_new_fixed_size_method branch from 1638b41 to 6de10fc Compare May 2, 2026 23:05
@graphite-app graphite-app Bot force-pushed the om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation branch from bd7048a to 2c044b5 Compare May 2, 2026 23:05
graphite-app Bot pushed a commit that referenced this pull request May 2, 2026
Remove `can_grow` flag from `Arena`. Instead refuse to grow the `Arena` with a new chunk if `ChunkFooter::is_fixed_size` (introduced in #22085) is `true`. This flag is set for fixed-size allocators, so it performs the same purpose as the old `can_grow` flag.
Base automatically changed from om/05-02-refactor_allocator_add_allocator_new_fixed_size_method to main May 2, 2026 23:08
@graphite-app graphite-app Bot merged commit 2c044b5 into main May 2, 2026
37 checks passed
@graphite-app graphite-app Bot deleted the om/05-02-refactor_allocator_fixed_size_allocators_handle_their_own_deallocation branch May 2, 2026 23:09
graphite-app Bot pushed a commit that referenced this pull request May 3, 2026
…22093)

Comments-only change. #22085 altered the docs for `Arena::from_raw_parts` to reflect that arena chunk created by this method will be deallocated via `System` allocator by default, but neglected to update docs for `Allocator::from_raw_parts`. Update the doc comment for this method to bring it into sync.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-allocator Area - Allocator C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants