9.5.1总体逻辑
// file: cmd/compile/internal/escape/escape.go
func Funcs(all []ir.Node) {
ir.VisitFuncsBottomUp(all, Batch)
}// file: cmd/compile/internal/escape/escape.go
func Batch(fns []*ir.Func, recursive bool) {
var b batch
b.heapLoc.escapes = true
// 1. 构建数据流有向图,分为三步完成
// 1.1 遍历函数内的变量,为每个变量创建一个有向图的顶点。顶点用 location 表示,下文中会介绍该数据结构
for _, fn := range fns {
b.initFunc(fn)
}
// 1.2 遍历函数的 IR Tree, 根据赋值语句创建有向图的边并计算权重。边用 edge 表示,下文中会介绍该数据结构
for _, fn := range fns {
// 闭包在下一步处理
if !fn.IsHiddenClosure() {
b.walkFunc(fn)
}
}
// 1.3 处理闭包,继续创建有向图的边
for _, closure := range b.closures {
b.flowClosure(closure.k, closure.clo)
}
b.closures = nil
// 2. 先检查各个变量的大小,大对象直接逃逸到堆上
for _, loc := range b.allLocs {
if why := HeapAllocReason(loc.n); why != "" {
b.flow(b.heapHole().addr(loc.n, why), loc)
}
}
// 3. 对有向图的各个顶点进行逃逸分析
b.walkAll()
// 4. 逃逸分析完成,在 IR Tree 中标记各个变量顶点的结果
b.finish(fns)
}最后更新于