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
Labels
binary-size compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@egonelbre
Copy link
Contributor

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 commented Apr 7, 2020

@aclements

@andybons andybons added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 7, 2020
@andybons andybons added this to the Go1.15 milestone Apr 7, 2020
@mvdan
Copy link
Member

mvdan commented Apr 12, 2020

This could maybe help with smaller binaries.

/cc @josharian @randall77

@martisch
Copy link
Contributor

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 commented May 1, 2020

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

@egonelbre
Copy link
Contributor Author

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

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

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

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

@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
binary-size compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

7 participants