]> Cypherpunks repositories - gostls13.git/commit
cmd/compile: redo arm64 LR/FP save and restore
authorKeith Randall <khr@golang.org>
Sat, 17 May 2025 22:05:56 +0000 (15:05 -0700)
committerKeith Randall <khr@golang.org>
Mon, 6 Oct 2025 21:11:41 +0000 (14:11 -0700)
commit719dfcf8a8478d70360bf3c34c0e920be7b32994
treed58aaf3289de3bb18901e34b336da46b425f8075
parentf3312124c2370c2f64a7f9ad29732ec30209647a
cmd/compile: redo arm64 LR/FP save and restore

Instead of storing LR (the return address) at 0(SP) and the FP
(parent's frame pointer) at -8(SP), store them at framesize-8(SP)
and framesize-16(SP), respectively.

We push and pop data onto the stack such that we're never accessing
anything below SP.

The prolog/epilog lengths are unchanged (3 insns for a typical prolog,
2 for a typical epilog).

We use 8 bytes more per frame.

Typical prologue:

    STP.W   (FP, LR), -16(SP)
    MOVD    SP, FP
    SUB     $C, SP

Typical epilogue:

    ADD     $C, SP
    LDP.P   16(SP), (FP, LR)
    RET

The previous word where we stored LR, at 0(SP), is now unused.
We could repurpose that slot for storing a local variable.

The new prolog and epilog instructions are recognized by libunwind,
so pc-sampling tools like perf should now be accurate. (TODO: except
maybe after the first RET instruction? Have to look into that.)

Update #73753 (fixes, for arm64)
Update #57302 (Quim thinks this will help on that issue)

Change-Id: I4800036a9a9a08aaaf35d9f99de79a36cf37ebb8
Reviewed-on: https://go-review.googlesource.com/c/go/+/674615
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
23 files changed:
src/cmd/compile/abi-internal.md
src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/ssagen/pgen.go
src/cmd/compile/internal/ssagen/ssa.go
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/arm64/obj7.go
src/cmd/link/internal/amd64/obj.go
src/cmd/link/internal/arm64/obj.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/stackcheck.go
src/cmd/link/internal/x86/obj.go
src/runtime/asm_arm64.s
src/runtime/mkpreempt.go
src/runtime/panic.go
src/runtime/preempt_arm64.s
src/runtime/race_arm64.s
src/runtime/signal_arm64.go
src/runtime/stack.go
src/runtime/testdata/testprog/badtraceback.go
src/runtime/traceback.go
test/nosplit.go