Age | Commit message (Collapse) | Author |
|
Before register ABI, we always pass argument in memory, and the
compiler chooses interface conversion functions solely based on
the memory layout. As long as the two types have identical memory
layout, it is fine to mix and match, e.g. convT64 takes a uint64
argument, but it can be used for things like float64 or
struct { x [4]struct{}; y int64 }.
With register ABI, those types may be passed differently, e.g.
uint64 is passed in an integer register, float64 is passed in a
floating point register, the struct above is passed in memory.
I made a few attempts in the previous CLs to try to choose the
right function based on the argument type, but none of them is
really correct.
Instead, this CL changes it to always pass the argument in the
same type the runtime expects, and do conversion before the call
in the compiler. The conversion can be no-op (e.g. a named type
to its underlying type), direct (e.g. int64 to uint64), or
through memory (e.g. *(*uint64)(unsafe.Pointer(&arg))). This way,
the front end does not need to know the ABI. (It only needs to
know how to convert types, and it already does.)
TODO: do something similar for map functions.
Change-Id: I33fc780a47c3f332b765e09b5e527f52ea1d6b5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/309029
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
|
|
Currently, when converting a float (say float64), we use convT64
function. In the runtime convT64 expects a uint64 argument. In
the compiler, convT64 is defined as taking an "any" argument (so
it works with also uint64-like types such as [1]uint64). The "any"
type is instantiated with the concrete type in walk. So the
backend will see instances such as convT64([1]uint64).
Currently, float64 is treated as uint64-like. So the backend will
see convT64(float64). With a memory-based calling convention this
is fine. With a register-based calling convention, however, it
will pass the argument in a floating point register, whereas the
runtime expects the argument in an integer register (as it is
declared as uint64).
To fix this, this CL introduces runtime functions convT32F and
convT64F. They behave the same as convT32/convT64, but with a
float argument. In the compiler, use convT32F/convT64F to convert
float-like type to interface.
With this, "GOEXPERIMENT=regabi,regabiargs go test math fmt"
works.
Updates #40724.
Change-Id: I8b2e232096a95e4a7c4ab81795d77ef224ffaab3
Reviewed-on: https://go-review.googlesource.com/c/go/+/307232
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
|
|
When converting a type T to a non-empty interface I, we build the
itab which contains the code pointers of the methods. Currently,
this brings those methods live (if the itab is live), even if the
interface method is never used. This CL changes the itab to use
weak references, so the methods can be pruned if not otherwise
live.
Fixes #42421.
Change-Id: Iee5de2ba11d603c5a102a2ba60440d839a7f9702
Reviewed-on: https://go-review.googlesource.com/c/go/+/268479
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
|
|
This CL rebases CL 273694 on top of master with @mdempsky's permission.
For assertE2I and assertI2I, there's no need to pass through the
interface's data pointer: it's always going to come back unmodified.
For assertE2I2 and assertI2I2, there's no need for an extra bool
result parameter: it's redundant with testing the returned interface
value for nil.
Change-Id: Ic92d4409ad381952f875d3d74b8cf11c32702fa6
Reviewed-on: https://go-review.googlesource.com/c/go/+/292892
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
|
This reverts commit 8f26b57f9afc238bdecb9b7030bc2f4364093885.
Reason for revert: break a bunch of code, include standard library.
Fixes #42123
Change-Id: Ife90ecbafd2cb395623d1db555fbfc9c1b0098e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/264026
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
|
|
Currently, mhdr/methods is emitted with the same len/cap. There's no way
to distinguish between exported and non-exported methods statically.
This CL splits mhdr/methods into two parts, use "len" for number of
exported methods, and "cap" for all methods. This fixes the bug in
issue #22075, which intends to return the number of exported methods but
currently return all methods.
Note that with this encoding, we still can access either
all/exported-only/non-exported-only methods:
mhdr[:cap(mhdr)] // all methods
mhdr // exported methods
mhdr[len(mhdr):cap(mhdr)] // non-exported methods
Thank to Matthew Dempsky (@mdempsky) for suggesting this encoding.
Fixes #22075
Change-Id: If662adb03ccff27407d55a5578a0ed05a15e7cdd
Reviewed-on: https://go-review.googlesource.com/c/go/+/259237
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
|
I took some of the infrastructure from Austin's lock logging CR
https://go-review.googlesource.com/c/go/+/192704 (with deadlock
detection from the logs), and developed a setup to give static lock
ranking for runtime locks.
Static lock ranking establishes a documented total ordering among locks,
and then reports an error if the total order is violated. This can
happen if a deadlock happens (by acquiring a sequence of locks in
different orders), or if just one side of a possible deadlock happens.
Lock ordering deadlocks cannot happen as long as the lock ordering is
followed.
Along the way, I found a deadlock involving the new timer code, which Ian fixed
via https://go-review.googlesource.com/c/go/+/207348, as well as two other
potential deadlocks.
See the constants at the top of runtime/lockrank.go to show the static
lock ranking that I ended up with, along with some comments. This is
great documentation of the current intended lock ordering when acquiring
multiple locks in the runtime.
I also added an array lockPartialOrder[] which shows and enforces the
current partial ordering among locks (which is embedded within the total
ordering). This is more specific about the dependencies among locks.
I don't try to check the ranking within a lock class with multiple locks
that can be acquired at the same time (i.e. check the ranking when
multiple hchan locks are acquired).
Currently, I am doing a lockInit() call to set the lock rank of most
locks. Any lock that is not otherwise initialized is assumed to be a
leaf lock (a very high rank lock), so that eliminates the need to do
anything for a bunch of locks (including all architecture-dependent
locks). For two locks, root.lock and notifyList.lock (only in the
runtime/sema.go file), it is not as easy to do lock initialization, so
instead, I am passing the lock rank with the lock calls.
For Windows compilation, I needed to increase the StackGuard size from
896 to 928 because of the new lock-rank checking functions.
Checking of the static lock ranking is enabled by setting
GOEXPERIMENT=staticlockranking before doing a run.
To make sure that the static lock ranking code has no overhead in memory
or CPU when not enabled by GOEXPERIMENT, I changed 'go build/install' so
that it defines a build tag (with the same name) whenever any experiment
has been baked into the toolchain (by checking Expstring()). This allows
me to avoid increasing the size of the 'mutex' type when static lock
ranking is not enabled.
Fixes #38029
Change-Id: I154217ff307c47051f8dae9c2a03b53081acd83a
Reviewed-on: https://go-review.googlesource.com/c/go/+/207619
Reviewed-by: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
|
This was the last remaining use of staticbytes, so we can now
delete it.
The new code appears slightly faster on amd64:
name old time/op new time/op delta
SliceByteToString/1-4 6.29ns ± 2% 5.89ns ± 1% -6.46% (p=0.000 n=14+14)
This may not be the case on the big-endian architectures, since they have
to do an extra addition.
Updates #37612
Change-Id: Icb84c5911ba025f798de152849992a55be99e4f3
Reviewed-on: https://go-review.googlesource.com/c/go/+/221979
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
|
Prior to this change, we avoid allocation when
converting 0 to an interface.
This change extends that optimization to larger value types
whose values happens to be in the range 0 to 255.
This is marginally more expensive in the case of a 0 value,
in that the address is computed rather than fixed.
name old time/op new time/op delta
ConvT2ESmall-8 2.36ns ± 4% 2.65ns ± 4% +12.23% (p=0.000 n=87+91)
ConvT2EUintptr-8 2.36ns ± 4% 2.84ns ± 6% +20.05% (p=0.000 n=96+99)
ConvT2ELarge-8 23.8ns ± 2% 23.1ns ± 3% -2.94% (p=0.000 n=93+95)
ConvT2ISmall-8 2.67ns ± 5% 2.74ns ±27% ~ (p=0.214 n=99+100)
ConvT2IUintptr-8 2.65ns ± 5% 2.46ns ± 5% -7.19% (p=0.000 n=98+98)
ConvT2ILarge-8 24.2ns ± 2% 23.5ns ± 4% -3.16% (p=0.000 n=91+97)
ConvT2Ezero/zero/16-8 2.79ns ± 6% 2.99ns ± 4% +7.52% (p=0.000 n=94+88)
ConvT2Ezero/zero/32-8 2.34ns ± 3% 2.65ns ± 3% +13.06% (p=0.000 n=92+98)
ConvT2Ezero/zero/64-8 2.35ns ± 4% 2.65ns ± 6% +12.86% (p=0.000 n=99+94)
ConvT2Ezero/zero/str-8 2.55ns ± 4% 2.54ns ± 4% ~ (p=0.063 n=97+99)
ConvT2Ezero/zero/slice-8 2.82ns ± 4% 2.85ns ± 5% +1.00% (p=0.000 n=99+95)
ConvT2Ezero/zero/big-8 94.3ns ± 5% 93.4ns ± 4% -0.94% (p=0.000 n=88+90)
ConvT2Ezero/nonzero/str-8 29.6ns ± 3% 27.7ns ± 3% -6.69% (p=0.000 n=98+97)
ConvT2Ezero/nonzero/slice-8 36.6ns ± 2% 37.1ns ± 2% +1.31% (p=0.000 n=94+90)
ConvT2Ezero/nonzero/big-8 93.4ns ± 3% 92.7ns ± 3% -0.74% (p=0.000 n=88+84)
ConvT2Ezero/smallint/16-8 13.3ns ± 4% 2.7ns ± 6% -79.82% (p=0.000 n=100+97)
ConvT2Ezero/smallint/32-8 12.5ns ± 1% 2.9ns ± 5% -77.17% (p=0.000 n=85+96)
ConvT2Ezero/smallint/64-8 14.7ns ± 3% 2.6ns ± 3% -82.05% (p=0.000 n=94+94)
ConvT2Ezero/largeint/16-8 14.0ns ± 4% 13.2ns ± 7% -5.44% (p=0.000 n=95+99)
ConvT2Ezero/largeint/32-8 12.8ns ± 4% 12.9ns ± 3% ~ (p=0.096 n=99+87)
ConvT2Ezero/largeint/64-8 15.5ns ± 2% 15.0ns ± 2% -3.46% (p=0.000 n=95+96)
An example of a program for which this makes a perceptible difference
is running the compiler with the -S flag:
name old time/op new time/op delta
Template 349ms ± 2% 344ms ± 2% -1.48% (p=0.000 n=23+25)
Unicode 138ms ± 4% 136ms ± 3% -1.67% (p=0.003 n=25+25)
GoTypes 1.25s ± 2% 1.24s ± 2% -1.11% (p=0.001 n=24+25)
Compiler 5.73s ± 2% 5.67s ± 2% -1.09% (p=0.002 n=25+24)
SSA 20.2s ± 2% 19.9s ± 2% -1.45% (p=0.000 n=25+23)
Flate 216ms ± 4% 210ms ± 2% -2.77% (p=0.000 n=25+24)
GoParser 283ms ± 2% 278ms ± 3% -1.58% (p=0.000 n=23+23)
Reflect 757ms ± 2% 745ms ± 2% -1.58% (p=0.000 n=25+25)
Tar 303ms ± 4% 296ms ± 2% -2.20% (p=0.000 n=22+23)
XML 415ms ± 2% 411ms ± 3% -0.94% (p=0.002 n=25+22)
[Geo mean] 726ms 715ms -1.59%
name old user-time/op new user-time/op delta
Template 434ms ± 3% 427ms ± 2% -1.66% (p=0.000 n=23+24)
Unicode 204ms ±12% 198ms ±12% -2.83% (p=0.032 n=25+25)
GoTypes 1.59s ± 2% 1.56s ± 2% -1.64% (p=0.000 n=22+25)
Compiler 7.50s ± 1% 7.40s ± 2% -1.32% (p=0.000 n=25+25)
SSA 27.2s ± 2% 26.8s ± 2% -1.50% (p=0.000 n=24+23)
Flate 266ms ± 6% 254ms ± 3% -4.38% (p=0.000 n=25+25)
GoParser 357ms ± 2% 351ms ± 2% -1.90% (p=0.000 n=24+23)
Reflect 966ms ± 2% 947ms ± 2% -1.94% (p=0.000 n=24+25)
Tar 387ms ± 2% 380ms ± 3% -1.83% (p=0.000 n=22+24)
XML 538ms ± 1% 532ms ± 1% -1.15% (p=0.000 n=24+20)
[Geo mean] 942ms 923ms -2.02%
name old alloc/op new alloc/op delta
Template 54.1MB ± 0% 52.9MB ± 0% -2.26% (p=0.000 n=25+25)
Unicode 33.5MB ± 0% 33.1MB ± 0% -1.03% (p=0.000 n=25+24)
GoTypes 189MB ± 0% 185MB ± 0% -2.27% (p=0.000 n=25+25)
Compiler 875MB ± 0% 858MB ± 0% -1.99% (p=0.000 n=23+25)
SSA 3.19GB ± 0% 3.13GB ± 0% -1.95% (p=0.000 n=25+25)
Flate 32.9MB ± 0% 32.2MB ± 0% -2.26% (p=0.000 n=25+25)
GoParser 44.0MB ± 0% 42.9MB ± 0% -2.33% (p=0.000 n=25+25)
Reflect 117MB ± 0% 114MB ± 0% -2.60% (p=0.000 n=25+25)
Tar 48.6MB ± 0% 47.5MB ± 0% -2.18% (p=0.000 n=25+24)
XML 65.7MB ± 0% 64.4MB ± 0% -1.96% (p=0.000 n=23+25)
[Geo mean] 118MB 115MB -2.08%
name old allocs/op new allocs/op delta
Template 1.07M ± 0% 0.92M ± 0% -14.29% (p=0.000 n=25+25)
Unicode 539k ± 0% 494k ± 0% -8.27% (p=0.000 n=25+25)
GoTypes 3.97M ± 0% 3.43M ± 0% -13.71% (p=0.000 n=24+25)
Compiler 17.6M ± 0% 15.4M ± 0% -12.69% (p=0.000 n=25+24)
SSA 66.1M ± 0% 58.1M ± 0% -12.17% (p=0.000 n=25+25)
Flate 629k ± 0% 536k ± 0% -14.73% (p=0.000 n=24+24)
GoParser 929k ± 0% 799k ± 0% -13.96% (p=0.000 n=25+25)
Reflect 2.49M ± 0% 2.11M ± 0% -15.28% (p=0.000 n=25+25)
Tar 919k ± 0% 788k ± 0% -14.30% (p=0.000 n=25+25)
XML 1.28M ± 0% 1.11M ± 0% -12.85% (p=0.000 n=24+25)
[Geo mean] 2.32M 2.01M -13.24%
There is a slight increase in binary size from this change:
file before after Δ %
addr2line 4307728 4307760 +32 +0.001%
api 5972680 5972728 +48 +0.001%
asm 5114200 5114232 +32 +0.001%
buildid 2843720 2847848 +4128 +0.145%
cgo 4823736 4827864 +4128 +0.086%
compile 24912056 24912104 +48 +0.000%
cover 5259800 5259832 +32 +0.001%
dist 3665080 3665128 +48 +0.001%
doc 4672712 4672744 +32 +0.001%
fix 3376952 3376984 +32 +0.001%
link 6618008 6622152 +4144 +0.063%
nm 4253280 4257424 +4144 +0.097%
objdump 4655376 4659504 +4128 +0.089%
pack 2294280 2294328 +48 +0.002%
pprof 14747476 14751620 +4144 +0.028%
test2json 2819320 2823448 +4128 +0.146%
trace 11665068 11669212 +4144 +0.036%
vet 8342360 8342408 +48 +0.001%
Change-Id: I38ef70244e23069bfd14334061d43ae22a294519
Reviewed-on: https://go-review.googlesource.com/c/go/+/216401
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
The hash is used in type switches. However, compiler statically generates itab's
for all interface/type pairs used in switches (which are added to itabTable
in itabsinit). The dynamically-generated itab's never participate in type switches,
and thus the hash is irrelevant.
Change-Id: I4f6e37be31b8f5605cca7a1806cb04708e948cea
Reviewed-on: https://go-review.googlesource.com/c/go/+/202448
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
Prepared with gofmt -r.
Change-Id: Ifea325c209d800b5692d318955930b10debb548b
Reviewed-on: https://go-review.googlesource.com/c/go/+/198494
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
For a failed interface conversion not in ",ok" form, getitab
calls itab.init to get the name of the missing method for the
panic message. itab.init will try to find the methods, populate
the method table as it goes. When some method is missing, it sets
itab.fun[0] to 0 before return. There is a small window that
itab.fun[0] could be non-zero.
If concurrently, another goroutine tries to do the same interface
conversion, it will read the same itab's fun[0]. If this happens
in the small window, it sees a non-zero fun[0] and thinks the
conversion succeeded, which is bad.
Fix the race by setting fun[0] to non-zero only when we know the
conversion succeeds. While here, also simplify the syntax
slightly.
Fixes #31419.
Change-Id: Ied34d3043079eb933e330c5877b85e13f98f1916
Reviewed-on: https://go-review.googlesource.com/c/go/+/171759
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
to be used by errors package for checking assignability
and setting error values in As.
Updates #29934.
Change-Id: I8c1d02a2c6efa0919d54b286cfe8b4edc26da059
Reviewed-on: https://go-review.googlesource.com/c/161759
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
|
|
convT2E16 and other specialized type-to-interface routines
accept a type/itab argument and return a complete interface value.
However, we know enough in the routine to do without the type.
And the caller can construct the interface value using the type.
Doing so shrinks the call sites of ten of the specialized convT2x routines.
It also lets us unify the empty and non-empty interface routines.
Cuts 12k off cmd/go.
name old time/op new time/op delta
ConvT2ESmall-8 2.96ns ± 2% 2.34ns ± 4% -21.01% (p=0.000 n=175+189)
ConvT2EUintptr-8 3.00ns ± 3% 2.34ns ± 4% -22.02% (p=0.000 n=189+187)
ConvT2ELarge-8 21.3ns ± 7% 21.5ns ± 5% +1.02% (p=0.000 n=200+197)
ConvT2ISmall-8 2.99ns ± 4% 2.33ns ± 3% -21.95% (p=0.000 n=193+184)
ConvT2IUintptr-8 3.02ns ± 3% 2.33ns ± 3% -22.82% (p=0.000 n=198+190)
ConvT2ILarge-8 21.7ns ± 5% 22.2ns ± 4% +2.31% (p=0.000 n=199+198)
ConvT2Ezero/zero/16-8 2.96ns ± 2% 2.33ns ± 3% -21.11% (p=0.000 n=174+187)
ConvT2Ezero/zero/32-8 2.96ns ± 1% 2.35ns ± 4% -20.62% (p=0.000 n=163+193)
ConvT2Ezero/zero/64-8 2.99ns ± 2% 2.34ns ± 4% -21.78% (p=0.000 n=183+188)
ConvT2Ezero/zero/str-8 3.27ns ± 3% 2.54ns ± 3% -22.32% (p=0.000 n=195+192)
ConvT2Ezero/zero/slice-8 3.46ns ± 4% 2.81ns ± 3% -18.96% (p=0.000 n=197+164)
ConvT2Ezero/zero/big-8 88.4ns ±20% 90.0ns ±20% +1.84% (p=0.000 n=196+198)
ConvT2Ezero/nonzero/16-8 12.6ns ± 3% 12.3ns ± 3% -2.34% (p=0.000 n=167+196)
ConvT2Ezero/nonzero/32-8 12.3ns ± 4% 11.9ns ± 3% -2.95% (p=0.000 n=187+193)
ConvT2Ezero/nonzero/64-8 14.2ns ± 6% 13.8ns ± 5% -2.94% (p=0.000 n=198+199)
ConvT2Ezero/nonzero/str-8 27.2ns ± 5% 26.8ns ± 5% -1.33% (p=0.000 n=200+198)
ConvT2Ezero/nonzero/slice-8 33.3ns ± 8% 33.1ns ± 6% -0.82% (p=0.000 n=199+200)
ConvT2Ezero/nonzero/big-8 88.8ns ±22% 90.2ns ±18% +1.58% (p=0.000 n=200+199)
Neligible toolspeed impact.
name old alloc/op new alloc/op delta
Template 35.4MB ± 0% 35.3MB ± 0% -0.06% (p=0.008 n=5+5)
Unicode 29.1MB ± 0% 29.1MB ± 0% ~ (p=0.310 n=5+5)
GoTypes 122MB ± 0% 122MB ± 0% -0.08% (p=0.008 n=5+5)
Compiler 514MB ± 0% 513MB ± 0% -0.02% (p=0.008 n=5+5)
SSA 1.94GB ± 0% 1.94GB ± 0% -0.01% (p=0.008 n=5+5)
Flate 24.2MB ± 0% 24.2MB ± 0% ~ (p=0.548 n=5+5)
GoParser 28.5MB ± 0% 28.5MB ± 0% -0.05% (p=0.016 n=5+5)
Reflect 86.3MB ± 0% 86.2MB ± 0% -0.02% (p=0.008 n=5+5)
Tar 34.9MB ± 0% 34.9MB ± 0% ~ (p=0.095 n=5+5)
XML 47.1MB ± 0% 47.1MB ± 0% -0.05% (p=0.008 n=5+5)
[Geo mean] 81.0MB 81.0MB -0.03%
name old allocs/op new allocs/op delta
Template 349k ± 0% 349k ± 0% -0.08% (p=0.008 n=5+5)
Unicode 340k ± 0% 340k ± 0% ~ (p=0.111 n=5+5)
GoTypes 1.28M ± 0% 1.28M ± 0% -0.09% (p=0.008 n=5+5)
Compiler 4.92M ± 0% 4.92M ± 0% -0.08% (p=0.008 n=5+5)
SSA 15.3M ± 0% 15.3M ± 0% -0.03% (p=0.008 n=5+5)
Flate 233k ± 0% 233k ± 0% ~ (p=0.500 n=5+5)
GoParser 292k ± 0% 292k ± 0% -0.06% (p=0.008 n=5+5)
Reflect 1.05M ± 0% 1.05M ± 0% -0.02% (p=0.008 n=5+5)
Tar 344k ± 0% 343k ± 0% -0.06% (p=0.008 n=5+5)
XML 430k ± 0% 429k ± 0% -0.08% (p=0.008 n=5+5)
[Geo mean] 809k 809k -0.05%
name old object-bytes new object-bytes delta
Template 507kB ± 0% 507kB ± 0% -0.04% (p=0.008 n=5+5)
Unicode 225kB ± 0% 225kB ± 0% ~ (all equal)
GoTypes 1.85MB ± 0% 1.85MB ± 0% -0.08% (p=0.008 n=5+5)
Compiler 6.75MB ± 0% 6.75MB ± 0% +0.01% (p=0.008 n=5+5)
SSA 21.4MB ± 0% 21.4MB ± 0% -0.02% (p=0.008 n=5+5)
Flate 328kB ± 0% 328kB ± 0% -0.03% (p=0.008 n=5+5)
GoParser 403kB ± 0% 402kB ± 0% -0.06% (p=0.008 n=5+5)
Reflect 1.41MB ± 0% 1.41MB ± 0% -0.03% (p=0.008 n=5+5)
Tar 457kB ± 0% 457kB ± 0% -0.05% (p=0.008 n=5+5)
XML 601kB ± 0% 600kB ± 0% -0.16% (p=0.008 n=5+5)
[Geo mean] 1.05MB 1.04MB -0.05%
Change-Id: I677a4108c0ecd32617549294036aa84f9214c4fe
Reviewed-on: https://go-review.googlesource.com/c/147360
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
|
|
When we pass these types by reference, we usually have to allocate
temporaries on the stack, initialize them, then pass their address
to the conversion functions. It's simpler to pass these types
directly by value.
This particularly applies to conversions needed for fmt.Printf
(to interface{} for constructing a [...]interface{}).
func f(a, b, c string) {
fmt.Printf("%s %s\n", a, b)
fmt.Printf("%s %s\n", b, c)
}
This function's stack frame shrinks from 200 to 136 bytes, and
its code shrinks from 535 to 453 bytes.
The go binary shrinks 0.3%.
Update #24286
Aside: for this function f, we don't really need to allocate
temporaries for the convT2E function. We could use the address
of a, b, and c directly. That might get similar (or maybe better?)
improvements. I investigated a bit, but it seemed complicated
to do it safely. This change was much easier.
Change-Id: I78cbe51b501fb41e1e324ce4203f0de56a1db82d
Reviewed-on: https://go-review.googlesource.com/c/135377
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
|
|
Fix the panic message produced for an interface conversion error to
only say "types from different packages" if they are definitely from
different packges. If they may be from the same package, say "types
from different scopes."
Updates #18911
Fixes #26094
Change-Id: I0cea50ba31007d88e70c067b4680009ede69bab9
Reviewed-on: https://go-review.googlesource.com/123395
Reviewed-by: Austin Clements <austin@google.com>
|
|
Code comments should have a space between comments characters and
actual words.
Change-Id: I6274baf1fc09b37a32ec6c69ddbb8edca9eb5469
Reviewed-on: https://go-review.googlesource.com/120475
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
The motivation is avoid generating a pointer to the data being
converted so it can be garbage collected.
The change also slightly reduces binary size by shrinking call sites.
Fixes #24286
Benchmark results:
name old time/op new time/op delta
ConvT2ESmall-4 2.86ns ± 0% 2.80ns ± 1% -2.12% (p=0.000 n=29+28)
ConvT2EUintptr-4 2.88ns ± 1% 2.88ns ± 0% -0.20% (p=0.002 n=28+30)
ConvT2ELarge-4 19.6ns ± 0% 20.4ns ± 1% +4.22% (p=0.000 n=19+30)
ConvT2ISmall-4 3.01ns ± 0% 2.85ns ± 0% -5.32% (p=0.000 n=24+28)
ConvT2IUintptr-4 3.00ns ± 1% 2.87ns ± 0% -4.44% (p=0.000 n=29+25)
ConvT2ILarge-4 20.4ns ± 1% 21.3ns ± 1% +4.41% (p=0.000 n=30+26)
ConvT2Ezero/zero/16-4 2.84ns ± 1% 2.99ns ± 0% +5.38% (p=0.000 n=30+25)
ConvT2Ezero/zero/32-4 2.83ns ± 2% 3.00ns ± 0% +5.91% (p=0.004 n=27+3)
Change-Id: I65016ec94c53f97c52113121cab582d0c342b7a8
Reviewed-on: https://go-review.googlesource.com/102636
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
|
They have either already been called by preprintpanics, or they can
not be called safely because of the various conditions checked at the
start of gopanic.
Fixes #24059
Change-Id: I4a6233d12c9f7aaaee72f343257ea108bae79241
Reviewed-on: https://go-review.googlesource.com/96755
Reviewed-by: Austin Clements <austin@google.com>
|
|
Now that getcallerpc is a compiler intrinsic on x86 and non-x86
platforms don't need the argument, we can drop it.
Sadly, this doesn't let us remove any dummy arguments since all of
those cases also use getcallersp, which still takes the argument
pointer, but this is at least an improvement.
Change-Id: I9c34a41cf2c18cba57f59938390bf9491efb22d2
Reviewed-on: https://go-review.googlesource.com/65474
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
|
|
This change could improve the hit rate on itabTable during growth.
While we are here patch comments to refer to existing functions.
Change-Id: I76f81c860a3d6107e077e7e3932550858a8b7651
Reviewed-on: https://go-review.googlesource.com/55912
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
I noticed that we don't set an itab's function pointers at compile
time. Instead, we currently do it at executable startup.
Set the function pointers at compile time instead. This shortens
startup time. It has no effect on normal binary size. Object files
will have more relocations, but that isn't a big deal.
For PIE there are additional pointers that will need to be adjusted at
load time. There are already other pointers in an itab that need to be
adjusted, so the cache line will already be paged in. There might be
some binary size overhead to mark these pointers. The "go test -c
-buildmode=pie net/http" binary is 0.18% bigger.
Update #20505
Change-Id: I267c82489915b509ff66e512fc7319b2dd79b8f7
Reviewed-on: https://go-review.googlesource.com/44341
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
|
|
We weren't initializing this field for dynamically-generated itabs.
Turns out it doesn't matter, as any time we use this field we also
generate a static itab for the interface type / concrete type pair.
But we should initialize it anyway, just to be safe.
Performance on the benchmarks in CL 44339:
benchmark old ns/op new ns/op delta
BenchmarkItabFew-12 1040585 26466 -97.46%
BenchmarkItabAll-12 228873499 4287696 -98.13%
Change-Id: I58ed2b31e6c98b584122bdaf844fee7268b58295
Reviewed-on: https://go-review.googlesource.com/44475
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
|
|
Just use fun[0]==0 to indicate a bad itab.
Change-Id: I28ecb2d2d857090c1ecc40b1d1866ac24a844848
Reviewed-on: https://go-review.googlesource.com/44473
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
|
|
Keep itabs in a growable hash table.
Use a simple open-addressable hash table, quadratic probing, power
of two sized.
Synchronization gets a bit more tricky. The common read path now
has two atomic reads, one to get the table pointer and one to read
the entry out of the table.
I set the max load factor to 75%, kind of arbitrarily. There's a
space-speed tradeoff here, and I'm not sure where we should land.
Because we use open addressing the itab.link field is no longer needed.
I'll remove it in a separate CL.
Fixes #20505
Change-Id: Ifb3d9a337512d6cf968c1fceb1eeaf89559afebf
Reviewed-on: https://go-review.googlesource.com/44472
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
|
|
Prior to this CL, all runtime conversions
from a concrete value to an interface went
through one of two runtime calls: convT2E or convT2I.
However, in practice, basic types are very common.
Specializing convT2x for those basic types allows
for a more efficient implementation for those types.
For basic scalars and strings, allocation and copying
can use the same methods as normal code.
For pointer-free types, allocation can occur without
zeroing, and copying can take place without GC calls.
For slices, copying is cheaper and simpler.
This CL adds twelve runtime routines:
convT2E16, convT2I16
convT2E32, convT2I32
convT2E64, convT2I64
convT2Estring, convT2Istring
convT2Eslice, convT2Islice
convT2Enoptr, convT2Inoptr
While compiling make.bash, 93% of all convT2x calls
are now to one of these specialized convT2x call.
Within specialized convT2x routines, it is cheap to check
for a zero value, in a way that it is not in general.
When we detect a zero value there, we return a pointer
to zeroVal, rather than allocating.
name old time/op new time/op delta
ConvT2Ezero/zero/16-8 17.9ns ± 2% 3.0ns ± 3% -83.20% (p=0.000 n=56+56)
ConvT2Ezero/zero/32-8 17.8ns ± 2% 3.0ns ± 3% -83.15% (p=0.000 n=59+60)
ConvT2Ezero/zero/64-8 20.1ns ± 1% 3.0ns ± 2% -84.98% (p=0.000 n=57+57)
ConvT2Ezero/zero/str-8 32.6ns ± 1% 3.0ns ± 4% -90.70% (p=0.000 n=59+60)
ConvT2Ezero/zero/slice-8 36.7ns ± 2% 3.0ns ± 2% -91.78% (p=0.000 n=59+59)
ConvT2Ezero/zero/big-8 91.9ns ± 2% 85.9ns ± 2% -6.52% (p=0.000 n=57+57)
ConvT2Ezero/nonzero/16-8 17.7ns ± 2% 12.7ns ± 3% -28.38% (p=0.000 n=55+60)
ConvT2Ezero/nonzero/32-8 17.8ns ± 1% 12.7ns ± 1% -28.44% (p=0.000 n=54+57)
ConvT2Ezero/nonzero/64-8 20.0ns ± 1% 15.0ns ± 1% -24.90% (p=0.000 n=56+58)
ConvT2Ezero/nonzero/str-8 32.6ns ± 1% 25.7ns ± 1% -21.17% (p=0.000 n=58+55)
ConvT2Ezero/nonzero/slice-8 36.8ns ± 2% 30.4ns ± 1% -17.32% (p=0.000 n=60+52)
ConvT2Ezero/nonzero/big-8 92.1ns ± 2% 85.9ns ± 2% -6.70% (p=0.000 n=57+59)
Benchmarks on a real program (the compiler):
name old time/op new time/op delta
Template 227ms ± 5% 221ms ± 2% -2.48% (p=0.000 n=30+26)
Unicode 102ms ± 5% 100ms ± 3% -1.30% (p=0.009 n=30+26)
GoTypes 656ms ± 5% 659ms ± 4% ~ (p=0.208 n=30+30)
Compiler 2.82s ± 2% 2.82s ± 1% ~ (p=0.614 n=29+27)
Flate 128ms ± 2% 128ms ± 5% ~ (p=0.783 n=27+28)
GoParser 158ms ± 3% 158ms ± 3% ~ (p=0.261 n=28+30)
Reflect 408ms ± 7% 401ms ± 3% ~ (p=0.075 n=30+30)
Tar 123ms ± 6% 121ms ± 8% ~ (p=0.287 n=29+30)
XML 220ms ± 2% 220ms ± 4% ~ (p=0.805 n=29+29)
name old user-ns/op new user-ns/op delta
Template 281user-ms ± 4% 279user-ms ± 3% -0.87% (p=0.044 n=28+28)
Unicode 142user-ms ± 4% 141user-ms ± 3% -1.04% (p=0.015 n=30+27)
GoTypes 884user-ms ± 3% 886user-ms ± 2% ~ (p=0.532 n=30+30)
Compiler 3.94user-s ± 3% 3.92user-s ± 1% ~ (p=0.185 n=30+28)
Flate 165user-ms ± 2% 165user-ms ± 4% ~ (p=0.780 n=27+29)
GoParser 209user-ms ± 2% 208user-ms ± 3% ~ (p=0.453 n=28+30)
Reflect 533user-ms ± 6% 526user-ms ± 3% ~ (p=0.057 n=30+30)
Tar 156user-ms ± 6% 154user-ms ± 6% ~ (p=0.133 n=29+30)
XML 288user-ms ± 4% 288user-ms ± 4% ~ (p=0.633 n=30+30)
name old alloc/op new alloc/op delta
Template 41.0MB ± 0% 40.9MB ± 0% -0.11% (p=0.000 n=29+29)
Unicode 32.6MB ± 0% 32.6MB ± 0% ~ (p=0.572 n=29+30)
GoTypes 122MB ± 0% 122MB ± 0% -0.10% (p=0.000 n=30+30)
Compiler 482MB ± 0% 481MB ± 0% -0.07% (p=0.000 n=30+29)
Flate 26.6MB ± 0% 26.6MB ± 0% ~ (p=0.096 n=30+30)
GoParser 32.7MB ± 0% 32.6MB ± 0% -0.06% (p=0.011 n=28+28)
Reflect 84.2MB ± 0% 84.1MB ± 0% -0.17% (p=0.000 n=29+30)
Tar 27.7MB ± 0% 27.7MB ± 0% -0.05% (p=0.032 n=27+28)
XML 44.7MB ± 0% 44.7MB ± 0% ~ (p=0.131 n=28+30)
name old allocs/op new allocs/op delta
Template 373k ± 1% 370k ± 1% -0.76% (p=0.000 n=30+30)
Unicode 325k ± 1% 325k ± 1% ~ (p=0.383 n=29+30)
GoTypes 1.16M ± 0% 1.15M ± 0% -0.75% (p=0.000 n=29+30)
Compiler 4.15M ± 0% 4.13M ± 0% -0.59% (p=0.000 n=30+29)
Flate 238k ± 1% 237k ± 1% -0.62% (p=0.000 n=30+30)
GoParser 304k ± 1% 302k ± 1% -0.64% (p=0.000 n=30+28)
Reflect 1.00M ± 0% 0.99M ± 0% -1.10% (p=0.000 n=29+30)
Tar 245k ± 1% 244k ± 1% -0.59% (p=0.000 n=27+29)
XML 391k ± 1% 389k ± 1% -0.59% (p=0.000 n=29+30)
Change-Id: Id7f456d690567c2b0a96b0d6d64de8784b6e305f
Reviewed-on: https://go-review.googlesource.com/36476
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
When doing i.(T) for non-empty-interface i and concrete type T,
there's no need to read the type out of the itab. Just compare the
itab to the itab we expect for that interface/type pair.
Also optimize type switches by putting the type hash of the
concrete type in the itab. That way we don't need to load the
type pointer out of the itab.
Update #18492
Change-Id: I49e280a21e5687e771db5b8a56b685291ac168ce
Reviewed-on: https://go-review.googlesource.com/34810
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
|
|
Based in part on khr's CL 2500.
Updates #17725
Updates #18121
Change-Id: I744e1f92fc2104e6c5bd883a898c30b2eea8cc31
Reviewed-on: https://go-review.googlesource.com/35555
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
golang.org/issue/17594 was caused by additab being called more than once for
an itab. golang.org/cl/32131 fixed that by making the itabs local symbols,
but that in turn causes golang.org/issue/18252 because now there are now
multiple itab symbols in a process for a given (type,interface) pair and
different code paths can end up referring to different itabs which breaks
lots of reflection stuff. So this makes itabs global again and just takes
care to only call additab once for each itab.
Fixes #18252
Change-Id: I781a193e2f8dd80af145a3a971f6a25537f633ea
Reviewed-on: https://go-review.googlesource.com/34173
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
|
|
Fixes #17938
Change-Id: Iad12155f4976846bd4a9a53869f89e40e5b3deb3
Reviewed-on: https://go-review.googlesource.com/34147
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
|
|
The code to do the conversion is smaller than the
call to the runtime.
The 1-result asserts need to call panic if they fail, but that
code is out of line.
The only conversions left in the runtime are those which
might allocate and those which might need to generate an itab.
Given the following types:
type E interface{}
type I interface { foo() }
type I2 iterface { foo(); bar() }
type Big [10]int
func (b Big) foo() { ... }
This CL inlines the following conversions:
was assertE2T
var e E = ...
b := i.(Big)
was assertE2T2
var e E = ...
b, ok := i.(Big)
was assertI2T
var i I = ...
b := i.(Big)
was assertI2T2
var i I = ...
b, ok := i.(Big)
was assertI2E
var i I = ...
e := i.(E)
was assertI2E2
var i I = ...
e, ok := i.(E)
These are the remaining runtime calls:
convT2E:
var b Big = ...
var e E = b
convT2I:
var b Big = ...
var i I = b
convI2I:
var i2 I2 = ...
var i I = i2
assertE2I:
var e E = ...
i := e.(I)
assertE2I2:
var e E = ...
i, ok := e.(I)
assertI2I:
var i I = ...
i2 := i.(I2)
assertI2I2:
var i I = ...
i2, ok := i.(I2)
Fixes #17405
Fixes #8422
Change-Id: Ida2367bf8ce3cd2c6bb599a1814f1d275afabe21
Reviewed-on: https://go-review.googlesource.com/32313
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
|
|
The introduction of -buildmode=plugin means modules can be added to a
Go program while it is running. This means there exists some time
while the program is running with the module is on the moduledata
linked list, but it has not been initialized to the satisfaction of
other parts of the runtime. Notably, the GC.
This CL adds a new way of access modules, an activeModules function.
It returns a slice of modules that is built in the background and
atomically swapped in. The parts of the runtime that need to wait on
module initialization can use this slice instead of the linked list.
Fixes #17455
Change-Id: I04790fd07e40c7295beb47cea202eb439206d33d
Reviewed-on: https://go-review.googlesource.com/32357
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
The hybrid barrier requires distinguishing typed and untyped memory
even when zeroing because the *current* contents of the memory matters
even when overwriting.
This commit introduces runtime.typedmemclr and runtime.memclrHasPointers
as a typed memory clearing functions parallel to runtime.typedmemmove.
Currently these simply call memclr, but with the hybrid barrier we'll
need to shade any pointers we're overwriting. These will provide us
with the necessary hooks to do so.
Updates #17503.
Change-Id: I74478619f8907825898092aaa204d6e4690f27e6
Reviewed-on: https://go-review.googlesource.com/31366
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
|
|
Otherwise, the way the ELF dynamic linker works means that you can end up with
the same itab being passed to additab twice, leading to the itab linked list
having a cycle in it. Add a test to additab in runtime to catch this when it
happens, not some arbitrary and surprsing time later.
Fixes #17594
Change-Id: I6c82edcc9ac88ac188d1185370242dc92f46b1ad
Reviewed-on: https://go-review.googlesource.com/32131
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
|
This reverts commit 7dd9c385f6896c7dcb5d76353e52e36c81af2838.
Reason for revert: Reverting the revert, which will re-enable the convI2E optimization. We originally reverted the convI2E optimization because it was making the builder fail, but the underlying cause was later determined to be unrelated.
Original CL: https://go-review.googlesource.com/31260
Revert CL: https://go-review.googlesource.com/31310
Real bug: https://go-review.googlesource.com/c/25159
Real fix: https://go-review.googlesource.com/c/31316
Change-Id: I17237bb577a23a7675a5caab970ccda71a4124f2
Reviewed-on: https://go-review.googlesource.com/32023
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
|
This reverts commit 395d36a67df8d25b35617ec8709f0164ae2f655e.
Appears to be responsible for builder failures.
Change-Id: Ic6c6307f662767e529060b88704a9f074785d99e
Reviewed-on: https://go-review.googlesource.com/31310
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
|
|
It's pretty simple. For:
e = (interface{})(i)
Do:
tmp = i.itab
if tmp != nil {
tmp = tmp.typ_ // load type from itab
}
e = eface{tmp, i.data}
It is smaller and faster than calling the runtime.
Change-Id: I0ad27f62f4ec0b6cd53bc8530e4da0eae3e67a6c
Reviewed-on: https://go-review.googlesource.com/31260
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
|
No point in calling a function when we can build the interface
using a known type (or itab) and the address of a local.
Get rid of third arg (preallocated stack space) to convT2{I,E}.
Makes go binary smaller by 0.2%
benchmark old ns/op new ns/op delta
BenchmarkEfaceInteger-8 16.7 10.1 -39.52%
Update #17118
Update #15375
Change-Id: I9724a1f802bfa1e3957bf1856b55558278e198a2
Reviewed-on: https://go-review.googlesource.com/29373
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
|
We already inlined
_, ok = e.(T)
_, ok = i.(E)
_, ok = e.(E)
The only ok-only variants not inlined are now
_, ok = i.(I)
_, ok = e.(I)
These call getitab, so are non-trivial.
Change-Id: Ie45fd8933ee179a679b92ce925079b94cff0ee12
Reviewed-on: https://go-review.googlesource.com/26658
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
A straight conversion from a type T to an interface type I, where T does
not implement I, should always panic with an interface conversion error
that shows the missing method. This was not happening if the conversion
was done once using the comma-ok form (the result would not be OK) and
then again in a straight conversion. Due to an error in the runtime
package the second conversion was failing with a nil pointer
dereference.
Fixes #16130.
Change-Id: I8b9fca0f1bb635a6181b8b76de8c2385bb7ac2d2
Reviewed-on: https://go-review.googlesource.com/24284
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Michel Lespinasse <walken@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
|
|
linux/amd64 PIE:
cmd/go: -62KB (0.5%)
jujud: -550KB (0.7%)
For #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>
|
|
linux/amd64:
cmd/go: -8KB (basically nothing)
linux/amd64 PIE:
cmd/go: -191KB (1.6%)
jujud: -1.5MB (1.9%)
Updates #6853
Fixes #15064
Change-Id: I0adbb95685e28be92e8548741df0e11daa0a9b5f
Reviewed-on: https://go-review.googlesource.com/21777
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
We now inline type to interface conversions when the type
is pointer-shaped. No need to keep code to handle that in
convT2{I,E}.
Change-Id: I3a6668259556077cbb2986a9e8fe42a625d506c9
Reviewed-on: https://go-review.googlesource.com/22249
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michel Lespinasse <walken@google.com>
|
|
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 #6853.
Change-Id: Ia044423f010fb987ce070b94c46a16fc78666ff6
Reviewed-on: https://go-review.googlesource.com/21396
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
By replacing the *string used to represent pkgPath with a
reflect.name everywhere, the embedded *string for package paths
inside the reflect.name can be replaced by an offset, nameOff.
This reduces the number of pointers in the type information.
This also moves all reflect.name types into the same section, making
it possible to use nameOff more widely in later CLs.
No significant binary size change for normal binaries, but:
linux/amd64 PIE:
cmd/go: -440KB (3.7%)
jujud: -2.6MB (3.2%)
For #6853.
Change-Id: I3890b132a784a1090b1b72b32febfe0bea77eaee
Reviewed-on: https://go-review.googlesource.com/21395
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
|
This CL introduces the typeOff type and a lookup method of the same
name that can turn a typeOff offset into an *rtype.
In a typical Go binary (built with buildmode=exe, pie, c-archive, or
c-shared), there is one moduledata and all typeOff values are offsets
relative to firstmoduledata.types. This makes computing the pointer
cheap in typical programs.
With buildmode=shared (and one day, buildmode=plugin) there are
multiple modules whose relative offset is determined at runtime.
We identify a type in the general case by the pair of the original
*rtype that references it and its typeOff value. We determine
the module from the original pointer, and then use the typeOff from
there to compute the final *rtype.
To ensure there is only one *rtype representing each type, the
runtime initializes a typemap for each module, using any identical
type from an earlier module when resolving that offset. This means
that types computed from an offset match the type mapped by the
pointer dynamic relocations.
A series of followup CLs will replace other *rtype values with typeOff
(and name/*string with nameOff).
For types created at runtime by reflect, type offsets are treated as
global IDs and reference into a reflect offset map kept by the runtime.
darwin/amd64:
cmd/go: -57KB (0.6%)
jujud: -557KB (0.8%)
linux/amd64 PIE:
cmd/go: -361KB (3.0%)
jujud: -3.5MB (4.2%)
For #6853.
Change-Id: Icf096fd884a0a0cb9f280f46f7a26c70a9006c96
Reviewed-on: https://go-review.googlesource.com/21285
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
|
getcallerpc's arg needs to point to the first argument slot.
I believe this bug was introduced by Michel's itab changes
(specifically https://go-review.googlesource.com/c/20902).
Fixes #15145
Change-Id: Ifb2e17f3658e2136c7950dfc789b4d5706320683
Reviewed-on: https://go-review.googlesource.com/21931
Reviewed-by: Michel Lespinasse <walken@google.com>
|
|
See #14874
Updates #6853
This change adds a compiler optimization for non pointer shaped convT2I.
Since itab symbols are now emitted by the compiler, the itab address can
be passed directly to convT2I instead of passing the iface type and a
cache pointer argument.
Compilebench results for the 5-commits series ending here:
name old time/op new time/op delta
Template 336ms ± 4% 344ms ± 4% +2.61% (p=0.027 n=9+8)
Unicode 165ms ± 6% 173ms ± 7% +5.11% (p=0.014 n=9+9)
GoTypes 1.09s ± 1% 1.06s ± 2% -3.29% (p=0.000 n=9+9)
Compiler 5.09s ±10% 4.75s ±10% -6.64% (p=0.011 n=10+10)
MakeBash 31.1s ± 5% 30.3s ± 3% ~ (p=0.089 n=10+10)
name old text-bytes new text-bytes delta
HelloSize 558k ± 0% 558k ± 0% +0.02% (p=0.000 n=10+10)
CmdGoSize 6.24M ± 0% 6.11M ± 0% -2.11% (p=0.000 n=10+10)
name old data-bytes new data-bytes delta
HelloSize 3.66k ± 0% 3.74k ± 0% +2.41% (p=0.000 n=10+10)
CmdGoSize 134k ± 0% 162k ± 0% +20.76% (p=0.000 n=10+10)
name old bss-bytes new bss-bytes delta
HelloSize 126k ± 0% 126k ± 0% ~ (all samples are equal)
CmdGoSize 149k ± 0% 146k ± 0% -2.17% (p=0.000 n=10+10)
name old exe-bytes new exe-bytes delta
HelloSize 924k ± 0% 924k ± 0% +0.05% (p=0.000 n=10+10)
CmdGoSize 9.77M ± 0% 9.62M ± 0% -1.47% (p=0.000 n=10+10)
Change-Id: Ib230ddc04988824035c32287ae544a965fedd344
Reviewed-on: https://go-review.googlesource.com/20902
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: Michel Lespinasse <walken@google.com>
|
|
See #14874
This change makes the runtime register all compiler generated itabs
(as obtained from the moduledata) during init.
Change-Id: I9969a0985b99b8bda820a631f7fe4c78f1174cdf
Reviewed-on: https://go-review.googlesource.com/20900
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Michel Lespinasse <walken@google.com>
|
|
Create a byte encoding designed for static Go names.
It is intended to be a compact representation of a name
and optional tag data that can be turned into a Go string
without allocating, and describes whether or not it is
exported without unicode table.
The encoding is described in reflect/type.go:
// The first byte is a bit field containing:
//
// 1<<0 the name is exported
// 1<<1 tag data follows the name
// 1<<2 pkgPath *string follow the name and tag
//
// The next two bytes are the data length:
//
// l := uint16(data[1])<<8 | uint16(data[2])
//
// Bytes [3:3+l] are the string data.
//
// If tag data follows then bytes 3+l and 3+l+1 are the tag length,
// with the data following.
//
// If the import path follows, then ptrSize bytes at the end of
// the data form a *string. The import path is only set for concrete
// methods that are defined in a different package than their type.
Shrinks binary sizes:
cmd/go: 164KB (1.6%)
jujud: 1.0MB (1.5%)
For #6853.
Change-Id: I46b6591015b17936a443c9efb5009de8dfe8b609
Reviewed-on: https://go-review.googlesource.com/20968
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|