Source file
src/runtime/tracestring.go
1
2
3
4
5
6
7 package runtime
8
9 import "internal/trace/tracev2"
10
11
12
13
14
15
16
17 type traceStringTable struct {
18
19 lock mutex
20 buf *traceBuf
21
22
23 tab traceMap
24 }
25
26
27 func (t *traceStringTable) put(gen uintptr, s string) uint64 {
28
29
30 if len(s) > tracev2.MaxEventTrailerDataSize {
31 s = s[:tracev2.MaxEventTrailerDataSize]
32 }
33
34 ss := stringStructOf(&s)
35 id, added := t.tab.put(ss.str, uintptr(ss.len))
36 if added {
37
38 systemstack(func() {
39 t.writeString(gen, id, s)
40 })
41 }
42 return id
43 }
44
45
46 func (t *traceStringTable) emit(gen uintptr, s string) uint64 {
47 if len(s) == 0 {
48 return 0
49 }
50
51 id := t.tab.stealID()
52 systemstack(func() {
53 t.writeString(gen, id, s)
54 })
55 return id
56 }
57
58
59
60
61
62
63 func (t *traceStringTable) writeString(gen uintptr, id uint64, s string) {
64
65 if len(s) > tracev2.MaxEventTrailerDataSize {
66 s = s[:tracev2.MaxEventTrailerDataSize]
67 }
68
69 lock(&t.lock)
70 w := unsafeTraceWriter(gen, t.buf)
71
72
73 var flushed bool
74 w, flushed = w.ensure(2 + 2*traceBytesPerNumber + len(s) )
75 if flushed {
76
77 w.byte(byte(tracev2.EvStrings))
78 }
79
80
81 w.byte(byte(tracev2.EvString))
82 w.varint(id)
83 w.varint(uint64(len(s)))
84 w.stringData(s)
85
86
87 t.buf = w.traceBuf
88 unlock(&t.lock)
89 }
90
91
92
93
94
95 func (t *traceStringTable) reset(gen uintptr) {
96 if t.buf != nil {
97 systemstack(func() {
98 lock(&trace.lock)
99 traceBufFlush(t.buf, gen)
100 unlock(&trace.lock)
101 })
102 t.buf = nil
103 }
104
105
106 t.tab.reset()
107 }
108
View as plain text