runtime/jit: add user frame support for JIT compilers and VMs - #81237
runtime/jit: add user frame support for JIT compilers and VMs#81237carli2 wants to merge 12 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
7259e81 to
fc9129b
Compare
|
This PR (HEAD: fc9129b) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
|
Message from Gopher Robot: Patch Set 1: (1 comment) Please don’t reply on this GitHub thread. Visit golang.org/cl/826384. |
|
This PR (HEAD: ee6687e) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
|
This PR (HEAD: 724544f) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
|
This PR (HEAD: 946caf2) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
|
Message from Carl-Philip Hänsch: Patch Set 4: (2 comments) Please don’t reply on this GitHub thread. Visit golang.org/cl/826384. |
|
This PR (HEAD: c3e63e0) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
Add a new package runtime/jit that allows programs to register regions
of dynamically generated executable code with the Go runtime. This
enables the stack unwinder, panic/recover, and GC to handle frames
from JIT-compiled code, WASM engines, and embedded VMs gracefully
instead of crashing with "unknown pc".
The package provides:
- Three unwind modes: UnwindStop (end traceback), UnwindSkip (skip
user frames via Next callback), UnwindDeclare (skip + describe
in tracebacks via Describe callback)
- GC integration via ScanStack callback for marking Go pointers
held in user code shadow stacks
- Register/Unregister lifecycle with Handle type
Runtime internals:
- Copy-on-write region registry with atomic pointer swap for
lock-free reads from the unwinder (runs on system stack)
- Unwinder patches in initAt() and next() to resolve user frame
PCs via the Next callback before throwing on unknown PCs
- traceback2() patch to call Describe for UnwindDeclare regions
- markroot() fixed root to call ScanStack during GC mark phase
Gated behind GOEXPERIMENT=jit. Without the experiment, the runtime/jit
package is excluded from builds. The runtime-internal code has negligible
cost when no regions are registered (single atomic load returning nil).
Tests cover registration, concurrency, panic/recover through user frames,
runtime.Callers, runtime.Stack, GC, UnwindDeclare with Describe, and
ScanStack. ISA-specific JIT trampolines for all 13 Linux architectures.
Fixes golang#78189
Keep UnwindStop as a hard traceback boundary even when the region has an unwind recipe. Preserve trailing padding when a repeated tail has zero-sized elements. Add coverage for the stack-check metadata and both boundary cases. Updates golang#78189
c3e63e0 to
1c0b2e3
Compare
|
This PR (HEAD: 1c0b2e3) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/826384. Important tips:
|
|
Message from Carl-Philip Hänsch: Patch Set 6: Code-Review+1 (1 comment) Please don’t reply on this GitHub thread. Visit golang.org/cl/826384. |
This implements proposal #78189 on the current master branch.
It adds an experimental runtime/jit API for cooperative dynamically
generated code. JIT compilers and VMs can register executable regions with
declarative unwind metadata, provide precise stack maps, preserve Go pointers
and caller frame pointers across stack growth, support panic and recover
across registered frames, participate in tracebacks, observe cooperative
preemption requests, and obtain the metadata needed to emit Go-compatible
split-stack checks. Consecutive generated frames are unwound, scanned, and
relocated as one chain.
The API also supports prepared, precisely typed allocations for objects with
repeated tails. MemCP uses this for variable-sized JIT closure environments.
It is included because raw byte allocations cannot describe their pointers to
the garbage collector. Reviewer feedback is welcome on whether this part
should remain here or move to a separate proposal and change.
The complete feature is gated behind GOEXPERIMENT=jit. The stack walker and
garbage collector consume copied declarative metadata and do not invoke
JIT-owned callbacks.
MemCP uses this implementation to JIT-compile Scheme and query-planner code.
A self-recursion microbenchmark improves by 30 to 33 times. Its complete
Scheme and SQL regression workload improved from approximately 11 to 13
minutes to 8 minutes 31 seconds when the integration was introduced. These
are consumer measurements, not Go project benchmarks.
The change covers registered return PCs, nested generated frames, precise GC
scanning, stack relocation, panic/recover, tracebacks, and forced stack
growth. Recoverable synchronous hardware faults whose interrupted PC itself
lies in generated code are not yet specified or tested; proposal discussion
should decide whether that belongs here or in a follow-up.
The implementation was rebased onto current master and built using the Go
1.27 JIT fork as bootstrap. On linux/amd64,
GOEXPERIMENT=jit go test runtime/jit, GOEXPERIMENT=jit go test runtime, and
GOEXPERIMENT=jit go test cmd/api pass. The default runtime test without the
experiment and the runtime/jit race test pass as well. The runtime/jit tests
cross-compile for every architecture covered by their Linux trampolines and
for 386, amd64, and arm64 on Windows.
The separate Go 1.27 branch in the organization fork remains a reproducible
downstream toolchain snapshot. This change intentionally targets master.
Updates #78189