Source File
trace2string.go
Belonging Package
runtime
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build goexperiment.exectracer2
// Trace string management.
package runtime
// Trace strings.
const maxTraceStringLen = 1024
// traceStringTable is map of string -> unique ID that also manages
// writing strings out into the trace.
type traceStringTable struct {
// lock protects buf.
lock mutex
buf *traceBuf // string batches to write out to the trace.
// tab is a mapping of string -> unique ID.
tab traceMap
}
// put adds a string to the table, emits it, and returns a unique ID for it.
func ( *traceStringTable) ( uintptr, string) uint64 {
// Put the string in the table.
:= stringStructOf(&)
, := .tab.put(.str, uintptr(.len))
if {
// Write the string to the buffer.
systemstack(func() {
.writeString(, , )
})
}
return
}
// emit emits a string and creates an ID for it, but doesn't add it to the table. Returns the ID.
func ( *traceStringTable) ( uintptr, string) uint64 {
// Grab an ID and write the string to the buffer.
:= .tab.stealID()
systemstack(func() {
.writeString(, , )
})
return
}
// writeString writes the string to t.buf.
//
// Must run on the systemstack because it may flush buffers and thus could acquire trace.lock.
//
//go:systemstack
func ( *traceStringTable) ( uintptr, uint64, string) {
// Truncate the string if necessary.
if len() > maxTraceStringLen {
= [:maxTraceStringLen]
}
lock(&.lock)
:= unsafeTraceWriter(, .buf)
// Ensure we have a place to write to.
var bool
, = .ensure(2 + 2*traceBytesPerNumber + len() /* traceEvStrings + traceEvString + ID + len + string data */)
if {
// Annotate the batch as containing strings.
.byte(byte(traceEvStrings))
}
// Write out the string.
.byte(byte(traceEvString))
.varint()
.varint(uint64(len()))
.stringData()
// Store back buf if it was updated during ensure.
.buf = .traceBuf
unlock(&.lock)
}
// reset clears the string table and flushes any buffers it has.
//
// Must be called only once the caller is certain nothing else will be
// added to this table.
//
// Because it flushes buffers, this may acquire trace.lock and thus
// must run on the systemstack.
//
//go:systemstack
func ( *traceStringTable) ( uintptr) {
if .buf != nil {
lock(&trace.lock)
traceBufFlush(.buf, )
unlock(&trace.lock)
.buf = nil
}
// Reset the table.
lock(&.tab.lock)
.tab.reset()
unlock(&.tab.lock)
}
The pages are generated with Golds v0.6.9-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |