Skip to content

Commit

Permalink
make pcNameFileLine 0-allocs by forbidden magic
Browse files Browse the repository at this point in the history
  • Loading branch information
phuslu committed May 5, 2024
1 parent 7136d3a commit a378486
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 43 deletions.
2 changes: 1 addition & 1 deletion runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

type funcInfo struct {
_func *uintptr
_func unsafe.Pointer
datap unsafe.Pointer //nolint:unused
}

Expand Down
3 changes: 0 additions & 3 deletions runtime_go1.18.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ func funcname(f funcInfo) string
//go:linkname funcdata runtime.funcdata
func funcdata(f funcInfo, i uint8) unsafe.Pointer

//go:linkname pcdatavalue runtime.pcdatavalue
func pcdatavalue(f funcInfo, table int32, targetpc uintptr, cache unsafe.Pointer) int32

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

Expand Down
3 changes: 0 additions & 3 deletions runtime_go1.19.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ func funcname(f funcInfo) string
//go:linkname funcdata runtime.funcdata
func funcdata(f funcInfo, i uint8) unsafe.Pointer

//go:linkname pcdatavalue runtime.pcdatavalue
func pcdatavalue(f funcInfo, table int32, targetpc uintptr, cache unsafe.Pointer) int32

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

Expand Down
3 changes: 0 additions & 3 deletions runtime_go1.20.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ func funcname(f funcInfo) string
//go:linkname funcdata runtime.funcdata
func funcdata(f funcInfo, i uint8) unsafe.Pointer

//go:linkname pcdatavalue runtime.pcdatavalue
func pcdatavalue(f funcInfo, table int32, targetpc uintptr, cache unsafe.Pointer) int32

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

Expand Down
38 changes: 27 additions & 11 deletions runtime_go1.21.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ type srcFunc struct {
funcID uint8
}

type _func struct {
entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
nameOff int32 // function name, as index into moduledata.funcnametab.

args int32 // in/out args size
deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.

pcsp uint32
pcfile uint32
pcln uint32
npcdata uint32
cuOffset uint32 // runtime.cutab offset of this function's CU
startLine int32 // line number of start of function (func keyword/TEXT directive)
funcID uint8 // set for certain special runtime functions
flag uint8
_ [1]byte // pad
nfuncdata uint8 // must be last, must end on a uint32-aligned boundary
}

func pcNameFileLine(pc uintptr) (name, file string, line int32) {
funcInfo := findfunc(pc)
if funcInfo._func == nil {
Expand All @@ -58,28 +77,25 @@ func pcNameFileLine(pc uintptr) (name, file string, line int32) {
// 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, pc, nil)
sf := inlineUnwinder_srcFunc(&u, uf)
var sf srcFunc
if uf.index < 0 {
f := (*_func)(funcInfo._func)
sf = srcFunc{funcInfo.datap, f.nameOff, f.startLine, f.funcID}
} else {
t := &u.inlTree[uf.index]
sf = srcFunc{u.f.datap, t.nameOff, t.startLine, t.funcID}
}
name = srcFunc_name(sf)
// name = funcNameForPrint(srcFunc_name(sf))

return
}

//go:linkname newInlineUnwinder runtime.newInlineUnwinder
func newInlineUnwinder(f funcInfo, pc uintptr, 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

// Fastrandn returns a pseudorandom uint32 in [0,n).
//
//go:noescape
Expand Down
42 changes: 29 additions & 13 deletions runtime_go1.22.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package log

import (
_ "unsafe"
"unsafe"
)

// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
Expand All @@ -30,12 +30,31 @@ type inlineFrame struct {
}

type srcFunc struct {
datap *uintptr
datap unsafe.Pointer
nameOff int32
startLine int32
funcID uint8
}

type _func struct {
entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
nameOff int32 // function name, as index into moduledata.funcnametab.

args int32 // in/out args size
deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.

pcsp uint32
pcfile uint32
pcln uint32
npcdata uint32
cuOffset uint32 // runtime.cutab offset of this function's CU
startLine int32 // line number of start of function (func keyword/TEXT directive)
funcID uint8 // set for certain special runtime functions
flag uint8
_ [1]byte // pad
nfuncdata uint8 // must be last, must end on a uint32-aligned boundary
}

func pcNameFileLine(pc uintptr) (name, file string, line int32) {
funcInfo := findfunc(pc)
if funcInfo._func == nil {
Expand All @@ -57,28 +76,25 @@ func pcNameFileLine(pc uintptr) (name, file string, line int32) {
// 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, pc)
sf := inlineUnwinder_srcFunc(&u, uf)
var sf srcFunc
if uf.index < 0 {
f := (*_func)(funcInfo._func)
sf = srcFunc{funcInfo.datap, f.nameOff, f.startLine, f.funcID}
} else {
t := &u.inlTree[uf.index]
sf = srcFunc{u.f.datap, t.nameOff, t.startLine, t.funcID}
}
name = srcFunc_name(sf)
// name = funcNameForPrint(srcFunc_name(sf))

return
}

//go:linkname newInlineUnwinder runtime.newInlineUnwinder
func newInlineUnwinder(f funcInfo, pc uintptr) (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

// Fastrandn returns a pseudorandom uint32 in [0,n).
//
//go:noescape
Expand Down
11 changes: 2 additions & 9 deletions runtime_go1.23.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package log

import (
_ "unsafe"
"unsafe"
)

// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
Expand All @@ -30,7 +30,7 @@ type inlineFrame struct {
}

type srcFunc struct {
datap *uintptr
datap unsafe.Pointer
nameOff int32
startLine int32
funcID uint8
Expand Down Expand Up @@ -59,7 +59,6 @@ func pcNameFileLine(pc uintptr) (name, file string, line int32) {
u, uf := newInlineUnwinder(funcInfo, pc)
sf := inlineUnwinder_srcFunc(&u, uf)
name = srcFunc_name(sf)
// name = funcNameForPrint(srcFunc_name(sf))

return
}
Expand All @@ -70,15 +69,9 @@ func newInlineUnwinder(f funcInfo, pc uintptr) (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

// Fastrandn returns a pseudorandom uint32 in [0,n).
//
//go:noescape
Expand Down

0 comments on commit a378486

Please sign in to comment.