-
Notifications
You must be signed in to change notification settings - Fork 45
/
fastcaller_go1.18.go
107 lines (84 loc) · 3.06 KB
/
fastcaller_go1.18.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//go:build go1.18 && !go1.19
// MIT license, copy and modify from https://github.com/tlog-dev/loc
//nolint:unused
package log
import (
"unsafe"
)
// Fastrandn returns a pseudorandom uint32 in [0,n).
//
//go:noescape
//go:linkname Fastrandn runtime.fastrandn
func Fastrandn(n uint32) uint32
func pcFileLine(pc uintptr) (file string, line int32) {
funcInfo := findfunc(pc)
if funcInfo._func == nil {
return
}
entry := funcInfoEntry(funcInfo)
if pc > 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.
pc--
}
return funcline1(funcInfo, pc, false)
}
func pcFileLineName(pc uintptr) (file string, line int32, name string) {
funcInfo := findfunc(pc)
if funcInfo._func == nil {
return
}
entry := funcInfoEntry(funcInfo)
if pc > 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.
pc--
}
file, line = funcline1(funcInfo, pc, false)
name = funcname(funcInfo)
const _PCDATA_InlTreeIndex = 2
const _FUNCDATA_InlTree = 3
if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, pc, 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?
}
}
return
}
type funcInfo struct {
_func unsafe.Pointer
datap unsafe.Pointer //nolint:unused
}
// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
type inlinedCall struct {
parent int16 // index of parent in the inltree, or < 0
funcID uint8 // type of the called function
_ byte
file int32 // fileno index into filetab
line int32 // line number of the call site
func_ int32 // offset into pclntab for name of called function
parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
}
//go:linkname findfunc runtime.findfunc
func findfunc(pc uintptr) funcInfo
//go:linkname funcInfoEntry runtime.funcInfo.entry
func funcInfoEntry(f funcInfo) uintptr
//go:linkname funcline1 runtime.funcline1
func funcline1(f funcInfo, targetpc uintptr, 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 uintptr, cache unsafe.Pointer, strict bool) int32
//go:linkname funcnameFromNameoff runtime.funcnameFromNameoff
func funcnameFromNameoff(f funcInfo, nameoff int32) string