Skip to content

Commit 063c72f

Browse files
committed
[dev.regabi] cmd/compile: backport changes from dev.typeparams (9456804)
This CL backports a bunch of changes that landed on dev.typeparams, but are not dependent on types2 or generics. By backporting, we reduce the divergence between development branches, hopefully improving test coverage and reducing risk of merge conflicts. Updates #43866. Change-Id: I382510855c9b5fac52b17066e44a00bd07fe86f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/286172 Trust: Matthew Dempsky <[email protected]> Trust: Robert Griesemer <[email protected]> Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent d05d6fa commit 063c72f

File tree

14 files changed

+398
-330
lines changed

14 files changed

+398
-330
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright 2021 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 dwarfgen
6+
7+
import (
8+
"cmd/compile/internal/base"
9+
"cmd/compile/internal/ir"
10+
"cmd/internal/src"
11+
)
12+
13+
// A ScopeMarker tracks scope nesting and boundaries for later use
14+
// during DWARF generation.
15+
type ScopeMarker struct {
16+
parents []ir.ScopeID
17+
marks []ir.Mark
18+
}
19+
20+
// checkPos validates the given position and returns the current scope.
21+
func (m *ScopeMarker) checkPos(pos src.XPos) ir.ScopeID {
22+
if !pos.IsKnown() {
23+
base.Fatalf("unknown scope position")
24+
}
25+
26+
if len(m.marks) == 0 {
27+
return 0
28+
}
29+
30+
last := &m.marks[len(m.marks)-1]
31+
if xposBefore(pos, last.Pos) {
32+
base.FatalfAt(pos, "non-monotonic scope positions\n\t%v: previous scope position", base.FmtPos(last.Pos))
33+
}
34+
return last.Scope
35+
}
36+
37+
// Push records a transition to a new child scope of the current scope.
38+
func (m *ScopeMarker) Push(pos src.XPos) {
39+
current := m.checkPos(pos)
40+
41+
m.parents = append(m.parents, current)
42+
child := ir.ScopeID(len(m.parents))
43+
44+
m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: child})
45+
}
46+
47+
// Pop records a transition back to the current scope's parent.
48+
func (m *ScopeMarker) Pop(pos src.XPos) {
49+
current := m.checkPos(pos)
50+
51+
parent := m.parents[current-1]
52+
53+
m.marks = append(m.marks, ir.Mark{Pos: pos, Scope: parent})
54+
}
55+
56+
// Unpush removes the current scope, which must be empty.
57+
func (m *ScopeMarker) Unpush() {
58+
i := len(m.marks) - 1
59+
current := m.marks[i].Scope
60+
61+
if current != ir.ScopeID(len(m.parents)) {
62+
base.FatalfAt(m.marks[i].Pos, "current scope is not empty")
63+
}
64+
65+
m.parents = m.parents[:current-1]
66+
m.marks = m.marks[:i]
67+
}
68+
69+
// WriteTo writes the recorded scope marks to the given function,
70+
// and resets the marker for reuse.
71+
func (m *ScopeMarker) WriteTo(fn *ir.Func) {
72+
m.compactMarks()
73+
74+
fn.Parents = make([]ir.ScopeID, len(m.parents))
75+
copy(fn.Parents, m.parents)
76+
m.parents = m.parents[:0]
77+
78+
fn.Marks = make([]ir.Mark, len(m.marks))
79+
copy(fn.Marks, m.marks)
80+
m.marks = m.marks[:0]
81+
}
82+
83+
func (m *ScopeMarker) compactMarks() {
84+
n := 0
85+
for _, next := range m.marks {
86+
if n > 0 && next.Pos == m.marks[n-1].Pos {
87+
m.marks[n-1].Scope = next.Scope
88+
continue
89+
}
90+
m.marks[n] = next
91+
n++
92+
}
93+
m.marks = m.marks[:n]
94+
}

0 commit comments

Comments
 (0)