fix: compile the float overflow-widening ladder eagerly (trim compatibility) - #207
Merged
Conversation
…bility) Remove Base.inferencebarrier from the four widened recursive calls in floats.jl (_parsedigits/_parsefrac/_parseexp). The ladder is bounded in type space (UInt64 -> UInt128 -> BigInt, overflows(BigInt) == false ends the recursion) and the @noinline wrappers already keep each step compiling separately, so base-case compilation stays contained. The barrier made the widened continuation reachable only through runtime dispatch. Under the JIT that's just a lazy-compile; in a statically compiled binary (juliac --trim) the widened instance doesn't exist, so parsing a wide-digit float would fail at runtime — and the four dynamic sites are verifier errors that block trim builds of anything using Parsers' float path. Measured: precompile does not regress (compilecache 5.3s -> 3.8s on this machine vs the release lineage); full suite green (566038 tests); all ladder rungs verified correct (20+, 40+ digit mantissas, wide exponents, BigFloat).
Compiles test/parsers_trim_workload.jl with juliac --trim=safe (JuliaC.jl, error budget zero) and runs the executable, so the overflow-widening ladder fix can't silently regress — under the old Base.inferencebarrier form these were verifier errors AND the widened instances were missing from trimmed binaries (wide-mantissa parses would fail at runtime). The workload asserts bit-exact rounding through every ladder rung (UInt64 → UInt128 → BigInt mantissas, fractional and exponent variants), float edge cases (Inf overflow, denormals, floatmax, NaN), Float16/32/64, ints, and tryparse. Skips on Julia < 1.12 and on prerelease builds.
quinnj
added a commit
to JuliaIO/JSON.jl
that referenced
this pull request
Jul 14, 2026
Compiles test/json_trim_workload.jl with juliac --trim=safe (JuliaC.jl, error budget zero) and runs the executable, so the trim-verifier fixes in this PR can't silently regress. Same harness shape as StructUtils/HTTP. The workload asserts runtime values across typed parse (@defaults incl. defaulted fields, Vector/Dict targets), the rewritten error paths (the unknown-field message with its PtrString key formatting, and the bad unknown_fields-option message — both triggered and matched at runtime), untyped parse with the isa-narrowing pattern trim-compiled consumers need, JSON writing incl. escapes and struct roundtrips, and the hand-formatted Date/DateTime/Time lowers (exact renderings incl. millisecond padding). The trim env temporarily pins Parsers#trim-verifier-fixes: JSON's number parsing pulls Parsers' float path into the verify set, and the registered release fails verification until JuliaData/Parsers.jl#207 ships (TODO in the setup script). Skips on Julia < 1.12 and on prerelease builds.
Skip JuliaC trim compilation on 32-bit hosts that lack a compatible C toolchain. Constrain the ARFFFiles downstream job to OrderedCollections 1 until ARFFFiles stops constructing ordered tables from unordered Dict inputs.
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.
Removes
Base.inferencebarrierfrom the four widened recursive calls infloats.jl(_parsedigits/_parsefrac/_parseexpcontinuations).Why
The barrier makes the widened continuation reachable only through runtime dispatch. Under the JIT that's a lazy compile; in a statically compiled binary (
juliac --trim) the widened instance doesn't exist, so parsing a wide-digit float would fail at runtime — and the four dynamic sites are verifier errors that block trim builds of anything using Parsers' float path (e.g. JSON number parsing).Why it's safe
UInt64 → UInt128 → BigInt, andoverflows(BigInt) == falseends the recursion — so eager inference terminates with at most three ladder instances per concrete (conf, source, continuation) combination.@noinline_parsedigits/_parsefrac/_parseexpwrappers (which exist precisely to contain base-case compilation) still keep each ladder step compiling separately.Measurements
Base.compilecache(Parsers)5.3s → 3.8s on the same machine vs the release lineage.BigFloattargets.juliac --trim=safewith zero verifier errors and the binary runs.🤖 Generated with Claude Code
Co-authored by Codex