mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: don't write unique string to trace if it's length zero
While we're here, document that ID 0 is implicitly assigned to an empty set of data for both stacks and strings. Change-Id: Ic52ff3a1132abc5a8f6f6c4e4357e31e6e7799fc Reviewed-on: https://go-review.googlesource.com/c/go/+/723061 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
d4f5650cc5
commit
0bc192368a
3 changed files with 18 additions and 3 deletions
|
|
@ -23,6 +23,13 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// traceMap is a map of a variable-sized array of bytes to a unique ID.
|
||||
//
|
||||
// Because traceMap just operates on raw bytes, this type is used as the
|
||||
// backing store for both the trace string table and trace stack table,
|
||||
// the latter of which is just an array of PCs.
|
||||
//
|
||||
// ID 0 is reserved for arrays of bytes of size zero.
|
||||
type traceMap struct {
|
||||
root atomic.UnsafePointer // *traceMapNode (can't use generics because it's notinheap)
|
||||
_ cpu.CacheLinePad
|
||||
|
|
|
|||
|
|
@ -136,8 +136,9 @@ func traceStack(skip int, gp *g, tab *traceStackTable) uint64 {
|
|||
return id
|
||||
}
|
||||
|
||||
// traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids.
|
||||
// It is lock-free for reading.
|
||||
// traceStackTable maps stack traces (arrays of PC's) to unique IDs.
|
||||
//
|
||||
// ID 0 is reserved for a zero-length stack.
|
||||
type traceStackTable struct {
|
||||
tab traceMap
|
||||
}
|
||||
|
|
@ -145,8 +146,10 @@ type traceStackTable struct {
|
|||
// put returns a unique id for the stack trace pcs and caches it in the table,
|
||||
// if it sees the trace for the first time.
|
||||
func (t *traceStackTable) put(pcs []uintptr) uint64 {
|
||||
// Even though put will handle this for us, taking the address of pcs forces a bounds check
|
||||
// that will fail if len(pcs) == 0.
|
||||
if len(pcs) == 0 {
|
||||
return 0
|
||||
return 0 // ID 0 is reserved for zero-length stacks.
|
||||
}
|
||||
id, _ := t.tab.put(noescape(unsafe.Pointer(&pcs[0])), uintptr(len(pcs))*unsafe.Sizeof(uintptr(0)))
|
||||
return id
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import "internal/trace/tracev2"
|
|||
|
||||
// traceStringTable is map of string -> unique ID that also manages
|
||||
// writing strings out into the trace.
|
||||
//
|
||||
// ID 0 is reserved for the empty string.
|
||||
type traceStringTable struct {
|
||||
// lock protects buf.
|
||||
lock mutex
|
||||
|
|
@ -37,6 +39,9 @@ func (t *traceStringTable) put(gen uintptr, s string) uint64 {
|
|||
|
||||
// emit emits a string and creates an ID for it, but doesn't add it to the table. Returns the ID.
|
||||
func (t *traceStringTable) emit(gen uintptr, s string) uint64 {
|
||||
if len(s) == 0 {
|
||||
return 0 // Empty strings are implicitly assigned ID 0 already.
|
||||
}
|
||||
// Grab an ID and write the string to the buffer.
|
||||
id := t.tab.stealID()
|
||||
systemstack(func() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue