Skip to content

Commit

Permalink
pc: Add unsafe asm implementation for arm64 (#10)
Browse files Browse the repository at this point in the history
On arm, there's a link register (LR) that typically contains the return
address. For non-leaf functions, the function saves the LR to the stack.

In our asm implementation, the LR will contain the return address to the
caller `errtrace.Wrap`, but we want its' caller. We can rely on the SP
containing the address saved by the caller, as the SP is not modified by
the caller, but by the callee.

This is based on:

https://go.googlesource.com/go/+/refs/heads/master/src/cmd/compile/abi-internal.md#architecture-specifics-arm64-architecture-stack-layout

specifically:
```
| return PC                    | ← RSP points to
```

Benchmark results:
```
          │   main.txt    │               asm.txt               │
          │    sec/op     │   sec/op     vs base                │
GetCaller   203.150n ± 1%   2.062n ± 0%  -98.98% (p=0.000 n=10)

     │   main.txt   │               asm.txt               │
     │    sec/op    │   sec/op     vs base                │
Wrap   221.50n ± 0%   15.95n ± 1%  -92.80% (p=0.000 n=10)
```
  • Loading branch information
prashantv authored Nov 12, 2023
1 parent 1527ec7 commit a73cb06
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
12 changes: 12 additions & 0 deletions internal/pc/pc_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build !safe && arm64

package pc

func getcallerpc() uintptr

// GetCaller gets the caller's PC.
//
//go:inline
func GetCaller[T any](firstArgAddr *T) uintptr {
return getcallerpc()
}
9 changes: 9 additions & 0 deletions internal/pc/pc_arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !safe && arm64

#include "textflag.h"

// func getcallerpc() uintptr
TEXT ·getcallerpc(SB),NOSPLIT|NOFRAME,$0-8
MOVD x+0(SP), R20
MOVD R20, ret+0(FP)
RET
2 changes: 1 addition & 1 deletion internal/pc/pc_safe.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build safe || !(amd64 || 386)
//go:build safe || !(amd64 || 386 || arm64)

package pc

Expand Down

0 comments on commit a73cb06

Please sign in to comment.