Skip to content

[wasm64] Fix 32-bit size limits in emmalloc - #28035

Open
sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:fix_emmalloc_wasm64
Open

sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:fix_emmalloc_wasm64

Conversation

@sbc100

@sbc100 sbc100 commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

In system/lib/emmalloc.c:

  • Define FREE_REGION_FLAG as ((size_t)1) instead of 0x1u so that
    ~FREE_REGION_FLAG does not clear the upper 32 bits of 64-bit region
    sizes when decoding ceiling sizes or merging free regions.
  • Increase MAX_ALLOC_SIZE on wasm64 to 0xFFFFFFFFFFull (~1 TiB)
    rather than a 32-bit constant, allowing allocations >= 4 GiB.
  • Cast alignment to uintptr_t in ALIGN_UP, ALIGN_DOWN, and
    HAS_ALIGNMENT so ~((uintptr_t)(alignment)-1) is 64-bit clean.
  • Return NUM_FREE_BUCKETS - 1 directly for sizes >= 128 MiB in
    compute_free_list_bucket (and clamp sizes >= 2 GiB in
    emmalloc_compute_free_dynamic_memory_fragmentation_map) to avoid
    32-bit truncation in __builtin_clz.

Fixes: #28028

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates emmalloc to support 64-bit architectures (wasm64) by transitioning size fields and constants to use size_t, fixing potential overflow issues in allocation size checks, and adding comprehensive tests for large allocations. The feedback suggests addressing a potential signed/unsigned comparison warning in compute_free_list_bucket by explicitly using an unsigned literal for the bitwise shift.

Comment thread system/lib/emmalloc.c Resolved
@sbc100
sbc100 force-pushed the fix_emmalloc_wasm64 branch from 1d47865 to a73a2d2 Compare October 20, 2026 21:49
@sbc100
sbc100 requested a review from juj October 20, 2026 21:50
@sbc100

sbc100 commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

@juj, WDTY? The solution here was mostly vibe coded but looks reasonable to me.

@sbc100
sbc100 requested a review from kleisauke October 20, 2026 21:51
@sbc100
sbc100 force-pushed the fix_emmalloc_wasm64 branch 3 times, most recently from 187b09c to b36b43c Compare October 27, 2026 19:07
Comment thread system/lib/emmalloc.c Resolved
Comment thread system/lib/emmalloc.c
? 110 - (clz<<2) + ((allocSize >> (29-clz)) ^ 4)
: MIN( 71 - (clz<<1) + ((allocSize >> (30-clz)) ^ 2), NUM_FREE_BUCKETS-1);
? 110 - (clz<<2) + ((allocSize >> (29-clz)) ^ 4)
: 71 - (clz<<1) + ((allocSize >> (30-clz)) ^ 2);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks like code size neutral change, lgtm. (There might be a way to squeeze out the if() with a bit trick, but might not make much difference)

Comment thread system/lib/emmalloc.c Resolved
@sbc100
sbc100 force-pushed the fix_emmalloc_wasm64 branch from b36b43c to 1fdc655 Compare October 29, 2026 00:02
@sbc100
sbc100 requested review from juj and kripken October 29, 2026 00:26
@sbc100

sbc100 commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

ping @juj, I think all your comments are addressed now.

In `system/lib/emmalloc.c`:
- Define `FREE_REGION_FLAG` as `((size_t)1)` instead of `0x1u` so that
  `~FREE_REGION_FLAG` does not clear the upper 32 bits of 64-bit region
  sizes when decoding ceiling sizes or merging free regions.
- Increase `MAX_ALLOC_SIZE` on `wasm64` to `0xFFFFFFFFFFull` (~1 TiB)
  rather than a 32-bit constant, allowing allocations >= 4 GiB.
- Cast `alignment` to `uintptr_t` in `ALIGN_UP`, `ALIGN_DOWN`, and
  `HAS_ALIGNMENT` so `~((uintptr_t)(alignment)-1)` is 64-bit clean.
- Return `NUM_FREE_BUCKETS - 1` directly for sizes >= 128 MiB in
  `compute_free_list_bucket` (and clamp sizes >= 2 GiB in
  `emmalloc_compute_free_dynamic_memory_fragmentation_map`) to avoid
  32-bit truncation in `__builtin_clz`.

Fixes: emscripten-core#28028
@sbc100
sbc100 force-pushed the fix_emmalloc_wasm64 branch from 1fdc655 to c1ae2ea Compare October 30, 2026 21:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

emmalloc in wasm64 (-m64): no block of 4 GiB or more, and free regions of 4 GiB or more corrupt the heap

2 participants