diff options
author | Russ Cox <rsc@golang.org> | 2015-03-20 00:06:10 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2015-03-20 20:05:37 +0000 |
commit | 4224d81fae7bfce98629894d14f4644018037cfb (patch) | |
tree | a69bfb0356406df650405a15ceee342f33313549 /test/interface | |
parent | b115c35ee337ac6026539802d2ff085949dd1919 (diff) | |
download | go-4224d81fae7bfce98629894d14f4644018037cfb.tar.gz go-4224d81fae7bfce98629894d14f4644018037cfb.zip |
cmd/internal/gc: inline x := y.(*T) and x, ok := y.(*T)
These can be implemented with just a compare and a move instruction.
Do so, avoiding the overhead of a call into the runtime.
These assertions are a significant cost in Go code that uses interface{}
as a safe alternative to C's void* (or unsafe.Pointer), such as the
current version of the Go compiler.
*T here includes pointer to T but also any Go type represented as
a single pointer (chan, func, map). It does not include [1]*T or struct{*int}.
That requires more work in other parts of the compiler; there is a TODO.
Change-Id: I7ff681c20d2c3eb6ad11dd7b3a37b1f3dda23965
Reviewed-on: https://go-review.googlesource.com/7862
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'test/interface')
-rw-r--r-- | test/interface/assertinline.go | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/test/interface/assertinline.go b/test/interface/assertinline.go new file mode 100644 index 0000000000..faa848a18c --- /dev/null +++ b/test/interface/assertinline.go @@ -0,0 +1,53 @@ +// errorcheck -0 -d=typeassert + +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func assertptr(x interface{}) *int { + return x.(*int) // ERROR "type assertion inlined" +} + +func assertptr2(x interface{}) (*int, bool) { + z, ok := x.(*int) // ERROR "type assertion inlined" + return z, ok +} + +func assertfunc(x interface{}) func() { + return x.(func()) // ERROR "type assertion inlined" +} + +func assertfunc2(x interface{}) (func(), bool) { + z, ok := x.(func()) // ERROR "type assertion inlined" + return z, ok +} + +// TODO(rsc): struct{*int} is stored directly in the interface +// and should be possible to fetch back out of the interface, +// but more of the general data movement code needs to +// realize that before we can inline the assertion. + +func assertstruct(x interface{}) struct{ *int } { + return x.(struct{ *int }) // ERROR "type assertion not inlined" +} + +func assertstruct2(x interface{}) (struct{ *int }, bool) { + z, ok := x.(struct{ *int }) // ERROR "type assertion not inlined" + return z, ok +} + +func assertbig(x interface{}) complex128 { + return x.(complex128) // ERROR "type assertion not inlined" +} + +func assertbig2(x interface{}) (complex128, bool) { + z, ok := x.(complex128) // ERROR "type assertion not inlined" + return z, ok +} + +func assertbig2ok(x interface{}) (complex128, bool) { + _, ok := x.(complex128) // ERROR "type assertion [(]ok only[)] inlined" + return 0, ok +} |