...
Source file src/pkg/cmd/compile/internal/gc/scope.go
1
2
3
4
5 package gc
6
7 import (
8 "cmd/internal/dwarf"
9 "cmd/internal/obj"
10 "cmd/internal/src"
11 "sort"
12 )
13
14
15 func xposBefore(p, q src.XPos) bool {
16 return Ctxt.PosTable.Pos(p).Before(Ctxt.PosTable.Pos(q))
17 }
18
19 func findScope(marks []Mark, pos src.XPos) ScopeID {
20 i := sort.Search(len(marks), func(i int) bool {
21 return xposBefore(pos, marks[i].Pos)
22 })
23 if i == 0 {
24 return 0
25 }
26 return marks[i-1].Scope
27 }
28
29 func assembleScopes(fnsym *obj.LSym, fn *Node, dwarfVars []*dwarf.Var, varScopes []ScopeID) []dwarf.Scope {
30
31 dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func.Parents))
32 for i, parent := range fn.Func.Parents {
33 dwarfScopes[i+1].Parent = int32(parent)
34 }
35
36 scopeVariables(dwarfVars, varScopes, dwarfScopes)
37 scopePCs(fnsym, fn.Func.Marks, dwarfScopes)
38 return compactScopes(dwarfScopes)
39 }
40
41
42 func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ScopeID, dwarfScopes []dwarf.Scope) {
43 sort.Stable(varsByScopeAndOffset{dwarfVars, varScopes})
44
45 i0 := 0
46 for i := range dwarfVars {
47 if varScopes[i] == varScopes[i0] {
48 continue
49 }
50 dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:i]
51 i0 = i
52 }
53 if i0 < len(dwarfVars) {
54 dwarfScopes[varScopes[i0]].Vars = dwarfVars[i0:]
55 }
56 }
57
58
59 func scopePCs(fnsym *obj.LSym, marks []Mark, dwarfScopes []dwarf.Scope) {
60
61
62 if len(marks) == 0 {
63 return
64 }
65 p0 := fnsym.Func.Text
66 scope := findScope(marks, p0.Pos)
67 for p := fnsym.Func.Text; p != nil; p = p.Link {
68 if p.Pos == p0.Pos {
69 continue
70 }
71 dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: p.Pc})
72 p0 = p
73 scope = findScope(marks, p0.Pos)
74 }
75 if p0.Pc < fnsym.Size {
76 dwarfScopes[scope].AppendRange(dwarf.Range{Start: p0.Pc, End: fnsym.Size})
77 }
78 }
79
80 func compactScopes(dwarfScopes []dwarf.Scope) []dwarf.Scope {
81
82 for i := len(dwarfScopes) - 1; i > 0; i-- {
83 s := &dwarfScopes[i]
84 dwarfScopes[s.Parent].UnifyRanges(s)
85 }
86
87 return dwarfScopes
88 }
89
90 type varsByScopeAndOffset struct {
91 vars []*dwarf.Var
92 scopes []ScopeID
93 }
94
95 func (v varsByScopeAndOffset) Len() int {
96 return len(v.vars)
97 }
98
99 func (v varsByScopeAndOffset) Less(i, j int) bool {
100 if v.scopes[i] != v.scopes[j] {
101 return v.scopes[i] < v.scopes[j]
102 }
103 return v.vars[i].StackOffset < v.vars[j].StackOffset
104 }
105
106 func (v varsByScopeAndOffset) Swap(i, j int) {
107 v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
108 v.scopes[i], v.scopes[j] = v.scopes[j], v.scopes[i]
109 }
110
View as plain text