Repository navigation
A global initialised from another global runs after it (#446) - #476
Merged
Merged
Conversation
Every global whose initializer runs code got a constructor at the same priority, 1000 (LAST_GLOBAL_CONSTRUCTOR_PRIORITY). LLVM leaves the order of equal priorities undefined, and GlobalOpt uses that: optimised, `b`'s constructor in `let a = [1, 2]; let b = a;` was evaluated before `a`'s and read zeroes. The JIT's __mlir_gctors put each constructor at the start of the function, so it ran them in reverse. Each constructor now gets a priority one above every one before it, in MLIRGen and in GlobalOpLowering, and the JIT inserts each call in priority order (after the calls it already holds with a lower or equal priority). Closes #446 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ASDAlexander77
added a commit
that referenced
this pull request
Oct 22, 2026
…636) `let k = a` at module level, with `a` another global, and `let k = h.c` gave the global no reference of its own: rc and own both read freed memory once `a` (or `h.c`) was given a new value. Under own a Shared<T> handle copied this way (`let k = a` in the initializer, then `k = a` releasing a count it never took) did the same. claimGlobalInitializers skipped a read of another global (#446 made it read null; #476 fixed that) and retained a field read only for handles. - rc: a read of another global, a field or an element in a global's initializer is retained for the global. - own: a handle read that way is retained too (handles are counted); any other such initializer is an error, since a global cannot borrow (rejectBorrowedGlobalInitializers). 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.
Closes #446.
Problem
A module-level variable initialised from another one read garbage:
Every global whose initializer runs code gets a constructor, and all of them had the same priority (1000). LLVM leaves the order of equal priorities undefined, and GlobalOpt uses that: optimised,
b's constructor was evaluated beforea's. The JIT's__mlir_gctorsinserted each constructor at the start of the function, so it ran them in reverse.Fix
MLIRGenModule.cpp(addGlobalConstructor) andLowerToLLVM.cpp(GlobalOpLowering): each constructor gets a priority one above every one made before it.GlobalConstructorOpLowering(JIT): the calls in__mlir_gctorsare kept in priority order. Each call goes before the first one with a higher priority, otherwise after the last one. The three per-function-op branches collapse into one.Tests
00global_from_global.tscovers an array, a class instance, a union, a string and a computed number, each read from another global. It runs compile + JIT, plus the rc and none corpora.test-compile-gc-defaultlib-collector, also fails without this change: the local default lib is stale (Error..size32 vs 48, ExactMatch comdat).-mm=owncorpus: unchanged (with and without--opt).🤖 Generated with Claude Code