Today the linker keeps all methods of reachable types. This is
necessary if a program uses reflect.Value.Call. But while use of
reflection is widespread in Go for encoders and decoders, using
it to call a method is rare.
This CL looks for the use of reflect.Value.Call in a program, and
if it is absent, adopts a (reasonably conservative) method pruning
strategy as part of dead code elimination. Any method that is
directly called is kept, and any method that matches a used
interface's method signature is kept.
Whether or not a method body is kept is determined by the relocation
from its receiver's *rtype to its *rtype. A small change in the
compiler marks these relocations as R_METHOD so they can be easily
collected and manipulated by the linker.
As a bonus, this technique removes the text segment of methods that
have been inlined. Looking at the output of building cmd/objdump with
-ldflags=-v=2 shows that inlined methods like
runtime.(*traceAllocBlockPtr).ptr are removed from the program.
Relatively little work is necessary to do this. Linking two
examples, jujud and cmd/objdump show no more than +2% link time.
Binaries that do not use reflect.Call.Value drop 4 - 20% in size:
addr2line: -793KB (18%)
asm: -346KB (8%)
cgo: -490KB (10%)
compile: -564KB (4%)
dist: -736KB (17%)
fix: -404KB (12%)
link: -328KB (7%)
nm: -827KB (19%)
objdump: -712KB (16%)
pack: -327KB (14%)
yacc: -350KB (10%)
Binaries that do use reflect.Call.Value see a modest size decrease
of 2 - 6% thanks to pruning of unexported methods:
api: -151KB (3%)
cover: -222KB (4%)
doc: -106KB (2.5%)
pprof: -314KB (3%)
trace: -357KB (4%)
vet: -187KB (2.7%)
jujud: -4.4MB (5.8%)
cmd/go: -384KB (3.4%)
The trivial Hello example program goes from 2MB to 1.68MB:
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Method pruning also helps when building small binaries with
"-ldflags=-s -w". The above program goes from 1.43MB to 1.2MB.
Unfortunately the linker can only tell if reflect.Value.Call has been
statically linked, not if it is dynamically used. And while use is
rare, it is linked into a very common standard library package,
text/template. The result is programs like cmd/go, which don't use
reflect.Value.Call, see limited benefit from this CL. If binary size
is important enough it may be possible to address this in future work.
For #6853.
Change-Id: Iabe90e210e813b08c3f8fd605f841f0458973396
Reviewed-on: https://go-review.googlesource.com/20483
Reviewed-by: Russ Cox <rsc@golang.org>
Drops cmd/binary size from 14.41 MiB to 11.42 MiB.
Before:
text data bss dec hex filename
8121210 3521696 737960 12380866 bceac2 ../pkg/tool/linux_amd64/compile
bradfitz@dev-bradfitz-debian2:~/go/src$ ls -l ../pkg/tool/linux_amd64/compile
-rwxr-xr-x 1 bradfitz bradfitz 15111272 Mar 8 23:32 ../pkg/tool/linux_amd64/compile
a2afc0 51312 R html.statictmp_0085
6753f0 56592 T cmd/internal/obj/x86.doasm
625480 58080 T cmd/compile/internal/gc.typecheck1
f34c40 65688 D runtime.trace
be0a20 133552 D cmd/compile/internal/ppc64.varianttable
c013e0 265856 D cmd/compile/internal/arm.progtable
c42260 417280 D cmd/compile/internal/amd64.progtable
ca8060 417280 D cmd/compile/internal/x86.progtable
f44ce0 500640 D cmd/internal/obj/arm64.oprange
d0de60 534208 D cmd/compile/internal/ppc64.progtable
d90520 667520 D cmd/compile/internal/arm64.progtable
e334a0 790368 D cmd/compile/internal/mips64.progtable
a3e8c0 1579362 r runtime.pclntab
After:
text data bss dec hex filename
8128226 375954 246432 8750612 858614 ../pkg/tool/linux_amd64/compile
-rwxr-xr-x 1 bradfitz bradfitz 11971432 Mar 8 23:35 ../pkg/tool/linux_amd64/compile
6436d0 43936 T cmd/compile/internal/gc.walkexpr
c13ca0 45056 D cmd/compile/internal/ssa.opcodeTable
5d8ea0 50256 T cmd/compile/internal/gc.(*state).expr
818c50 50448 T cmd/compile/internal/ssa.rewriteValueAMD64_OpMove
a2d0e0 51312 R html.statictmp_0085
6753d0 56592 T cmd/internal/obj/x86.doasm
625460 58080 T cmd/compile/internal/gc.typecheck1
c38fe0 65688 D runtime.trace
a409e0 1578810 r runtime.pclntab
Fixes#14703
Change-Id: I2177596d5c7fd67db0a3c423cd90801cf52adb12
Reviewed-on: https://go-review.googlesource.com/20450
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Uses a switch statement for direct format function selection
similar to other types verb handling in fmt.
Applies padding also to nil pointers formatted with %v.
Guards against "slice bounds out of range" panic in TestSprintf
when a pointer test results in a formatted string s
that is shorter than the index i the pointer should appear in.
Adds more and rearranges tests.
Fixes#14712Fixes#14714
Change-Id: Iaf5ae37b7e6ba7d27d528d199f2b2eb9d5829b8c
Reviewed-on: https://go-review.googlesource.com/20371
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
On Plan 9, there's no "kill all threads" system call, so exit is done
by sending a "go: exit" note to each OS process. If concurrent GC
occurs during this loop, deadlock sometimes results. Prevent this by
incrementing m.locks before sending notes.
Change-Id: I31aa15134ff6e42d9a82f9f8a308620b3ad1b1b1
Reviewed-on: https://go-review.googlesource.com/20477
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This prevents a fatal "missing stackmap" error if garbage collection
occurs during exit.
Also annotate argument sizes for "go vet".
Change-Id: I2473e0ef6aef8f26d0bbeaee9bd8f8a52eaaf941
Reviewed-on: https://go-review.googlesource.com/20476
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
* Move lowering into a separate pass.
* SliceLen/SliceCap is now available to various intermediate passes
which use useful for bounds checking.
* Add a second opt pass to handle the new opportunities
Decreases the code size of binaries in pkg/tool/linux_amd64
by ~45K.
Updates #14564#14606
Change-Id: I5b2bd6202181c50623a3585fbf15c0d6db6d4685
Reviewed-on: https://go-review.googlesource.com/20172
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
It's only used once, so just make the caller responsible for iterating
both the receiver and input params.
Change-Id: Icb34f3f0cf96e80fbe27f3f49d12eddc26599b92
Reviewed-on: https://go-review.googlesource.com/20454
Reviewed-by: Dave Cheney <dave@cheney.net>
so the code is more readable.
Also use n[i] = val instead of n = append(n, val),
because this avoids a function call to append.
NOTE: compiles, but I had trouble running toolstash -cmp and need sleep
now.
@Ian this might save you some grunt work :-)
Change-Id: I2a4c70396c58905f7d5aabf83f3020f11dea0e89
Reviewed-on: https://go-review.googlesource.com/20430
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Adds a type of output to Examples that allows tests to have unordered
output. This is intended to help clarify when the output of a command
will produce a fixed return, but that return might not be in an constant
order.
Examples where this is useful would be documenting the rand.Perm()
call, or perhaps the (os.File).Readdir(), both of which can not guarantee
order, but can guarantee the elements of the output.
Fixes#10149
Change-Id: Iaf0cf1580b686afebd79718ed67ea744f5ed9fc5
Reviewed-on: https://go-review.googlesource.com/19280
Reviewed-by: Andrew Gerrand <adg@golang.org>
Suggested by Dave Cheney in golang.org/cl/20405.
Change-Id: I581c11ae80034cb6ebef3de976e8ae9484472322
Reviewed-on: https://go-review.googlesource.com/20453
Reviewed-by: Dave Cheney <dave@cheney.net>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This CL was automatically generated using a special-purpose AST
rewriting tool, followed by manual editing to put some comments back in
the right places and fix some bad line breaks.
The result is not perfect but it's a big step toward getting back to
sanity, and because it was automatically generated there is a decent
chance that it is correct.
Passes toolstash -cmp.
Update #14473.
Change-Id: I01c09078a6d78e2b008bc304d744b79469a38d3d
Reviewed-on: https://go-review.googlesource.com/20440
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
More idiomatic naming (in particular, matches the naming used for
go/types.Signature).
Also, convert more code to use these methods and/or IterFields.
(Still more to go; only made a quick pass for low hanging fruit.)
Passes toolstash -cmp.
Change-Id: I61831bfb1ec2cd50d4c7efc6062bca4e0dcf267b
Reviewed-on: https://go-review.googlesource.com/20451
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Alternative to golang.org/cl/19852. This memory layout doesn't have
an easy type representation, but it is noticeably smaller than the
current funcType, and saves significant extra space.
Some notes on the layout are in reflect/type.go:
// A *rtype for each in and out parameter is stored in an array that
// directly follows the funcType (and possibly its uncommonType). So
// a function type with one method, one input, and one output is:
//
// struct {
// funcType
// uncommonType
// [2]*rtype // [0] is in, [1] is out
// uncommonTypeSliceContents
// }
There are three arbitrary limits introduced by this CL:
1. No more than 65535 function input parameters.
2. No more than 32767 function output parameters.
3. reflect.FuncOf is limited to 128 parameters.
I don't think these are limits in practice, but are worth noting.
Reduces godoc binary size by 2.4%, 330KB.
For #6853.
Change-Id: I225c0a0516ebdbe92d41dfdf43f716da42dfe347
Reviewed-on: https://go-review.googlesource.com/19916
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Instead of a pointer on every rtype, use a bit flag to indicate that
the contents of uncommonType directly follows the rtype value when it
is needed.
This requires a bit of juggling in the compiler's rtype encoder. The
backing arrays for fields in the rtype are presently encoded directly
after the slice header. This packing requires separating the encoding
of the uncommonType slice headers from their backing arrays.
Reduces binary size of godoc by ~180KB (1.5%).
No measurable change in all.bash time.
For #6853.
Change-Id: I60205948ceb5c0abba76fdf619652da9c465a597
Reviewed-on: https://go-review.googlesource.com/19790
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Converting an and-K into a pair of shifts for K that will
fit in a one-byte argument is probably not an optimization,
and it also interferes with other patterns that we want to
see fire, like (<< (AND K)) [for small K] and bounds check
elimination for masked indices.
Turns out that on Intel, even 32-bit signed immediates beat
the shift pair; the size reduction of tool binaries is 0.09%
vs 0.07% for only the 8-bit immediates.
RLH found this one working on the new/next GC.
Change-Id: I2414a8de1dd58d680d18587577fbadb7ff4f67d9
Reviewed-on: https://go-review.googlesource.com/20410
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: David Chase <drchase@google.com>
Some cleaned up documentation, but no code changes.
Change-Id: I145398bb6d118c626ab3873ef75dbb64ebc286e9
Reviewed-on: https://go-review.googlesource.com/20404
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Don't do a substring search to test for a timeout error.
Fixes#14722 (maybe)
Change-Id: I4e18c749d6fd92c084a1b0b83a805119e1ae5ff2
Reviewed-on: https://go-review.googlesource.com/20403
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
* Simplify the nilcheck generated by
for _, e := range a {}
* No effect on the generated code because these nil checks
don't end up in the generated code.
* Useful for other analysis, e.g. it'll remove one dependecy
on the induction variable.
Change-Id: I6ee66ddfdc010ae22aea8dca48163303d93de7a9
Reviewed-on: https://go-review.googlesource.com/20307
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Make more idiomatic with a defer cleanup, which allows declaring
variables closer to their first use, rather than up front before the
first goto statement.
Also, split the legacy code generation code path into a separate
genlegacy function, analogous to the new genssa.
Passes toolstash -cmp.
Change-Id: I86c22838704f6861b75716ae64ba103b0e73b12f
Reviewed-on: https://go-review.googlesource.com/20353
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
getgrouplist is non-standard and has slightly different semantics on
each platform. Darwin defines the function in terms of ints instead of
gid_ts. Solaris only recently supported the call, so stubbing out for
now.
Fixes#14696Fixes#14709
Change-Id: I5a44538d41594909efb6f3f9610c55d638c36757
Reviewed-on: https://go-review.googlesource.com/20348
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Accidentally added in https://golang.org/cl/20242.
This is in preparation for transformation by an automated tool.
Passes toolstash -cmp.
Update #14473.
Change-Id: I28c637d220df3ccaa8e368bfbea7282a6e66662e
Reviewed-on: https://go-review.googlesource.com/20402
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Before, those C files might have been intended for the Plan 9 C compiler,
but that option was removed in Go 1.5. We can simplify the maintenance
of cgo packages now if we assume C files (and C++ and M and SWIG files)
should only be considered when cgo is enabled.
Also remove newly unnecessary build tags in runtime/cgo's C files.
Fixes#14123
Change-Id: Ia5a7fe62b9469965aa7c3547fe43c6c9292b8205
Reviewed-on: https://go-review.googlesource.com/19613
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Bug accidentally inserted in https://golang.org/cl/20210. Doesn't seem
to make a difference, but restore original code anyhow.
Update #14473.
Change-Id: I9cf87987ff158e27c7231027819317cdde8c132c
Reviewed-on: https://go-review.googlesource.com/20401
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Trailers() returns the headers that were set by the handler after the
headers were written "to the wire" (in this case HeaderMap) and that
were also specified in a proper header called "Trailer".
Neither HeaderMap or trailerMap (used for Trailers()) are manipulated by
the handler code, instead a third stagingMap is given to the
handler. This avoid a reference kept by handler to affect the recorded
results.
If a handler just modify the header but doesn't call any Write or Flush
method from ResponseWriter (or Flusher) interface, HeaderMap will not be
updated. In this case, calling Flush in the recorder is enough to get
the HeaderMap filled.
Fixes#14531.
Fixes#8857.
Change-Id: I42842341ec3e95c7b87d7e6f178c65cd03d63cc3
Reviewed-on: https://go-review.googlesource.com/20047
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Deleting the string merging pass makes the linker 30-35% faster
but makes jujud (using the github.com/davecheney/benchjuju snapshot) 2.5% larger.
Two optimizations bring the space overhead down to 0.6%.
First, change the default alignment for string data to 1 byte.
(It was previously defaulting to larger amounts, usually pointer width.)
Second, write out the type string for T (usually a bigger expression) as "*T"[1:],
so that the type strings for T and *T share storage.
Combined, these obtain the bulk of the benefit of string merging
at essentially no cost. The remaining benefit from string merging
is not worth the excessive cost, so delete it.
As penance for making the jujud binary 0.6% larger,
the next CL in this sequence trims the reflect functype
information enough to make the jujud binary overall 0.75% smaller
(that is, that CL has a net -1.35% effect).
For #6853.
Fixes#14648.
Change-Id: I3fdd74c85410930c36bb66160ca4174ed540fc6e
Reviewed-on: https://go-review.googlesource.com/20334
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
cmd/link is clearly the way forward.
The original rationale for cmd/newlink was that it would be a clean Go reimplementation.
But when push came to shove, cmd/link got converted from C instead,
and all the work on build modes and the like is in cmd/link now.
Cleaning up cmd/link is likely a much better plan.
This directory is something to delete from releases and the
testdata is something that breaks every time the .6 format changes.
Fix both problems by just deleting it outright.
Change-Id: Ib00fecda258ba685f1752725971182af9d4459eb
Reviewed-on: https://go-review.googlesource.com/20380
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Also, add more failure output to debug why linux/mips64le and
linux/ppc64 are failing. They should be working. I suspect their
builder test envs are missing something.
Change-Id: I97273fe72c4e3009db400394636d0da1ef147485
Reviewed-on: https://go-review.googlesource.com/20358
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This adds "slicing by 8" optimization to Castagnoli tables which will
speed up CRC32 calculation on systems without asssembler,
which are all but AMD64.
In my tests, it is faster to use "slicing by 8" for sizes all down to
16 bytes, so the switchover point has been adjusted.
There are no benchmarks for small sizes, so I have added one for 40 bytes,
as well as one for bigger sizes (32KB).
Castagnoli, No assembler, 40 Byte payload: (before, after)
BenchmarkCastagnoli40B-4 10000000 161 ns/op 246.94 MB/s
BenchmarkCastagnoli40B-4 20000000 100 ns/op 398.01 MB/s
Castagnoli, No assembler, 32KB payload: (before, after)
BenchmarkCastagnoli32KB-4 10000 115426 ns/op 283.89 MB/s
BenchmarkCastagnoli32KB-4 30000 45171 ns/op 725.41 MB/s
IEEE, No assembler, 1KB payload: (before, after)
BenchmarkCrc1KB-4 500000 3604 ns/op 284.10 MB/s
BenchmarkCrc1KB-4 1000000 1463 ns/op 699.79 MB/s
Compared:
benchmark old ns/op new ns/op delta
BenchmarkCastagnoli40B-4 161 100 -37.89%
BenchmarkCastagnoli32KB-4 115426 45171 -60.87%
BenchmarkCrc1KB-4 3604 1463 -59.41%
benchmark old MB/s new MB/s speedup
BenchmarkCastagnoli40B-4 246.94 398.01 1.61x
BenchmarkCastagnoli32KB-4 283.89 725.41 2.56x
BenchmarkCrc1KB-4 284.10 699.79 2.46x
Change-Id: I303e4ec84e8d4dafd057d64c0e43deb2b498e968
Reviewed-on: https://go-review.googlesource.com/19335
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Without SSA:
$ go build -a -gcflags='-S -ssa=0' runtime 2>&1 | grep 'TEXT.*""\.init(SB)'
0x0000 00000 ($GOROOT/src/runtime/write_err.go:14) TEXT "".init(SB), $88-0
With SSA, before this CL:
$ go build -a -gcflags='-S -ssa=1' runtime 2>&1 | grep 'TEXT.*""\.init(SB)'
0x0000 00000 ($GOROOT/src/runtime/traceback.go:608) TEXT "".init(SB), $152-0
With SSA, after this CL:
$ go build -a -gcflags='-S -ssa=1' runtime 2>&1 | grep 'TEXT.*""\.init(SB)'
0x0000 00000 ($GOROOT/src/runtime/write_err.go:14) TEXT "".init(SB), $152-0
Change-Id: Ida3541e03a1af6ffc753ee5c3abeb653459edbf6
Reviewed-on: https://go-review.googlesource.com/20321
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
The existing implementation deals with absolute relocations in __TEXT
for darwin/amd64 in build-mode c-shared, but it ignores c-archive.
This results in issues when trying to use a c-archive in an iOS
app on the 64-bit simulator. This patch adds c-archive to the
handling of this issue.
Fixes#14217
Change-Id: I2e4d5193caa531171ad22fd0cd420a8bfb4646a6
Reviewed-on: https://go-review.googlesource.com/19206
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>