libgo: update to Go 1.11
[official-gcc.git] / libgo / go / runtime / pprof / internal / profile / encode.go
blobaf319330d9ad12564a208b05dc644273dc6753d6
1 // Copyright 2014 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.
5 package profile
7 import (
8 "errors"
9 "fmt"
10 "sort"
13 func (p *Profile) decoder() []decoder {
14 return profileDecoder
17 // preEncode populates the unexported fields to be used by encode
18 // (with suffix X) from the corresponding exported fields. The
19 // exported fields are cleared up to facilitate testing.
20 func (p *Profile) preEncode() {
21 strings := make(map[string]int)
22 addString(strings, "")
24 for _, st := range p.SampleType {
25 st.typeX = addString(strings, st.Type)
26 st.unitX = addString(strings, st.Unit)
29 for _, s := range p.Sample {
30 s.labelX = nil
31 var keys []string
32 for k := range s.Label {
33 keys = append(keys, k)
35 sort.Strings(keys)
36 for _, k := range keys {
37 vs := s.Label[k]
38 for _, v := range vs {
39 s.labelX = append(s.labelX,
40 Label{
41 keyX: addString(strings, k),
42 strX: addString(strings, v),
47 var numKeys []string
48 for k := range s.NumLabel {
49 numKeys = append(numKeys, k)
51 sort.Strings(numKeys)
52 for _, k := range numKeys {
53 vs := s.NumLabel[k]
54 for _, v := range vs {
55 s.labelX = append(s.labelX,
56 Label{
57 keyX: addString(strings, k),
58 numX: v,
63 s.locationIDX = nil
64 for _, l := range s.Location {
65 s.locationIDX = append(s.locationIDX, l.ID)
69 for _, m := range p.Mapping {
70 m.fileX = addString(strings, m.File)
71 m.buildIDX = addString(strings, m.BuildID)
74 for _, l := range p.Location {
75 for i, ln := range l.Line {
76 if ln.Function != nil {
77 l.Line[i].functionIDX = ln.Function.ID
78 } else {
79 l.Line[i].functionIDX = 0
82 if l.Mapping != nil {
83 l.mappingIDX = l.Mapping.ID
84 } else {
85 l.mappingIDX = 0
88 for _, f := range p.Function {
89 f.nameX = addString(strings, f.Name)
90 f.systemNameX = addString(strings, f.SystemName)
91 f.filenameX = addString(strings, f.Filename)
94 p.dropFramesX = addString(strings, p.DropFrames)
95 p.keepFramesX = addString(strings, p.KeepFrames)
97 if pt := p.PeriodType; pt != nil {
98 pt.typeX = addString(strings, pt.Type)
99 pt.unitX = addString(strings, pt.Unit)
102 p.stringTable = make([]string, len(strings))
103 for s, i := range strings {
104 p.stringTable[i] = s
108 func (p *Profile) encode(b *buffer) {
109 for _, x := range p.SampleType {
110 encodeMessage(b, 1, x)
112 for _, x := range p.Sample {
113 encodeMessage(b, 2, x)
115 for _, x := range p.Mapping {
116 encodeMessage(b, 3, x)
118 for _, x := range p.Location {
119 encodeMessage(b, 4, x)
121 for _, x := range p.Function {
122 encodeMessage(b, 5, x)
124 encodeStrings(b, 6, p.stringTable)
125 encodeInt64Opt(b, 7, p.dropFramesX)
126 encodeInt64Opt(b, 8, p.keepFramesX)
127 encodeInt64Opt(b, 9, p.TimeNanos)
128 encodeInt64Opt(b, 10, p.DurationNanos)
129 if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {
130 encodeMessage(b, 11, p.PeriodType)
132 encodeInt64Opt(b, 12, p.Period)
135 var profileDecoder = []decoder{
136 nil, // 0
137 // repeated ValueType sample_type = 1
138 func(b *buffer, m message) error {
139 x := new(ValueType)
140 pp := m.(*Profile)
141 pp.SampleType = append(pp.SampleType, x)
142 return decodeMessage(b, x)
144 // repeated Sample sample = 2
145 func(b *buffer, m message) error {
146 x := new(Sample)
147 pp := m.(*Profile)
148 pp.Sample = append(pp.Sample, x)
149 return decodeMessage(b, x)
151 // repeated Mapping mapping = 3
152 func(b *buffer, m message) error {
153 x := new(Mapping)
154 pp := m.(*Profile)
155 pp.Mapping = append(pp.Mapping, x)
156 return decodeMessage(b, x)
158 // repeated Location location = 4
159 func(b *buffer, m message) error {
160 x := new(Location)
161 pp := m.(*Profile)
162 pp.Location = append(pp.Location, x)
163 return decodeMessage(b, x)
165 // repeated Function function = 5
166 func(b *buffer, m message) error {
167 x := new(Function)
168 pp := m.(*Profile)
169 pp.Function = append(pp.Function, x)
170 return decodeMessage(b, x)
172 // repeated string string_table = 6
173 func(b *buffer, m message) error {
174 err := decodeStrings(b, &m.(*Profile).stringTable)
175 if err != nil {
176 return err
178 if *&m.(*Profile).stringTable[0] != "" {
179 return errors.New("string_table[0] must be ''")
181 return nil
183 // repeated int64 drop_frames = 7
184 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
185 // repeated int64 keep_frames = 8
186 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
187 // repeated int64 time_nanos = 9
188 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) },
189 // repeated int64 duration_nanos = 10
190 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
191 // optional string period_type = 11
192 func(b *buffer, m message) error {
193 x := new(ValueType)
194 pp := m.(*Profile)
195 pp.PeriodType = x
196 return decodeMessage(b, x)
198 // repeated int64 period = 12
199 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
200 // repeated int64 comment = 13
201 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },
202 // int64 defaultSampleType = 14
203 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },
206 // postDecode takes the unexported fields populated by decode (with
207 // suffix X) and populates the corresponding exported fields.
208 // The unexported fields are cleared up to facilitate testing.
209 func (p *Profile) postDecode() error {
210 var err error
212 mappings := make(map[uint64]*Mapping)
213 for _, m := range p.Mapping {
214 m.File, err = getString(p.stringTable, &m.fileX, err)
215 m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
216 mappings[m.ID] = m
219 functions := make(map[uint64]*Function)
220 for _, f := range p.Function {
221 f.Name, err = getString(p.stringTable, &f.nameX, err)
222 f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
223 f.Filename, err = getString(p.stringTable, &f.filenameX, err)
224 functions[f.ID] = f
227 locations := make(map[uint64]*Location)
228 for _, l := range p.Location {
229 l.Mapping = mappings[l.mappingIDX]
230 l.mappingIDX = 0
231 for i, ln := range l.Line {
232 if id := ln.functionIDX; id != 0 {
233 l.Line[i].Function = functions[id]
234 if l.Line[i].Function == nil {
235 return fmt.Errorf("Function ID %d not found", id)
237 l.Line[i].functionIDX = 0
240 locations[l.ID] = l
243 for _, st := range p.SampleType {
244 st.Type, err = getString(p.stringTable, &st.typeX, err)
245 st.Unit, err = getString(p.stringTable, &st.unitX, err)
248 for _, s := range p.Sample {
249 labels := make(map[string][]string)
250 numLabels := make(map[string][]int64)
251 for _, l := range s.labelX {
252 var key, value string
253 key, err = getString(p.stringTable, &l.keyX, err)
254 if l.strX != 0 {
255 value, err = getString(p.stringTable, &l.strX, err)
256 labels[key] = append(labels[key], value)
257 } else {
258 numLabels[key] = append(numLabels[key], l.numX)
261 if len(labels) > 0 {
262 s.Label = labels
264 if len(numLabels) > 0 {
265 s.NumLabel = numLabels
267 s.Location = nil
268 for _, lid := range s.locationIDX {
269 s.Location = append(s.Location, locations[lid])
271 s.locationIDX = nil
274 p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
275 p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
277 if pt := p.PeriodType; pt == nil {
278 p.PeriodType = &ValueType{}
281 if pt := p.PeriodType; pt != nil {
282 pt.Type, err = getString(p.stringTable, &pt.typeX, err)
283 pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
285 for _, i := range p.commentX {
286 var c string
287 c, err = getString(p.stringTable, &i, err)
288 p.Comments = append(p.Comments, c)
291 p.commentX = nil
292 p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err)
293 p.stringTable = nil
294 return nil
297 func (p *ValueType) decoder() []decoder {
298 return valueTypeDecoder
301 func (p *ValueType) encode(b *buffer) {
302 encodeInt64Opt(b, 1, p.typeX)
303 encodeInt64Opt(b, 2, p.unitX)
306 var valueTypeDecoder = []decoder{
307 nil, // 0
308 // optional int64 type = 1
309 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
310 // optional int64 unit = 2
311 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
314 func (p *Sample) decoder() []decoder {
315 return sampleDecoder
318 func (p *Sample) encode(b *buffer) {
319 encodeUint64s(b, 1, p.locationIDX)
320 for _, x := range p.Value {
321 encodeInt64(b, 2, x)
323 for _, x := range p.labelX {
324 encodeMessage(b, 3, x)
328 var sampleDecoder = []decoder{
329 nil, // 0
330 // repeated uint64 location = 1
331 func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
332 // repeated int64 value = 2
333 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
334 // repeated Label label = 3
335 func(b *buffer, m message) error {
336 s := m.(*Sample)
337 n := len(s.labelX)
338 s.labelX = append(s.labelX, Label{})
339 return decodeMessage(b, &s.labelX[n])
343 func (p Label) decoder() []decoder {
344 return labelDecoder
347 func (p Label) encode(b *buffer) {
348 encodeInt64Opt(b, 1, p.keyX)
349 encodeInt64Opt(b, 2, p.strX)
350 encodeInt64Opt(b, 3, p.numX)
353 var labelDecoder = []decoder{
354 nil, // 0
355 // optional int64 key = 1
356 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) },
357 // optional int64 str = 2
358 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) },
359 // optional int64 num = 3
360 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) },
363 func (p *Mapping) decoder() []decoder {
364 return mappingDecoder
367 func (p *Mapping) encode(b *buffer) {
368 encodeUint64Opt(b, 1, p.ID)
369 encodeUint64Opt(b, 2, p.Start)
370 encodeUint64Opt(b, 3, p.Limit)
371 encodeUint64Opt(b, 4, p.Offset)
372 encodeInt64Opt(b, 5, p.fileX)
373 encodeInt64Opt(b, 6, p.buildIDX)
374 encodeBoolOpt(b, 7, p.HasFunctions)
375 encodeBoolOpt(b, 8, p.HasFilenames)
376 encodeBoolOpt(b, 9, p.HasLineNumbers)
377 encodeBoolOpt(b, 10, p.HasInlineFrames)
380 var mappingDecoder = []decoder{
381 nil, // 0
382 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) }, // optional uint64 id = 1
383 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) }, // optional uint64 memory_offset = 2
384 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) }, // optional uint64 memory_limit = 3
385 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) }, // optional uint64 file_offset = 4
386 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) }, // optional int64 filename = 5
387 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) }, // optional int64 build_id = 6
388 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) }, // optional bool has_functions = 7
389 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) }, // optional bool has_filenames = 8
390 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) }, // optional bool has_line_numbers = 9
391 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
394 func (p *Location) decoder() []decoder {
395 return locationDecoder
398 func (p *Location) encode(b *buffer) {
399 encodeUint64Opt(b, 1, p.ID)
400 encodeUint64Opt(b, 2, p.mappingIDX)
401 encodeUint64Opt(b, 3, p.Address)
402 for i := range p.Line {
403 encodeMessage(b, 4, &p.Line[i])
407 var locationDecoder = []decoder{
408 nil, // 0
409 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) }, // optional uint64 id = 1;
410 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
411 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) }, // optional uint64 address = 3;
412 func(b *buffer, m message) error { // repeated Line line = 4
413 pp := m.(*Location)
414 n := len(pp.Line)
415 pp.Line = append(pp.Line, Line{})
416 return decodeMessage(b, &pp.Line[n])
420 func (p *Line) decoder() []decoder {
421 return lineDecoder
424 func (p *Line) encode(b *buffer) {
425 encodeUint64Opt(b, 1, p.functionIDX)
426 encodeInt64Opt(b, 2, p.Line)
429 var lineDecoder = []decoder{
430 nil, // 0
431 // optional uint64 function_id = 1
432 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
433 // optional int64 line = 2
434 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
437 func (p *Function) decoder() []decoder {
438 return functionDecoder
441 func (p *Function) encode(b *buffer) {
442 encodeUint64Opt(b, 1, p.ID)
443 encodeInt64Opt(b, 2, p.nameX)
444 encodeInt64Opt(b, 3, p.systemNameX)
445 encodeInt64Opt(b, 4, p.filenameX)
446 encodeInt64Opt(b, 5, p.StartLine)
449 var functionDecoder = []decoder{
450 nil, // 0
451 // optional uint64 id = 1
452 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
453 // optional int64 function_name = 2
454 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
455 // optional int64 function_system_name = 3
456 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
457 // repeated int64 filename = 4
458 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
459 // optional int64 start_line = 5
460 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
463 func addString(strings map[string]int, s string) int64 {
464 i, ok := strings[s]
465 if !ok {
466 i = len(strings)
467 strings[s] = i
469 return int64(i)
472 func getString(strings []string, strng *int64, err error) (string, error) {
473 if err != nil {
474 return "", err
476 s := int(*strng)
477 if s < 0 || s >= len(strings) {
478 return "", errMalformed
480 *strng = 0
481 return strings[s], nil