What is considered “small” object in Go regarding stack allocation?

左心房为你撑大大i 提交于 2019-12-04 19:31:19

Since this is not mentioned in the language spec, it is an implementation detail, and as such, it may vary based on a number of things (Go version, target OS, architecture etc.).

If you want to find out its current value or a place to start digging, check out the cmd/compile/internal/gc package.

The escape analysis which decides where to allocate the variable is in cmd/compile/internal/gc/esc.go. Check of the make slice operation is in unexported function esc():

func esc(e *EscState, n *Node, up *Node) {
    // ...

    // Big stuff escapes unconditionally
    // "Big" conditions that were scattered around in walk have been gathered here
    if n.Esc != EscHeap && n.Type != nil &&
        (n.Type.Width > MaxStackVarSize ||
            (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= 1<<16 ||
            n.Op == OMAKESLICE && !isSmallMakeSlice(n)) {
        if Debug['m'] > 2 {
            Warnl(n.Lineno, "%v is too large for stack", n)
        }
        n.Esc = EscHeap
        addrescapes(n)
        escassignSinkNilWhy(e, n, n, "too large for stack") // TODO category: tooLarge
    }

    // ...
}

The decision involving the size is in function isSmallMakeSlice(), this is in file cmd/compile/internal/gc/walk.go:

func isSmallMakeSlice(n *Node) bool {
    if n.Op != OMAKESLICE {
        return false
    }
    l := n.Left
    r := n.Right
    if r == nil {
        r = l
    }
    t := n.Type

    return Smallintconst(l) && Smallintconst(r) && (t.Elem().Width == 0 || r.Int64() < (1<<16)/t.Elem().Width)
}

The size limit is this:

r.Int64() < (1<<16)/t.Elem().Width

r is the length or capacity of the slice (if cap is provided), t.Elem().Width is the byte size of the element type:

NumElem < 65536 / SizeElem

In your case:

NumElem < 65536 / 8 = 8192

So if the slice type is []uint64, 8192 is the limit from which it is allocated on the heap (instead of the stack), just as you experienced.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!