Conversation
With HXCPP_GC_GENERATIONAL, ImmixAllocator::alloc skips 4 bytes when needed so that each nursery object is 8-byte aligned, and the nursery scan that finds conservatively referenced objects (GetEnclosingNurseryType) walks the holes with that alignment. The inline allocation that the JIT emits for a new did not align. After an object it placed off alignment, the scan read a wrong header and missed the objects that follow, so an object referenced only from the stack was freed by the next collection. The cppia host now builds with HXCPP_GC_GENERATIONAL. The new test has jitted code allocate two objects, then keeps an array only on the stack across a generational collection. Without the fix, the -jit run crashes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
With
HXCPP_GC_GENERATIONALand the cppia JIT, an object referenced only from the stack can be freed by the next collection.With a generational GC, new objects go into the nursery.
ImmixAllocator::allocskips 4 bytes when it needs to, so that each nursery object is 8-byte aligned (HXCPP_ALIGN_ALLOC, always defined). The scan that finds objects referenced conservatively from the stack (GetEnclosingNurseryType) relies on that alignment when it walks a hole from header to header.For a
newof a script class, the JIT emits its own inline nursery allocation (NewExpr::genCode, underHXCPP_GC_NURSERY), which did not align. After an object the JIT placed off alignment, the scan reads a wrong header and misses the objects that follow in that hole. Any of them referenced only from the stack, script or host, is then freed while still in use. Without the JIT,createInstanceallocates through the aligned path, so only-jitwas affected.The fix aligns the JIT's inline allocation the same way as
ImmixAllocator::alloc. Builds without a generational GC do not emit this path, so they are unchanged.The cppia host in
test/cppianow builds withHXCPP_GC_GENERATIONAL, so the suite runs with the nursery. The existing tests pass with it in both modes, but none of them forces a collection. The new test callsClientNursery.allocate, whose twoneware jitted with-jit, then keeps an array only on the stack across a generational collection. Onmaster, the-jitrun crashes every time (5/5): host objects that only the stack references are freed, and utest crashes on one of them right after the test. With the fix, both modes pass (5/5 each).