Skip to content

codegen: SIGBUS in LLVM statepoint lowering makes next@16.3.0's jsonwebtoken bundle uncompilable at every opt level #8145

Description

@proggeramlug

Summary

On origin/main (0a1e78e5f), next@16.3.0's bundled jsonwebtoken
(dist/compiled/jsonwebtoken/index.js, sha256 056c2ddd…a6b9 — the #8132
fixture) cannot be compiled at any optimization level while precise roots
lower to statepoints. Both arms die with the same fault:

EXC_BAD_ACCESS (SIGBUS), KERN_PROTECTION_FAILURE
  llvm::AArch64TargetLowering::LowerCall(...)
  llvm::TargetLowering::LowerCallTo(...)
  llvm::SelectionDAGBuilder::lowerInvokable(...)
  llvm::SelectionDAGBuilder::LowerAsSTATEPOINT(...)
  llvm::SelectionDAGBuilder::LowerStatepoint(...)
  ...
  perry_codegen::inprocess::optimize_and_emit_module
arm outcome
-Os (today's default for this unit) SIGBUS at 292 s (261 s CPU)
-O0 (PERRY_LL_SIZE_OPT=0) SIGBUS at 120-208 s
PERRY_RS4GC=0, -O0 succeeds, 20.2 s, 6.6 MB dylib
PERRY_RS4GC=0, -Os succeeds, 48.6 s, 4.3 MB dylib
PERRY_LLVM_INPROCESS=0 (text backend) clang: error: unterminated attribute group at line 2034949 of the 414 MB rendered unit

4/4 reproductions of the SIGBUS.

It is not a stack overflow

The faulting address lands inside a reserved, never-mapped VM range (the
GPU Carveout span in the crash report's vmRegionInfo), not on a stack guard
page. Raising the codegen worker stack from the std default (2 MiB, these are
std::thread::scope spawns in native_emit.rs) to 1 GiB changed nothing: same
site, same signal, same timing. RUST_MIN_STACK=268435456 likewise.

Peak footprint at the crash is ~2.5 GB, so it is not a plain OOM either.

The input is the one #8132 describes: 21,774 statepoints and 1.5M gc.relocates
after RS4GC, mean 83 operands per statepoint, max 426.

Why it matters

#8132 records -O0 on this bundle as "2m46.5s, 40 MB dylib". That does not
reproduce on 0a1e78e5f.
Any plan that routes this unit to -O0 — including
the opt-level-threshold direction in #8132 (see #8144, where it is measured and
declined) — therefore swaps a hang for a crash, and does not unblock #8040.

The other two #8132 directions (reduce values live across safepoints; split the
monolith) both attack this as well, since both shrink the statepoint operand
lists this is choking on.

Reproduction

npm i next@16.3.0
cp node_modules/next/dist/compiled/jsonwebtoken/index.js /tmp/fx/jwt.js
printf '{"name":"fx","version":"1.0.0","private":true}\n' > /tmp/fx/package.json
PERRY_NO_AUTO_OPTIMIZE=1 PERRY_LL_SIZE_OPT=0 \
  perry compile /tmp/fx/jwt.js -o /tmp/fx/app --output-type dylib

Environment: arm64 macOS 26.5, LLVM 22.1.4, Apple clang 21.0.0, compiler built
--profile perry-dev. Not yet checked against a --release/dist build.

Refs #8132, #8040.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions