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 return value can take very long time to compile #14032

Closed
dominikh opened this issue Jan 20, 2016 · 8 comments
Closed

cmd/compile: large return value can take very long time to compile #14032

dominikh opened this issue Jan 20, 2016 · 8 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. ToolSpeed
Milestone

Comments

@dominikh
Copy link
Member

The following piece of code takes several minutes to compile (I gave up after a while):

package main

func fn() (arr [1e10]bool) {
    println(len(arr))
    return
}

func main() {
    fn()
}

Possibly but not necessarily related to #14028.

@minux
Copy link
Member

minux commented Jan 20, 2016 via email

@dominikh
Copy link
Member Author

You can reduce it to 1e9 bytes, which will compile in ~30 seconds and run just fine. However, it only runs fine if using println(len(arr)) – Using fmt.Println(len(arr)) will fail with

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

I agree that this issue doesn't matter by itself. Nobody will/should write code like that. But I do think it is uncovering real issues that may matter in other situations. Why does it take so long to compile (is that expected or not)? Should the println version even work? If everything is WAI, by all means, close the issue. I was hoping it could point at real bugs.

@bradfitz
Copy link
Contributor

Taking long to compile is a bug.

@minux
Copy link
Member

minux commented Jan 20, 2016 via email

@ianlancetaylor
Copy link
Contributor

I suggest that we change the ABI so that objects above a certain size are returned by invisible reference. The function will allocate them on the heap and return a pointer. The caller will use the pointer instead of storing the value on the stack, as it already does for large local variables (see MaxStackVarSize in cmd/compile/internal/gc).

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone Jan 20, 2016
@rsc rsc modified the milestones: Go1.8, Go1.7 May 17, 2016
@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 11, 2016
@rsc
Copy link
Contributor

rsc commented Oct 21, 2016

I'm going back and forth between milestone Go1.9 and milestone Unplanned. I feel like the compiler used to reject this kind of thing out of hand as the stack frame being too large. That seems fine to me. Not sure we should bother to make it "work".

@rsc rsc modified the milestones: Go1.9, Go1.8 Oct 21, 2016
@dominikh
Copy link
Member Author

As a data point from my end: The code isn't from an actual use case, but rather came to exist while trying to reproduce the issue in the linked bug. I don't see a practical reason for going out of your way to make it work and failing cleanly seems fine. My only concern would be how it relates to the spec and whether it'd be a compiler limitation or not?

@josharian
Copy link
Contributor

With tip (638ebb0), this now compiles and executes in a moderate amount of time:

$ time go run x.go
10000000000

real	0m3.598s
user	0m2.975s
sys	0m0.667s

Seems good enough to me; closing.

@golang golang locked and limited conversation to collaborators May 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. ToolSpeed
Projects
None yet
Development

No branches or pull requests

8 participants