1// Copyright 2024 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime
6
7// traceExpWriter is a wrapper around trace writer that produces traceEvExperimentalBatch
8// batches. This means that the data written to the writer need not conform to the standard
9// trace format.
10type traceExpWriter struct {
11	traceWriter
12	exp traceExperiment
13}
14
15// unsafeTraceExpWriter produces a traceExpWriter that doesn't lock the trace.
16//
17// It should only be used in contexts where either:
18// - Another traceLocker is held.
19// - trace.gen is prevented from advancing.
20//
21// buf may be nil.
22func unsafeTraceExpWriter(gen uintptr, buf *traceBuf, exp traceExperiment) traceExpWriter {
23	return traceExpWriter{traceWriter{traceLocker: traceLocker{gen: gen}, traceBuf: buf}, exp}
24}
25
26// ensure makes sure that at least maxSize bytes are available to write.
27//
28// Returns whether the buffer was flushed.
29func (w traceExpWriter) ensure(maxSize int) (traceExpWriter, bool) {
30	refill := w.traceBuf == nil || !w.available(maxSize)
31	if refill {
32		w.traceWriter = w.traceWriter.refill(w.exp)
33	}
34	return w, refill
35}
36
37// traceExperiment is an enumeration of the different kinds of experiments supported for tracing.
38type traceExperiment uint8
39
40const (
41	// traceNoExperiment indicates no experiment.
42	traceNoExperiment traceExperiment = iota
43
44	// traceExperimentAllocFree is an experiment to add alloc/free events to the trace.
45	traceExperimentAllocFree
46)
47
48// Experimental events.
49const (
50	_ traceEv = 127 + iota
51
52	// Experimental events for ExperimentAllocFree.
53
54	// Experimental heap span events. IDs map reversibly to base addresses.
55	traceEvSpan      // heap span exists [timestamp, id, npages, type/class]
56	traceEvSpanAlloc // heap span alloc [timestamp, id, npages, type/class]
57	traceEvSpanFree  // heap span free [timestamp, id]
58
59	// Experimental heap object events. IDs map reversibly to addresses.
60	traceEvHeapObject      // heap object exists [timestamp, id, type]
61	traceEvHeapObjectAlloc // heap object alloc [timestamp, id, type]
62	traceEvHeapObjectFree  // heap object free [timestamp, id]
63
64	// Experimental goroutine stack events. IDs map reversibly to addresses.
65	traceEvGoroutineStack      // stack exists [timestamp, id, order]
66	traceEvGoroutineStackAlloc // stack alloc [timestamp, id, order]
67	traceEvGoroutineStackFree  // stack free [timestamp, id]
68)
69