const traceBytesPerNumber … type traceWriter … // writer returns an a traceWriter that writes into the current M's stream. // // Once this is called, the caller must guard against stack growth until // end is called on it. Therefore, it's highly recommended to use this // API in a "fluent" style, for example tl.writer().event(...).end(). // Better yet, callers just looking to write events should use eventWriter // when possible, which is a much safer wrapper around this function. // // nosplit to allow for safe reentrant tracing from stack growth paths. // //go:nosplit func (tl traceLocker) writer() traceWriter { … } // unsafeTraceWriter produces a traceWriter that doesn't lock the trace. // // It should only be used in contexts where either: // - Another traceLocker is held. // - trace.gen is prevented from advancing. // // This does not have the same stack growth restrictions as traceLocker.writer. // // buf may be nil. func unsafeTraceWriter(gen uintptr, buf *traceBuf) traceWriter { … } // event writes out the bytes of an event into the event stream. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (w traceWriter) event(ev traceEv, args ...traceArg) traceWriter { … } // end writes the buffer back into the m. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (w traceWriter) end() { … } // ensure makes sure that at least maxSize bytes are available to write. // // Returns whether the buffer was flushed. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (w traceWriter) ensure(maxSize int) (traceWriter, bool) { … } // flush puts w.traceBuf on the queue of full buffers. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (w traceWriter) flush() traceWriter { … } // refill puts w.traceBuf on the queue of full buffers and refresh's w's buffer. func (w traceWriter) refill() traceWriter { … } type traceBufQueue … // push queues buf into queue of buffers. func (q *traceBufQueue) push(buf *traceBuf) { … } // pop dequeues from the queue of buffers. func (q *traceBufQueue) pop() *traceBuf { … } func (q *traceBufQueue) empty() bool { … } type traceBufHeader … type traceBuf … // byte appends v to buf. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) byte(v byte) { … } // varint appends v to buf in little-endian-base-128 encoding. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) varint(v uint64) { … } // varintReserve reserves enough space in buf to hold any varint. // // Space reserved this way can be filled in with the varintAt method. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) varintReserve() int { … } // stringData appends s's data directly to buf. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) stringData(s string) { … } // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) available(size int) bool { … } // varintAt writes varint v at byte position pos in buf. This always // consumes traceBytesPerNumber bytes. This is intended for when the caller // needs to reserve space for a varint but can't populate it until later. // Use varintReserve to reserve this space. // // nosplit because it's part of writing an event for an M, which must not // have any stack growth. // //go:nosplit func (buf *traceBuf) varintAt(pos int, v uint64) { … } // traceBufFlush flushes a trace buffer. // // Must run on the system stack because trace.lock must be held. // //go:systemstack func traceBufFlush(buf *traceBuf, gen uintptr) { … }