Source file
src/runtime/tracetype.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/abi"
11 "internal/goarch"
12 "unsafe"
13 )
14
15
16
17 type traceTypeTable struct {
18 tab traceMap
19 }
20
21
22
23
24
25 func (t *traceTypeTable) put(typ *abi.Type) uint64 {
26 if typ == nil {
27 return 0
28 }
29
30 id, _ := t.tab.put(noescape(unsafe.Pointer(&typ)), goarch.PtrSize)
31 return id
32 }
33
34
35
36
37 func (t *traceTypeTable) dump(gen uintptr) {
38 w := unsafeTraceExpWriter(gen, nil, traceExperimentAllocFree)
39 if root := (*traceMapNode)(t.tab.root.Load()); root != nil {
40 w = dumpTypesRec(root, w)
41 }
42 w.flush().end()
43 t.tab.reset()
44 }
45
46 func dumpTypesRec(node *traceMapNode, w traceExpWriter) traceExpWriter {
47 typ := (*abi.Type)(*(*unsafe.Pointer)(unsafe.Pointer(&node.data[0])))
48 typName := toRType(typ).string()
49
50
51 maxBytes := 1 + 5*traceBytesPerNumber + len(typName)
52
53
54
55
56
57
58 var flushed bool
59 w, flushed = w.ensure(1 + maxBytes)
60 if flushed {
61
62 w.byte(byte(traceAllocFreeTypesBatch))
63 }
64
65
66 w.varint(uint64(node.id))
67 w.varint(uint64(uintptr(unsafe.Pointer(typ))))
68 w.varint(uint64(typ.Size()))
69 w.varint(uint64(typ.PtrBytes))
70 w.varint(uint64(len(typName)))
71 w.stringData(typName)
72
73
74 for i := range node.children {
75 child := node.children[i].Load()
76 if child == nil {
77 continue
78 }
79 w = dumpTypesRec((*traceMapNode)(child), w)
80 }
81 return w
82 }
83
View as plain text