Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: large slice literals allocated in stack, causing very big frame #47197

Open
go101 opened this issue Jul 14, 2021 · 4 comments
Open
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@go101
Copy link

go101 commented Jul 14, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.6 linux/amd64
go version go1.17rc1 linux/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

Moved from #27447 (comment)

package main

const N = 100 * 1024 * 1024

var m = make(map[byte][N]byte, 1)
func foo() {
	// [N]byte{} is unnecessarily allocated on stack, then copied to heap.
	m[0] = [N]byte{}
}

var i interface{}
func bar() {
	// [N]byte{} is unnecessarily allocated on stack, then copied to heap.
	i = [N]byte{}
}

// parameter a is allocated on stack, argument is copied to it.
func pen(a [N]byte) { // 
	type _ int // avoid being inlined
}

// argument is unnecessarily allocated on stack, then copied to heap.
func cup(v ...interface{}) {
	type _ int // avoid being inlined
}

func qin(m map[byte][N]byte) {
	type _ int // avoid being inlined
	// [N]byte{} is unnecessarily allocated on stack, then copied to heap.
	m[1] = [N]byte{}
}

func main() {
	run := func(f func(), c chan struct{}) {
		defer close(c)
		var x int
		println(&x) // <address 1>
		f()
		println(&x) // <address 2>
	}
	{
		c := make(chan struct{})
		go run(foo, c)
		<-c
	}
	{
		c := make(chan struct{})
		go run(bar, c)
		<-c
	}
	{
		c := make(chan struct{})
		go run(func() {cup([N]byte{})}, c)
		<-c
	}
	{
		c := make(chan struct{})
		go run(func() {pen([N]byte{})}, c)
		<-c
	}
	{
		c := make(chan struct{})
		go run(func() {qin(map[byte][N]byte{})}, c)
		<-c
	}
}
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} // elements are allocated on stack
	b = bs[n]
}

func main() {
	x := t.AllocsPerRun(2, f)
	println(int(x)) // 0
}

What did you expect to see?

It is better to allocate them on heap.

What did you see instead?

They are allocated on stack.

@go101 go101 changed the title cmd/compile: corner cases in which big-size values are allocated in stack cmd/compile: corner cases in which arbitrary-size values are allocated in stack Jul 14, 2021
@cherrymui cherrymui changed the title cmd/compile: corner cases in which arbitrary-size values are allocated in stack cmd/compile: large slice literals allocated in stack, causing very big frame Jul 14, 2021
@cherrymui cherrymui added the NeedsFix The path to resolution is known, but the work has not been done. label Jul 14, 2021
@cherrymui cherrymui added this to the Unplanned milestone Jul 14, 2021
@cherrymui
Copy link
Member

Thanks for reporting.

It is better to allocate them on heap.

It would be helpful to be clearer what "them" are, which value(s) in which function(s). Thanks.

@go101
Copy link
Author

go101 commented Jul 14, 2021

Added some comments, which are just my understanding so might be not correct.

@go101
Copy link
Author

go101 commented Jul 14, 2021

BTW, the pen case is literal uninvolved.

package main

const N = 100 * 1024 * 1024
var a [N]byte

// parameter a is allocated on stack, argument is copied to it.
func pen(a [N]byte) { // 
	type _ int // avoid being inlined
}

func main() {
	run := func(f func(), c chan struct{}) {
		defer close(c)
		var x int
		println(&x) // <address 1>
		f()
		println(&x) // <address 2>
	}
	{
		c := make(chan struct{})
		go run(func() {pen(a)}, c)
		<-c
	}
}

@fzipp
Copy link
Contributor

fzipp commented Jul 14, 2021

[N]byte is an array, not a slice.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants