Skip to content

Commit

Permalink
go1.21; fix go1.16
Browse files Browse the repository at this point in the history
  • Loading branch information
nikandfor committed Nov 11, 2023
1 parent 5a722be commit 49383d4
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ It's a fast, alloc-free and convinient version of `runtime.Caller`.

Performance benefits are available when using the `nikandfor_loc_unsafe` build tag. This relies on the internal runtime implementation, which means that older versions of the package may not compile with future versions of Go. Without the tag, it is safe to use with any version of Go.

It was born from [tlog](https://github.com/nikandfor/tlog).
It was born from [tlog](https://github.com/tlog-dev/tlog).

## What is similar

Expand Down
9 changes: 5 additions & 4 deletions name_file_line_go1.12.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build nikandfor_loc_unsafe && !go1.17
// +build nikandfor_loc_unsafe,!go1.17
//go:build nikandfor_loc_unsafe && !go1.16
// +build nikandfor_loc_unsafe,!go1.16

package loc

Expand All @@ -24,8 +24,6 @@ func (l PC) nameFileLine() (name, file string, line int) {
}

name = funcname(funcInfo)
file, line32 := funcline1(funcInfo, l, false)
line = int(line32)
if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
ix := pcdatavalue(funcInfo, _PCDATA_InlTreeIndex, l, nil)
if ix >= 0 {
Expand All @@ -37,6 +35,9 @@ func (l PC) nameFileLine() (name, file string, line int) {
}
}

file, line32 := funcline1(funcInfo, l, false)
line = int(line32)

return
}

Expand Down
60 changes: 60 additions & 0 deletions name_file_line_go1.16.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//go:build nikandfor_loc_unsafe && go1.16 && !go1.17
// +build nikandfor_loc_unsafe,go1.16,!go1.17

package loc

import "unsafe"

func (l PC) nameFileLine() (name, file string, line int) {
if l == 0 {
return
}

funcInfo := findfunc(l)
if funcInfo.entry == nil {
return
}

if uintptr(l) > *funcInfo.entry {
// We store the pc of the start of the instruction following
// the instruction in question (the call or the inline mark).
// This is done for historical reasons, and to make FuncForPC
// work correctly for entries in the result of runtime.Callers.
l--
}

name = funcname(funcInfo)
if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, l, nil, false)
if ix >= 0 {
inltree := (*[1 << 20]inlinedCall)(inldata)
// Note: entry is not modified. It always refers to a real frame, not an inlined one.
name = funcnameFromNameoff(funcInfo, inltree[ix].func_)
// File/line is already correct.
// TODO: remove file/line from InlinedCall?
}
}

file, line32 := funcline1(funcInfo, l, false)
line = int(line32)

return
}

//go:linkname findfunc runtime.findfunc
func findfunc(pc PC) funcInfo

//go:linkname funcline1 runtime.funcline1
func funcline1(f funcInfo, targetpc PC, strict bool) (file string, line int32)

//go:linkname funcname runtime.funcname
func funcname(f funcInfo) string

//go:linkname funcdata runtime.funcdata
func funcdata(f funcInfo, i uint8) unsafe.Pointer

//go:linkname pcdatavalue1 runtime.pcdatavalue1
func pcdatavalue1(f funcInfo, table int32, targetpc PC, cache unsafe.Pointer, strict bool) int32

//go:linkname funcnameFromNameoff runtime.funcnameFromNameoff
func funcnameFromNameoff(f funcInfo, nameoff int32) string
4 changes: 2 additions & 2 deletions name_file_line_go1.20.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build nikandfor_loc_unsafe && go1.20
// +build nikandfor_loc_unsafe,go1.20
//go:build nikandfor_loc_unsafe && go1.20 && !go1.21
// +build nikandfor_loc_unsafe,go1.20,!go1.21

package loc

Expand Down
78 changes: 78 additions & 0 deletions name_file_line_go1.21.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//go:build nikandfor_loc_unsafe && go1.21
// +build nikandfor_loc_unsafe,go1.21

package loc

import "unsafe"

type (
inlineUnwinder struct {
f funcInfo
cache *uintptr
inlTree *uintptr
}

inlineFrame struct {
pc uintptr
index int32
}

srcFunc struct {
datap *uintptr
nameOff int32
startLine int32
funcID funcID
}
)

func (l PC) nameFileLine() (name, file string, line int) {
funcInfo := findfunc(l)
if funcInfo._func == nil {
return
}

entry := funcInfoEntry(funcInfo)

if l > entry {
// We store the pc of the start of the instruction following
// the instruction in question (the call or the inline mark).
// This is done for historical reasons, and to make FuncForPC
// work correctly for entries in the result of runtime.Callers.
l--
}

// It's important that interpret pc non-strictly as cgoTraceback may
// have added bogus PCs with a valid funcInfo but invalid PCDATA.
u, uf := newInlineUnwinder(funcInfo, l, nil)
sf := inlineUnwinder_srcFunc(&u, uf)

name = funcNameForPrint(srcFunc_name(sf))
file, line32 := funcline1(funcInfo, l, false)
line = int(line32)

return
}

//go:linkname findfunc runtime.findfunc
func findfunc(pc PC) funcInfo

//go:linkname funcInfoEntry runtime.funcInfo.entry
func funcInfoEntry(f funcInfo) PC

//go:linkname newInlineUnwinder runtime.newInlineUnwinder
func newInlineUnwinder(f funcInfo, pc PC, cache unsafe.Pointer) (inlineUnwinder, inlineFrame)

//go:linkname inlineUnwinder_srcFunc runtime.(*inlineUnwinder).srcFunc
func inlineUnwinder_srcFunc(*inlineUnwinder, inlineFrame) srcFunc

//go:linkname inlineUnwinder_isInlined runtime.(*inlineUnwinder).isInlined
func inlineUnwinder_isInlined(*inlineUnwinder, inlineFrame) bool

//go:linkname srcFunc_name runtime.srcFunc.name
func srcFunc_name(srcFunc) string

//go:linkname funcNameForPrint runtime.funcNameForPrint
func funcNameForPrint(name string) string

//go:linkname funcline1 runtime.funcline1
func funcline1(f funcInfo, targetpc PC, strict bool) (file string, line int32)
6 changes: 3 additions & 3 deletions unsafe_go1.13.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//go:build nikandfor_loc_unsafe && go1.13 && !go1.17
// +build nikandfor_loc_unsafe,go1.13,!go1.17
//go:build nikandfor_loc_unsafe && go1.13 && !go1.16
// +build nikandfor_loc_unsafe,go1.13,!go1.16

package loc

//nolint
// nolint
const (
_PCDATA_InlTreeIndex = 2
_FUNCDATA_InlTree = 4
Expand Down
10 changes: 10 additions & 0 deletions unsafe_go1.16.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build nikandfor_loc_unsafe && go1.16
// +build nikandfor_loc_unsafe,go1.16

package loc

// nolint
const (
_PCDATA_InlTreeIndex = 2
_FUNCDATA_InlTree = 3
)
10 changes: 0 additions & 10 deletions unsafe_go1.17.go

This file was deleted.

0 comments on commit 49383d4

Please sign in to comment.