Fix HXCPP_GC_BIG_BLOCKS row count regression - #1409
Open
dimensionscape wants to merge 1 commit into
Open
dimensionscape wants to merge 1 commit into
dimensionscape wants to merge 1 commit into
Conversation
HaxeFoundation#1402 made BlockDataInfo's mUsedRows and mFraggedRows uint8_t, which fits the default 32k blocks (254 usable lines) but not big blocks (508). With HXCPP_GC_BIG_BLOCKS the counts wrap, the GC underestimates the live heap, and it ends up collecting on almost every new block. Use uint16_t for both (and for the allocator's mFraggedRows pointer), with static_asserts so they can't drop below IMMIX_USEFUL_LINES again.
tobil4sk
reviewed
Oct 3, 2026
| }; | ||
|
|
||
| // A block's row counts run up to IMMIX_USEFUL_LINES: 254 with the default 32k blocks, but 508 with | ||
| // HXCPP_GC_BIG_BLOCKS' 64k blocks, more than a uint8_t holds. |
Member
There was a problem hiding this comment.
This comment doesn't seem very useful to keep, since it refers to the uint8_t that is removed by this PR. I think the static assert is more helpful at documenting the requirement
Contributor
Author
There was a problem hiding this comment.
Yeah, that's fair. It was originally a warning against regression, but the static asserts keep us safe. I'll remove it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#1402 changed
mUsedRowsandmFraggedRowsinBlockDataInfofrominttouint8_t. That's enough for the default 32k blocks, which have 254 usable lines, butHXCPP_GC_BIG_BLOCKSuses 64k blocks with 508 usable lines, so the counts wrap once a block has more than 255 lines in use.The worst effect is that the GC badly underestimates how much memory is in use after a collection. The working-memory target it sets stays far too small, so it ends up collecting almost every time it needs a new block, and a big-blocks build with a reasonable amount of live data spends most of its time in the GC. The wrap also means
countRows()never sees a full block as full, and a block with exactly 256 used lines looks empty.This changes both fields back to
uint16_t, along with the allocator'smFraggedRowspointer and the casts into it. It also addsstatic_asserts so the counts can't end up smaller thanIMMIX_USEFUL_LINESagain. The byte counts are fine asuint16_t(508 x 128 = 65024).See Repro:
Build with
-D HXCPP_GC_BIG_BLOCKSand compare against a build without it. With the define, the churn loop is dramatically slower.Note: on current master you may also hit the marking crash fixed by #1407 while testing this.