golang leaks 代码
文件路径:/src/cmd/compile/internal/escape/leaks.go
/ Copyright 2018 The Go Authors. All rights reserved.
/ Use of this source code is governed by a BSD-style
/ license that can be found in the LICENSE file.
package escape
import (
"cmd/compile/internal/base"
"math"
"strings"
)
const numEscResults = 7
/ An leaks represents a set of assignment flows from a parameter
/ to the heap or to any of its function's (first numEscResults)
/ result parameters.
type leaks [1 + numEscResults]uint8
/ Empty reports whether l is an empty set (i.e., no assignment flows).
func (l leaks) Empty() bool { return l == leaks{} }
/ Heap returns the minimum deref count of any assignment flow from l
/ to the heap. If no such flows exist, Heap returns -1.
func (l leaks) Heap() int { return l.get(0) }
/ Result returns the minimum deref count of any assignment flow from
/ l to its function's i'th result parameter. If no such flows exist,
/ Result returns -1.
func (l leaks) Result(i int) int { return l.get(1 + i) }
/ AddHeap adds an assignment flow from l to the heap.
func (l *leaks) AddHeap(derefs int) { l.add(0, derefs) }
/ AddResult adds an assignment flow from l to its function's i'th
/ result parameter.
func (l *leaks) AddResult(i, derefs int) { l.add(1+i, derefs) }
func (l *leaks) setResult(i, derefs int) { l.set(1+i, derefs) }
func (l leaks) get(i int) int { return int(l[i]) - 1 }
func (l *leaks) add(i, derefs int) {
if old := l.get(i); old < 0 || derefs < old {
l.set(i, derefs)
}
}
func (l *leaks) set(i, derefs int) {
v := derefs + 1
if v < 0 {
base.Fatalf("invalid derefs count: %v", derefs)
}
if v > math.MaxUint8 {
v = math.MaxUint8
}
l[i] = uint8(v)
}
/ Optimize removes result flow paths that are equal in length or
/ longer than the shortest heap flow path.
func (l *leaks) Optimize() {
/ If we have a path to the heap, then there's no use in
/ keeping equal or longer paths elsewhere.
if x := l.Heap(); x >= 0 {
for i := 0; i < numEscResults; i++ {
if l.Result(i) >= x {
l.setResult(i, -1)
}
}
}
}
var leakTagCache = map[leaks]string{}
/ Encode converts l into a binary string for export data.
func (l leaks) Encode() string {
if l.Heap() == 0 {
/ Space optimization: empty string encodes more
/ efficiently in export data.
return ""
}
if s, ok := leakTagCache[l]; ok {
return s
}
n := len(l)
for n > 0 && l[n-1] == 0 {
n--
}
s := "esc:" + string(l[:n])
leakTagCache[l] = s
return s
}
/ parseLeaks parses a binary string representing a leaks
func parseLeaks(s string) leaks {
var l leaks
if !strings.HasPrefix(s, "esc:") {
l.AddHeap(0)
return l
}
copy(l[:], s[4:])
return l
}