podman

Форк
0
131 строка · 4.0 Кб
1
// Copyright 2017 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 obj
6

7
import "github.com/twitchyliquid64/golang-asm/src"
8

9
// InlTree is a collection of inlined calls. The Parent field of an
10
// InlinedCall is the index of another InlinedCall in InlTree.
11
//
12
// The compiler maintains a global inlining tree and adds a node to it
13
// every time a function is inlined. For example, suppose f() calls g()
14
// and g has two calls to h(), and that f, g, and h are inlineable:
15
//
16
//  1 func main() {
17
//  2     f()
18
//  3 }
19
//  4 func f() {
20
//  5     g()
21
//  6 }
22
//  7 func g() {
23
//  8     h()
24
//  9     h()
25
// 10 }
26
// 11 func h() {
27
// 12     println("H")
28
// 13 }
29
//
30
// Assuming the global tree starts empty, inlining will produce the
31
// following tree:
32
//
33
//   []InlinedCall{
34
//     {Parent: -1, Func: "f", Pos: <line 2>},
35
//     {Parent:  0, Func: "g", Pos: <line 5>},
36
//     {Parent:  1, Func: "h", Pos: <line 8>},
37
//     {Parent:  1, Func: "h", Pos: <line 9>},
38
//   }
39
//
40
// The nodes of h inlined into main will have inlining indexes 2 and 3.
41
//
42
// Eventually, the compiler extracts a per-function inlining tree from
43
// the global inlining tree (see pcln.go).
44
type InlTree struct {
45
	nodes []InlinedCall
46
}
47

48
// InlinedCall is a node in an InlTree.
49
type InlinedCall struct {
50
	Parent   int      // index of the parent in the InlTree or < 0 if outermost call
51
	Pos      src.XPos // position of the inlined call
52
	Func     *LSym    // function that was inlined
53
	ParentPC int32    // PC of instruction just before inlined body. Only valid in local trees.
54
}
55

56
// Add adds a new call to the tree, returning its index.
57
func (tree *InlTree) Add(parent int, pos src.XPos, func_ *LSym) int {
58
	r := len(tree.nodes)
59
	call := InlinedCall{
60
		Parent: parent,
61
		Pos:    pos,
62
		Func:   func_,
63
	}
64
	tree.nodes = append(tree.nodes, call)
65
	return r
66
}
67

68
func (tree *InlTree) Parent(inlIndex int) int {
69
	return tree.nodes[inlIndex].Parent
70
}
71

72
func (tree *InlTree) InlinedFunction(inlIndex int) *LSym {
73
	return tree.nodes[inlIndex].Func
74
}
75

76
func (tree *InlTree) CallPos(inlIndex int) src.XPos {
77
	return tree.nodes[inlIndex].Pos
78
}
79

80
func (tree *InlTree) setParentPC(inlIndex int, pc int32) {
81
	tree.nodes[inlIndex].ParentPC = pc
82
}
83

84
// OutermostPos returns the outermost position corresponding to xpos,
85
// which is where xpos was ultimately inlined to. In the example for
86
// InlTree, main() contains inlined AST nodes from h(), but the
87
// outermost position for those nodes is line 2.
88
func (ctxt *Link) OutermostPos(xpos src.XPos) src.Pos {
89
	pos := ctxt.InnermostPos(xpos)
90

91
	outerxpos := xpos
92
	for ix := pos.Base().InliningIndex(); ix >= 0; {
93
		call := ctxt.InlTree.nodes[ix]
94
		ix = call.Parent
95
		outerxpos = call.Pos
96
	}
97
	return ctxt.PosTable.Pos(outerxpos)
98
}
99

100
// InnermostPos returns the innermost position corresponding to xpos,
101
// that is, the code that is inlined and that inlines nothing else.
102
// In the example for InlTree above, the code for println within h
103
// would have an innermost position with line number 12, whether
104
// h was not inlined, inlined into g, g-then-f, or g-then-f-then-main.
105
// This corresponds to what someone debugging main, f, g, or h might
106
// expect to see while single-stepping.
107
func (ctxt *Link) InnermostPos(xpos src.XPos) src.Pos {
108
	return ctxt.PosTable.Pos(xpos)
109
}
110

111
// AllPos returns a slice of the positions inlined at xpos, from
112
// innermost (index zero) to outermost.  To avoid gratuitous allocation
113
// the result is passed in and extended if necessary.
114
func (ctxt *Link) AllPos(xpos src.XPos, result []src.Pos) []src.Pos {
115
	pos := ctxt.InnermostPos(xpos)
116
	result = result[:0]
117
	result = append(result, ctxt.PosTable.Pos(xpos))
118
	for ix := pos.Base().InliningIndex(); ix >= 0; {
119
		call := ctxt.InlTree.nodes[ix]
120
		ix = call.Parent
121
		result = append(result, ctxt.PosTable.Pos(call.Pos))
122
	}
123
	return result
124
}
125

126
func dumpInlTree(ctxt *Link, tree InlTree) {
127
	for i, call := range tree.nodes {
128
		pos := ctxt.PosTable.Pos(call.Pos)
129
		ctxt.Logf("%0d | %0d | %s (%s) pc=%d\n", i, call.Parent, call.Func, pos, call.ParentPC)
130
	}
131
}
132

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.