package main
import t "testing"
const M = 1024 * 1024 * 100
var n int = M - 1
var b byte
func f() {
type _ int
var bs = []byte{M+M: 0}
b = bs[n]
}
func main() {
x := t.AllocsPerRun(2, f)
println(int(x)) // 0
}
{edit] 一些数组字面量的特殊情况:
package main
const N = 100 * 1024 * 1024
var m = make(map[byte][N]byte, 1)
func foo() {
m[0] = [N]byte{} // copy stack to heap
}
var i interface{}
func bar() {
i = [N]byte{} // copy stack to heap
}
func pen(vx ...interface{}) {
type _ int
}
func qin(m map[byte][N]byte) {
m[1] = [N]byte{} // copy stack to heap
}
func main() {
run := func(f func(), c chan struct{}) {
defer close(c)
var x int
println(&x) // <address 1>
f()
println(&x) // <address 2>
}
c1 := make(chan struct{})
go run(foo, c1)
<-c1
c2 := make(chan struct{})
go run(bar, c2)
<-c2
c3 := make(chan struct{})
go run(func() {qin(map[byte][N]byte{})}, c3)
<-c3
c4 := make(chan struct{})
go run(func() {pen([N]byte{})}, c4)
<-c4
}
5条答案
按热度按时间kdfy810k1#
这是一个错误:
gmol16392#
在walk.go文件中(func是smallMakeSlice,case是ONEW),cutoff (
1<<16
)也在几个地方重复出现。应该统一它们。ttvkxqim3#
我们如何让autotemps堆分配这个case?顺序发生在逃逸分析完成后。
b09cbbtk4#
这可能是个棘手的问题。乍一看,没有立即出现问题——顺序可能会引入对新对象的调用。如果对象是无指针的,那么它可以正常工作。但是如果对象有指针,那么之前不会逃逸的东西现在会逃逸。我认为正确的解决方案(尽管困难)是将这些堆分配的对象以某种方式视为栈(没有写屏障,作为栈扫描的一部分进行扫描等)。
一个好的第一步是仅解决无指针对象的问题。
bnl4lu3b5#
看起来这也适用于切片字面量。
{edit] 一些数组字面量的特殊情况: