Skip to content

fix: compile the float overflow-widening ladder eagerly (trim compatibility) - #207

Merged
quinnj merged 3 commits into
mainfrom
trim-verifier-fixes
Jul 15, 2026
Merged

fix: compile the float overflow-widening ladder eagerly (trim compatibility)#207
quinnj merged 3 commits into
mainfrom
trim-verifier-fixes

Conversation

@quinnj

@quinnj quinnj commented Jul 11, 2026

Copy link
Copy Markdown
Member

Removes Base.inferencebarrier from the four widened recursive calls in floats.jl (_parsedigits/_parsefrac/_parseexp continuations).

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

  • The widening ladder is bounded in type space: UInt64 → UInt128 → BigInt, and overflows(BigInt) == false ends the recursion — so eager inference terminates with at most three ladder instances per concrete (conf, source, continuation) combination.
  • The @noinline _parsedigits/_parsefrac/_parseexp wrappers (which exist precisely to contain base-case compilation) still keep each ladder step compiling separately.

Measurements

🤖 Generated with Claude Code

Co-authored by Codex

quinnj added 2 commits July 10, 2026 21:18
…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.
@quinnj
quinnj merged commit 24a05a9 into main Jul 15, 2026
12 checks passed
@quinnj
quinnj deleted the trim-verifier-fixes branch July 15, 2026 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant