github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/runtime/pprof/internal/profile/encode.go (about)

     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.
     4  
     5  package profile
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"sort"
    11  )
    12  
    13  func (p *Profile) decoder() []decoder {
    14  	return profileDecoder
    15  }
    16  
    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, "")
    23  
    24  	for _, st := range p.SampleType {
    25  		st.typeX = addString(strings, st.Type)
    26  		st.unitX = addString(strings, st.Unit)
    27  	}
    28  
    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)
    34  		}
    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),
    43  					},
    44  				)
    45  			}
    46  		}
    47  		var numKeys []string
    48  		for k := range s.NumLabel {
    49  			numKeys = append(numKeys, k)
    50  		}
    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,
    59  					},
    60  				)
    61  			}
    62  		}
    63  		s.locationIDX = nil
    64  		for _, l := range s.Location {
    65  			s.locationIDX = append(s.locationIDX, l.ID)
    66  		}
    67  	}
    68  
    69  	for _, m := range p.Mapping {
    70  		m.fileX = addString(strings, m.File)
    71  		m.buildIDX = addString(strings, m.BuildID)
    72  	}
    73  
    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
    80  			}
    81  		}
    82  		if l.Mapping != nil {
    83  			l.mappingIDX = l.Mapping.ID
    84  		} else {
    85  			l.mappingIDX = 0
    86  		}
    87  	}
    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)
    92  	}
    93  
    94  	p.dropFramesX = addString(strings, p.DropFrames)
    95  	p.keepFramesX = addString(strings, p.KeepFrames)
    96  
    97  	if pt := p.PeriodType; pt != nil {
    98  		pt.typeX = addString(strings, pt.Type)
    99  		pt.unitX = addString(strings, pt.Unit)
   100  	}
   101  
   102  	p.stringTable = make([]string, len(strings))
   103  	for s, i := range strings {
   104  		p.stringTable[i] = s
   105  	}
   106  }
   107  
   108  func (p *Profile) encode(b *buffer) {
   109  	for _, x := range p.SampleType {
   110  		encodeMessage(b, 1, x)
   111  	}
   112  	for _, x := range p.Sample {
   113  		encodeMessage(b, 2, x)
   114  	}
   115  	for _, x := range p.Mapping {
   116  		encodeMessage(b, 3, x)
   117  	}
   118  	for _, x := range p.Location {
   119  		encodeMessage(b, 4, x)
   120  	}
   121  	for _, x := range p.Function {
   122  		encodeMessage(b, 5, x)
   123  	}
   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)
   131  	}
   132  	encodeInt64Opt(b, 12, p.Period)
   133  }
   134  
   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)
   143  	},
   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)
   150  	},
   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)
   157  	},
   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)
   164  	},
   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)
   171  	},
   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
   177  		}
   178  		if *&m.(*Profile).stringTable[0] != "" {
   179  			return errors.New("string_table[0] must be ''")
   180  		}
   181  		return nil
   182  	},
   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)
   197  	},
   198  	// repeated int64 period = 12
   199  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
   200  }
   201  
   202  // postDecode takes the unexported fields populated by decode (with
   203  // suffix X) and populates the corresponding exported fields.
   204  // The unexported fields are cleared up to facilitate testing.
   205  func (p *Profile) postDecode() error {
   206  	var err error
   207  
   208  	mappings := make(map[uint64]*Mapping)
   209  	for _, m := range p.Mapping {
   210  		m.File, err = getString(p.stringTable, &m.fileX, err)
   211  		m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
   212  		mappings[m.ID] = m
   213  	}
   214  
   215  	functions := make(map[uint64]*Function)
   216  	for _, f := range p.Function {
   217  		f.Name, err = getString(p.stringTable, &f.nameX, err)
   218  		f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
   219  		f.Filename, err = getString(p.stringTable, &f.filenameX, err)
   220  		functions[f.ID] = f
   221  	}
   222  
   223  	locations := make(map[uint64]*Location)
   224  	for _, l := range p.Location {
   225  		l.Mapping = mappings[l.mappingIDX]
   226  		l.mappingIDX = 0
   227  		for i, ln := range l.Line {
   228  			if id := ln.functionIDX; id != 0 {
   229  				l.Line[i].Function = functions[id]
   230  				if l.Line[i].Function == nil {
   231  					return fmt.Errorf("Function ID %d not found", id)
   232  				}
   233  				l.Line[i].functionIDX = 0
   234  			}
   235  		}
   236  		locations[l.ID] = l
   237  	}
   238  
   239  	for _, st := range p.SampleType {
   240  		st.Type, err = getString(p.stringTable, &st.typeX, err)
   241  		st.Unit, err = getString(p.stringTable, &st.unitX, err)
   242  	}
   243  
   244  	for _, s := range p.Sample {
   245  		labels := make(map[string][]string)
   246  		numLabels := make(map[string][]int64)
   247  		for _, l := range s.labelX {
   248  			var key, value string
   249  			key, err = getString(p.stringTable, &l.keyX, err)
   250  			if l.strX != 0 {
   251  				value, err = getString(p.stringTable, &l.strX, err)
   252  				labels[key] = append(labels[key], value)
   253  			} else {
   254  				numLabels[key] = append(numLabels[key], l.numX)
   255  			}
   256  		}
   257  		if len(labels) > 0 {
   258  			s.Label = labels
   259  		}
   260  		if len(numLabels) > 0 {
   261  			s.NumLabel = numLabels
   262  		}
   263  		s.Location = nil
   264  		for _, lid := range s.locationIDX {
   265  			s.Location = append(s.Location, locations[lid])
   266  		}
   267  		s.locationIDX = nil
   268  	}
   269  
   270  	p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
   271  	p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
   272  
   273  	if pt := p.PeriodType; pt == nil {
   274  		p.PeriodType = &ValueType{}
   275  	}
   276  
   277  	if pt := p.PeriodType; pt != nil {
   278  		pt.Type, err = getString(p.stringTable, &pt.typeX, err)
   279  		pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
   280  	}
   281  	p.stringTable = nil
   282  	return nil
   283  }
   284  
   285  func (p *ValueType) decoder() []decoder {
   286  	return valueTypeDecoder
   287  }
   288  
   289  func (p *ValueType) encode(b *buffer) {
   290  	encodeInt64Opt(b, 1, p.typeX)
   291  	encodeInt64Opt(b, 2, p.unitX)
   292  }
   293  
   294  var valueTypeDecoder = []decoder{
   295  	nil, // 0
   296  	// optional int64 type = 1
   297  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
   298  	// optional int64 unit = 2
   299  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
   300  }
   301  
   302  func (p *Sample) decoder() []decoder {
   303  	return sampleDecoder
   304  }
   305  
   306  func (p *Sample) encode(b *buffer) {
   307  	encodeUint64s(b, 1, p.locationIDX)
   308  	for _, x := range p.Value {
   309  		encodeInt64(b, 2, x)
   310  	}
   311  	for _, x := range p.labelX {
   312  		encodeMessage(b, 3, x)
   313  	}
   314  }
   315  
   316  var sampleDecoder = []decoder{
   317  	nil, // 0
   318  	// repeated uint64 location = 1
   319  	func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
   320  	// repeated int64 value = 2
   321  	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
   322  	// repeated Label label = 3
   323  	func(b *buffer, m message) error {
   324  		s := m.(*Sample)
   325  		n := len(s.labelX)
   326  		s.labelX = append(s.labelX, Label{})
   327  		return decodeMessage(b, &s.labelX[n])
   328  	},
   329  }
   330  
   331  func (p Label) decoder() []decoder {
   332  	return labelDecoder
   333  }
   334  
   335  func (p Label) encode(b *buffer) {
   336  	encodeInt64Opt(b, 1, p.keyX)
   337  	encodeInt64Opt(b, 2, p.strX)
   338  	encodeInt64Opt(b, 3, p.numX)
   339  }
   340  
   341  var labelDecoder = []decoder{
   342  	nil, // 0
   343  	// optional int64 key = 1
   344  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) },
   345  	// optional int64 str = 2
   346  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) },
   347  	// optional int64 num = 3
   348  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) },
   349  }
   350  
   351  func (p *Mapping) decoder() []decoder {
   352  	return mappingDecoder
   353  }
   354  
   355  func (p *Mapping) encode(b *buffer) {
   356  	encodeUint64Opt(b, 1, p.ID)
   357  	encodeUint64Opt(b, 2, p.Start)
   358  	encodeUint64Opt(b, 3, p.Limit)
   359  	encodeUint64Opt(b, 4, p.Offset)
   360  	encodeInt64Opt(b, 5, p.fileX)
   361  	encodeInt64Opt(b, 6, p.buildIDX)
   362  	encodeBoolOpt(b, 7, p.HasFunctions)
   363  	encodeBoolOpt(b, 8, p.HasFilenames)
   364  	encodeBoolOpt(b, 9, p.HasLineNumbers)
   365  	encodeBoolOpt(b, 10, p.HasInlineFrames)
   366  }
   367  
   368  var mappingDecoder = []decoder{
   369  	nil, // 0
   370  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },            // optional uint64 id = 1
   371  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },         // optional uint64 memory_offset = 2
   372  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },         // optional uint64 memory_limit = 3
   373  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },        // optional uint64 file_offset = 4
   374  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },          // optional int64 filename = 5
   375  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },       // optional int64 build_id = 6
   376  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },    // optional bool has_functions = 7
   377  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8
   378  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9
   379  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
   380  }
   381  
   382  func (p *Location) decoder() []decoder {
   383  	return locationDecoder
   384  }
   385  
   386  func (p *Location) encode(b *buffer) {
   387  	encodeUint64Opt(b, 1, p.ID)
   388  	encodeUint64Opt(b, 2, p.mappingIDX)
   389  	encodeUint64Opt(b, 3, p.Address)
   390  	for i := range p.Line {
   391  		encodeMessage(b, 4, &p.Line[i])
   392  	}
   393  }
   394  
   395  var locationDecoder = []decoder{
   396  	nil, // 0
   397  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },         // optional uint64 id = 1;
   398  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
   399  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },    // optional uint64 address = 3;
   400  	func(b *buffer, m message) error { // repeated Line line = 4
   401  		pp := m.(*Location)
   402  		n := len(pp.Line)
   403  		pp.Line = append(pp.Line, Line{})
   404  		return decodeMessage(b, &pp.Line[n])
   405  	},
   406  }
   407  
   408  func (p *Line) decoder() []decoder {
   409  	return lineDecoder
   410  }
   411  
   412  func (p *Line) encode(b *buffer) {
   413  	encodeUint64Opt(b, 1, p.functionIDX)
   414  	encodeInt64Opt(b, 2, p.Line)
   415  }
   416  
   417  var lineDecoder = []decoder{
   418  	nil, // 0
   419  	// optional uint64 function_id = 1
   420  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
   421  	// optional int64 line = 2
   422  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
   423  }
   424  
   425  func (p *Function) decoder() []decoder {
   426  	return functionDecoder
   427  }
   428  
   429  func (p *Function) encode(b *buffer) {
   430  	encodeUint64Opt(b, 1, p.ID)
   431  	encodeInt64Opt(b, 2, p.nameX)
   432  	encodeInt64Opt(b, 3, p.systemNameX)
   433  	encodeInt64Opt(b, 4, p.filenameX)
   434  	encodeInt64Opt(b, 5, p.StartLine)
   435  }
   436  
   437  var functionDecoder = []decoder{
   438  	nil, // 0
   439  	// optional uint64 id = 1
   440  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
   441  	// optional int64 function_name = 2
   442  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
   443  	// optional int64 function_system_name = 3
   444  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
   445  	// repeated int64 filename = 4
   446  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
   447  	// optional int64 start_line = 5
   448  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
   449  }
   450  
   451  func addString(strings map[string]int, s string) int64 {
   452  	i, ok := strings[s]
   453  	if !ok {
   454  		i = len(strings)
   455  		strings[s] = i
   456  	}
   457  	return int64(i)
   458  }
   459  
   460  func getString(strings []string, strng *int64, err error) (string, error) {
   461  	if err != nil {
   462  		return "", err
   463  	}
   464  	s := int(*strng)
   465  	if s < 0 || s >= len(strings) {
   466  		return "", errMalformed
   467  	}
   468  	*strng = 0
   469  	return strings[s], nil
   470  }