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: anonymous structs consume space in binary #38291

Open
egonelbre opened this issue Apr 7, 2020 · 8 comments
Open

cmd/compile: anonymous structs consume space in binary #38291

egonelbre opened this issue Apr 7, 2020 · 8 comments

Comments

@egonelbre
Copy link
Contributor

@egonelbre egonelbre commented Apr 7, 2020

Anonymous structs can take quite a significant amount of space in the compiled binary. Since anonymous structs do not have a proper name hence the full anonymous struct description used as the name.

As a quick experiment, by replacing some anonymous structs in Go compiler with a named type the compiler shrunk 14KB and the gofmt shrunk by 10KB.

As an extreme example: by changing:

var work struct {
to a named type, the compiler binary shrunk ~5KB.

diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 7a8ab5314f..94693e5e87 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -945 +945,4 @@ const gcOverAssistWork = 64 << 10
-var work struct {
+var work _work
+
+//go:notinheap
+type _work struct {

Related issues #6853, #36313

Go Version

$ go version
go version devel +74d6de03fd Mon Apr 6 18:06:41 2020 +0000 windows/amd64
@andybons
Copy link
Member

@andybons andybons commented Apr 7, 2020

@andybons andybons added this to the Go1.15 milestone Apr 7, 2020
@mvdan
Copy link
Member

@mvdan mvdan commented Apr 12, 2020

This could maybe help with smaller binaries.

/cc @josharian @randall77

@martisch
Copy link
Contributor

@martisch martisch commented May 1, 2020

Instead of adding all the fields as part of the name could we take the variables package path and variables name and add a prefix or suffix that can only be generated by the compiler?

@mvdan
Copy link
Member

@mvdan mvdan commented May 1, 2020

This is probably interesting to @bradfitz too, particularly the runtime example saving 5KiB.

@bradfitz bradfitz added the binary-size label May 1, 2020
@egonelbre
Copy link
Contributor Author

@egonelbre egonelbre commented May 1, 2020

@martisch just to clarify, I wasn't proposing fixing all these manually :D. It's something that compiler/linker could do. And yeah, my thoughts were along the same line, A) use variable name for instead of the string description or B) generate dynamically the name when needed and use some hash in the binary.

@aclements
Copy link
Member

@aclements aclements commented May 1, 2020

It turns out we just significantly improved this! Commit 44d2286 drops type descriptors that aren't used, which means these long symbols names and many other things no longer appear in the binary. This shrinks cmd/compile by 140 KiB.

There's still more that could be done. If you put a large anonymous type in an interface, the linker will still pull in the type descriptor and all of these large symbol names. On our list of things to explore in the linker (not for 1.15) is to use structural hashes to name and dedup type symbols. The downside, of course, is that the type symbol names in the binary become much less informative.

@aclements
Copy link
Member

@aclements aclements commented May 1, 2020

Moving to unplanned since we fixed a lot of this problem for 1.15, and exploring further improvements is on the list for the linker, but involves trade-offs that need to be explored.

@aclements aclements modified the milestones: Go1.15, Unplanned May 1, 2020
@egonelbre
Copy link
Contributor Author

@egonelbre egonelbre commented May 1, 2020

I can confirm that on tip the _work example reduces compiler size by ~500 bytes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.