Skip to content

cmd/compile/internal/ssagen,runtime: merge trace consts into internal/abi #64905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 11 additions & 45 deletions src/cmd/compile/internal/ssagen/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -7095,48 +7095,14 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice()
}

// Populate the data.
// The data is a stream of bytes, which contains the offsets and sizes of the
// non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
// arguments, along with special "operators". Specifically,
// - for each non-aggrgate arg/field/element, its offset from FP (1 byte) and
// size (1 byte)
// - special operators:
// - 0xff - end of sequence
// - 0xfe - print { (at the start of an aggregate-typed argument)
// - 0xfd - print } (at the end of an aggregate-typed argument)
// - 0xfc - print ... (more args/fields/elements)
// - 0xfb - print _ (offset too large)
// These constants need to be in sync with runtime.traceback.go:printArgs.
const (
_endSeq = 0xff
_startAgg = 0xfe
_endAgg = 0xfd
_dotdotdot = 0xfc
_offsetTooLarge = 0xfb
_special = 0xf0 // above this are operators, below this are ordinary offsets
)

const (
limit = 10 // print no more than 10 args/components
maxDepth = 5 // no more than 5 layers of nesting

// maxLen is a (conservative) upper bound of the byte stream length. For
// each arg/component, it has no more than 2 bytes of data (size, offset),
// and no more than one {, }, ... at each level (it cannot have both the
// data and ... unless it is the last one, just be conservative). Plus 1
// for _endSeq.
maxLen = (maxDepth*3+2)*limit + 1
)

wOff := 0
n := 0
writebyte := func(o uint8) { wOff = objw.Uint8(x, wOff, o) }

// Write one non-aggregate arg/field/element.
write1 := func(sz, offset int64) {
if offset >= _special {
writebyte(_offsetTooLarge)
if offset >= rtabi.TraceArgsSpecial {
writebyte(rtabi.TraceArgsOffsetTooLarge)
} else {
writebyte(uint8(offset))
writebyte(uint8(sz))
Expand All @@ -7148,19 +7114,19 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
// Returns whether to continue visiting.
var visitType func(baseOffset int64, t *types.Type, depth int) bool
visitType = func(baseOffset int64, t *types.Type, depth int) bool {
if n >= limit {
writebyte(_dotdotdot)
if n >= rtabi.TraceArgsLimit {
writebyte(rtabi.TraceArgsDotdotdot)
return false
}
if !isAggregate(t) {
write1(t.Size(), baseOffset)
return true
}
writebyte(_startAgg)
writebyte(rtabi.TraceArgsStartAgg)
depth++
if depth >= maxDepth {
writebyte(_dotdotdot)
writebyte(_endAgg)
if depth >= rtabi.TraceArgsMaxDepth {
writebyte(rtabi.TraceArgsDotdotdot)
writebyte(rtabi.TraceArgsEndAgg)
n++
return true
}
Expand Down Expand Up @@ -7197,7 +7163,7 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
}
}
}
writebyte(_endAgg)
writebyte(rtabi.TraceArgsEndAgg)
return true
}

Expand All @@ -7212,8 +7178,8 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
break
}
}
writebyte(_endSeq)
if wOff > maxLen {
writebyte(rtabi.TraceArgsEndSeq)
if wOff > rtabi.TraceArgsMaxLen {
base.Fatalf("ArgInfo too large")
}

Expand Down
33 changes: 33 additions & 0 deletions src/internal/abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -710,3 +710,36 @@ func NewName(n, tag string, exported, embedded bool) Name {

return Name{Bytes: &b[0]}
}

const (
TraceArgsLimit = 10 // print no more than 10 args/components
TraceArgsMaxDepth = 5 // no more than 5 layers of nesting

// maxLen is a (conservative) upper bound of the byte stream length. For
// each arg/component, it has no more than 2 bytes of data (size, offset),
// and no more than one {, }, ... at each level (it cannot have both the
// data and ... unless it is the last one, just be conservative). Plus 1
// for _endSeq.
TraceArgsMaxLen = (TraceArgsMaxDepth*3+2)*TraceArgsLimit + 1
)

// Populate the data.
// The data is a stream of bytes, which contains the offsets and sizes of the
// non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
// arguments, along with special "operators". Specifically,
// - for each non-aggrgate arg/field/element, its offset from FP (1 byte) and
// size (1 byte)
// - special operators:
// - 0xff - end of sequence
// - 0xfe - print { (at the start of an aggregate-typed argument)
// - 0xfd - print } (at the end of an aggregate-typed argument)
// - 0xfc - print ... (more args/fields/elements)
// - 0xfb - print _ (offset too large)
const (
TraceArgsEndSeq = 0xff
TraceArgsStartAgg = 0xfe
TraceArgsEndAgg = 0xfd
TraceArgsDotdotdot = 0xfc
TraceArgsOffsetTooLarge = 0xfb
TraceArgsSpecial = 0xf0 // above this are operators, below this are ordinary offsets
)
30 changes: 6 additions & 24 deletions src/runtime/traceback.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,25 +650,7 @@ func tracebackPCs(u *unwinder, skip int, pcBuf []uintptr) int {

// printArgs prints function arguments in traceback.
func printArgs(f funcInfo, argp unsafe.Pointer, pc uintptr) {
// The "instruction" of argument printing is encoded in _FUNCDATA_ArgInfo.
// See cmd/compile/internal/ssagen.emitArgInfo for the description of the
// encoding.
// These constants need to be in sync with the compiler.
const (
_endSeq = 0xff
_startAgg = 0xfe
_endAgg = 0xfd
_dotdotdot = 0xfc
_offsetTooLarge = 0xfb
)

const (
limit = 10 // print no more than 10 args/components
maxDepth = 5 // no more than 5 layers of nesting
maxLen = (maxDepth*3+2)*limit + 1 // max length of _FUNCDATA_ArgInfo (see the compiler side for reasoning)
)

p := (*[maxLen]uint8)(funcdata(f, abi.FUNCDATA_ArgInfo))
p := (*[abi.TraceArgsMaxLen]uint8)(funcdata(f, abi.FUNCDATA_ArgInfo))
if p == nil {
return
}
Expand Down Expand Up @@ -721,19 +703,19 @@ printloop:
o := p[pi]
pi++
switch o {
case _endSeq:
case abi.TraceArgsEndSeq:
break printloop
case _startAgg:
case abi.TraceArgsStartAgg:
printcomma()
print("{")
start = true
continue
case _endAgg:
case abi.TraceArgsEndAgg:
print("}")
case _dotdotdot:
case abi.TraceArgsDotdotdot:
printcomma()
print("...")
case _offsetTooLarge:
case abi.TraceArgsOffsetTooLarge:
printcomma()
print("_")
default:
Expand Down