|
@@ -37,6 +37,7 @@ type Options struct {
|
37
|
37
|
SampleValue func(s []int64) int64 // Function to compute the value of a sample
|
38
|
38
|
FormatTag func(int64, string) string // Function to format a sample tag value into a string
|
39
|
39
|
ObjNames bool // Always preserve obj filename
|
|
40
|
+ OrigFnNames bool // Preserve original (eg mangled) function names
|
40
|
41
|
|
41
|
42
|
CallTree bool // Build a tree instead of a graph
|
42
|
43
|
DropNegative bool // Drop nodes with overall negative values
|
|
@@ -244,7 +245,7 @@ func New(prof *profile.Profile, o *Options) *Graph {
|
244
|
245
|
// a map from the profile location indices to the corresponding graph
|
245
|
246
|
// nodes.
|
246
|
247
|
func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) {
|
247
|
|
- nodes, locationMap := CreateNodes(prof, o.ObjNames, o.KeptNodes)
|
|
248
|
+ nodes, locationMap := CreateNodes(prof, o)
|
248
|
249
|
for _, sample := range prof.Sample {
|
249
|
250
|
weight := o.SampleValue(sample.Value)
|
250
|
251
|
if weight == 0 {
|
|
@@ -313,8 +314,6 @@ type nodePair struct {
|
313
|
314
|
}
|
314
|
315
|
|
315
|
316
|
func newTree(prof *profile.Profile, o *Options) (g *Graph) {
|
316
|
|
- kept := o.KeptNodes
|
317
|
|
- keepBinary := o.ObjNames
|
318
|
317
|
parentNodeMap := make(map[*Node]NodeMap, len(prof.Sample))
|
319
|
318
|
for _, sample := range prof.Sample {
|
320
|
319
|
weight := o.SampleValue(sample.Value)
|
|
@@ -336,7 +335,7 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) {
|
336
|
335
|
nodeMap = make(NodeMap)
|
337
|
336
|
parentNodeMap[parent] = nodeMap
|
338
|
337
|
}
|
339
|
|
- n := nodeMap.findOrInsertLine(l, lines[lidx], keepBinary, kept)
|
|
338
|
+ n := nodeMap.findOrInsertLine(l, lines[lidx], o)
|
340
|
339
|
if n == nil {
|
341
|
340
|
continue
|
342
|
341
|
}
|
|
@@ -454,9 +453,8 @@ func isNegative(n *Node) bool {
|
454
|
453
|
// set of corresponding nodes (one per location.Line). If kept is
|
455
|
454
|
// non-nil, only nodes in that set are included; nodes that do not
|
456
|
455
|
// match are represented as a nil.
|
457
|
|
-func CreateNodes(prof *profile.Profile, keepBinary bool, kept NodeSet) (Nodes, map[uint64]Nodes) {
|
|
456
|
+func CreateNodes(prof *profile.Profile, o *Options) (Nodes, map[uint64]Nodes) {
|
458
|
457
|
locations := make(map[uint64]Nodes, len(prof.Location))
|
459
|
|
-
|
460
|
458
|
nm := make(NodeMap, len(prof.Location))
|
461
|
459
|
for _, l := range prof.Location {
|
462
|
460
|
lines := l.Line
|
|
@@ -465,7 +463,7 @@ func CreateNodes(prof *profile.Profile, keepBinary bool, kept NodeSet) (Nodes, m
|
465
|
463
|
}
|
466
|
464
|
nodes := make(Nodes, len(lines))
|
467
|
465
|
for ln := range lines {
|
468
|
|
- nodes[ln] = nm.findOrInsertLine(l, lines[ln], keepBinary, kept)
|
|
466
|
+ nodes[ln] = nm.findOrInsertLine(l, lines[ln], o)
|
469
|
467
|
}
|
470
|
468
|
locations[l.ID] = nodes
|
471
|
469
|
}
|
|
@@ -480,35 +478,37 @@ func (nm NodeMap) nodes() Nodes {
|
480
|
478
|
return nodes
|
481
|
479
|
}
|
482
|
480
|
|
483
|
|
-func (nm NodeMap) findOrInsertLine(l *profile.Location, li profile.Line, keepBinary bool, kept NodeSet) *Node {
|
|
481
|
+func (nm NodeMap) findOrInsertLine(l *profile.Location, li profile.Line, o *Options) *Node {
|
484
|
482
|
var objfile string
|
485
|
483
|
if m := l.Mapping; m != nil && m.File != "" {
|
486
|
484
|
objfile = filepath.Base(m.File)
|
487
|
485
|
}
|
488
|
486
|
|
489
|
|
- if ni := nodeInfo(l, li, objfile, keepBinary); ni != nil {
|
490
|
|
- return nm.FindOrInsertNode(*ni, kept)
|
|
487
|
+ if ni := nodeInfo(l, li, objfile, o); ni != nil {
|
|
488
|
+ return nm.FindOrInsertNode(*ni, o.KeptNodes)
|
491
|
489
|
}
|
492
|
490
|
return nil
|
493
|
491
|
}
|
494
|
492
|
|
495
|
|
-func nodeInfo(l *profile.Location, line profile.Line, objfile string, keepBinary bool) *NodeInfo {
|
|
493
|
+func nodeInfo(l *profile.Location, line profile.Line, objfile string, o *Options) *NodeInfo {
|
496
|
494
|
if line.Function == nil {
|
497
|
495
|
return &NodeInfo{Address: l.Address, Objfile: objfile}
|
498
|
496
|
}
|
499
|
497
|
ni := &NodeInfo{
|
500
|
|
- Address: l.Address,
|
501
|
|
- Lineno: int(line.Line),
|
502
|
|
- Name: line.Function.Name,
|
503
|
|
- OrigName: line.Function.SystemName,
|
|
498
|
+ Address: l.Address,
|
|
499
|
+ Lineno: int(line.Line),
|
|
500
|
+ Name: line.Function.Name,
|
504
|
501
|
}
|
505
|
502
|
if fname := line.Function.Filename; fname != "" {
|
506
|
503
|
ni.File = filepath.Clean(fname)
|
507
|
504
|
}
|
508
|
|
- if keepBinary {
|
|
505
|
+ if o.ObjNames {
|
509
|
506
|
ni.Objfile = objfile
|
510
|
507
|
ni.StartLine = int(line.Function.StartLine)
|
511
|
508
|
}
|
|
509
|
+ if o.OrigFnNames {
|
|
510
|
+ ni.OrigName = line.Function.SystemName
|
|
511
|
+ }
|
512
|
512
|
return ni
|
513
|
513
|
}
|
514
|
514
|
|