Address regions can be reused before their old pages finish discarding #2799

Open
opened 2026-11-12 14:41:11 +00:00 by github-sync · 0 comments
Owner

@Arkex-ai opened on GitHub · 2026-11-12 13:47 UTC · original

Problem

In host/hos_mem.c at 51da0464b4cf0c7f56b81ebd6bb309325835e175, hos_region_free removes a range from the allocation table, unlocks it, and only then calls discard_pages. Another thread can allocate the same address before that discard finishes, so the old discard can clear the new owner's pages. Freeing the lowest high address region also leaves region_floor at its old value, retaining a heap-capacity restriction after the region is gone.

Reproduction

A game-free test compiles the actual allocator functions with native threads and a controlled discard callback: allocate A; stop A's finalization at a barrier inside discard; allocate B and write its payload; then let the old discard finish. On current source B reuses A and its payload is cleared. An allocate/free check also shows that the freed boundary still refuses heap growth.

These source-level cases reproduce on Windows with llvm-mingw and Linux with GCC/Clang. The callback is deliberately delayed to exercise the ordering; this is not an observed game crash or a measurement of its frequency.

Scope and claim

Draft #2823 keeps retiring entries reserved until discard returns, excludes them from live-range queries, and restores the boundary after removal. Discard/commit policy and GPU imports are unchanged. Private investigation preceded this claim; the team-room overlap notice was delivered.

Current file overlaps are #2558 (lazy heap commit) and #2478 (an additional mapped-range reader). The latter reader must also exclude retiring entries when combined. No shader-loading, VMA-pool or FSR work is included.

This does not establish the cause of the reported multi-GiB RAM growth or claim physical memory savings. Gameplay validation is pending; the contribution will remain draft.

Priority is left unranked until actual game incidence is measured. The source interleaving is reproducible, but an S0 score and broad reach are not supported by a reproduced player incident. The worklist row was removed in 45dfb561; in-game frees, retiring-entry skips and newly permitted heap resizes still need measurement.

> [@Arkex-ai](https://github.com/Arkex-ai) opened on GitHub · 2026-11-12 13:47 UTC · [original](https://github.com/NotRexed/Hookshot/issues/2799) ## Problem In `host/hos_mem.c` at `51da0464b4cf0c7f56b81ebd6bb309325835e175`, `hos_region_free` removes a range from the allocation table, unlocks it, and only then calls `discard_pages`. Another thread can allocate the same address before that discard finishes, so the old discard can clear the new owner's pages. Freeing the lowest high address region also leaves `region_floor` at its old value, retaining a heap-capacity restriction after the region is gone. ## Reproduction A game-free test compiles the actual allocator functions with native threads and a controlled discard callback: allocate A; stop A's finalization at a barrier inside discard; allocate B and write its payload; then let the old discard finish. On current source B reuses A and its payload is cleared. An allocate/free check also shows that the freed boundary still refuses heap growth. These source-level cases reproduce on Windows with llvm-mingw and Linux with GCC/Clang. The callback is deliberately delayed to exercise the ordering; this is not an observed game crash or a measurement of its frequency. ## Scope and claim Draft #2823 keeps retiring entries reserved until discard returns, excludes them from live-range queries, and restores the boundary after removal. Discard/commit policy and GPU imports are unchanged. Private investigation preceded this claim; the team-room overlap notice was delivered. Current file overlaps are #2558 (lazy heap commit) and #2478 (an additional mapped-range reader). The latter reader must also exclude retiring entries when combined. No shader-loading, VMA-pool or FSR work is included. This does **not** establish the cause of the reported multi-GiB RAM growth or claim physical memory savings. Gameplay validation is pending; the contribution will remain draft. Priority is left unranked until actual game incidence is measured. The source interleaving is reproducible, but an S0 score and broad reach are not supported by a reproduced player incident. The worklist row was removed in 45dfb561; in-game frees, retiring-entry skips and newly permitted heap resizes still need measurement. <!-- github-sync:item:2799 -->
Commenting is not possible because the repository is archived.
No milestone
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Hookshot#2799
No description provided.