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

all: binaries too big and growing #6853

Open
robpike opened this issue Nov 30, 2013 · 111 comments
Open

all: binaries too big and growing #6853

robpike opened this issue Nov 30, 2013 · 111 comments

Comments

@robpike
Copy link
Contributor

@robpike robpike commented Nov 30, 2013

As an experiment, I build "hello, world" at the release points for go 1.0.
1.1, and 1.2. Here are the binary's sizes:

% ls -l x.1.?
-rwxr-xr-x  1 r  staff  1191952 Nov 30 10:25 x.1.0
-rwxr-xr-x  1 r  staff  1525936 Nov 30 10:20 x.1.1
-rwxr-xr-x  1 r  staff  2188576 Nov 30 10:18 x.1.2
% size x.1.?
__TEXT  __DATA  __OBJC  others  dec hex
880640  33682096    0   4112    34566848    20f72c0 x.1.0
1064960 94656   0   75952   1235568 12da70  x.1.1
1429504 147896  0   177440  1754840 1ac6d8  x.1.2
% 

A near-doubling of the binary size in two releases is a bug of a kind. I will hold on to
the files so they can be analyzed more, but am filing this issue to get the topic
registered. We need to develop a better understanding of the problem and how to address
it.

Marking this 1.3 (not maybe) because I consider it a priority.


A few months ago I exchanged mail with Russ about this topic regarding a different, much
larger binary. To avoid him having to redo the analysis, here is what he said at the
time:

====
i sent CL 13722046 to make the nm -S output a bit more useful.
for the toy binary i now get

  4a2280  1898528 D symtab
  26f3a0  1405936 D type.*
  671aa0  1058432 D pclntab
  3c6790   598056 D go.string.*
  4620c0    49600 D gcbss
  7a7c20    45496 B runtime.mheap
  46e280    21936 D gcdata
  7a29e0    21056 b bufferList
  1ed600    16480 T crypto/tls.(*Conn).clientHandshake
  79eb20    16064 b semtable
  1b3d90    14224 T net/http.init

that seems plausible to me. some notes:

symtab is the plan 9 symbol table. it in the binary but never referenced at run time. it
supports things like nm -S only. it needs to move into an unmapped section of the
binary, but it is only costing at most 8k at run time right now due to fragmentation and
it just wasn't worth the effort to try to move. the new linker will make this easier. of
course, moving it in the file doesn't shrink the file.

the thing named pclntab is a reencoding of the original pclntab and the parts of the
plan 9 symbol table that we did need at run time (mostly just a list of functions and
their names and addresses). as you can see, it is much smaller than the old form (the
symbol table dominates).

type.* is the reflect types and go.string.* is the static go string data. the *
indicates that i coalesced many symbols into one, to avoid useless individual names
bloating the symbol table. if we tried we could probably cut the reflect types by 2-4x.
it would mean packing the data a bit more compactly than an ordinary go data structure
would and then using unsafe to get it back out.

gcbss and gcdata are garbage collection bits for the bss and data segments. that's what
atom symbol did, and it's not clear whether it will last (probably not) and whether what
will replace it will be smaller. time will tell. i have a meeting with dmitriy, carl,
and keith next week to figure out what the plan is.

runtime.mheap, bufferList, and semtable are bss.

you're not seeing the gdb dwarf debug information here, because it's not a runtime
symbol.
 
g% otool -l $(which toy) | egrep '^  segname|filesize'
  segname __PAGEZERO
 filesize 0
  segname __TEXT
 filesize 7811072
  segname __DATA
 filesize 126560
  segname __LINKEDIT
 filesize 921772
  segname __DWARF
 filesize 2886943
g% 

there's another 3 MB. you can build with -ldflags -w to get rid of that at least.
if you read the full otool -l output you will find

Load command 6
     cmd LC_SYMTAB
 cmdsize 24
  symoff 10825728
   nsyms 22559
  stroff 11186924
 strsize 560576

looks like another 1 MB or so (560576+11186924-10825728 or 22559*16+560576) for the
mach-o symbol table.

when we do the new linker we can make recording this kind of information in a useful
form a priority.
@robpike
Copy link
Contributor Author

@robpike robpike commented Nov 30, 2013

Comment 1:

Note: the binaries were build on amd64 10.7.5 (Lion), with  gcc -version
i686-apple-darwin11-llvm-gcc-4.2
For the record, I couldn't do this experiment on 10.9 with Xcode 5 because the older
releases wouldn't build due to gcc/clang skew.
@robpike
Copy link
Contributor Author

@robpike robpike commented Nov 30, 2013

Comment 2:

Labels changed: added priority-later, removed priority-triage.

@gopherbot
Copy link

@gopherbot gopherbot commented Dec 2, 2013

Comment 3 by jlourenco27:

Just for added reference, this are the size on go 1.1.2 vs 1.2 with OS X 10.9 and Xcode
5 (darwin gcc llvm 5.0 x86_64):
$ ls -l *1.*
-rwxr-xr-x  1 j      staff  1525984  2 Dez 21:44 hello_1.1.2
-rwxr-xr-x  1 j      staff  2192672  2 Dez 21:40 hello_1.2
$ size *1.*
__TEXT  __DATA  __OBJC  others  dec hex
1064960 94720   0   76000   1235680 12dae0  hello_1.1.2
1433600 147896  0   177440  1758936 1ad6d8  hello_1.2
@randall77
Copy link
Contributor

@randall77 randall77 commented Dec 3, 2013

Comment 4:

This issue was updated by revision f238049.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/35940047
@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 5:

Labels changed: added release-go1.3.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 6:

Labels changed: removed go1.3.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 7:

Labels changed: added repo-main.

@zephyr
Copy link

@zephyr zephyr commented Dec 7, 2013

Comment 8:

In this context, please reevaluate if the golang binaries can be changed to work with
UPX (ultimate packer for executables).¹²
For a small amount of computing power, upx can reduce the size of a binary down to a
quarter of its original size. You can authenticate this using a existing example
›fixer‹ programm for golang binaries on linux/amd64.³
While this approach doesn't fix the root of the problem – only the symptoms – it
would be nice to have this possibility always on hand.
For technical background of this problem (PT_LOAD[0].p_offset==0), please look at the
UPX bugtracker⁴.
¹ http://upx.sourceforge.net/
² https://en.wikipedia.org/wiki/UPX
³ https://github.com/pwaller/goupxhttp://sourceforge.net/p/upx/bugs/195/
@minux
Copy link
Member

@minux minux commented Dec 7, 2013

Comment 9:

re #8, I don't think it's Go's problem. upx should be made more flexible to handle this.
@leo-liu
Copy link

@leo-liu leo-liu commented Dec 8, 2013

Comment 10:

minux:
We may figure out why the binaries are growing fast first (lager runtime, optimization,
etc.), before we claim that it isn't Go's problem.
@minux
Copy link
Member

@minux minux commented Dec 8, 2013

Comment 11:

re #10, my #9 reply is to #8, which is about an entirely different problem.
i'm not saying that the ever-growing binaries is not our problem, only that i
don't believe that upx not accepting our binaries is our problem.
it's clear that upx isn't able to handle all possible and correct ELF files (i.e.
if the kernel can execute our binaries just fine, it's upx's problem to not be
able to compress them).
@robpike
Copy link
Contributor Author

@robpike robpike commented Feb 19, 2014

Comment 12:

More detail. The Plan 9 symbol table is about to be deleted. Here is a reference point,
adding one new entry to the list above:
$ ls -l *1.*
-rwxr-xr-x  1 j      staff  1525984  2 Dez 21:44 hello_1.1.2
-rwxr-xr-x  1 j      staff  2192672  2 Dez 21:40 hello_1.2
-rwxr-xr-x  1 j      staff  2474512 Feb 18 20:27 hello_1.2.x
$ size *1.*
__TEXT  __DATA  __OBJC  others  dec hex
1064960 94720   0   76000   1235680 12dae0  hello_1.1.2
1433600 147896  0   177440  1758936 1ad6d8  hello_1.2
1699840 160984  0   188944  2049768 1f46e8     hello_1.2.x
Text has grown substantially, as has data. At least some of this is due to new
annotations for the garbage collector.
@robpike
Copy link
Contributor Author

@robpike robpike commented Feb 19, 2014

Comment 13:

More detail. The Plan 9 symbol table is about to be deleted. Here is a reference point,
adding one new entry to the list above:
$ ls -l *1.*
-rwxr-xr-x  1 r  staff  1191952 Nov 30 10:25 x.1.0
-rwxr-xr-x  1 r  staff  1525936 Nov 30 10:20 x.1.1
-rwxr-xr-x  1 r  staff  2188576 Nov 30 10:18 x.1.2
-rwxr-xr-x  1 r  staff  2474512 Feb 18 20:27 hello_1.2.x
$ size *1.*
__TEXT  __DATA  __OBJC  others  dec hex
880640  33682096     0  4112    34566848     20f72c0    x.1.0
1064960 94656   0   75952   1235568 12da70  x.1.1
1429504 147896  0   177440  1754840 1ac6d8  x.1.2
1699840 160984  0   188944  2049768 1f46e8     hello_1.2.x
Text has grown substantially, as has data. At least some of this is due to new
annotations for the garbage collector.
@robpike
Copy link
Contributor Author

@robpike robpike commented Feb 19, 2014

Comment 14:

More detail. The Plan 9 symbol table is about to be deleted. Here is a reference point,
adding one new entry to the list above:
$ ls -l *1.*
-rwxr-xr-x  1 r  staff  1191952 Nov 30 10:25 x.1.0
-rwxr-xr-x  1 r  staff  1525936 Nov 30 10:20 x.1.1
-rwxr-xr-x  1 r  staff  2188576 Nov 30 10:18 x.1.2
-rwxr-xr-x  1 r  staff  2474512 Feb 18 20:27 hello_1.2.x
$ size *1.*
__TEXT  __DATA  __OBJC  others  dec hex
880640  33682096     0  4112    34566848     20f72c0    x.1.0
1064960 94656   0   75952   1235568 12da70  x.1.1
1429504 147896  0   177440  1754840 1ac6d8  x.1.2
1699840 160984  0   188944  2049768 1f46e8     x.1.2.x
Text has grown substantially, as has data. At least some of this is due to new
annotations for the garbage collector.
@rsc
Copy link
Contributor

@rsc rsc commented Feb 19, 2014

Comment 15:

This issue was updated by revision 964f6d3.

Nothing reads the Plan 9 symbol table anymore.
The last holdout was 'go tool nm', but since being rewritten in Go
it uses the standard symbol table for the binary format
(ELF, Mach-O, PE) instead.
Removing the Plan 9 symbol table saves ~15% disk space
on most binaries.
Two supporting changes included in this CL:
debug/gosym: use Go 1.2 pclntab to synthesize func-only
symbol table when there is no Plan 9 symbol table
debug/elf, debug/macho, debug/pe: ignore final EOF from ReadAt
LGTM=r
R=r, bradfitz
CC=golang-codereviews
https://golang.org/cl/65740045
@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Feb 19, 2014

Comment 16:

After revision 737767dd81fd, I see a 25% reduction:
Before:
-rwxr-xr-x  1 bradfitz  staff  23556028 Feb 18 20:47 bin/camlistored
After:
-rwxr-xr-x  1 bradfitz  staff  17727420 Feb 18 20:48 bin/camlistored
@robpike
Copy link
Contributor Author

@robpike robpike commented Feb 19, 2014

Comment 17:

For my test case before/after deleting the Plan 9 symbol table:
% ls -l ...
-rwxr-xr-x  1 r  staff  2474512 Feb 18 20:27 hello_1.2.x
-rwxr-xr-x  1 r  staff  2150928 Feb 18 22:28 hello_1.2.y
% size ...
__TEXT  __DATA  __OBJC  others  dec hex
1699840 160984  0   188944  2049768 1f46e8     hello_1.2.x
1376256 160984  0   188944  1726184 1a56e8    hello_1.2.x
% 
So deleting the Plan 9 symbol table pretty close to exactly compensates for the GC
information. We're back at Go 1.2 levels, still far too large but it's a start.
@rsc
Copy link
Contributor

@rsc rsc commented Feb 19, 2014

Comment 18:

This issue was updated by revision 2541cc8.

Every function now has a gcargs and gclocals symbol
holding associated garbage collection information.
Put them all in the same meta-symbol as the go.func data
and then drop individual entries from symbol table.
Removing gcargs and gclocals reduces the size of a
typical binary by 10%.
LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/65870044
@rsc
Copy link
Contributor

@rsc rsc commented Feb 19, 2014

Comment 19:

This issue was updated by revision ae38b03.

For an ephemeral binary - one created, run, and then deleted -
there is no need to write dwarf debug information, since the
binary will not be used with gdb. In this case, instruct the linker
not to spend time and disk space generating the debug information
by passing the -w flag to the linker.
Omitting dwarf information reduces the size of most binaries by 25%.
We may be more aggressive about this in the future.
LGTM=bradfitz, r
R=r, bradfitz
CC=golang-codereviews
https://golang.org/cl/65890043
@robpike
Copy link
Contributor Author

@robpike robpike commented Feb 19, 2014

Comment 20:

After removing gcargs from the symbol table (stepping across CL 65870044)
% ls -l x.1.2.[yz]
-rwxr-xr-x  1 r  staff  2150928 Feb 18 22:28 hello_1.2.y
-rwxr-xr-x  1 r  staff  1932880 Feb 19 08:14 hello_1.2.z
% size x.1.2.[yz] 
__TEXT  __DATA  __OBJC  others  dec hex
1376256 160984  0   188944  1726184 1a56e8    hello_1.2.y
1376256 160984  0   110160  1647400 192328 hello_1.2.z
% 
It's now smaller than at 1.2 but still much bigger than 1.1, let alone 1.0.
@gopherbot
Copy link

@gopherbot gopherbot commented Mar 4, 2014

Comment 21:

I would like to take a look at compressing pclntab. Is it compressible?
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Mar 4, 2014

Comment 22:

The pclntab data should be reasonably compact, and note that fast access to the data is
important, since it is used for runtime.Callers and friends.  If you can find a
significant reduction in size that would be great, but small tweaks are probably not
desirable at this point.
@gopherbot
Copy link

@gopherbot gopherbot commented Mar 4, 2014

Comment 23 by fuzxxl:

Is there any documentation for what the pclntab contains and for what constraints its
data structure must fullfill?
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Mar 4, 2014

Comment 24:

Let's not use this issue as a discussion list.  Please ask questions on golang-dev. 
Thanks.
@gopherbot
Copy link

@gopherbot gopherbot commented Mar 6, 2014

Comment 25 by allard.guy.m:

From the peanut gallery, AFAICT this breaks pprof interactive command 'list'.  At tip I
get, e.g.:
(pprof) list runner
Total: 6424 samples
objdump: syminit: Success
no filename found in main.runner<400c40>
Which works as expected with 1.2.1.
@rsc
Copy link
Contributor

@rsc rsc commented Apr 3, 2014

Comment 26:

Let's not use this issue as a discussion list.  Please ask questions on golang-dev. 
Thanks.
pprof not working is issue #7452.

Labels changed: added restrict-addissuecomment-commit.

@rsc
Copy link
Contributor

@rsc rsc commented Apr 3, 2014

Comment 27:

This is as fixed as it is going to be for Go 1.3.
Right now at tip + CL 80370045 on darwin/amd64, compiling this program:
package main
import "fmt"
func main() {
    fmt.Println("hello, world")
}
I get 1830352 bytes for the binary. Assuming this is the same case for which Rob's
numbers are reported, by this metric Go 1.3 will roll back more than half the size
increase caused by Go 1.2 (relative to Go 1.1). Will leave further improvement for Go
1.4.

Labels changed: added release-go1.4, removed release-go1.3.

@rsc
Copy link
Contributor

@rsc rsc commented Apr 3, 2014

Comment 28:

This issue was updated by revision a26c01a.

LGTM=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/80370045
@rsc
Copy link
Contributor

@rsc rsc commented Sep 15, 2014

Comment 29:

Labels changed: added release-go1.5, removed release-go1.4.

@robpike robpike added the accepted label Sep 15, 2014
@gopherbot
Copy link

@gopherbot gopherbot commented Nov 4, 2019

Change https://golang.org/cl/205139 mentions this issue: net/http: support disabling built-in HTTP/2 with a new build tag

gopherbot pushed a commit that referenced this issue Nov 4, 2019
Fixes #35082
Updates #6853

Change-Id: I4eeb0e15f534cff57fefb6039cd33fadf15b946e
Reviewed-on: https://go-review.googlesource.com/c/go/+/205139
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
@tklauser tklauser mentioned this issue Feb 7, 2020
9 of 10 tasks complete
@lynncyrin lynncyrin mentioned this issue Feb 29, 2020
1 of 5 tasks complete
@gopherbot
Copy link

@gopherbot gopherbot commented May 1, 2020

Change https://golang.org/cl/231397 mentions this issue: cmd/link: don't mark a symbol's Gotype reachable

@bradfitz bradfitz added the binary-size label May 1, 2020
@mvdan
Copy link
Member

@mvdan mvdan commented May 1, 2020

For those of you following this issue, we now have a binary-size label to collect all related issues. You can see the list here: https://github.com/golang/go/labels/binary-size

gopherbot pushed a commit that referenced this issue May 1, 2020
A symbol being reachable doesn't imply its type descriptor is
needed. Don't mark it.

If the type is converted to interface somewhere in the program,
there will be an explicit use of the type descriptor, which
will make it marked.

A println("hello") program before and after

-rwxr-xr-x  1 cherryyz  primarygroup  1259824 Apr 30 23:00 hello
-rwxr-xr-x  1 cherryyz  primarygroup  1169680 Apr 30 23:10 hello

Updates #38782.
Updates #6853.

Change-Id: I88884c126ce75ba073f1ba059c4b892c87d2ac96
Reviewed-on: https://go-review.googlesource.com/c/go/+/231397
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented May 1, 2020

Some good news: https://twitter.com/bradfitz/status/1256348714198654976

dev:~ $ cat go-many.go
package main

import (
  "archive/zip"
  "encoding/json"
  "go/format"
  "net/http"
  "text/template"
)

func main() {
  _ = http.ListenAndServe
  _ = http.ListenAndServeTLS
  _ = http.Get
  _ = json.NewDecoder
  _ = json.NewEncoder
  _ = zip.NewReader
  _ = zip.NewWriter
  _ = format.Source
  _ = template.HTMLEscape
}

dev:~ $ go version
go version devel +cb00d93431 Fri May 1 20:39:53 2020 +0000 linux/amd64

dev:~ $ go1.14.2 build -o go-many.go1.14 go-many.go
dev:~ $ go build -o go-many.go1.15 go-many.go

dev:~ $ ls -l go-many*
-rw-r--r-- 1 bradfitz bradfitz     307 May  1 15:19 go-many.go
-rwxr-xr-x 1 bradfitz bradfitz 8510732 May  1 15:21 go-many.go1.14
-rwxr-xr-x 1 bradfitz bradfitz 4055570 May  1 15:21 go-many.go1.15
xujianhai666 added a commit to xujianhai666/go-1 that referenced this issue May 21, 2020
A symbol being reachable doesn't imply its type descriptor is
needed. Don't mark it.

If the type is converted to interface somewhere in the program,
there will be an explicit use of the type descriptor, which
will make it marked.

A println("hello") program before and after

-rwxr-xr-x  1 cherryyz  primarygroup  1259824 Apr 30 23:00 hello
-rwxr-xr-x  1 cherryyz  primarygroup  1169680 Apr 30 23:10 hello

Updates golang#38782.
Updates golang#6853.

Change-Id: I88884c126ce75ba073f1ba059c4b892c87d2ac96
Reviewed-on: https://go-review.googlesource.com/c/go/+/231397
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
Introduce and start using nameOff for two encoded names. This pair
of changes is best done together because the linker's method decoder
expects the method layouts to match.

Precursor to converting all existing name and *string fields to
nameOff.

linux/amd64:
	cmd/go:  -45KB (0.5%)
	jujud:  -389KB (0.6%)

linux/amd64 PIE:
	cmd/go: -170KB (1.4%)
	jujud:  -1.5MB (1.8%)

For golang#6853.

Change-Id: Ia044423f010fb987ce070b94c46a16fc78666ff6
Reviewed-on: https://go-review.googlesource.com/21396
Reviewed-by: Ian Lance Taylor <iant@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
Use (part of) a SHA-1 checksum to replace type symbol names.

In typical programs this has no effect because types are not included
in the symbol table. But when dynamically linking, types are in the
table to make sure there is only one *rtype per Go type.

Eventually we may be able to get rid of all pointers to rtype values in
the binary, but probably not by 1.7. And this has a nice effect on
binary size today:

libstd.so:
	before 27.4MB
	after  26.2MB

For golang#6853.

Change-Id: I603d7f3e5baad84f59f2fd37eeb1e4ae5acfe44a
Reviewed-on: https://go-review.googlesource.com/21583
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
Now that reflect.name objects contain an offset to pkgPath instead of a
pointer, there is no need to align the symbol data.

Removes approx. 10KB from the cmd/go binary. The effect becomes more
important later as more type data is moved into name objects.

For golang#6853

Change-Id: Idb507fdbdad04f16fc224378f82272cb5c236ab7
Reviewed-on: https://go-review.googlesource.com/21776
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
linux/amd64:
	cmd/go:   -8KB (basically nothing)

linux/amd64 PIE:
	cmd/go: -191KB (1.6%)
	jujud:  -1.5MB (1.9%)

Updates golang#6853
Fixes golang#15064

Change-Id: I0adbb95685e28be92e8548741df0e11daa0a9b5f
Reviewed-on: https://go-review.googlesource.com/21777
Reviewed-by: Ian Lance Taylor <iant@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
linux/amd64 PIE:
	cmd/go:  -62KB (0.5%)
	jujud:  -550KB (0.7%)

For golang#6853.

Change-Id: Ieb67982abce5832e24b997506f0ae7108f747108
Reviewed-on: https://go-review.googlesource.com/22371
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
  func f(x, y, z *int) {
    a := []*int{x,y,z}
    ...
  }

We used to use:
  var tmp [3]*int
  a := tmp[:]
  a[0] = x
  a[1] = y
  a[2] = z

Now we do:
  var tmp [3]*int
  tmp[0] = x
  tmp[1] = y
  tmp[2] = z
  a := tmp[:]

Doesn't sound like a big deal, but the compiler has trouble
eliminating write barriers when using the former method because it
doesn't know that the slice points to the stack.  In the latter
method, the compiler knows the array is on the stack and as a result
doesn't emit any write barriers.

This turns out to be extremely common when building ... args, like
for calls fmt.Printf.

Makes go binaries ~1% smaller.

Doesn't have a measurable effect on the go1 fmt benchmarks,
unfortunately.

Fixes golang#14263
Update golang#6853

Change-Id: I9074a2788ec9e561a75f3b71c119b69f304d6ba2
Reviewed-on: https://go-review.googlesource.com/22395
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
Note that this is only safe because
the compiler generates multiple distinct
gc.Types. If we switch to having canonical
gc.Types, then this will need to be updated
to handle the case in which the user uses both
map[[n]T]S and also calls a function f(...T) with n arguments.
In that case, the runtime needs algs for [n]T, but this could
mark the sole [n]T type as Noalg. This is a general
problem with having a single bool to represent
whether alg generation is needed for a type.

Cuts 17k off cmd/go and 13k off golang.org/x/tools/cmd/godoc,
approx 0.14% and 0.07% respectively.

For golang#6853 and golang#9930

Change-Id: Iccb6b9fd88ade5497d7090528a903816d340bf0a
Reviewed-on: https://go-review.googlesource.com/19770
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
salewski pushed a commit to salewski/go that referenced this issue Aug 6, 2020
Note that this is only safe because
the compiler generates multiple distinct
gc.Types. If we switch to having canonical
gc.Types, then this will need to be updated
to handle the case in which the user uses both
map[T]S and also map[[8]T]S. In that case,
the runtime needs algs for [8]T, but this could
mark the sole [8]T type as Noalg. This is a general
problem with having a single bool to represent
whether alg generation is needed for a type.

Cuts 5k off cmd/go and 22k off golang.org/x/tools/cmd/godoc,
approx 0.04% and 0.12% respectively.

For golang#6853 and golang#9930

Change-Id: I30a15ec72ecb62e2aa053260a7f0f75015fc0ade
Reviewed-on: https://go-review.googlesource.com/19769
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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
You can’t perform that action at this time.