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"
|
"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 {
|
type traceMap struct {
|
||||||
root atomic.UnsafePointer // *traceMapNode (can't use generics because it's notinheap)
|
root atomic.UnsafePointer // *traceMapNode (can't use generics because it's notinheap)
|
||||||
_ cpu.CacheLinePad
|
_ cpu.CacheLinePad
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,9 @@ func traceStack(skip int, gp *g, tab *traceStackTable) uint64 {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
// traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids.
|
// traceStackTable maps stack traces (arrays of PC's) to unique IDs.
|
||||||
// It is lock-free for reading.
|
//
|
||||||
|
// ID 0 is reserved for a zero-length stack.
|
||||||
type traceStackTable struct {
|
type traceStackTable struct {
|
||||||
tab traceMap
|
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,
|
// 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.
|
// if it sees the trace for the first time.
|
||||||
func (t *traceStackTable) put(pcs []uintptr) uint64 {
|
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 {
|
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)))
|
id, _ := t.tab.put(noescape(unsafe.Pointer(&pcs[0])), uintptr(len(pcs))*unsafe.Sizeof(uintptr(0)))
|
||||||
return id
|
return id
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import "internal/trace/tracev2"
|
||||||
|
|
||||||
// traceStringTable is map of string -> unique ID that also manages
|
// traceStringTable is map of string -> unique ID that also manages
|
||||||
// writing strings out into the trace.
|
// writing strings out into the trace.
|
||||||
|
//
|
||||||
|
// ID 0 is reserved for the empty string.
|
||||||
type traceStringTable struct {
|
type traceStringTable struct {
|
||||||
// lock protects buf.
|
// lock protects buf.
|
||||||
lock mutex
|
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.
|
// 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 {
|
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.
|
// Grab an ID and write the string to the buffer.
|
||||||
id := t.tab.stealID()
|
id := t.tab.stealID()
|
||||||
systemstack(func() {
|
systemstack(func() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue