functions splits apart the lines to show in a file into a list of per-function ranges.
(f *sourceFile)
| 715 | |
| 716 | // functions splits apart the lines to show in a file into a list of per-function ranges. |
| 717 | func (sp *sourcePrinter) functions(f *sourceFile) []sourceFunction { |
| 718 | var funcs []sourceFunction |
| 719 | |
| 720 | // Get interesting lines in sorted order. |
| 721 | lines := make([]int, 0, len(f.lines)) |
| 722 | for l := range f.lines { |
| 723 | lines = append(lines, l) |
| 724 | } |
| 725 | sort.Ints(lines) |
| 726 | |
| 727 | // Merge adjacent lines that are in same function and not too far apart. |
| 728 | const mergeLimit = 20 |
| 729 | for _, l := range lines { |
| 730 | name := f.funcName[l] |
| 731 | if pretty, ok := sp.prettyNames[name]; ok { |
| 732 | // Use demangled name if available. |
| 733 | name = pretty |
| 734 | } |
| 735 | |
| 736 | fn := sourceFunction{name: name, begin: l, end: l + 1} |
| 737 | for _, x := range f.lines[l] { |
| 738 | inst := sp.insts[x.addr] |
| 739 | fn.flat += inst.flat |
| 740 | fn.cum += inst.cum |
| 741 | } |
| 742 | |
| 743 | // See if we should merge into preceding function. |
| 744 | if len(funcs) > 0 { |
| 745 | last := funcs[len(funcs)-1] |
| 746 | if l-last.end < mergeLimit && last.name == name { |
| 747 | last.end = l + 1 |
| 748 | last.flat += fn.flat |
| 749 | last.cum += fn.cum |
| 750 | funcs[len(funcs)-1] = last |
| 751 | continue |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | // Add new function. |
| 756 | funcs = append(funcs, fn) |
| 757 | } |
| 758 | |
| 759 | // Expand function boundaries to show neighborhood. |
| 760 | const expand = 5 |
| 761 | for i, f := range funcs { |
| 762 | if i == 0 { |
| 763 | // Extend backwards, stopping at line number 1, but do not disturb 0 |
| 764 | // since that is a special line number that can show up when addr2line |
| 765 | // cannot determine the real line number. |
| 766 | if f.begin > expand { |
| 767 | f.begin -= expand |
| 768 | } else if f.begin > 1 { |
| 769 | f.begin = 1 |
| 770 | } |
| 771 | } else { |
| 772 | // Find gap from predecessor and divide between predecessor and f. |
| 773 | halfGap := min((f.begin-funcs[i-1].end)/2, expand) |
| 774 | funcs[i-1].end += halfGap |